mirror of https://github.com/ConsenSys/mythril
parent
df965ea723
commit
bae397512d
@ -0,0 +1,92 @@ |
|||||||
|
from mythril.ether import asm,evm,util |
||||||
|
from mythril.rpc.client import EthJsonRpc |
||||||
|
from ethereum import utils |
||||||
|
import binascii |
||||||
|
import sys |
||||||
|
import os |
||||||
|
import json |
||||||
|
|
||||||
|
|
||||||
|
class Block: |
||||||
|
|
||||||
|
def __init__(self, code_index, start_addr, funcname): |
||||||
|
self.code_index = code_index |
||||||
|
self.funcname = funcname |
||||||
|
self.xrefs = [] |
||||||
|
|
||||||
|
|
||||||
|
def update_length(self, num_instructions): |
||||||
|
self.length = num_instructions |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Disassembly: |
||||||
|
|
||||||
|
def __init__(self, code): |
||||||
|
self.instruction_list = asm.disassemble(util.safe_decode(code)) |
||||||
|
self.blocks = [] |
||||||
|
self.func_to_addr = {} |
||||||
|
self.addr_to_func = [] |
||||||
|
|
||||||
|
# Parse jump table & resolve function names |
||||||
|
|
||||||
|
script_dir = os.path.dirname(os.path.realpath(__file__)) |
||||||
|
signature_file = os.path.join(script_dir, 'signatures.json') |
||||||
|
|
||||||
|
with open(signature_file) as f: |
||||||
|
signatures = json.load(f) |
||||||
|
|
||||||
|
jmptable_indices = asm.find_opcode_sequence(["PUSH4", "EQ"], self.instruction_list) |
||||||
|
|
||||||
|
for i in jmptable_indices: |
||||||
|
func_hash = self.instruction_list[i]['argument'] |
||||||
|
try: |
||||||
|
func_name = signatures[func_hash] |
||||||
|
except KeyError: |
||||||
|
func_name = "UNK_" + func_hash |
||||||
|
|
||||||
|
try: |
||||||
|
offset = self.instruction_list[i+2]['argument'] |
||||||
|
jump_target = self.instruction_list[i]['address'] + int(offset, 16) |
||||||
|
|
||||||
|
self.func_to_addr[func_name] = jump_target |
||||||
|
self.addr_to_func[jump_target] = func_name |
||||||
|
except: |
||||||
|
continue |
||||||
|
|
||||||
|
# Parse instructions into basic blocks |
||||||
|
|
||||||
|
current_block = Block(0, 0, "prologue") |
||||||
|
|
||||||
|
index = 0 |
||||||
|
blocklen = 0 |
||||||
|
|
||||||
|
for instruction in self.instruction_list: |
||||||
|
|
||||||
|
blocklen += 1 |
||||||
|
|
||||||
|
if (instruction['opcode'] == "JUMPDEST"): |
||||||
|
|
||||||
|
try: |
||||||
|
func_name = self.addr_to_func[instruction['address']] |
||||||
|
except IndexError: |
||||||
|
func_name = "UNKNOWN_JUMPDEST" |
||||||
|
|
||||||
|
current_block.update_length(blocklen) |
||||||
|
self.blocks.append(current_block) |
||||||
|
current_block = Block(index, instruction['address'], func_name) |
||||||
|
blocklen = 0 |
||||||
|
|
||||||
|
index += 1 |
||||||
|
|
||||||
|
|
||||||
|
def get_easm(self): |
||||||
|
|
||||||
|
easm = "" |
||||||
|
|
||||||
|
for block in self.blocks: |
||||||
|
easm += str(self.instruction_list[block.code_index]['address']) + " --- " + block.funcname + "---\n" |
||||||
|
|
||||||
|
easm += asm.instruction_list_to_easm(self.instruction_list[block.code_index + 1:block.code_index + block.length]) |
||||||
|
|
||||||
|
return easm |
File diff suppressed because one or more lines are too long
Loading…
Reference in new issue