def init_parser(cls): super(GccRTTIParser, cls).init_parser() cls.type_vmi = ( ida_name.get_name_ea(idaapi.BADADDR, cls.VMI) + cls.OFFSET_FROM_TYPEINF_SYM ) cls.type_si = ( ida_name.get_name_ea(idaapi.BADADDR, cls.SI) + cls.OFFSET_FROM_TYPEINF_SYM ) cls.type_none = ( ida_name.get_name_ea(idaapi.BADADDR, cls.NONE) + cls.OFFSET_FROM_TYPEINF_SYM ) cls.types = (cls.type_vmi, cls.type_si, cls.type_none)
def set_name(address, new_name, local=None): assert type(new_name) == str is_hidden = idc.is_tail(idc.get_full_flags(address)) if is_hidden: print "0x%x: can't rename byte as '%s' because the address is not visible" % ( address, new_name) return False flags = idc.SN_CHECK | idc.SN_NOWARN if local: flags = flags | idc.SN_LOCAL ret = ida_name.set_name(address, new_name, flags) if ret is False: current_name_location = ida_name.get_name_ea(0, new_name) if current_name_location != idc.BADADDR: print "0x%x: can't rename byte as '%s' because the name is already used at 0x%x" % ( address, new_name, current_name_location) else: print "0x%x: Error renaming byte as '%s' for unknown reasons" % ( address, new_name) return ret
def handle_dll_calls(self): dll_call_count = ida_bytes.get_dword(self.E_info_entry_ea + self.dll_call_count_offset) dll_call_lib_names_ea = ida_bytes.get_dword( self.E_info_entry_ea + self.dll_call_lib_names_offset) dll_call_func_names_ea = ida_bytes.get_dword( self.E_info_entry_ea + self.dll_call_func_names_offset) self.dll_calls = Dll_calls(dll_call_lib_names_ea, dll_call_func_names_ea, dll_call_count) ida_auto.auto_wait() ea = ida_name.get_name_ea(idaapi.BADADDR, "j__krnl_MCallDllCmd") code_fref_eas = [] fref_ea = ida_xref.get_first_fcref_to(ea) while fref_ea != idaapi.BADADDR: code_fref_eas.append(fref_ea) fref_ea = ida_xref.get_next_cref_to(ea, fref_ea) for ref_ea in code_fref_eas: #get prev mov instruction prev_ins_ea = idaapi.get_item_head(ref_ea - 1) ins = ida_lines.generate_disasm_line(prev_ins_ea, ida_lines.GENDSM_REMOVE_TAGS) if (ins.startswith("mov eax,")): index = ida_bytes.get_dword(prev_ins_ea + 1) cmt = self.dll_calls[index] ida_bytes.set_cmt(ref_ea, cmt, False)
def apply_like(path): with open('{}.log'.format(path), 'w') as log_fp: with open(path) as fp: like = json.load(fp) for item in like.values(): if item[0] != 'subprogram': continue _, return_type, name, parameters, has_varargs = item address = get_name_ea(BADADDR, str(name)) if address == BADADDR: log_fp.write('Subprogram not found: {}\n'.format(name)) log_fp.flush() continue decl = resolve_type(like, return_type, log_fp) + ' ' + name + '(' first = True for parameter_type, parameter_name in parameters: if first: first = False else: decl += ', ' if not _is_uname(str(parameter_name)): parameter_name = '_' + parameter_name decl += resolve_type(like, parameter_type, log_fp) if _is_uname(str(parameter_name)): decl += ' ' + parameter_name if has_varargs: if not first: decl += ', ' decl += '...' decl += ')' log_fp.write('{}: ...\n'.format(decl)) log_fp.flush() ret = apply_type(address, parse_decl(str(decl), 0)) log_fp.write('... ret={}\n'.format(ret)) log_fp.flush()
def get_next_unused_label(label): i = 2 while True: if ida_name.get_name_ea(0, label) == 0xffffffffffffffff: return label label = "{}_{}".format(label, i) i += 1
def target_to_ea(target): # convert target to address address = ida_idaapi.BADADDR if type(target) is str: address = ida_name.get_name_ea(ida_idaapi.BADADDR, target) elif type(target) is int: address = target return address
def name_to_addr(s): """ 返回任意名称的地址:function, label, global... """ addr = ida_name.get_name_ea(ida_idaapi.BADADDR, s) if addr == ida_idaapi.BADADDR: print("[Error] name_to_addr: Failed to find '%s' symbol" % s) return None return addr
def allocate_rwx(size): # this is the explicit way to create an Appcall callable # see also: `Appcall.proto` VirtualAlloc = ida_idd.Appcall.typedobj("int __stdcall VirtualAlloc( int lpAddress, DWORD dwSize, DWORD flAllocationType, DWORD flProtect);") VirtualAlloc.ea = ida_name.get_name_ea(0, "kernel32_VirtualAlloc") ptr = VirtualAlloc(c.NULL, int(size), c.MEM_COMMIT, c.PAGE_EXECUTE_READWRITE) if ptr == 0: print("VirtualAlloc failed: 0x%x" % GetLastError()) raise ValueError("VirtualAlloc failed: 0x%x" % GetLastError()) idc.RefreshDebuggerMemory() return ptr
def view_dblclick(self, viewer, point): widget_type = ida_kernwin.get_widget_type(viewer) if not (widget_type == 48 or widget_type == 28): return # Decompiler or Structures window place, x, y = ida_kernwin.get_custom_viewer_place(viewer, False) line = utils.get_curline_striped_from_viewer(viewer) func_cand_name = cpp_utils.find_valid_cppname_in_line(line, x) if func_cand_name is not None: func_cand_ea = ida_name.get_name_ea(BADADDR, func_cand_name) if func_cand_ea is not None and utils.is_func(func_cand_ea): idc.jumpto(func_cand_ea)
def xrefs_to_lib_entry(): tl_api_lib_entry = ida_name.get_name_ea(ida_idaapi.BADADDR, 'tlApiLibEntry') if tl_api_lib_entry == ida_idaapi.BADADDR: return xref = ida_xref.xrefblk_t() xref.first_to(tl_api_lib_entry, ida_xref.XREF_DATA) while True: yield xref.frm if not xref.next_to(): break
def sync_func_folder_cmts(): func_dir: dirtree_t = ida_dirtree.get_std_dirtree( ida_dirtree.DIRTREE_FUNCS) for root, _, files in dirtree_walk(func_dir, "/"): if root == "/" or root == "": continue tag = root.lstrip("/") for file in files: va = ida_name.get_name_ea(ida_idaapi.BADADDR, file) if va == ida_idaapi.BADADDR: continue set_func_folder_cmt(va, tag)
def auto_rename_all(targets, force=False): refs = set() for name in targets: addr = ida_name.get_name_ea(ida_idaapi.BADADDR, name) if not addr: continue for ref in idautils.CodeRefsTo(addr, True): func = ida_funcs.get_func(ref) if func: refs.add(func.start_ea) ca = CallAnalyzer(targets) for addr in refs: auto_rename_single(ca, addr, force=force)
def __init__(self, name_funcs=[]): ida_dbg.DBG_Hooks.__init__(self) # important for ea, func_name in name_funcs: log("Renaming 0x%08x to \"%s\"" % (ea, func_name)) ida_name.set_name(ea, func_name) for func_name, func_proto in [ ("ref4", "int ref4(int *);"), ("ref8", "int ref8(long long int *);"), ]: log("Setting '%s's prototype" % func_name) func_ea = ida_name.get_name_ea(ida_idaapi.BADADDR, func_name) assert (ida_typeinf.apply_cdecl(None, func_ea, func_proto))
def GetEltByName(name): """ Same as :func:`GetElt` but using a name and not an address. :param str name: The name of the element to get. If a "dummy" name (``byte_xxxx``, ...) is provided the database is not consulted. :return: An object representing the element or ``None`` if the name was not found. :rtype: Subclass of :class:`BipBaseElt`. """ ea = ida_name.get_name_ea(idc.BADADDR, name) if ea is None or ea == idc.BADADDR: return None return GetElt(ea)
def find_putchar(base_ea): str_ea = ida_name.get_name_ea(idaapi.BADADDR, "aPanic") if str_ea != idaapi.BADADDR: apanic_ea = list(idautils.XrefsTo(str_ea))[0].frm if apanic_ea == idaapi.BADADDR: return idaapi.BADADDR opnd0 = idc.print_operand(apanic_ea + 8, 0) ins_str = idaapi.ua_mnem(apanic_ea + 8) if ins_str == "BL": func_ea = ida_name.get_name_ea(idaapi.BADADDR, opnd0) ea = func_ea while ea != idaapi.BADADDR: ins_str = idaapi.ua_mnem(ea) if ins_str == "ADD": opnd2 = idc.print_operand(ea, 2) if opnd2 == "#1": ins_ea = ea - 4 opnd0 = idc.print_operand(ins_ea, 0) ins_str = idaapi.ua_mnem(ins_ea) if ins_str == "BL": pc_ea = ida_name.get_name_ea(idaapi.BADADDR, opnd0) print("\t[+] _putchar = 0x%x" % (pc_ea)) ida_name.set_name(pc_ea, "_putchar") return pc_ea ea = ea + 4 return idaapi.BADADDR
def get_by_name(cls, name): """ Class method allowing to get a function from its name. :return: A :class:`BipFunction` with the correct name or None if the function was not found. """ ea = ida_name.get_name_ea(idc.BADADDR, name) if ea is None or ea == idc.BADADDR: return None try: return cls(ea) except ValueError: return None return None
def update_structs(): """Update xrefs to the major EFI tables to be struct offsets.""" structs = { SYSTEM_TABLE_NAME: SYSTEM_TABLE_STRUCT, BOOT_SERVICES_NAME: BOOT_SERVICES_STRUCT, RUNTIME_SERVICES_NAME: RUNTIME_SERVICES_STRUCT } for key in structs: addr = ida_name.get_name_ea(0, key) if addr == ida_idaapi.BADADDR: print "Couldn't find address for " + key else: print "Updating structure references for {} ({})".format( key, structs[key] ) update_struct_offsets(addr, key, structs[key])
def get_name_ea(name, fromaddr=idc.BADADDR): """Get the address of a name. This function returns the linear address associated with the given name. Arguments: name: The name to look up. Options: fromaddr: The referring address. Default is BADADDR. Some addresses have a location-specific name (for example, labels within a function). If fromaddr is not BADADDR, then this function will try to retrieve the address of the name from fromaddr's perspective. If name is not a local name, its address as a global name will be returned. Returns: The address of the name or BADADDR. """ return ida_name.get_name_ea(fromaddr, name)
def view_dblclick(self, viewer, point): widget_type = ida_kernwin.get_widget_type(viewer) if not (widget_type == 48 or widget_type == 28): return # Decompiler or Structures window func_cand_name = None place, x, y = ida_kernwin.get_custom_viewer_place(viewer, False) if place.name() == "structplace_t": # Structure window: structplace = ida_kernwin.place_t_as_structplace_t(place) if structplace is not None: s = ida_struct.get_struc(ida_struct.get_struc_by_idx(structplace.idx)) if s: member = ida_struct.get_member(s, structplace.offset) if member: func_cand_name = ida_struct.get_member_name(member.id) if func_cand_name is None: line = utils.get_curline_striped_from_viewer(viewer) func_cand_name = cpp_utils.find_valid_cppname_in_line(line, x) if func_cand_name is not None: func_cand_ea = ida_name.get_name_ea(BADADDR, func_cand_name) if func_cand_ea is not None and utils.is_func_start(func_cand_ea): idc.jumpto(func_cand_ea)
def find_macho_load(base_ea): pz_ea = ida_name.get_name_ea(idaapi.BADADDR, "aPagezero") if pz_ea != idaapi.BADADDR: if len(list(idautils.XrefsTo(pz_ea))) != 3: return idaapi.BADADDR func1_ea = ida_funcs.get_func(list( idautils.XrefsTo(pz_ea))[0].frm).start_ea func2_ea = ida_funcs.get_func(list( idautils.XrefsTo(pz_ea))[1].frm).start_ea func3_ea = ida_funcs.get_func(list( idautils.XrefsTo(pz_ea))[2].frm).start_ea if func2_ea != func3_ea: return idaapi.BADADDR if func1_ea != func2_ea: print("\t[+] _macho_load = 0x%x" % (func2_ea)) ida_name.set_name(func2_ea, "_macho_load") return func2_ea return idaapi.BADADDR
def __import_name(self, segments, name, addr): addr_components = addr.split(':') name_addr = 0 if len(addr_components) > 1: try: segment_ea = segments[int(addr_components[0])] name_addr = segment_ea + int(addr_components[1]) except KeyError: print('import_name: %s -> segment %s not found' % (name, addr_components[0])) return else: name_addr = int(addr_components[0], 16) #replace <> in name because IDA does not support it name = name.replace('<', '(').replace('>', ')').encode('ascii') #fix situation where name already exists while ida_name.get_name_ea(ida_idaapi.BADADDR, name) != ida_idaapi.BADADDR: name = name + "_" ida_name.set_name(name_addr, name)
Patterns.AddExpr( Patterns.VarBind('len'), Patterns.NumberExpr(Patterns.NumberConcrete(1)) ), Patterns.NumberExpr(Patterns.NumberConcrete(0x1000)) ), Patterns.AnyPattern() ), Patterns.ExprInst( Patterns.CallExpr( Patterns.ObjConcrete(0x{:x}), [Patterns.AnyPattern()] ) ) ], False) )""".format(ida_name.get_name_ea(0, "free_0")) def handle_string_destr(idx, ctx): print '%x' % (idx.ea) var = ctx.get_var('len') var2 = ctx.get_var('ptr') print var off1 = get_var_offset(ctx.fcn, var.idx) off2 = get_var_offset(ctx.fcn, var2.idx) print off1 - off2 if off1 - off2 == 20: print "[+] Found string destructor" varexp = make_var_expr(var2.idx, var2.typ, var2.mba, arg=True) arglist = ida_hexrays.carglist_t() arglist.push_back(varexp)
def resolve_type(like, die_offset, log_fp, alias=None): if die_offset is None: return 'void' type = like.get(str(die_offset)) if type is None: return DEFAULT_TYPE kind = type[0] if kind in ('struct', 'union'): if type[1] is None: if alias is None: struct_name = '{}_{}'.format(kind, hex(die_offset)) else: struct_name = alias else: struct_name = type[1] if (not _is_uname(str(struct_name)) or (get_struc_id(str(struct_name)) == BADADDR and get_name_ea(BADADDR, str(struct_name)) != BADADDR)): struct_name = '_' + struct_name struct_id = get_struc_id(str(struct_name)) if struct_id != BADADDR: if len(type) == 4: type.append(struct_id) return struct_name log_fp.write('{}: ...\n'.format(struct_name)) log_fp.flush() struct_id = add_struc(BADADDR, str(struct_name), kind == 'union') log_fp.write('... id={}\n'.format(hex(struct_id))) log_fp.flush() if struct_id == BADADDR: return DEFAULT_TYPE type.append(struct_id) if kind == 'struct' and type[2] != 0: ret = add_end_member(struct_id, struct_name, type[2], log_fp) have_end_member = ret == 0 else: have_end_member = False for member_type_die_offset, member_name, member_offset in type[3]: if member_name is None: if kind == 'struct': field_n = member_offset else: field_n = sum(1 for _ in StructMembers(struct_id)) member_name = 'field_{:X}'.format(field_n) elif not _is_uname(str(member_name)): member_name = '_' + member_name member_type_str = str(resolve_type( like, member_type_die_offset, log_fp)) member_size = get_type_size(like, member_type_die_offset) if have_end_member and member_offset + member_size == type[2]: del_struc_member(struct_id, type[2] - 1) have_end_member = False log_fp.write('{} {}.{}: ...\n'.format( member_type_str, struct_name, member_name)) log_fp.flush() ret = add_struc_member( struct_id, str(member_name), member_offset, DEFAULT_TYPE_FLAGS, DEFAULT_TYPE_ID, DEFAULT_TYPE_SIZE, ) log_fp.write('... ret={}\n'.format(ret)) log_fp.flush() if ret == 0: member_id = get_name_ea( BADADDR, '{}.{}'.format(struct_name, member_name)) apply_type(member_id, parse_decl(member_type_str, 0)) return struct_name if kind == 'typedef': return resolve_type(like, type[2], log_fp, type[1]) if kind == 'pointer': return resolve_type(like, type[1], log_fp) + '*' if kind == 'base': if type[1]: return '__int' + str(type[2] * 8) else: return 'unsigned __int' + str(type[2] * 8) if kind in ('const', 'volatile'): return resolve_type(like, type[1], log_fp) if kind == 'array': return '{}[{}]'.format(resolve_type(like, type[1], log_fp), type[2]) return DEFAULT_TYPE
inst2 = idautils.DecodePreviousInstruction(inst.ea) if (inst2 != None) and (inst2.get_canon_mnem() == "mov"): inst3 = idautils.DecodePreviousInstruction(inst2.ea) if (inst3 != None) and (inst3.get_canon_mnem() == "lea"): length = inst.Op2.value data_addr = inst3.Op2.addr return data_addr, length def decrypt_string(data, key): crypt = b64decode(data) plain = "".join(chr(ord(c) ^ ord(k)) for c, k in izip(crypt, cycle(key))) return b64decode(plain) arch = 64 if idaapi.get_inf_structure().is_64bit() else 32 ea = ida_name.get_name_ea(idaapi.BADADDR, "main.decodeString") key_addr = ida_name.get_name_ea(idaapi.BADADDR, "main.encoderKey") key = ida_bytes.get_bytes(ida_bytes.get_dword(key_addr), ida_bytes.get_dword(key_addr + arch / 8)) for xref in idautils.CodeRefsTo(ea, True): inst = idautils.DecodeInstruction(xref) if (inst != None) and (inst.get_canon_mnem() == "call"): data_addr, length = get_params(xref) data = ida_bytes.get_bytes(data_addr, length) decrypted_str = decrypt_string(data, key) print "0x{:08x} -> 0x{:x}[0x{:x}] = \"{}\"".format( xref, data_addr, length, decrypted_str) ida_bytes.set_cmt(xref, decrypted_str, False)