Skip to content

Commit

Permalink
Fix issues with statespace on solc 0.8.26 (#1863)
Browse files Browse the repository at this point in the history
* Fix issues with statespace on solc 0.8.26

* Sort the import
  • Loading branch information
norhh authored Aug 29, 2024
1 parent ea60b14 commit 8201bfd
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 41 deletions.
46 changes: 22 additions & 24 deletions mythril/analysis/callgraph.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
graphs."""

import re
from typing import Dict, List

from jinja2 import Environment, PackageLoader, select_autoescape
from z3 import Z3Exception
Expand Down Expand Up @@ -125,63 +126,60 @@
}


def extract_nodes(statespace):
def extract_nodes(statespace) -> List[Dict]:
"""
Extract nodes from the given statespace and create a list of node dictionaries
with visual attributes for graph representation.
:param statespace:
:param color_map:
:return:
:param statespace: The statespace object containing nodes and states information.
:return: A list of dictionaries representing each node with its attributes.
"""
nodes = []
color_map = {}
for node_key in statespace.nodes:
node = statespace.nodes[node_key]
for node_key, node in statespace.nodes.items():
instructions = [state.get_current_instruction() for state in node.states]
code_split = []

for instruction in instructions:
if instruction["opcode"].startswith("PUSH"):
code_line = "%d %s %s" % (
instruction["address"],
instruction["opcode"],
instruction["argument"],
)
address = instruction["address"]
opcode = instruction["opcode"]
if opcode.startswith("PUSH"):
code_line = f"{address} {opcode} {instruction.get('argument', '')}"
elif (
instruction["opcode"].startswith("JUMPDEST")
opcode.startswith("JUMPDEST")
and NodeFlags.FUNC_ENTRY in node.flags
and instruction["address"] == node.start_addr
and address == node.start_addr
):
code_line = node.function_name
else:
code_line = "%d %s" % (instruction["address"], instruction["opcode"])
code_line = f"{address} {opcode}"

code_line = re.sub(
"([0-9a-f]{8})[0-9a-f]+", lambda m: m.group(1) + "(...)", code_line
)
code_line = re.sub(r"([0-9a-f]{8})[0-9a-f]+", r"\1(...)", code_line)
code_split.append(code_line)

truncated_code = (
"\n".join(code_split)
if (len(code_split) < 7)
if len(code_split) < 7
else "\n".join(code_split[:6]) + "\n(click to expand +)"
)

if node.get_cfg_dict()["contract_name"] not in color_map.keys():
contract_name = node.get_cfg_dict()["contract_name"]
if contract_name not in color_map:
color = default_colors[len(color_map) % len(default_colors)]
color_map[node.get_cfg_dict()["contract_name"]] = color
color_map[contract_name] = color

nodes.append(
{
"id": str(node_key),
"color": color_map.get(
node.get_cfg_dict()["contract_name"], default_colors[0]
),
"color": color_map.get(contract_name, default_colors[0]),
"size": 150,
"fullLabel": "\n".join(code_split),
"label": truncated_code,
"truncLabel": truncated_code,
"isExpanded": False,
}
)

return nodes


Expand Down
38 changes: 21 additions & 17 deletions mythril/laser/ethereum/cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,25 +59,29 @@ def __init__(

def get_cfg_dict(self) -> Dict:
"""
Generate a configuration dictionary for the current state of the contract.
:return:
:return: A dictionary containing the contract's configuration details.
"""
code = ""
for state in self.states:
instruction = state.get_current_instruction()

code += str(instruction["address"]) + " " + instruction["opcode"]
if instruction["opcode"].startswith("PUSH"):
code += " " + "".join(str(instruction["argument"]))

code += "\\n"

return dict(
contract_name=self.contract_name,
start_addr=self.start_addr,
function_name=self.function_name,
code=code,
)
code_lines = [
f"{instruction['address']} {instruction['opcode']}"
+ (
f" {instruction['argument']}"
if instruction["opcode"].startswith("PUSH")
and "argument" in instruction
else ""
)
for state in self.states
for instruction in [state.get_current_instruction()]
]
code = "\\n".join(code_lines)

return {
"contract_name": self.contract_name,
"start_addr": self.start_addr,
"function_name": self.function_name,
"code": code,
}


class Edge:
Expand Down

0 comments on commit 8201bfd

Please sign in to comment.