def sanitize_graph_head(ircfg, head): """ In multiple algorithm, the @head of the ircfg may not have predecessors. The function transform the @ircfg in order to ensure this property @ircfg: IRCFG instance @head: the location of the graph's head """ if not ircfg.predecessors(head): return original_edges = ircfg.predecessors(head) sub_head = ircfg.loc_db.add_location() # Duplicate graph, replacing references to head by sub_head replaced_expr = { ExprLoc(head, ircfg.IRDst.size): ExprLoc(sub_head, ircfg.IRDst.size) } ircfg.simplify(lambda expr: expr.replace_expr(replaced_expr)) # Duplicate head block ircfg.add_irblock(IRBlock(ircfg.loc_db, sub_head, list(ircfg.blocks[head]))) # Remove original head block ircfg.del_node(head) for src in original_edges: ircfg.add_edge(src, sub_head) # Create new head, jumping to sub_head assignblk = AssignBlock({ircfg.IRDst: ExprLoc(sub_head, ircfg.IRDst.size)}) new_irblock = IRBlock(ircfg.loc_db, head, [assignblk]) ircfg.add_irblock(new_irblock)
def recoverAlgorithm(self): if self.normalIRCFG is None: self.getNormalIRCFG() newLocDB = LocationDB() size = BinaryAnalysis.disasmEngine.attrib newIRA = BinaryAnalysis.iraType(newLocDB) newIRCFG = newIRA.new_ircfg() numLockey = 0 head = LocKey(numLockey) todo = [(self.address, head, {}, None)] numLockey += 1 while todo: nextTarget, lockey, state, preBlock = todo.pop() nextTarget, state = self.symbolicExecution(self.normalIRA, self.normalIRCFG, nextTarget, state) if isinstance(nextTarget, ExprCond): newLockey1 = LocKey(numLockey) newLockey2 = LocKey(numLockey + 1) ir_dst = state[newIRCFG.IRDst] new_cond = ExprCond(ir_dst.cond, ExprLoc(newLockey1, size), ExprLoc(newLockey2, size)) state[newIRCFG.IRDst] = new_cond numLockey += 2 newIRBlock = self.addIRBlock(newIRCFG, state, lockey) state[newIRCFG.IRDst] = ir_dst todo.append((nextTarget.src1, newLockey1, state, newIRBlock)) todo.append((nextTarget.src2, newLockey2, state, newIRBlock)) else: self.addIRBlock(newIRCFG, state, lockey) return newLocDB, newIRCFG
def asm_ast_to_expr(self, arg, loc_db): """Convert AST to expressions Note: - code inspired by miasm/arch/mips32/arch.py""" if isinstance(arg, AstId): if isinstance(arg.name, ExprId): return arg.name if isinstance(arg.name, str) and arg.name in gpr_names: return None # GV: why? loc_key = loc_db.get_or_create_name_location(arg.name.encode()) return ExprLoc(loc_key, 32) elif isinstance(arg, AstMem): addr = self.asm_ast_to_expr(arg.ptr, loc_db) if addr is None: return None return ExprMem(addr, 32) elif isinstance(arg, AstInt): return ExprInt(arg.value, 32) elif isinstance(arg, AstOp): args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args] if None in args: return None return ExprOp(arg.op, *args) # Raise an exception if the argument was not processed message = "mep_arg.asm_ast_to_expr(): don't know what \ to do with a '%s' instance." % type(arg) raise Exception(message)
def dstflow2label(self, loc_db): if self.name in ["J", 'JAL']: expr = self.args[0].arg addr = (self.offset & (0xFFFFFFFF ^ ((1 << 28) - 1))) + expr loc_key = loc_db.get_or_create_offset_location(addr) self.args[0] = ExprLoc(loc_key, expr.size) return ndx = self.get_dst_num() expr = self.args[ndx] if not isinstance(expr, ExprInt): return addr = expr.arg + self.offset loc_key = loc_db.get_or_create_offset_location(addr) self.args[ndx] = ExprLoc(loc_key, expr.size)
def dstflow2label(self, loc_db): """Set the label for the current destination. Note: it is used at disassembly""" loc_arg = self.get_dst_num() expr = self.args[loc_arg] if not expr.is_int(): return addr = ((int(expr)*4)+self.offset + 8) & 0xffffffff loc_key = loc_db.get_or_create_offset_location(addr) self.args[0] = ExprLoc(loc_key, expr.size)
def dstflow2label(self, loc_db): """Set the label for the current destination. Note: it is used at disassembly""" loc_arg = self.get_dst_num() expr = self.args[loc_arg] if not expr.is_int(): return # mega hack we add 2 because imm16 is 2 bytes addr = (int(expr) + self.offset + 2) & int(expr.mask) loc_key = loc_db.get_or_create_offset_location(addr) self.args[loc_arg] = ExprLoc(loc_key, expr.size)
def canonize_to_exprloc(self, expr): """ If expr is ExprInt, return ExprLoc with corresponding loc_key Else, return expr @expr: Expr instance """ if expr.is_int(): loc_key = self.get_or_create_offset_location(int(expr)) ret = ExprLoc(loc_key, expr.size) return ret return expr
def detect_func_name(cur_bloc, loc_db, *args, **kwargs): for line in cur_bloc.lines: for i in range(len(line.args)): arg = line.args[i] if isinstance(arg, ExprMem): ptr = arg.ptr if isinstance(ptr, ExprOp): if isinstance(ptr.args[0], ExprId) and ('IP' in str( ptr.args[0])) and isinstance(ptr.args[1], ExprInt): ip = line.offset + line.l offset = ptr.args[1].arg loc_key = loc_db.get_offset_location(ip + offset) if loc_key is not None: line.args[i] = ExprLoc(loc_key, arg.size) names = loc_db.get_location_names(cur_bloc.loc_key) if len(names) == 0: new_name = list( loc_db.get_location_names(loc_key)) if len(new_name) != 0: new_name = '_' + new_name[0].decode() try: loc_db.add_location_name( cur_bloc.loc_key, new_name) except: pass elif isinstance(ptr, ExprInt) and line.name == 'JMP': offset = ptr.arg loc_key = loc_db.get_offset_location(offset) if loc_key is not None: line.args[i] = ExprLoc(loc_key, arg.size) names = loc_db.get_location_names(cur_bloc.loc_key) if len(names) == 0: new_name = list(loc_db.get_location_names(loc_key)) if len(new_name) != 0: new_name = '_' + new_name[0].decode() try: loc_db.add_location_name( cur_bloc.loc_key, new_name) except: pass
def casp(ir, instr, arg1, arg2, arg3): # XXX TODO: memory barrier e = [] if arg1.size == 32: regs = gpregs32_expr else: regs = gpregs64_expr index1 = regs.index(arg1) index2 = regs.index(arg2) # TODO endianness comp_value = ExprCompose(regs[index1], regs[index1 + 1]) new_value = ExprCompose(regs[index2], regs[index2 + 1]) assert arg3.is_op('preinc') ptr = arg3.args[0] data = ExprMem(ptr, comp_value.size) loc_store = ExprLoc(ir.loc_db.add_location(), ir.IRDst.size) loc_do = ExprLoc(ir.loc_db.add_location(), ir.IRDst.size) loc_next = ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size) e.append( ExprAssign( ir.IRDst, ExprCond(ExprOp("FLAG_EQ_CMP", data, comp_value), loc_do, loc_store))) e_store = [] e_store.append(ExprAssign(data, new_value)) e_store.append(ExprAssign(ir.IRDst, loc_do)) blk_store = IRBlock(loc_store.loc_key, [AssignBlock(e_store, instr)]) e_do = [] e_do.append(ExprAssign(regs[index1], data[:data.size // 2])) e_do.append(ExprAssign(regs[index1 + 1], data[data.size // 2:])) e_do.append(ExprAssign(ir.IRDst, loc_next)) blk_do = IRBlock(loc_do.loc_key, [AssignBlock(e_do, instr)]) return e, [blk_store, blk_do]
def assignblk_to_irbloc(self, instr, assignblk): """ Ensure IRDst is always set in the head @assignblk of the @instr @instr: an instruction instance @assignblk: Assignblk instance """ new_assignblk = dict(assignblk) if self.ir_arch.IRDst not in assignblk: offset = instr.offset + instr.l loc_key = self.ir_arch.loc_db.get_or_create_offset_location(offset) dst = ExprLoc(loc_key, self.ir_arch.IRDst.size) new_assignblk[self.ir_arch.IRDst] = dst irs = [AssignBlock(new_assignblk, instr)] return IRBlock(self.ir_arch.get_loc_key_for_instr(instr), irs)
def call_effects(self, ad, instr): call_assignblk = AssignBlock([ ExprAssign( self.ret_reg, ExprOp( 'call_func_ret', ad, self.arch.regs.R0, self.arch.regs.R1, self.arch.regs.R2, self.arch.regs.R3, )), ExprAssign(self.sp, ExprOp('call_func_stack', ad, self.sp)), ], instr) cond = instr.additional_info.cond if cond == 14: # COND_ALWAYS: return [call_assignblk], [] # Call is a conditional instruction cond = tab_cond[cond] loc_next = self.get_next_loc_key(instr) loc_next_expr = ExprLoc(loc_next, 32) loc_do = self.loc_db.add_location() loc_do_expr = ExprLoc(loc_do, 32) dst_cond = ExprCond(cond, loc_do_expr, loc_next_expr) call_assignblks = [ call_assignblk, AssignBlock([ExprAssign(self.IRDst, loc_next_expr)], instr), ] e_do = IRBlock(loc_do, call_assignblks) assignblks_out = [ AssignBlock([ExprAssign(self.IRDst, dst_cond)], instr) ] return assignblks_out, [e_do]
def dstflow2label(self, loc_db): """Set the label for the current destination. Note: it is used at disassembly""" if self.name == 'JMP': loc_arg = 0 elif self.name in ["JE", "JNE", "JGE", "JL"]: loc_arg = 2 else: return expr = self.args[loc_arg] if not expr.is_int(): return addr = int(expr) & int(expr.mask) loc_key = loc_db.get_or_create_offset_location(addr) self.args[loc_arg] = ExprLoc(loc_key, expr.size)
def stop_exec(jitter): global max_scount success_loc = ExprLoc(dse.loc_db.get_offset_location(success_ptr), 64) for path, model in dse.new_solutions.items(): scount = path.count(success_loc) if scount > max_scount: candidate = bytearray(0x20) for i in range(0x20): bb = model.eval( dse.z3_trans.from_expr(dse.memory_to_expr(flag_ptr + i))) candidate[i] = bb.as_long() if type( bb) == z3.z3.BitVecNumRef else current[i] ustr = candidate.decode('UTF-16') print(f'\tHit success bbl {scount} times with: "{ustr[:scount]}"') todo.append(bytes(candidate)) # Put it back in the todo list max_scount = scount return False # This ends execution
def asm_ast_to_expr(self, arg, loc_db): if isinstance(arg, AstId): if isinstance(arg.name, ExprId): return arg.name if arg.name in gpregs.str: return None loc_key = loc_db.get_or_create_name_location(arg.name.encode()) return ExprLoc(loc_key, 32) if isinstance(arg, AstOp): args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args] if None in args: return None return ExprOp(arg.op, *args) if isinstance(arg, AstInt): return ExprInt(arg.value, 32) if isinstance(arg, AstMem): ptr = self.asm_ast_to_expr(arg.ptr, loc_db) if ptr is None: return None return ExprMem(ptr, arg.size) return None
def emul(self, lifter, ctx=None, step=False): # Init ctx_init = {} if ctx is not None: ctx_init.update(ctx) solver = z3.Solver() symb_exec = SymbolicExecutionEngine(lifter, ctx_init) history = self.history[::-1] history_size = len(history) translator = Translator.to_language("z3") size = self._ircfg.IRDst.size for hist_nb, loc_key in enumerate(history, 1): if hist_nb == history_size and loc_key == self.initial_state.loc_key: line_nb = self.initial_state.line_nb else: line_nb = None irb = self.irblock_slice(self._ircfg.blocks[loc_key], line_nb) # Emul the block and get back destination dst = symb_exec.eval_updt_irblock(irb, step=step) # Add constraint if hist_nb < history_size: next_loc_key = history[hist_nb] expected = symb_exec.eval_expr(ExprLoc(next_loc_key, size)) solver.add( self._gen_path_constraints(translator, dst, expected)) # Save the solver self._solver = solver # Return only inputs values (others could be wrongs) return { element: symb_exec.eval_expr(element) for element in self.inputs }
def analyse_function(): # Get settings settings = TypePropagationForm() ret = settings.Execute() if not ret: return end = None if settings.cScope.value == 0: addr = settings.functionAddr.value else: addr = settings.startAddr.value if settings.cScope.value == 2: end = settings.endAddr # Init machine = guess_machine(addr=addr) mn, dis_engine, lifter_model_call = machine.mn, machine.dis_engine, machine.lifter_model_call bs = bin_stream_ida() loc_db = LocationDB() mdis = dis_engine(bs, loc_db=loc_db, dont_dis_nulstart_bloc=True) if end is not None: mdis.dont_dis = [end] lifter_model_callCallStackFixer = get_lifter_model_call_call_fixer( lifter_model_call) lifter = lifter_model_callCallStackFixer(loc_db) asmcfg = mdis.dis_multiblock(addr) # Generate IR ircfg = lifter.new_ircfg_from_asmcfg(asmcfg) cst_propag_link = {} if settings.cUnalias.value: init_infos = {lifter.sp: lifter.arch.regs.regs_init[lifter.sp]} cst_propag_link = propagate_cst_expr(lifter, ircfg, addr, init_infos) types_mngr = get_types_mngr(settings.headerFile.value, settings.arch.value) mychandler = MyCHandler(types_mngr, {}) infos_types = {} infos_types_raw = [] if settings.cTypeFile.value: infos_types_raw = open(settings.typeFile.value).read().split('\n') else: infos_types_raw = settings.strTypesInfo.value.split('\n') for line in infos_types_raw: if not line: continue expr_str, ctype_str = line.split(':') expr_str, ctype_str = expr_str.strip(), ctype_str.strip() expr = str_to_expr(expr_str) ast = mychandler.types_mngr.types_ast.parse_c_type(ctype_str) ctype = mychandler.types_mngr.types_ast.ast_parse_declaration( ast.ext[0]) objc = types_mngr.get_objc(ctype) print('=' * 20) print(expr, objc) infos_types[expr] = set([objc]) # Add fake head lbl_real_start = loc_db.get_offset_location(addr) lbl_head = loc_db.get_or_create_name_location("start") first_block = asmcfg.loc_key_to_block(lbl_real_start) assignblk_head = AssignBlock([ ExprAssign(lifter.IRDst, ExprLoc(lbl_real_start, lifter.IRDst.size)), ExprAssign(lifter.sp, lifter.arch.regs.regs_init[lifter.sp]) ], first_block.lines[0]) irb_head = IRBlock(loc_db, lbl_head, [assignblk_head]) ircfg.blocks[lbl_head] = irb_head ircfg.add_uniq_edge(lbl_head, lbl_real_start) state = TypePropagationEngine.StateEngine(infos_types) states = {lbl_head: state} todo = set([lbl_head]) done = set() while todo: lbl = todo.pop() state = states[lbl] if (lbl, state) in done: continue done.add((lbl, state)) if lbl not in ircfg.blocks: continue symbexec_engine = TypePropagationEngine(lifter, types_mngr, state) symbexec_engine.run_block_at(ircfg, lbl) symbexec_engine.del_mem_above_stack(lifter.sp) sons = ircfg.successors(lbl) for son in sons: add_state(ircfg, todo, states, son, symbexec_engine.get_state()) for lbl, state in viewitems(states): if lbl not in ircfg.blocks: continue symbexec_engine = CTypeEngineFixer(lifter, types_mngr, state, cst_propag_link) symbexec_engine.run_block_at(ircfg, lbl) symbexec_engine.del_mem_above_stack(lifter.sp)
def myfunc(cpu): """Execute the function according to cpu and vmmngr states @cpu: JitCpu instance """ # Get virtual memory handler vmmngr = cpu.vmmngr # Get execution engine (EmulatedSymbExec instance) exec_engine = self.symbexec # Refresh CPU values according to @cpu instance exec_engine.update_engine_from_cpu() # Get initial loc_key cur_loc_key = asmblock.loc_key # Update PC helper update_pc = lambda value: setattr(cpu, self.ir_arch.pc.name, value) while True: # Retrieve the expected irblock for instr, irblocks in zip(asmblock.lines, irblocks_list): for index, irblock in enumerate(irblocks): if irblock.loc_key == cur_loc_key: break else: continue break else: raise RuntimeError("Unable to find the block for %r" % cur_loc_key) instr_attrib, irblocks_attributes = codegen.get_attributes( instr, irblocks, self.log_mn, self.log_regs ) irblock_attributes = irblocks_attributes[index] # Do IRBlock new_irblock = self.ir_arch.irbloc_fix_regs_for_mode( irblock, self.ir_arch.attrib ) if index == 0: # Pre code if instr_attrib.log_mn: print("%.8X %s" % ( instr_attrib.instr.offset, instr_attrib.instr.to_string(loc_db) )) # Exec IRBlock instr = instr_attrib.instr for index, assignblk in enumerate(irblock): attributes = irblock_attributes[index] # Eval current instruction (in IR) exec_engine.eval_updt_assignblk(assignblk) # Check memory access / write exception # TODO: insert a check between memory reads and writes if attributes.mem_read or attributes.mem_write: # Restricted exception flag = ~csts.EXCEPT_CODE_AUTOMOD & csts.EXCEPT_DO_NOT_UPDATE_PC if (vmmngr.get_exception() & flag != 0): # Do not update registers update_pc(instr.offset) return instr.offset # Update registers values exec_engine.update_cpu_from_engine() # Check post assignblk exception flags if attributes.set_exception: # Restricted exception if cpu.get_exception() > csts.EXCEPT_NUM_UPDT_EIP: # Update PC update_pc(instr.offset) return instr.offset dst = exec_engine.eval_expr(self.ir_arch.IRDst) if dst.is_int(): loc_key = loc_db.get_or_create_offset_location(int(dst)) dst = ExprLoc(loc_key, dst.size) assert dst.is_loc() loc_key = dst.loc_key offset = loc_db.get_location_offset(loc_key) if offset is None: # Avoid checks on generated label cur_loc_key = loc_key continue if instr_attrib.log_regs: update_pc(offset) cpu.dump_gpregs_with_attrib(self.ir_arch.attrib) # Post-instr checks if instr_attrib.mem_read | instr_attrib.mem_write: vmmngr.check_memory_breakpoint() vmmngr.check_invalid_code_blocs() if vmmngr.get_exception(): update_pc(offset) return offset if instr_attrib.set_exception: if cpu.get_exception(): update_pc(offset) return offset if instr_attrib.mem_read | instr_attrib.mem_write: vmmngr.reset_memory_access() # Manage resulting address if (loc_key in local_loc_keys and offset > instr.offset): # Forward local jump # Note: a backward local jump has to be promoted to extern, # for max_exec_per_call support cur_loc_key = loc_key continue # Delay slot if has_delayslot: delay_slot_set = exec_engine.eval_expr(codegen.delay_slot_set) if delay_slot_set.is_int() and int(delay_slot_set) != 0: return int(exec_engine.eval_expr(codegen.delay_slot_dst)) # Extern of asmblock, must have an offset assert offset is not None return offset
from __future__ import print_function from miasm.expression.parser import str_to_expr from miasm.expression.expression import ExprInt, ExprId, ExprSlice, ExprMem, \ ExprCond, ExprCompose, ExprOp, ExprAssign, ExprLoc, LocKey for expr_test in [ExprInt(0x12, 32), ExprId('test', 32), ExprLoc(LocKey(12), 32), ExprSlice(ExprInt(0x10, 32), 0, 8), ExprMem(ExprInt(0x10, 32), 32), ExprCond(ExprInt(0x10, 32), ExprInt(0x11, 32), ExprInt(0x12, 32)), ExprCompose(ExprInt(0x10, 16), ExprInt(0x11, 8), ExprInt(0x12, 8)), ExprInt(0x11, 8) + ExprInt(0x12, 8), ExprAssign(ExprId('EAX', 32), ExprInt(0x12, 32)), ]: print('Test: %s' % expr_test) assert str_to_expr(repr(expr_test)) == expr_test
def blr(arg1): PC = arg1 ir.IRDst = arg1 LR = ExprLoc(ir.get_next_loc_key(instr), 64)
def b_lt(arg1): cond = cond2expr['LT'] dst = arg1 if cond else ExprLoc(ir.get_next_loc_key(instr), 64) PC = dst ir.IRDst = dst
def tbnz(arg1, arg2, arg3): bitmask = ExprInt(1, arg1.size) << arg2 dst = arg3 if arg1 & bitmask else ExprLoc(ir.get_next_loc_key(instr), 64) PC = dst ir.IRDst = dst
def cbnz(arg1, arg2): dst = arg2 if arg1 else ExprLoc(ir.get_next_loc_key(instr), 64) PC = dst ir.IRDst = dst
def cbz(arg1, arg2): dst = ExprLoc(ir.get_next_loc_key(instr), 64) if arg1 else arg2 PC = dst ir.IRDst = dst
"test_s64_greater", "test_s64_greater_or_equal", "test_s64_lesser", "test_s64_lesser_or_equal", "test_u64_greater", "test_u64_greater_or_equal", "test_u64_lesser", "test_u64_lesser_or_equal", ]: head = mdis.loc_db.get_name_location(func_name) addr = mdis.loc_db.get_location_offset(head) asmcfg = mdis.dis_multiblock(addr) ircfg = lifter.new_ircfg_from_asmcfg(asmcfg) # Add fake head dct = {lifter.IRDst: ExprLoc(head, lifter.IRDst.size)} dct.update(args_x86_32) dct.update(args_x86_64) dct.update(args_arm) dct.update(args_aarch64) dct.update(args_mips32) assignblk = AssignBlock(dct, None) irblock = IRBlock(loc_db, fake_head, [assignblk]) # print(irblock) ircfg.add_irblock(irblock) open("ircfg_%s.dot" % func_name, "w").write(ircfg.dot()) simplifier = IRCFGSimplifierSSA(lifter)
def parse_loc_key(t): assert len(t) == 2 loc_key, size = LocKey(t[0]), t[1] return ExprLoc(loc_key, size)
irs.append(AssignBlock(exprs)) irbl = IRBlock(loc_db, label, irs) return irbl ############# Tests ############# IRA = IRATest(loc_db) ########## G1 ########## # Input G1 = IRA.new_ircfg() G1_IRB0 = gen_irblock(LBL0, [[ ExprAssign(B, C), ExprAssign(IRDst, ExprLoc(LBL1, 32)), ]]) G1_IRB1 = gen_irblock(LBL1, [[ ExprAssign(IRDst, ExprLoc(LBL2, 32)), ]]) G1_IRB2 = gen_irblock(LBL2, [[ ExprAssign(A, B), ExprAssign(IRDst, C), ]]) for irb in [G1_IRB0, G1_IRB1, G1_IRB2]: G1.add_irblock(irb) # Result
for assignblk in xx: for dst in assignblk: if str(dst).startswith("r"): out.add(dst) """ out.add(r) return out IRA = IRATest(loc_db) END = ExprId("END", IRDst.size) G0_IRA = IRA.new_ircfg() G0_IRB0 = gen_irblock( LBL0, [[ExprAssign(a, CST1)], [ExprAssign(IRDst, ExprLoc(LBL1, 32))]]) G0_IRB1 = gen_irblock( LBL1, [[ExprAssign(a, a + CST1)], [ExprAssign(IRDst, ExprCond(x, ExprLoc(LBL1, 32), ExprLoc(LBL2, 32)))]]) G0_IRB2 = gen_irblock(LBL2, [[ExprAssign(r, a)], [ExprAssign(IRDst, END)]]) for irb in [G0_IRB0, G0_IRB1, G0_IRB2]: G0_IRA.add_irblock(irb) G1_IRA = IRA.new_ircfg() G1_IRB0 = gen_irblock( LBL0, [[ExprAssign(a, CST1)], [ExprAssign(IRDst, ExprCond(x, ExprLoc(LBL1, 32), ExprLoc(LBL2, 32)))]])
machine.mn, 32, ''' init: PUSH argv PUSH argc PUSH ret_addr ''', loc_db ) argc_lbl = loc_db.get_name_location('argc') argv_lbl = loc_db.get_name_location('argv') ret_addr_lbl = loc_db.get_name_location('ret_addr') init_lbl = loc_db.get_name_location('init') argc_loc = ExprLoc(argc_lbl, 32) argv_loc = ExprLoc(argv_lbl, 32) ret_addr_loc = ExprLoc(ret_addr_lbl, 32) ret_addr = ExprId("ret_addr", ret_addr_loc.size) fix_args = { argc_loc: ExprId("argc", argc_loc.size), argv_loc: ExprId("argv", argv_loc.size), ret_addr_loc: ret_addr, } block = asmcfg.loc_key_to_block(init_lbl)
for assignblk in xx: for dst in assignblk: if str(dst).startswith("r"): out.add(dst) """ out.add(r) return out IRA = IRATest(loc_db) END = ExprId("END", IRDst.size) G0_IRA = IRA.new_ircfg() G0_IRB0 = gen_irblock(LBL0, [ [ExprAssign(a, CST1)], [ExprAssign(IRDst, ExprLoc(LBL1, 32))] ]) G0_IRB1 = gen_irblock(LBL1, [ [ExprAssign(a, a+CST1)], [ExprAssign(IRDst, ExprCond(x, ExprLoc(LBL1, 32), ExprLoc(LBL2, 32) ) )] ]) G0_IRB2 = gen_irblock(LBL2, [ [ExprAssign(r, a)], [ExprAssign(IRDst, END)] ]) for irb in [G0_IRB0, G0_IRB1, G0_IRB2]:
DNA = DependencyNode(LBL2, A, 0) DNB = DependencyNode(LBL1, B, 1) DNC = DependencyNode(LBL1, C, 0) DNB2 = DependencyNode(LBL1, B, 1) DNC2 = DependencyNode(LBL1, C, 0) DNB3 = DependencyNode(LBL1, B, 1) DNC3 = DependencyNode(LBL1, C, 0) IRA = IRATest(loc_db) IRDst = IRA.IRDst END = ExprId("END", IRDst.size) # graph 1 G1_IRA = IRA.new_ircfg() G1_IRB0 = gen_irblock(LBL0, [[ExprAssign(C, CST1), ExprAssign(IRDst, ExprLoc(LBL1, 32))]]) G1_IRB1 = gen_irblock(LBL1, [[ExprAssign(B, C), ExprAssign(IRDst, ExprLoc(LBL2, 32))]]) G1_IRB2 = gen_irblock(LBL2, [[ExprAssign(A, B), ExprAssign(IRDst, END)]]) for irb in [G1_IRB0, G1_IRB1, G1_IRB2]: G1_IRA.add_irblock(irb) # graph 2 G2_IRA = IRA.new_ircfg() G2_IRB0 = gen_irblock(LBL0, [[ExprAssign(C, CST1), ExprAssign(IRDst, ExprLoc(LBL1, 32))]]) G2_IRB1 = gen_irblock(LBL1, [[ExprAssign(B, CST2), ExprAssign(IRDst, ExprLoc(LBL2, 32))]]) G2_IRB2 = gen_irblock(LBL2, [[ExprAssign(A, B + C), ExprAssign(IRDst, END)]]) for irb in [G2_IRB0, G2_IRB1, G2_IRB2]: