@@ -58,7 +58,7 @@ class Contract(object):
58
58
Main Input Class
59
59
"""
60
60
61
- def __init__ (self , bytecode = None , address = None , static_analysis = True , dynamic_analysis = True , network = "mainnet" ):
61
+ def __init__ (self , bytecode = None , address = None , static_analysis = True , dynamic_analysis = True , network = "mainnet" , simplify_show_unreachable = False , simplify_show_asm = False ):
62
62
if not bytecode and not address :
63
63
raise Exception ("missing bytecode or contract address" )
64
64
@@ -70,6 +70,8 @@ def __init__(self, bytecode=None, address=None, static_analysis=True, dynamic_an
70
70
self .bytecode , self .auxdata = Contract .get_auxdata (bytecode )
71
71
self ._evmcode = EvmCode (contract = self ,
72
72
static_analysis = static_analysis , dynamic_analysis = dynamic_analysis ) # do not reference this directly, always use self.disassembly()
73
+
74
+ self ._simplify_show_unreachable , self ._simplify_show_asm = simplify_show_unreachable , simplify_show_asm
73
75
74
76
@property
75
77
def disassembly (self ):
@@ -79,7 +81,10 @@ def disassembly(self):
79
81
80
82
@property
81
83
def simplified (self ):
82
- return evmsimplify .simplify (self .disassembly )
84
+ return evmsimplify .simplify (self .disassembly ,
85
+ show_pseudocode = True ,
86
+ show_asm = self ._simplify_show_asm ,
87
+ show_unreachable = self ._simplify_show_unreachable )
83
88
84
89
@property
85
90
def methods (self ):
@@ -530,7 +535,8 @@ def analyze_dynamic(self):
530
535
for addr , instr in self .jumptable .items (): # all JUMP/I s
531
536
# get symbolic stack
532
537
for node , state in self .symbolic_state_at .get (addr ,[]): # todo investigate keyerror
533
- dst = z3 .simplify (state .mstate .stack [- 1 ]).as_long () if z3 .is_expr (state .mstate .stack [- 1 ]) else state .mstate .stack [- 1 ]
538
+ dst = get_z3_value (state .mstate .stack [- 1 ])
539
+ #dst = z3.simplify().as_long() if z3.is_expr(state.mstate.stack[-1]) else get_z3_value(state.mstate.stack[-1])
534
540
if instr .jumpto and instr .jumpto != dst : # todo: needs to be a set
535
541
logger .warning ("Symbolic JUMP destination different: %s != %s" % (instr .jumpto , dst ))
536
542
instr .jumpto = dst
@@ -588,6 +594,10 @@ def main():
588
594
help = "disable static analysis" )
589
595
parser .add_option ("-s" , "--simplify" , dest = "simplify" , default = False , action = "store_true" ,
590
596
help = "simplify disassembly to human readable code" )
597
+ parser .add_option ("-x" , "--simplify-show-asm" , dest = "simplify_show_asm" , default = False , action = "store_true" ,
598
+ help = "simplify: show or hide asm annotations in simplified code" )
599
+ parser .add_option ("-y" , "--simplify-show-unreachable" , dest = "simplify_show_unreachable" , default = False , action = "store_true" ,
600
+ help = "simplify: show or hide annotations for unreachable instructions in simplified code" )
591
601
parser .add_option ("-n" , "--network" , dest = "network" , default = "mainnet" ,
592
602
help = "network for address lookup (default: mainnet, ropsten, rinkeby, kovan" )
593
603
@@ -609,25 +619,32 @@ def main():
609
619
if options .function_signature_lookup and not utils .signatures .ethereum_input_decoder :
610
620
logger .warning ("ethereum_input_decoder package not installed. function signature lookup not available.(pip install ethereum-input-decoder)" )
611
621
622
+ if options .simplify_show_asm or options .simplify_show_unreachable :
623
+ options .simplify = True
624
+
612
625
# get bytecode from stdin, or arg:file or arg:bytcode
613
626
614
627
if options .address :
615
628
contract = Contract (address = options .address ,
616
629
network = options .network ,
617
- static_analysis = options .static_analysis , dynamic_analysis = options .dynamic_analysis )
630
+ static_analysis = options .static_analysis , dynamic_analysis = options .dynamic_analysis ,
631
+ simplify_show_unreachable = options .simplify_show_unreachable , simplify_show_asm = options .simplify_show_asm )
618
632
elif not args :
619
633
contract = Contract (bytecode = sys .stdin .read ().strip (),
620
634
network = options .network ,
621
- static_analysis = options .static_analysis , dynamic_analysis = options .dynamic_analysis )
635
+ static_analysis = options .static_analysis , dynamic_analysis = options .dynamic_analysis ,
636
+ simplify_show_unreachable = options .simplify_show_unreachable , simplify_show_asm = options .simplify_show_asm )
622
637
else :
623
638
if os .path .isfile (args [0 ]):
624
639
contract = Contract (bytecode = open (args [0 ], 'r' ).read (),
625
640
network = options .network ,
626
- static_analysis = options .static_analysis , dynamic_analysis = options .dynamic_analysis )
641
+ static_analysis = options .static_analysis , dynamic_analysis = options .dynamic_analysis ,
642
+ simplify_show_unreachable = options .simplify_show_unreachable , simplify_show_asm = options .simplify_show_asm )
627
643
else :
628
644
contract = Contract (bytecode = args [0 ],
629
645
network = options .network ,
630
- static_analysis = options .static_analysis , dynamic_analysis = options .dynamic_analysis )
646
+ static_analysis = options .static_analysis , dynamic_analysis = options .dynamic_analysis ,
647
+ simplify_show_unreachable = options .simplify_show_unreachable , simplify_show_asm = options .simplify_show_asm )
631
648
632
649
#logger.debug(INSTRUCTIONS_BY_OPCODE)
633
650
0 commit comments