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