def run(self): self.decompiler.graph.transform_ir() self.decompiler.function = function_t(self.decompiler.graph) self.decompiler.ssa_tagger = ssa.ssa_tagger_t(self.decompiler.function) return
def steps(self): """ this is a generator function which yeilds the last decompilation step which was performed. the caller can then observe the function flow. """ self.flow = flow.flow_t(self.ea, self.disasm) yield self.set_step(step_nothing_done()) self.flow.find_control_flow() yield self.set_step(step_basic_blocks()) self.flow.transform_ir() yield self.set_step(step_ir_form()) self.ssa_tagger = ssa.ssa_tagger_t(self.flow) self.ssa_tagger.tag_registers() yield self.set_step(step_ssa_form_registers()) self.propagator = stack_propagator_t(self.flow) self.propagator.propagate() yield self.set_step(step_stack_propagated()) self.ssa_tagger.tag_derefs() self.restored_locations = self.ssa_tagger.restored_locations() self.spoiled_locations = self.ssa_tagger.spoiled_locations() self.adjust_returns() yield self.set_step(step_ssa_form_derefs()) self.register_arguments_renamer = register_arguments_renamer_t(self) self.register_arguments_renamer.rename() self.stack_arguments_renamer = stack_arguments_renamer_t(self) self.stack_arguments_renamer.rename() self.ssa_tagger.tag_arguments() self.ssa_tagger.verify() yield self.set_step(step_arguments_renamed()) # todo: properly find function call arguments. #conv = callconv.systemv_x64_abi() #self.solve_call_parameters(t, conv) #yield self.set_step(step_calls()) # prune unused registers self.pruner = unused_registers_pruner_t(self.flow) self.pruner.prune() # prune assignments for restored locations self.pruner = restored_locations_pruner_t(self) self.pruner.prune() self.ssa_tagger.verify() yield self.set_step(step_pruned()) self.stack_variables_renamer = stack_variables_renamer_t(self.flow) self.stack_variables_renamer.rename() self.ssa_tagger.tag_variables() yield self.set_step(step_stack_renamed()) # propagate assignments to local variables. self.propagator = registers_propagator_t(self.flow) self.propagator.propagate() self.ssa_tagger.verify() yield self.set_step(step_propagated()) # todo: rename local variables #yield self.set_step(step_locals_renamed()) # todo: remove unused definitions #yield self.set_step(step_pruned()) # get us out of ssa form. self.ssa_tagger.remove_ssa_form() yield self.set_step(step_ssa_removed()) # after everything is done, we can combine blocks! self.flow.combine_blocks() yield self.set_step(step_combined()) yield self.set_step(step_decompiled()) return
def steps(self): """ this is a generator function which yeilds the last decompilation step which was performed. the caller can then observe the function flow. """ self.flow = flow.flow_t(self.ea, self.disasm) self.current_step = STEP_NONE yield self.current_step self.flow.find_control_flow() self.current_step = STEP_BASIC_BLOCKS_FOUND yield self.current_step self.flow.transform_ir() self.current_step = STEP_IR_DONE yield self.current_step # tag all registers so that each instance of a register can be uniquely identified. t = ssa.ssa_tagger_t(self.flow) t.tag() self.current_step = STEP_SSA_DONE yield self.current_step #~ yield STEP_CALLS_DONE #~ yield STEP_PROPAGATED #~ yield STEP_PRUNED #~ yield STEP_COMBINED #~ # After registers are tagged, we can replace their uses by their definitions. this #~ # takes care of eliminating any instances of 'esp' which clears the way for #~ # determining stack variables correctly. #~ s = simplifier(f, COLLECT_ALL) #~ s.propagate_all(PROPAGATE_STACK_LOCATIONS) #~ # remove special flags (eflags) definitions that are not used, just for clarity #~ s = simplifier(f, COLLECT_FLAGS) #~ s.remove_unused_definitions() #~ s = simplifier(f, COLLECT_REGISTERS) #~ s.remove_unused_definitions() #~ # rename stack variables to differentiate them from other dereferences. #~ r = renamer(f, RENAME_STACK_LOCATIONS) #~ r.wrap_variables() #~ # collect function arguments that are passed on the stack #~ s = simplifier(f, COLLECT_ALL) #~ s.collect_argument_calls(conv) #~ # This propagates special flags. #~ s = simplifier(f, COLLECT_ALL) #~ s.propagate_all(PROPAGATE_REGISTERS | PROPAGATE_FLAGS) #~ # At this point we must take care of removing increments and decrements #~ # that are in their own statements and "glue" them to an adjacent use of #~ # that location. #~ s = simplifier(f, COLLECT_ALL) #~ s.glue_increments() #~ # re-propagate after gluing pre/post increments #~ s = simplifier(f, COLLECT_ALL) #~ s.propagate_all(PROPAGATE_REGISTERS | PROPAGATE_FLAGS) #~ s = simplifier(f, COLLECT_ALL) #~ s.propagate_all(PROPAGATE_ANY | PROPAGATE_SINGLE_USES) #~ # eliminate restored registers. during this pass, the simplifier also collects #~ # stack variables because registers may be preserved on the stack. #~ s = simplifier(f, COLLECT_REGISTERS | COLLECT_VARIABLES) #~ s.process_restores() #~ # ONLY after processing restores can we do this; any variable which is assigned #~ # and never used again is removed as dead code. #~ s = simplifier(f, COLLECT_REGISTERS) #~ s.remove_unused_definitions() #~ # rename registers to pretty names. #~ r = renamer(f, RENAME_REGISTERS) #~ r.fct_arguments = t.fct_arguments #~ r.wrap_variables() #~ # after everything is propagated, we can combine blocks! #~ f.combine_blocks() #~ print '----2----' #~ print print_function(arch, f) #~ print '----2----' return
def steps(self): """ this is a generator function which yeilds the last decompilation step which was performed. the caller can then observe the function flow. """ self.flow = flow.flow_t(self.ea, self.disasm) yield self.set_step(step_nothing_done()) self.flow.find_control_flow() yield self.set_step(step_basic_blocks()) self.flow.transform_ir() yield self.set_step(step_ir_form()) self.ssa_tagger = ssa.ssa_tagger_t(self.flow) self.ssa_tagger.tag_registers() yield self.set_step(step_ssa_form_registers()) self.propagator = stack_propagator_t(self.flow) self.propagator.propagate() yield self.set_step(step_stack_propagated()) self.ssa_tagger.tag_derefs() self.restored_locations = self.ssa_tagger.restored_locations() self.spoiled_locations = self.ssa_tagger.spoiled_locations() self.adjust_returns() yield self.set_step(step_ssa_form_derefs()) # properly find function call arguments. self.solve_call_parameters() yield self.set_step(step_calls()) self.register_arguments_renamer = register_arguments_renamer_t(self) self.register_arguments_renamer.rename() self.stack_arguments_renamer = stack_arguments_renamer_t(self) self.stack_arguments_renamer.rename() self.ssa_tagger.tag_arguments() self.ssa_tagger.verify() yield self.set_step(step_arguments_renamed()) # prune unused registers self.pruner = unused_registers_pruner_t(self.flow) self.pruner.prune() # prune assignments for restored locations self.pruner = restored_locations_pruner_t(self) self.pruner.prune() # remove unused return registers self.pruner = unused_call_returns_pruner_t(self.flow) self.pruner.prune() self.ssa_tagger.verify() yield self.set_step(step_pruned()) self.stack_variables_renamer = stack_variables_renamer_t(self.flow) self.stack_variables_renamer.rename() self.ssa_tagger.tag_variables() yield self.set_step(step_stack_renamed()) # propagate assignments to local variables. self.propagator = registers_propagator_t(self.flow) self.propagator.propagate() self.propagator = call_arguments_propagator_t(self.flow) self.propagator.propagate() self.ssa_tagger.verify() yield self.set_step(step_propagated()) # todo: rename local variables #yield self.set_step(step_locals_renamed()) # todo: remove unused definitions #yield self.set_step(step_pruned()) # get us out of ssa form. self.ssa_tagger.remove_ssa_form() yield self.set_step(step_ssa_removed()) # after everything is done, we can combine blocks! self.flow.combine_blocks() yield self.set_step(step_combined()) yield self.set_step(step_decompiled()) return