def org_reg(newname, ea, func): """get the reg_var structure for a renamed register""" for reg in REGS.split(): rv = idaapi.find_regvar(func, ea, ea + 1, reg, "") if rv is not None and rv.user == newname: return rv return None
def remove_regvars(func_addr): func = idaapi.get_func(func_addr) # Store register renaming. addr = func.startEA regvars = set() while addr <= func.endEA: for reg_str in __builtin__.REGISTERS._to_idx.keys(): regvar = idaapi.find_regvar(func, addr, reg_str) if regvar is not None: regvars.add((reg_str, regvar.user, regvar.cmt, regvar.startEA, regvar.endEA)) addr += 1 # Since IDA places two not connected CFGs sometimes in the same # functions (multiple entry basic blocks), we have to go # through all basic blocks also. ida_blocks = list(idaapi.FlowChart(func)) for b in ida_blocks: addr = b.startEA block_end = b.endEA while addr != BADADDR and addr < block_end: for reg_str in __builtin__.REGISTERS._to_idx.keys(): regvar = idaapi.find_regvar(func, addr, reg_str) if regvar is not None: regvars.add((reg_str, regvar.user, regvar.cmt, regvar.startEA, regvar.endEA)) addr = NextHead(addr) # Remove register renaming. for regvar in regvars: idaapi.del_regvar( func, regvar[3], # startEA regvar[4], # endEA regvar[0]) # register string return regvars
def main(): is_selected, sel_start, sel_end = idaapi.read_selection() if not is_selected: logger.error('range must be selected') return -1 sel_end = idc.NextHead(sel_end) buf = ida_bytes.get_bytes(sel_start, sel_end - sel_start) if buf is None: logger.error('failed to fetch instruction bytes') return -1 f = idaapi.get_func(sel_start) if f != idaapi.get_func(sel_end): logger.error('range must be within a single function') return -1 # find mappings from "$localN" to "custom_name" regvars = {} for i in range(0x1000): regvar = idaapi.find_regvar(f, sel_start, '$local%d' % (i)) if regvar is None: continue regvars[regvar.canon] = regvar.user if len(regvars) >= f.regvarqty: break globals_ = {} for i, offset in netnode.Netnode('$ wasm.offsets').get('globals', {}).items(): globals_['$global' + i] = ida_name.get_name(offset) frame = {} if f.frame != idc.BADADDR: names = set([]) for i in range(idc.GetStrucSize(f.frame)): name = idc.GetMemberName(f.frame, i) if not name: continue if name in names: continue frame[i] = name names.add(name) emu = Emulator(buf) emu.run() print(emu.render(ctx={ 'regvars': regvars, 'frame': frame, 'globals': globals_, }))
def getRegistersView(eaCodeBlockStart, eaCodeBlockEnd, func): """ IDAPython broken !!!! regvars only return the first regvar ! regvar_t *regvars; // array of register variables // this array is sorted by: startEA // use ...regvar...() functions to access this array We have to find a workaround ! """ registers = {} if func.regvarqty > 0: regs_text = set() # learn register name of this architecture ea = eaCodeBlockStart while ea < eaCodeBlockEnd: reg0 = idc.GetOpnd(ea, 0) reg1 = idc.GetOpnd(ea, 1) regs_text.add(reg0) regs_text.add(reg1) ea += idc.ItemSize(ea) # for each register name for reg_text in regs_text: # try to get regvar_t # regvar_canon = idaapi.find_regvar(func, eaCodeBlockStart, eaCodeBlockEnd, reg_text, None) regvar_user = idaapi.find_regvar(func, eaCodeBlockStart, eaCodeBlockEnd, None, reg_text) if regvar_user is not None: offset = regvar_user.startEA - eaCodeBlockStart # if offset < 0, it's already treated by an other BB if offset >= 0: try: register_offset = registers[offset] except KeyError: register_offset = [] registers[offset] = register_offset register_offset.append((regvar_user.canon, regvar_user.endEA - eaCodeBlockStart, regvar_user.user)) # check if we have found all modified regvars if ( (len(registers) != func.regvarqty) and not ((eaCodeBlockStart == func.startEA) and (eaCodeBlockEnd == func.endEA)) ): # if we don't find all regvars, search on whole function (some regvars are in other basic blocks) for (regvar_offset, regvar_info) in getRegistersView(func.startEA, func.endEA, func).iteritems(): registers[regvar_offset] = regvar_info return registers
def _getregvars(self, ea): """ Return all the regvar mappings as a dict """ func = idaapi.get_func(ea) regvars = {} #XXX: Broken in idapython #mapping = {rv.user: rv.canon for rv in func.regvars} #Check if each regvar exists and add it to the dict regs = ['eax', 'ebx', 'ecx', 'edx', 'esi', 'edi', 'esp', 'ebp'] for r in regs: rv = idaapi.find_regvar(func, ea, r) if not rv: continue regvars[rv.user] = rv.canon return regvars
out += method_name else: out += "%x" % methno # Method parameters if func_method.nparams == 0: print out + "()" else: print out + "(" out = "" maxp = min(func_method.nparams, 32) start_reg = func_method.reg_total - func_method.reg_params if func_method.access_flags & Dex.ACCESS_FLAGS["static"] == 0: start_reg += 1 for i in range(0, maxp): ptype = dex.get_type_string(func_method.proto_params[i]) out = " %s " % dex.get_full_type_name(ptype) regbuf = "v%u" % start_reg start_reg += 1 r = idaapi.find_regvar(f, f.start_ea, regbuf) if r is None: out += regbuf if Dex.is_wide_type(ptype): out += ':' regbuf = "v%u" % start_reg start_reg += 1 else: out += r.user out += ')' if i + 1 == maxp else ',' print out
out += method_name else: out += "%x" % methno # Method parameters if func_method.nparams == 0: print(out + "()") else: print(out + "(") out = "" maxp = min(func_method.nparams, 32) start_reg = func_method.reg_total - func_method.reg_params if func_method.access_flags & Dex.ACCESS_FLAGS["static"] == 0: start_reg += 1 for i in range(0, maxp): ptype = dex.get_type_string(func_start_ea, func_method.proto_params[i]) out = " %s " % dex.get_full_type_name(ptype) regbuf = "v%u" % start_reg start_reg += 1 r = idaapi.find_regvar(f, f.start_ea, regbuf) if r is None: out += regbuf if Dex.is_wide_type(ptype): out += ':' regbuf = "v%u" % start_reg start_reg += 1 else: out += r.user out += ')' if i + 1 == maxp else ',' print(out)