def find_main_task(base_ea): du_ea = ida_search.find_text(base_ea, 1, 1, "debug-uarts", ida_search.SEARCH_DOWN) if du_ea != ida_idaapi.BADADDR: for xref in idautils.XrefsTo(du_ea): func = idaapi.get_func(xref.frm) mt_ea = 0 if not func: mt_ea = ida_search.find_binary(xref.frm, base_ea, prologues[0], 16, ida_search.SEARCH_UP) if mt_ea == ida_idaapi.BADADDR: mt_ea = ida_search.find_binary(xref.frm, base_ea, "FF ?? ?? D1", 16, ida_search.SEARCH_UP) else: mt_ea = func.start_ea print("\t[+] _main_task = 0x%x" % (mt_ea)) idc.set_name(mt_ea, "_main_task", idc.SN_CHECK) return mt_ea print("\t[-] _main_task = not found") return ida_idaapi.BADADDR
def find_do_go(base_ea): str_ea = idc.get_name_ea_simple("aCebilefciladrm") if str_ea != ida_idaapi.BADADDR: for xref in idautils.XrefsTo(str_ea): # IDA messes up this function, so I find it this way: func = idaapi.get_func(xref.frm) dg_ea = 0 if func != none: dg_ea = ida_search.find_binary(xref.frm, func.start_ea, prologues[0], 16, ida_search.SEARCH_UP) if dg_ea == ida_idaapi.BADADDR: dg_ea = ida_search.find_binary(xref.frm, func.start_ea, "FF ?? ?? D1", 16, ida_search.SEARCH_UP) else: dg_ea = ida_search.find_binary(xref.frm, base_ea, "FF ?? ?? D1", 16, ida_search.SEARCH_UP) ida_funcs.add_func(dg_ea) print("\t[+] _do_go = 0x%x" % (dg_ea)) idc.set_name(dg_ea, "_do_go", idc.SN_CHECK) return dg_ea print("\t[-] _do_go = not found") return ida_idaapi.BADADDR
def process_strings(segm): # If you jump to the bottom of the file and search upwards for this hex, you'll get the string section start string_addr = find_probable_string_start(segm) if string_addr == BADADDR: print( "[-] Failed to find string information. Not much info can be pulled." ) return BADADDR, ida_search.find_binary(0x0, segm.end_ea, "41 70 70 6C 65 20 49", 16, ida_search.SEARCH_DOWN) strend = ida_search.find_binary(string_addr, segm.end_ea, "41 70 70 6C 65 20 49", 16, ida_search.SEARCH_DOWN) # 'Apple, I' ea = string_addr if strend == BADADDR: strend = string_addr + 0xFF # Best we can do here is just tell ida to make every single byte, individually, a string; it figures it out. for i in range(ea, strend): idc.create_strlit(i, BADADDR) idc.create_strlit(strend, BADADDR) # Create the "Apple, Inc." String return string_addr, strend
def find_hex_string(start_ea, stop_ea, hex_string): curr_ea = ida_search.find_binary(start_ea, stop_ea, hex_string, 16, ida_search.SEARCH_DOWN) while curr_ea != BADADDR: yield curr_ea curr_ea = ida_search.find_binary(curr_ea + len(hex_string), stop_ea, hex_string, 16, ida_search.SEARCH_DOWN)
def findGoPcLn(): possible_loc = ida_search.find_binary(0, idc.BADADDR, lookup, 16, idc.SEARCH_DOWN) #header of gopclntab while possible_loc != idc.BADADDR: if check_is_gopclntab(possible_loc): return possible_loc else: #keep searching till we reach end of binary possible_loc = ida_search.find_binary(possible_loc+1, idc.BADADDR, lookup, 16, idc.SEARCH_DOWN) return None
def find_hex_string(start_ea, stop_ea, hex_string): ea = ida_search.find_binary(start_ea, stop_ea, hex_string, 16, ida_search.SEARCH_DOWN) while ea != BADADDR: yield ea ea = ida_search.find_binary( ea, stop_ea, hex_string, 16, ida_search.SEARCH_DOWN | ida_search.SEARCH_NEXT, )
def iter_find_query(query, start=None, end=None, down=True): start, end = fix_addresses(start, end) if down: direction = ida_search.SEARCH_DOWN else: direction = ida_search.SEARCH_UP current = ida_search.find_binary(start, end, query, 16, direction) while current < end: yield current current = ida_search.find_binary(current + 1, end, query, 16, direction)
def create_func_by_prefix(func_name, prefix, force=False): addrs = [] start_addr = 0 func_addr = 0 while func_addr != idc.BADADDR: func_addr = ida_search.find_binary(start_addr, idc.BADADDR, prefix, 16, idc.SEARCH_DOWN) if func_addr == idc.BADADDR: break # already existing function but it is not the right prefix addr = idc.get_func_attr(func_addr, idc.FUNCATTR_START) if addr != idc.BADADDR and func_addr != addr: if not force: start_addr = func_addr + 4 continue idc.del_func(addr) idc.del_items(func_addr) # add_func is not applied to the existing function idc.add_func(func_addr) func_name = set_entry_name(func_addr, func_name) print("%s: 0x%x" % (func_name, func_addr)) addrs.append(func_addr) start_addr = func_addr + 4 return addrs
def get_E_main(): # .text:00485090 55 push ebp # .text:00485091 8B EC mov ebp, esp # .text:00485093 51 push ecx # .text:00485094 53 push ebx # .text:00485095 56 push esi # .text:00485096 8B F1 mov esi, ecx # .text:00485098 57 push edi # .text:00485099 8B 4E 68 mov ecx, [esi+68h] # .text:0048509C 8D 86 D8 00 00 00 lea eax, [esi+0D8h] # .text:004850A2 50 push eax ; int # .text:004850A3 51 push ecx ; hModule # .text:004850A4 E8 C7 D3 00 00 call krnln_?GetInstancePath@@YAXPAUHINSTANCE__@@AAVCString@@@Z E_main_pat = "55 8B EC 51 53 56 8B F1 57 8B 4E 68 8D 86 D8 00 00 00 50 51 E8" E_main_call_ins_offset = 0x37 E_main_func_ea = 0 code_segs = get_code_segs() for seg in code_segs: start_ea = seg.start_ea end_ea = seg.end_ea E_main_pat_ea = ida_search.find_binary(start_ea, end_ea, E_main_pat, 16, ida_search.SEARCH_DOWN) if E_main_pat_ea != idaapi.BADADDR: call_ins_ea = E_main_pat_ea + E_main_call_ins_offset addr_off = ida_bytes.get_dword(call_ins_ea + 1) E_main_func_ea = call_ins_ea + 5 + idaapi.as_int32(addr_off) print("Find E_main addr 0x%X" % (E_main_func_ea)) break return E_main_func_ea
def find_do_printf(base_ea, base_end_ea): str_ea = ida_search.find_text(base_ea, 1, 1, "<ptr>", ida_search.SEARCH_DOWN) if str_ea != ida_idaapi.BADADDR: for xref in idautils.XrefsTo(str_ea): func = idaapi.get_func(xref.frm) if not func: break print("\t[+] _do_printf = 0x%x" % (func.start_ea)) idc.set_name(func.start_ea, "_do_printf", idc.SN_CHECK) return func.start_ea cmp_ea = ida_search.find_binary(base_ea, base_end_ea, "3F 94 00 71", 16, ida_search.SEARCH_DOWN) if cmp_ea != ida_idaapi.BADADDR: func = idaapi.get_func(cmp_ea) if not func: print("\t[-] _do_printf = not found") return ida_idaapi.BADADDR print("\t[+] _do_printf = 0x%x" % (func.start_ea)) idc.set_name(func.start_ea, "_do_printf", idc.SN_CHECK) return func.start_ea print("\t[-] _do_printf = not found") return ida_idaapi.BADADDR
def FindInstructions(instr, asm_where=None): """ Finds instructions/opcodes @return: Returns a tuple(True, [ ea, ... ]) or a tuple(False, "error message") """ if not asm_where: # get first segment seg = ida_segment.get_first_seg() asm_where = seg.start_ea if seg else ida_idaapi.BADADDR if asm_where == ida_idaapi.BADADDR: return (False, "No segments defined") # regular expression to distinguish between opcodes and instructions re_opcode = re.compile('^[0-9a-f]{2} *', re.I) # split lines lines = instr.split(";") # all the assembled buffers (for each instruction) bufs = [] for line in lines: if re_opcode.match(line): # convert from hex string to a character list then join the list to form one string buf = bytes(bytearray([int(x, 16) for x in line.split()])) else: # assemble the instruction ret, buf = idautils.Assemble(asm_where, line) if not ret: return (False, "Failed to assemble:" + line) # add the assembled buffer bufs.append(buf) # join the buffer into one string buf = b''.join(bufs) # take total assembled instructions length tlen = len(buf) # convert from binary string to space separated hex string bin_str = ' '.join( ["%02X" % (ord(x) if sys.version_info.major < 3 else x) for x in buf]) # find all binary strings print("Searching for: [%s]" % bin_str) ea = ida_ida.cvar.inf.min_ea ret = [] while True: ea = ida_search.find_binary(ea, ida_idaapi.BADADDR, bin_str, 16, ida_search.SEARCH_DOWN) if ea == ida_idaapi.BADADDR: break ret.append(ea) ida_kernwin.msg(".") ea += tlen if not ret: return (False, "Could not match [%s]" % bin_str) ida_kernwin.msg("\n") return (True, ret)
def resolve_loops(): PATTERNS = ["81 FB ?? ?? ?? ?? 75"] count_patched = 0 count_not_patched = 0 for pattern in PATTERNS: ea = 0 while ea != BADADDR: ''' pattern: 81 FB ?? ?? ?? ?? 75 .text:00406AA0 01 C7 add edi, eax .text:00406AA2 66 41 inc cx .text:00406AA4 43 inc ebx .text:00406AA5 81 FB A6 01 00 00 cmp ebx, 1A6h .text:00406AAB 75 F3 jnz short loc_406AA0 patched: .text:00406AA0 01 C7 add edi, eax .text:00406AA2 66 41 inc cx .text:00406AA4 43 inc ebx .text:00406AA5 90 nop .text:00406AA6 90 nop .text:00406AA7 90 nop .text:00406AA8 90 nop .text:00406AA9 90 nop .text:00406AAA 90 nop .text:00406AAB 90 nop .text:00406AAC 90 nop ''' ea = ida_search.find_binary( ea, BADADDR, pattern, 16, SEARCH_NEXT | SEARCH_DOWN | SEARCH_CASE) if ea_in_bounds(ea): # Patch CMP and conditional jmp instructions in order to remove the loop ida_bytes.patch_byte(ea + 0, 0x90) ida_bytes.patch_byte(ea + 1, 0x90) ida_bytes.patch_byte(ea + 2, 0x90) ida_bytes.patch_byte(ea + 3, 0x90) ida_bytes.patch_byte(ea + 4, 0x90) ida_bytes.patch_byte(ea + 5, 0x90) ida_bytes.patch_byte(ea + 6, 0x90) ida_bytes.patch_byte(ea + 7, 0x90) idc.create_insn(ea) count_patched += 1 print("\tPatched resolve_loops: {0}".format(count_patched)) print("\tNot Patched resolve_loops: {0}".format(count_not_patched))
def FindInstructions(instr, asm_where=None): """ Finds instructions/opcodes @return: Returns a tuple(True, [ ea, ... ]) or a tuple(False, "error message") """ if not asm_where: # get first segment seg = ida_segment.get_first_seg() asm_where = seg.start_ea if seg else ida_idaapi.BADADDR if asm_where == ida_idaapi.BADADDR: return (False, "No segments defined") # regular expression to distinguish between opcodes and instructions re_opcode = re.compile('^[0-9a-f]{2} *', re.I) # split lines lines = instr.split(";") # all the assembled buffers (for each instruction) bufs = [] for line in lines: if re_opcode.match(line): # convert from hex string to a character list then join the list to form one string buf = ''.join([chr(int(x, 16)) for x in line.split()]) else: # assemble the instruction ret, buf = idautils.Assemble(asm_where, line) if not ret: return (False, "Failed to assemble:"+line) # add the assembled buffer bufs.append(buf) # join the buffer into one string buf = ''.join(bufs) # take total assembled instructions length tlen = len(buf) # convert from binary string to space separated hex string bin_str = ' '.join(["%02X" % ord(x) for x in buf]) # find all binary strings print("Searching for: [%s]" % bin_str) ea = ida_ida.cvar.inf.min_ea ret = [] while True: ea = ida_search.find_binary(ea, ida_idaapi.BADADDR, bin_str, 16, ida_search.SEARCH_DOWN) if ea == ida_idaapi.BADADDR: break ret.append(ea) ida_kernwin.msg(".") ea += tlen if not ret: return (False, "Could not match [%s]" % bin_str) ida_kernwin.msg("\n") return (True, ret)
def find_boot_check_panic(base_ea, base_end_ea): seq_ea = ida_search.find_binary(base_ea, base_end_ea, "1F ?? 03 71", 16, ida_search.SEARCH_DOWN) if seq_ea != ida_idaapi.BADADDR: func = idaapi.get_func(seq_ea) print("\t[+] _boot_check_panic = 0x%x" % (func.start_ea)) idc.set_name(func.start_ea, "_boot_check_panic", idc.SN_CHECK) return func.start_ea return ida_idaapi.BADADDR
def find_platform_early_init(base_ea, base_end_ea): seq_ea = ida_search.find_binary(base_ea, base_end_ea, "60 02 40 39", 16, ida_search.SEARCH_DOWN) if seq_ea != ida_idaapi.BADADDR: func = idaapi.get_func(seq_ea) print("\t[+] _platform_early_init = 0x%x" % (func.start_ea)) idc.set_name(func.start_ea, "_platform_early_init", idc.SN_CHECK) return func.start_ea return ida_idaapi.BADADDR
def find_macho_valid(base_ea, base_end_ea): seq_ea = ida_search.find_binary(base_ea, base_end_ea, "49 01 8B 9A", 16, ida_search.SEARCH_DOWN) if seq_ea != ida_idaapi.BADADDR: func = idaapi.get_func(seq_ea) print("\t[+] _macho_valid = 0x%x" % (func.start_ea)) idc.set_name(func.start_ea, "_macho_valid", idc.SN_CHECK) return func.start_ea return ida_idaapi.BADADDR
def find_aes_crypto_cmd(base_ea, base_end_ea): aes_ea = ida_search.find_binary(base_ea, base_end_ea, "89 2C 00 72", 16, ida_search.SEARCH_DOWN) if aes_ea != ida_idaapi.BADADDR: func = idaapi.get_func(aes_ea) print("\t[+] _aes_crypto_cmd = 0x%x" % (func.start_ea)) idc.set_name(func.start_ea, "_aes_crypto_cmd", idc.SN_CHECK) return func.start_ea return ida_idaapi.BADADDR
def find_chipid_get_chip_revision(base_ea, base_end_ea): seq_ea = ida_search.find_binary(base_ea, base_end_ea, "00 21 06 33", 16, ida_search.SEARCH_DOWN) if seq_ea != ida_idaapi.BADADDR: func = idaapi.get_func(seq_ea) print("\t[+] _chipid_get_chip_revision = 0x%x" % (func.start_ea)) idc.set_name(func.start_ea, "_chipid_get_chip_revision", idc.SN_CHECK) return func.start_ea return ida_idaapi.BADADDR
def function64(base_ea, base_end_ea, name, sequence): seq_ea = ida_search.find_binary(base_ea, base_end_ea, sequence, 0x10, ida_search.SEARCH_DOWN) if seq_ea != ida_idaapi.BADADDR: func = idaapi.get_func(seq_ea) print(" [sephelper]: %s = 0x%x" % (name, func.start_ea)) idc.set_name(func.start_ea, name, idc.SN_CHECK) return func.start_ea print(" [sephelper]: %s = NULL" % name) return ida_idaapi.BADADDR
def find_putchar(base_ea, base_end_ea): seq_ea = ida_search.find_binary(base_ea, base_end_ea, "A0 01 80 52 ?? ?? FF 97 E0", 16, ida_search.SEARCH_DOWN) if seq_ea != ida_idaapi.BADADDR: func = idaapi.get_func(seq_ea) print("\t[+] _putchar = 0x%x" % (func.start_ea)) idc.set_name(func.start_ea, "_putchar", idc.SN_CHECK) return func.start_ea return ida_idaapi.BADADDR
def find_image4_validate_property_callback(base_ea, base_end_ea): seq_ea = ida_search.find_binary(base_ea, base_end_ea, "?? 77 00 51", 16, ida_search.SEARCH_DOWN) if seq_ea != ida_idaapi.BADADDR: func = idaapi.get_func(seq_ea) print("\t[+] _image4_validate_property_callback = 0x%x" % (func.start_ea)) idc.set_name(func.start_ea, "_image4_validate_property_callback", idc.SN_CHECK) return func.start_ea return ida_idaapi.BADADDR
def __search_resultcount(self, signature): search_addr = ida_ida.cvar.inf.min_ea search_results = 0 while search_results < 2: search_addr = ida_search.find_binary( search_addr, ida_ida.cvar.inf.max_ea, signature, 16, ida_search.SEARCH_DOWN | ida_search.SEARCH_NEXT) if search_addr == ida_idaapi.BADADDR: break search_results += 1 return search_results
def findGoPcLn(): possible_loc = ida_search.find_binary( 0, idc.BADADDR, lookup, 16, idc.SEARCH_DOWN) #header of gopclntab while possible_loc != idc.BADADDR: if check_is_gopclntab(possible_loc): return possible_loc else: #keep searching till we reach end of binary possible_loc = ida_search.find_binary(possible_loc + 1, idc.BADADDR, lookup, 16, idc.SEARCH_DOWN) possible_loc = ida_search.find_binary( 0, idc.BADADDR, lookup16, 16, idc.SEARCH_DOWN) #header of gopclntab while possible_loc != idc.BADADDR: print(f"found possible 1.16 gopclntab") if check_is_gopclntab16(possible_loc): print("Looks like this is go1.16 binary") return possible_loc else: #keep searching till we reach end of binary possible_loc = ida_search.find_binary(possible_loc + 1, idc.BADADDR, lookup16, 16, idc.SEARCH_DOWN) return None
def locate_functions(segm): ss = find_probable_string_start(segm) print("[+] Strings = %s" % ss) for i in ["7F 23 03 D5", "BD A9", "BF A9"]: ea = segm.start_ea while ea != BADADDR: ea = ida_search.find_binary(ea, segm.end_ea, i, 16, ida_search.SEARCH_DOWN) if ea != BADADDR and ea <= ss: ea -= 2 if (ea % 4) == 0 and idaapi.get_full_flags(ea) < 0x200: # print("[+] Defining a function at 0x%x" % (ea)) ida_funcs.add_func(ea) ea += 4
def search_bytes_addr(byt, start_ea=None, end_ea=None, down=True, nxt=True): """ Static method for searching a sequence of bytes. This will search for the bytes which ever the data type is. This is a wrapper on the ``ida_search.find_binary`` (previously ``FindBinary``) function from IDA with a radix of 16. The byte should be represented in hexadecimal seperated by space. A ``?`` can be put for replacing a byte, for example: ``41 8B 44 ? 20``. :param byt: A string representing a sequence of byte. :param start_ea: The address at which to start the search, if ``None`` the current address will be used. :param end_ea: The address at which to stop the search, if ``None`` the maximum or minimum (depending of searching up or down) will be used. :param down: If True (the default) search below the given address, if False search above. :param nxt: If True (the default) the current element will not be included in the search. :return: The address at which the byte sequence is present or ``None`` if no element were found during the search. """ if start_ea is None: start_ea = ida_kernwin.get_screen_ea() if down: fl = ida_search.SEARCH_DOWN if end_ea is None: end_ea = idc.get_inf_attr(idc.INF_MAX_EA) else: fl = ida_search.SEARCH_UP if end_ea is None: end_ea = idc.get_inf_attr(idc.INF_MIN_EA) if nxt: fl |= ida_search.SEARCH_NEXT r = ida_search.find_binary(start_ea, end_ea, byt, 16, fl) if r == idc.BADADDR: return None else: return r
def find_img4decodeinit(base_ea): cur_ea = base_ea while true: ea_list = ida_search.find_imm(cur_ea, ida_search.SEARCH_DOWN, 0x494D) if ea_list[0] == ida_idaapi.BADADDR: ea_list = ida_search.find_imm(cur_ea, ida_search.SEARCH_DOWN, 0x494D0000) if ea_list[0] != ida_idaapi.BADADDR: ea = ea_list[0] func = ida_funcs.get_func(ea) func_ea = 0 if not func: func_ea = ida_search.find_binary(ea, base_ea, "?? ?? BD A9", 16, ida_search.SEARCH_UP) if func_ea != ida_idaapi.BADADDR: ida_funcs.add_func(func_ea) else: print("\t[-] _Img4DecodeInit = not found") return ida_idaapi.BADADDR else: func_ea = func.start_ea ea_func_list = list(idautils.XrefsTo(func_ea)) if not ea_func_list: cur_ea = ea + 4 continue if ea_func_list[0].frm != ida_idaapi.BADADDR: try: i4d_ea = ida_funcs.get_func(ea_func_list[0].frm).start_ea print("\t[+] _Img4DecodeInit = 0x%x" % (i4d_ea)) idc.set_name(i4d_ea, "_Img4DecodeInit", idc.SN_CHECK) return i4d_ea except: break cur_ea = ea + 4 print("\t[-] _Img4DecodeInit = not found") return ida_idaapi.BADADDR
def masked_search(start_addr: int, end_addr: int, bytes_data: bytes, masks_data: bytes) -> Tuple[int, Optional[bytes]]: def prepare_first_search(bd: bytes, md: bytes) -> bytes: bd_str = binascii.hexlify(bd, ' ').split(b' ') md_str = binascii.hexlify(md, ' ').split(b' ') for ii, md_token in enumerate(md_str): if md_token != b'ff': bd_str[ii] = b'?' bd_str = b' '.join(bd_str) return bd_str len_bytes = len(bytes_data) bytes_data_prep = prepare_first_search(bytes_data, masks_data) if idaapi.IDA_SDK_VERSION >= 760: patterns = ida_bytes.compiled_binpat_vec_t() idaapi.parse_binpat_str(patterns, start_addr, bytes_data_prep.decode(), 16) ea = ida_bytes.bin_search(start_addr, end_addr, patterns, ida_bytes.BIN_SEARCH_FORWARD | ida_bytes.BIN_SEARCH_NOBREAK | ida_bytes.BIN_SEARCH_NOSHOW) else: ea = ida_search.find_binary(start_addr, end_addr, bytes_data_prep.decode(), 16, idaapi.SEARCH_DOWN) if ea == idaapi.BADADDR: return idaapi.BADADDR, None found_bytes = idaapi.get_bytes(ea, len_bytes) equal = True for i in range(len_bytes): m = masks_data[i] if found_bytes[i] & m != bytes_data[i] & m: equal = False break if equal: return ea, found_bytes return idaapi.BADADDR, None
def resolve_opaque_push_retn(): PATTERNS = ["68 ?? ?? ?? ?? C3"] count_patched = 0 for pattern in PATTERNS: ea = 0 while ea != BADADDR: ea = ida_search.find_binary( ea, BADADDR, pattern, 16, SEARCH_NEXT | SEARCH_DOWN | SEARCH_CASE) ''' pattern: 68 ?? ?? ?? ?? C3 .text:00406922 68 B2 6A 00 10 push 0x10006ab2 .text:00406927 C3 retn patched: .text:00406922 E9 B2 6A 00 10 jmp 0x10006ab2 .text:00406927 90 nop ''' if ea_in_bounds(ea): j_pos = ea pos_jmp = idc.get_wide_dword(j_pos + 1) # absolute address offset = pos_jmp - 5 - j_pos # Patch the push and retn instructions with NOPs (6 bytes) for i in range(0, 6): ida_bytes.patch_byte(j_pos + i, 0x90) ida_bytes.patch_byte(j_pos, 0xE9) ida_bytes.patch_dword(j_pos + 0x1, offset) idc.create_insn(ea) count_patched += 1 print("\tPatched resolve_opaque_push_retn: {0}".format(count_patched))
def find_image4_validate_property_callback(base_ea, base_end_ea, ptr_ea): seq_ea = ida_search.find_binary(base_ea, base_end_ea, "?? 77 00 51", 16, ida_search.SEARCH_DOWN) func = none if seq_ea != ida_idaapi.BADADDR: func = idaapi.get_func(seq_ea) else: for xref in idautils.XrefsTo(ptr_ea): func = idaapi.get_func(xref.frm) break if func: print("\t[+] _image4_validate_property_callback = 0x%x" % (func.start_ea)) idc.set_name(func.start_ea, "_image4_validate_property_callback", idc.SN_CHECK) return func.start_ea print("\t[-] _image4_validate_property_callback = not found") return ida_idaapi.BADADDR
def get_E_info_entry(): # .text:004AE780 50 push eax # .text:004AE781 64 89 25 00 00 00 00 mov large fs:0, esp # .text:004AE788 81 EC AC 01 00 00 sub esp, 1ACh # .text:004AE78E 53 push ebx # .text:004AE78F 56 push esi # .text:004AE790 57 push edi E_lib_pat = "50 64 89 25 00 00 00 00 81 ec ac 01 00 00 53 56 57" E_lib_addr_offset = 0x25 E_lib_infos_ea = 0 code_segs = get_code_segs() for seg in code_segs: start_ea = seg.start_ea end_ea = seg.end_ea E_lib_pat_ea = ida_search.find_binary(start_ea, end_ea, E_lib_pat, 16, ida_search.SEARCH_DOWN) if E_lib_pat_ea != idaapi.BADADDR: mov_ins_ea = E_lib_pat_ea + E_lib_addr_offset E_lib_infos_ea = ida_bytes.get_dword(mov_ins_ea + 1) break return E_lib_infos_ea
def load_file(fd, neflags, format): global prologues global br_flag size = 0 base_addr = 0 ea = 0 nfunc = 0 idaapi.set_processor_type("arm", ida_idp.SETPROC_LOADER_NON_FATAL) idaapi.get_inf_structure().lflags |= idaapi.LFLG_64BIT if (neflags & idaapi.NEF_RELOAD) != 0: return 1 fd.seek(0, idaapi.SEEK_END) size = fd.tell() segm = idaapi.segment_t() segm.bitness = 2 # 64-bit segm.start_ea = 0 segm.end_ea = size if br_flag == false: idaapi.add_segm_ex(segm, "iBoot", "CODE", idaapi.ADDSEG_OR_DIE) else: idaapi.add_segm_ex(segm, "SecureROM", "CODE", idaapi.ADDSEG_OR_DIE) fd.seek(0) fd.file2base(0, 0, size, false) idaapi.add_entry(0, 0, "start", 1) ida_funcs.add_func(ea) print("[+] Marked as code") # heuristic while (true): mnemonic = idc.print_insn_mnem(ea) if "LDR" in mnemonic: base_str = idc.print_operand(ea, 1) base_addr = int(base_str.split("=")[1], 16) break ea += 4 print("[+] Rebasing to address 0x%x" % (base_addr)) idaapi.rebase_program(base_addr, idc.MSF_NOFIX) segment_start = base_addr segment_end = idc.get_segm_attr(segment_start, idc.SEGATTR_END) ea = segment_start print("[+] Searching and defining functions") for prologue in prologues: while ea != ida_idaapi.BADADDR: ea = ida_search.find_binary(ea, segment_end, prologue, 16, ida_search.SEARCH_DOWN) if ea != ida_idaapi.BADADDR: if len(prologue) < 8: ea = ea - 2 if (ea % 4) == 0 and ida_bytes.get_full_flags(ea) < 0x200: # print("[+] Defining a function at 0x%x" % (ea)) ida_funcs.add_func(ea) nfunc = nfunc + 1 ea = ea + 4 idc.plan_and_wait(segment_start, segment_end) print("[+] Identified %d new functions" % (nfunc)) print("[+] Looking for interesting functions") find_interesting(segment_start, segment_end) return 1