Beispiel #1
0
 def test_push_error(self):
     """
     Tests push error where an instruction tries to push to the stack at the end of a contract.abs
         PUSH ?
     This should not crash.
     """
     c = Contract('64')
     c.parse()
Beispiel #2
0
 def test_single_jumpdest(self):
     """
     Tests the following EVM code decompilation:
         JUMPDEST
     This should not crash.
     """
     c = Contract('5b')
     c.parse()
Beispiel #3
0
 def test_math_simplification(self):
     """
     Tests basic math simplification:
         PUSH 02
         PUSH 02
         PUSH 03
         MUL
         MUL
     """
     c = Contract('6002600260030202')
     c.parse()
     self.assertEqual(c.line_blocks[0].lines[0].args[0].value, 12)
Beispiel #4
0
 def test_dup_swap(self):
     """
     Tests the following EVM code decompilation:
         PUSH 20
         PUSH 30
         DUP2
         SWAP2
         MUL
         ADD
     The output of this code should be 0x620 or 1568.
     """
     c = Contract('6020603081910201')
     c.parse()
     self.assertIn(0x30, map(lambda l: l.value, c.line_blocks[0].lines[-2].args))
     self.assertIn(0x20, map(lambda l: l.value, c.line_blocks[0].lines[-2].args))
     self.assertIn(0x20, map(lambda l: l.value, c.line_blocks[0].lines[-1].args))
Beispiel #5
0
 def test_jump_arg_optimization(self):
     """
     Tests jump arg optimization:
         PUSH 03
         JUMP
         JUMPDEST
         PUSH 02
         PUSH 03
         MLOAD
         PUSH 0c
         JUMPI
         JUMPDEST
         THROW
     The conditional jump should reference func2.
     """
     c = Contract('6003565b6002600351600c575bfe')
     c.parse()
     self.assertEqual(c.line_blocks[1].lines[-2].jump_to, 'func2')
Beispiel #6
0
 def test_function_rollover(self):
     """
     Tests the following EVM code decompilation:
         PUSH 02
         PUSH 03
         JUMPDEST
         PUSH 02
         ADD
         JUMPDEST
         PUSH 04
         MUL
     There should be 2 different jump lines at the end of each block.
     """
     c = Contract('600260035b6002015b600402')
     c.parse()
     self.assertIsInstance(c.line_blocks[0].lines[-1], JumpLine)
     self.assertEqual(c.line_blocks[0].lines[-1].args[0].value, 2)
     self.assertTrue(c.line_blocks[0].lines[-1].args[0].is_variable)
     self.assertIsInstance(c.line_blocks[1].lines[-1], JumpLine)
     self.assertEqual(c.line_blocks[1].lines[-1].args[0].value, 3)
     self.assertTrue(c.line_blocks[1].lines[-1].args[0].is_variable)
Beispiel #7
0
parser = argparse.ArgumentParser()
parser.add_argument('input', help='input hex file to parse')
parser.add_argument('--decompile', action='store_true', help='decompiles the contract into a python-like pseudo-code')
parser.add_argument('--disassemble', action='store_true', help='disassemble contract into simplified op-codes')
parser.add_argument('--no-desc', dest='no_desc', action='store_true', help='omit description')
parser.add_argument('--no-opt', dest='no_opt', action='store_true', help='disable optimizations')
parser.add_argument('--out', type=str, help='outputs to a file; outputs to STDOUT if not specified')
args = parser.parse_args()

with open(args.input, 'r') as contract:
    contract_data = contract.read()
    contract_data = contract_data.replace('0x', '')
    contract_data = contract_data.lower()
    if args.decompile:
        contract = Contract(contract_data)
        blocks = contract.parse()
        output = ''
        for lines in blocks:
            output += str(lines) + '\n'
            for line in lines.lines:
                output += "\t" * lines.indentation_level + '{1}'.format(hex(line.address), str(line)) + '\n'
            output += '\n'
    else:
        blocks = Parser.parse(contract_data, args)
        output = ""
        for block in blocks:
            output += '\n'
            output += '; Procedure ' + hex(block.address) + '\n'
            for operation in block.instructions:
                output += '[{: >8}]'.format(hex(operation.address))
Beispiel #8
0
 def test_neg_numbers(self):
     c = Contract('6023602003')
     c.parse()
Beispiel #9
0
 def test_push_0(self):
     c = Contract('6000600201')
     c.parse()