From b30430252e30fad55e1a80dcb5f9a4b70e408227 Mon Sep 17 00:00:00 2001 From: Joran Honig Date: Mon, 22 Oct 2018 23:22:41 +0200 Subject: [PATCH] Move asm to disassembler + cleanup --- mythril/{ether => disassembler}/asm.py | 66 ++++++++++++-------------- mythril/disassembler/disassembly.py | 3 +- 2 files changed, 32 insertions(+), 37 deletions(-) rename mythril/{ether => disassembler}/asm.py (57%) diff --git a/mythril/ether/asm.py b/mythril/disassembler/asm.py similarity index 57% rename from mythril/ether/asm.py rename to mythril/disassembler/asm.py index 985b2f07..80623061 100644 --- a/mythril/ether/asm.py +++ b/mythril/disassembler/asm.py @@ -1,51 +1,46 @@ import sys import re +from typing import Pattern, Match + from ethereum.opcodes import opcodes from mythril.ether import util -regex_PUSH = re.compile('^PUSH(\d*)$') +regex_PUSH = re.compile("^PUSH(\d*)$") # Additional mnemonic to catch failed assertions - -opcodes[254] = ['ASSERT_FAIL', 0, 0, 0] +opcodes[254] = ["ASSERT_FAIL", 0, 0, 0] def instruction_list_to_easm(instruction_list): - easm = "" + result = "" for instruction in instruction_list: + result += "{} {}".format(instruction["address"], instruction["opcode"]) + if "argument" in instruction: + result += " " + instruction["argument"] + result += "\n" - easm += str(instruction['address']) + " " + instruction['opcode'] - - if 'argument' in instruction: - easm += " " + instruction['argument'] - - easm += "\n" + return result - return easm - -def easm_to_instruction_list(easm): - - regex_CODELINE = re.compile('^([A-Z0-9]+)(?:\s+([0-9a-fA-Fx]+))?$') +def easm_to_instruction_list(evm_assembly): + regex_CODELINE: Pattern[str] = re.compile("^([A-Z0-9]+)(?:\s+([0-9a-fA-Fx]+))?$") instruction_list = [] - codelines = easm.split('\n') + for line in evm_assembly.split("\n"): - for line in codelines: + match: Match[str] = re.search(regex_CODELINE, line) - m = re.search(regex_CODELINE, line) - - if not m: + if not match: # Invalid code line continue - instruction = {'opcode': m.group(1)} + instruction = {"opcode": match.group(1)} - if m.group(2): - instruction['argument'] = m.group(2)[2:] + if match.group(2): + instruction["argument"] = match.group(2)[2:] instruction_list.append(instruction) @@ -70,13 +65,13 @@ def find_opcode_sequence(pattern, instruction_list): for i in range(0, len(instruction_list) - pattern_length + 1): - if instruction_list[i]['opcode'] in pattern[0]: + if instruction_list[i]["opcode"] in pattern[0]: matched = True for j in range(1, len(pattern)): - if not (instruction_list[i + j]['opcode'] in pattern[j]): + if not (instruction_list[i + j]["opcode"] in pattern[j]): matched = False break @@ -99,7 +94,7 @@ def disassemble(bytecode): while addr < length: - instruction = {'address': addr} + instruction = {"address": addr} try: if sys.version_info > (3, 0): @@ -110,21 +105,20 @@ def disassemble(bytecode): except KeyError: # invalid opcode - instruction_list.append({'address': addr, 'opcode': "INVALID"}) + instruction_list.append({"address": addr, "opcode": "INVALID"}) addr += 1 continue - instruction['opcode'] = opcode[0] + instruction["opcode"] = opcode[0] m = re.search(regex_PUSH, opcode[0]) if m: - argument = bytecode[addr+1:addr+1+int(m.group(1))] - instruction['argument'] = "0x" + argument.hex() + argument = bytecode[addr + 1 : addr + 1 + int(m.group(1))] + instruction["argument"] = "0x" + argument.hex() addr += int(m.group(1)) - instruction_list.append(instruction) addr += 1 @@ -139,14 +133,14 @@ def assemble(instruction_list): for instruction in instruction_list: try: - opcode = get_opcode_from_name(instruction['opcode']) + opcode = get_opcode_from_name(instruction["opcode"]) except RuntimeError: - opcode = 0xbb + opcode = 0xBB - bytecode += opcode.to_bytes(1, byteorder='big') + bytecode += opcode.to_bytes(1, byteorder="big") - if 'argument' in instruction: + if "argument" in instruction: - bytecode += util.safe_decode(instruction['argument']) + bytecode += util.safe_decode(instruction["argument"]) return bytecode diff --git a/mythril/disassembler/disassembly.py b/mythril/disassembler/disassembly.py index e28a4d73..7163f241 100644 --- a/mythril/disassembler/disassembly.py +++ b/mythril/disassembler/disassembly.py @@ -1,4 +1,5 @@ -from mythril.ether import asm, util +from mythril.ether import util +from mythril.disassembler import asm from mythril.support.signatures import SignatureDb import logging