def test_callsite_maker(): project = angr.Project(os.path.join('..', '..', 'binaries', 'tests', 'x86_64', 'all'), auto_load_libs=False) manager = ailment.Manager(arch=project.arch) # Generate a CFG cfg = project.analyses.CFG() new_cc_found = True while new_cc_found: new_cc_found = False for func in cfg.kb.functions.itervalues(): if func.calling_convention is None: # determine the calling convention of each function cc_analysis = project.analyses.CallingConvention(func) if cc_analysis.cc is not None: func.calling_convention = cc_analysis.cc new_cc_found = True main_func = cfg.kb.functions['main'] for block in sorted(main_func.blocks, key=lambda x: x.addr): print block.vex.pp() ail_block = ailment.IRSBConverter.convert(block.vex, manager) simp = project.analyses.AILSimplifier(ail_block) csm = project.analyses.AILCallSiteMaker(simp.result_block) if csm.result_block: ail_block = csm.result_block simp = project.analyses.AILSimplifier(ail_block) print simp.result_block
def _analyze(self): # Make sure calling conventions of all functions have been recovered self.project.analyses.CompleteCallingConventions() # initialize the AIL conversion manager self._ail_manager = ailment.Manager(arch=self.project.arch) spt = self._track_stack_pointers() # Convert VEX blocks to AIL blocks and then simplify them self._convert_all() ail_graph = self._simplify_blocks(stack_pointer_tracker=spt) # Recover variables on AIL blocks self._recover_and_link_variables() # it does not change the AIL graph # Make call-sites self._make_callsites(ail_graph, stack_pointer_tracker=spt) # Simplify the entire function self._simplify_function(ail_graph) # Run simplification passes ail_graph = self._run_simplification_passes(ail_graph) self.graph = ail_graph
def _analyze(self): CallingConventionAnalysis.recover_calling_conventions(self.project) # initialize the AIL conversion manager self._ail_manager = ailment.Manager(arch=self.project.arch) spt = self._track_stack_pointers() self._convert_all() self._simplify_blocks(stack_pointer_tracker=spt) self._recover_and_link_variables() # Make call-sites self._make_callsites() # Simplify the entire function self._simplify_function() self._update_graph() ri = self.project.analyses.RegionIdentifier(self.function, graph=self.graph) # pylint:disable=unused-variable
def test_convert_from_pcode_irsb(self): arch = archinfo.arch_from_id('AMD64') manager = ailment.Manager(arch=arch) p = angr.load_shellcode(self.block_bytes, arch, self.block_addr, self.block_addr, engine=angr.engines.UberEnginePcode) irsb = p.factory.block(self.block_addr).vex ablock = ailment.IRSBConverter.convert(irsb, manager) assert ablock # TODO: test if this conversion is valid
def _analyze(self): # Set up the function graph according to configurations self._set_function_graph() # Remove alignment blocks self._remove_alignment_blocks() # if the graph is empty, don't continue if not self._func_graph: return # Make sure calling conventions of all functions have been recovered self._recover_calling_conventions() # initialize the AIL conversion manager self._ail_manager = ailment.Manager(arch=self.project.arch) # Track stack pointers spt = self._track_stack_pointers() # Convert VEX blocks to AIL blocks and then simplify them self._convert_all() ail_graph = self._simplify_blocks(stack_pointer_tracker=spt) # Simplify the entire function for the first time self._simplify_function(ail_graph, unify_variables=False) # clear _blocks_by_addr_and_size so no one can use it again # TODO: Totally remove this dict self._blocks_by_addr_and_size = None # Make call-sites self._make_callsites(ail_graph, stack_pointer_tracker=spt) # Simplify the entire function for the second time # TODO: Simplify until reaching a fixed point instead of calling _simplify_function() twice. self._simplify_function(ail_graph, unify_variables=True) self._simplify_function(ail_graph, unify_variables=True) # Make function arguments arg_list = self._make_argument_list() # Recover variables on AIL blocks variable_kb = self._recover_and_link_variables(ail_graph, arg_list) # Make function prototype self._make_function_prototype(arg_list, variable_kb) # Run simplification passes ail_graph = self._run_simplification_passes(ail_graph) self.graph = ail_graph self.arg_list = arg_list self.variable_kb = variable_kb
def test_convert_from_vex_irsb(): arch = archinfo.arch_from_id('AMD64') manager = ailment.Manager(arch=arch) irsb = pyvex.IRSB(block_bytes, block_addr, arch, opt_level=0) ablock = ailment.IRSBConverter.convert(irsb, manager) print(str(ablock))
def test_convert_from_irsb(): arch = archinfo.arch_from_id('AMD64') manager = ailment.Manager(arch=arch) block_bytes = bytes.fromhex( "554889E54883EC40897DCC488975C048C745F89508400048C745F0B6064000488B45C04883C008488B00BEA70840004889C7E883FEFFFF" ) irsb = pyvex.IRSB(block_bytes, 0x4006c6, arch, opt_level=0) ablock = ailment.IRSBConverter.convert(irsb, manager) print(str(ablock))
def _analyze(self): CallingConventionAnalysis.recover_calling_conventions(self.project) # initialize the AIL conversion manager self._ail_manager = ailment.Manager(arch=self.project.arch) self._convert_all() self._recover_and_link_variables() self._simplify_all() self._update_graph() ri = self.project.analyses.RegionIdentifier(self.function, graph=self.graph) # pylint:disable=unused-variable
def test_block_simplifier(): arch = archinfo.arch_from_id('AMD64') manager = ailment.Manager(arch=arch) block_bytes = bytes.fromhex("554889E54883EC40897DCC488975C048C745F89508400048C745F0B6064000488B45C04883C008488B00BEA70840004889C7E883FEFFFF") irsb = pyvex.IRSB(block_bytes, 0x4006c6, arch, opt_level=0) ablock = ailment.IRSBConverter.convert(irsb, manager) # we need a project... project = angr.Project(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..', 'binaries', 'tests', 'x86_64', 'all'), auto_load_libs=False) simp = project.analyses.AILBlockSimplifier(ablock)
def test_convert_from_pcode_irsb(): arch = archinfo.arch_from_id('AMD64') manager = ailment.Manager(arch=arch) p = angr.load_shellcode(block_bytes, arch, block_addr, block_addr, engine=angr.engines.UberEnginePcode) irsb = p.factory.block(block_addr).vex ablock = ailment.IRSBConverter.convert(irsb, manager) print(str(ablock))
def _test_loop_variant_common(code): def banner(s): print(s + '\n' + '='*40) banner('Input Assembly') print('\n'.join(l.strip() for l in code.splitlines())) print('') p = angr.load_shellcode(code, 'AMD64') p.analyses.CFGFast(normalize=True) f = p.kb.functions[0] banner('Raw AIL Nodes') nodes = sorted(list(f.nodes), key=lambda n: n.addr) am = ailment.Manager(arch=p.arch) for n in nodes: b = p.factory.block(n.addr, n.size) ab = ailment.IRSBConverter.convert(b.vex, am) print(ab) print('') banner('Optimized AIL Nodes') a = p.analyses.Clinic(f) nodes = sorted(list(a.graph.nodes), key=lambda n: n.addr) assert len(nodes) == 3 for n in nodes: print(n) print('') banner('Decompilation') d = p.analyses.Decompiler(f) print(d.codegen.text) print('') # cond_node = nodes[1] # cond_stmt = None # for stmt in cond_node.statements: # if type(stmt) is ailment.statement.ConditionalJump: # cond_stmt = stmt # break # assert(cond_stmt is not None) # print('Condition:' + str(cond_stmt)) # print(cond_proc.claripy_ast_from_ail_condition(cond_stmt.condition)) cond_proc = ConditionProcessor() ri = p.analyses.RegionIdentifier(f, graph=a.graph, cond_proc=cond_proc, kb=p.kb) rs = p.analyses.RecursiveStructurer(ri.region, cond_proc=cond_proc, kb=p.kb, func=f) snodes = rs.result.nodes assert len(snodes) == 3 assert isinstance(snodes[1], angr.analyses.decompiler.structurer_nodes.LoopNode) banner('Condition') print(str(snodes[1].condition)) return snodes[1].condition
def test_simplifier(): arch = archinfo.arch_from_id('AMD64') manager = ailment.Manager(arch=arch) block_bytes = "55 48 89 E5 48 83 EC 40 89 7D CC 48 89 75 C0 48 C7 45 F8 95 08 40 00 48 C7 45 F0" \ "B6 06 40 00 48 8B 45 C0 48 83 C0 08 48 8B 00 BE A7 08 40 00 48 89 C7 E8 83 FE FF" \ "FF".replace(" ", "").decode("hex") irsb = pyvex.IRSB(block_bytes, 0x4006c6, arch, opt_level=0) ablock = ailment.IRSBConverter.convert(irsb, manager) # we need a project... project = angr.Project(os.path.join('..', '..', 'binaries', 'tests', 'x86_64', 'all'), auto_load_libs=False) simp = project.analyses.AILSimplifier(ablock)
def _analyze(self): # Set up the function graph according to configurations self._set_function_graph() # Make sure calling conventions of all functions have been recovered self._recover_calling_conventions() # initialize the AIL conversion manager self._ail_manager = ailment.Manager(arch=self.project.arch) # Track stack pointers spt = self._track_stack_pointers() # Convert VEX blocks to AIL blocks and then simplify them self._convert_all() ail_graph = self._simplify_blocks(stack_pointer_tracker=spt) # Simplify the entire function for the first time self._simplify_function(ail_graph) # Recover variables on AIL blocks self._recover_and_link_variables(ail_graph) # clear _blocks_by_addr_and_size so no one can use it again # TODO: Totally remove this dict self._blocks_by_addr_and_size = None # Make call-sites self._make_callsites(ail_graph, stack_pointer_tracker=spt) # Simplify the entire function for the second time self._simplify_function(ail_graph) # Run simplification passes ail_graph = self._run_simplification_passes(ail_graph) self.graph = ail_graph
def _analyze(self): CallingConventionAnalysis.recover_calling_conventions(self.project) # initialize the AIL conversion manager self._ail_manager = ailment.Manager(arch=self.project.arch) spt = self._track_stack_pointers() self._convert_all() self._simplify_blocks(stack_pointer_tracker=spt) self._recover_and_link_variables() # Make call-sites self._make_callsites(stack_pointer_tracker=spt) # Simplify the entire function self._simplify_function() # Run simplification passes self._run_simplification_passes()
def _analyze(self): # Set up the function graph according to configurations self._update_progress(0., text="Setting up function graph") self._set_function_graph() # Remove alignment blocks self._update_progress(5., text="Removing alignment blocks") self._remove_alignment_blocks() # if the graph is empty, don't continue if not self._func_graph: return # Make sure calling conventions of all functions have been recovered self._update_progress(10., text="Recovering calling conventions") self._recover_calling_conventions() # initialize the AIL conversion manager self._ail_manager = ailment.Manager(arch=self.project.arch) # Track stack pointers self._update_progress(15., text="Tracking stack pointers") spt = self._track_stack_pointers() # Convert VEX blocks to AIL blocks and then simplify them self._update_progress(20., text="Converting VEX to AIL") self._convert_all() ail_graph = self._make_ailgraph() # Fix "fake" indirect jumps and calls self._update_progress(25., text="Analyzing simple indirect jumps") ail_graph = self._replace_single_target_indirect_transitions(ail_graph) # Make returns self._update_progress(30., text="Making return sites") if self.function.prototype is None or not isinstance(self.function.prototype.returnty, SimTypeBottom): ail_graph = self._make_returns(ail_graph) # Simplify blocks # we never remove dead memory definitions before making callsites. otherwise stack arguments may go missing # before they are recognized as stack arguments. self._update_progress(35., text="Simplifying blocks 1") ail_graph = self._simplify_blocks(ail_graph, stack_pointer_tracker=spt, remove_dead_memdefs=False) # Run simplification passes self._update_progress(40., text="Running simplifications 1") ail_graph = self._run_simplification_passes(ail_graph, stage=OptimizationPassStage.AFTER_SINGLE_BLOCK_SIMPLIFICATION) # Simplify the entire function for the first time self._update_progress(45., text="Simplifying function 1") self._simplify_function(ail_graph, remove_dead_memdefs=False, unify_variables=False) # clear _blocks_by_addr_and_size so no one can use it again # TODO: Totally remove this dict self._blocks_by_addr_and_size = None # Make call-sites self._update_progress(50., text="Making callsites") _, stackarg_offsets = self._make_callsites(ail_graph, stack_pointer_tracker=spt) # Simplify the entire function for the second time self._update_progress(55., text="Simplifying function 2") self._simplify_function(ail_graph, remove_dead_memdefs=self._remove_dead_memdefs, stack_arg_offsets=stackarg_offsets, unify_variables=True) # After global optimization, there might be more chances for peephole optimizations. # Simplify blocks for the second time self._update_progress(60., text="Simplifying blocks 2") ail_graph = self._simplify_blocks(ail_graph, remove_dead_memdefs=self._remove_dead_memdefs, stack_pointer_tracker=spt) # Simplify the entire function for the third time self._update_progress(65., text="Simplifying function 3") self._simplify_function(ail_graph, remove_dead_memdefs=self._remove_dead_memdefs, stack_arg_offsets=stackarg_offsets, unify_variables=True) # Make function arguments self._update_progress(70., text="Making argument list") arg_list = self._make_argument_list() # Run simplification passes self._update_progress(75., text="Running simplifications 2") ail_graph = self._run_simplification_passes(ail_graph, stage=OptimizationPassStage.AFTER_GLOBAL_SIMPLIFICATION) # Recover variables on AIL blocks self._update_progress(80., text="Recovering variables") variable_kb = self._recover_and_link_variables(ail_graph, arg_list) # Make function prototype self._update_progress(85., text="Making function prototype") self._make_function_prototype(arg_list, variable_kb) # Run simplification passes self._update_progress(90., text="Running simplifications 3") ail_graph = self._run_simplification_passes(ail_graph, stage=OptimizationPassStage.AFTER_VARIABLE_RECOVERY) self.graph = ail_graph self.arg_list = arg_list self.variable_kb = variable_kb
def _analyze(self): # Set up the function graph according to configurations self._set_function_graph() # Remove alignment blocks self._remove_alignment_blocks() # if the graph is empty, don't continue if not self._func_graph: return # Make sure calling conventions of all functions have been recovered self._recover_calling_conventions() # initialize the AIL conversion manager self._ail_manager = ailment.Manager(arch=self.project.arch) # Track stack pointers spt = self._track_stack_pointers() # Convert VEX blocks to AIL blocks and then simplify them self._convert_all() ail_graph = self._make_ailgraph() # Fix "fake" indirect jumps and calls ail_graph = self._replace_single_target_indirect_transitions(ail_graph) # Make returns if self.function.prototype is None or not isinstance(self.function.prototype.returnty, SimTypeBottom): ail_graph = self._make_returns(ail_graph) # Simplify blocks ail_graph = self._simplify_blocks(ail_graph, stack_pointer_tracker=spt) # Run simplification passes ail_graph = self._run_simplification_passes(ail_graph, stage=OptimizationPassStage.AFTER_SINGLE_BLOCK_SIMPLIFICATION) # Simplify the entire function for the first time self._simplify_function(ail_graph, unify_variables=False) # clear _blocks_by_addr_and_size so no one can use it again # TODO: Totally remove this dict self._blocks_by_addr_and_size = None # Make call-sites self._make_callsites(ail_graph, stack_pointer_tracker=spt) # Simplify the entire function for the second time self._simplify_function(ail_graph, unify_variables=True) # Make function arguments arg_list = self._make_argument_list() # Recover variables on AIL blocks variable_kb = self._recover_and_link_variables(ail_graph, arg_list) # Make function prototype self._make_function_prototype(arg_list, variable_kb) # Run simplification passes ail_graph = self._run_simplification_passes(ail_graph, stage=OptimizationPassStage.AFTER_GLOBAL_SIMPLIFICATION) self.graph = ail_graph self.arg_list = arg_list self.variable_kb = variable_kb
def test_convert_from_vex_irsb(self): arch = archinfo.arch_from_id('AMD64') manager = ailment.Manager(arch=arch) irsb = pyvex.IRSB(self.block_bytes, self.block_addr, arch, opt_level=0) ablock = ailment.IRSBConverter.convert(irsb, manager) assert ablock # TODO: test if this conversion is valid