def main(): print("[*] loading crypto constants") for const in non_sparse_consts: const["byte_array"] = convert_to_byte_array(const) for start in idautils.Segments(): print("[*] searching for crypto constants in %s" % idc.get_segm_name(start)) ea = start while ea < idc.get_segm_end(start): bbbb = list(struct.unpack("BBBB", idc.get_bytes(ea, 4))) for const in non_sparse_consts: if bbbb != const["byte_array"][:4]: continue if map(lambda x:ord(x), idc.get_bytes(ea, len(const["byte_array"]))) == const["byte_array"]: print(("0x%0" + str(digits) + "X: found const array %s (used in %s)") % (ea, const["name"], const["algorithm"])) idc.set_name(ea, const["name"]) if const["size"] == "B": idc.create_byte(ea) elif const["size"] == "L": idc.create_dword(ea) elif const["size"] == "Q": idc.create_qword(ea) idc.make_array(ea, len(const["array"])) ea += len(const["byte_array"]) - 4 break ea += 4 ea = start if idc.get_segm_attr(ea, idc.SEGATTR_TYPE) == 2: while ea < idc.get_segm_end(start): d = ida_bytes.get_dword(ea) for const in sparse_consts: if d != const["array"][0]: continue tmp = ea + 4 for val in const["array"][1:]: for i in range(8): if ida_bytes.get_dword(tmp + i) == val: tmp = tmp + i + 4 break else: break else: print(("0x%0" + str(digits) + "X: found sparse constants for %s") % (ea, const["algorithm"])) cmt = idc.get_cmt(idc.prev_head(ea), 0) if cmt: idc.set_cmt(idc.prev_head(ea), cmt + ' ' + const["name"], 0) else: idc.set_cmt(idc.prev_head(ea), const["name"], 0) ea = tmp break ea += 1 print("[*] finished")
def makeNameHard_ida7(ea, name): '''Keeps trying to name the given ea until it works, adding the optional _%d suffix''' count = 0 ret = idc.set_name(ea, name, idc.SN_PUBLIC|idc.SN_NOWARN) m = HARD_NAME_RE.match(name) if m is not None: #already a name in <name>_<count> format name, count = m.group(1,2) count = int(count) if ret == 0: while (count < 100) and (ret == 0): newName = '%s_%d' % (name, count) ret = idc.set_name(ea, newName, idc.SN_PUBLIC|idc.SN_NOWARN) count += 1
def load_file(li, neflags, format): # Set flags idaapi.set_processor_type( "arm", idaapi.SETPROC_LOADER_NON_FATAL | idaapi.SETPROC_LOADER) idc.set_inf_attr(idc.INF_LFLAGS, idc.get_inf_attr(idc.INF_LFLAGS) | idc.LFLG_64BIT) idc.set_inf_attr(idc.INF_DEMNAMES, idaapi.DEMNAM_GCC3) idaapi.set_compiler_id(idaapi.COMP_GNU) idaapi.add_til('gnulnx_arm64', 1) # Load IRAM memory li.seek(0) pk11 = li.read(PK1L_SIZE) idaapi.mem2base(pk11, PK1L_ADDRESS) # Add identity mappings add_segment(PK1L_ADDRESS, PK1L_SIZE, '.pk1_identity', 'RWX') add_segment(TZRAM_BASE, TZRAM_SIZE, '.tz_identity', 'RWX') # Emulate package1 to determine interesting extents emu = Emulator() emu.run_emulator(pk11) # Refresh IRAM contents to reflect any decompression that may have occurred. idaapi.mem2base(emu.read_mem(PK1L_ADDRESS, PK1L_SIZE), PK1L_ADDRESS) if not emu.found_smc_evp: # Set coldboot crt0 idc.create_insn(emu.entrypoint) idc.set_name(emu.entrypoint, 'coldboot_crt0') return 1 iram_mappings = [] dram_mappings = [] tzram_mappings = [] mmio_mappings = [] for m in emu.mappings: if is_tzram(m): tzram_mappings.append(m) elif is_dram(m): dram_mappings.append(m) elif is_iram(m): iram_mappings.append(m) else: assert is_mmio(m) mmio_mappings.append(m) for m in mmio_mappings: add_mmio_mapping(m) # Process IRAM mappings if len(iram_mappings) == 3: sorted_irams = sorted(iram_mappings, key=lambda m: m[2]) if [m[2] for m in sorted_irams] == [0x1000, 0x1000, 0x10000]: assert len(set([m[3] for m in sorted_irams])) == 2 if sorted_irams[1][3] == sorted_irams[2][3]: add_segment(sorted_irams[0][0], sorted_irams[0][2], '.bl_sync', 'IO') add_segment(sorted_irams[1][0], sorted_irams[1][2], '.sc7_fw', 'DATA') add_segment(sorted_irams[2][0], sorted_irams[2][2], '.sc7_tmp_save', 'DATA') else: assert sorted_irams[0][3] == sorted_irams[2][3] add_segment(sorted_irams[1][0], sorted_irams[1][2], '.bl_sync', 'IO') add_segment(sorted_irams[0][0], sorted_irams[0][2], '.sc7_fw', 'DATA') add_segment(sorted_irams[2][0], sorted_irams[2][2], '.sc7_tmp_save', 'DATA') else: print iram_mappings raise ValueError('Unknown IRAM mapping set') elif len(iram_mappings) == 2: sorted_irams = sorted(iram_mappings, key=lambda m: m[2]) if [m[2] for m in sorted_irams] == [0x1000, 0x10000]: assert len(set([m[3] for m in sorted_irams])) == 2 add_segment(sorted_irams[0][0], sorted_irams[0][2], '.bl_sync', 'IO') add_segment(sorted_irams[1][0], sorted_irams[1][2], '.sc7_tmp_save', 'DATA') else: print iram_mappings raise ValueError('Unknown IRAM mapping set') else: print iram_mappings raise ValueError('Unknown IRAM mapping set') # Process DRAM mappings if len(dram_mappings) == 2: sorted_drams = sorted(dram_mappings, key=lambda m: m[2]) if [m[2] for m in sorted_drams] == [0x1000, 0x10000]: add_segment(sorted_drams[0][0], sorted_drams[0][2], '.sc7_se_ctx', 'DATA') add_segment(sorted_drams[1][0], sorted_drams[1][2], '.sc7_sm_ctz', 'DATA') else: print dram_mappings raise ValueError('Unknown DRAM mapping set') else: print dram_mappings raise ValueError('Unknown DRAM mapping set') # Process TZRAM segments tzram_groups = [] for (vaddr, paddr, size, attr) in sorted(tzram_mappings, key=lambda m: m[0]): inserted = False for i in xrange(len(tzram_groups)): if vaddr == tzram_groups[i][-1][0] + tzram_groups[i][-1][ 2] and tzram_groups[i][-1][2] != 0x40000: tzram_groups[i].append((vaddr, paddr, size, attr)) inserted = True break if not inserted: tzram_groups.append([(vaddr, paddr, size, attr)]) for group in tzram_groups: print 'Group' for m in group: print ' %x %x %x %x' % m # Process groups for group in tzram_groups: if len(group) > 1: if is_executable(group[0]): # .text/.rodata/.rwdata :) if len(group) == 2: add_segment(group[0][0], group[0][2], '.text_rodata', 'CODE') add_segment(group[1][0], group[1][2], '.rwdata', 'DATA') load_mapping(emu, group[0]) load_mapping(emu, group[1]) else: assert len(group) == 3 add_segment(group[0][0], group[0][2], '.text', 'CODE') add_segment(group[1][0], group[1][2], '.rodata', 'CONST') add_segment(group[2][0], group[2][2], '.rwdata', 'DATA') load_mapping(emu, group[0]) load_mapping(emu, group[1]) load_mapping(emu, group[2]) elif is_executable(group[0]): assert len(group) == 1 vaddr, paddr, size, attr = group[0] if size > 0x8000: assert len( filter(lambda g: is_executable(g[0]) and g[0][2] > 0x8000, tzram_groups)) == 1 assert is_writable(group[0]) add_segment(vaddr, size, '.code', 'RWX') load_mapping(emu, group[0]) elif size == 0x2000: assert len( filter(lambda g: is_executable(g[0]) and g[0][2] == 0x2000, tzram_groups)) == 1 add_segment(vaddr, size, '.pk2ldr', 'RWX') load_mapping(emu, group[0]) else: assert size == 0x1000 assert len( filter(lambda g: is_executable(g[0]) and g[0][2] == 0x1000, tzram_groups)) == 1 add_segment(vaddr, size, '.vectors', 'CODE') load_mapping(emu, group[0]) elif len(group) == 1 and (group[0][2] == 0x10000 or group[0][2] == 0x40000): assert len( filter( lambda g: len(g) == 1 and not is_executable(g[0]) and (g[0][2] == 0x10000 or g[0][2] == 0x40000), tzram_groups)) == 1 assert not is_writable(group[0]) vaddr, paddr, size, attr = group[0] add_segment(vaddr, size, '.tzram_ro_view', 'CONST') elif len(group) == 1 and group[0][2] == 0x1000: vaddr, paddr, size, attr = group[0] pk2ldr_group = filter( lambda g: is_executable(g[0]) and g[0][2] == 0x2000, tzram_groups) assert len(pk2ldr_group) == 1 pk2ldr_group = pk2ldr_group[0][0] if paddr == emu.l3_table: add_segment(vaddr, size, '.l3_table', 'DATA') elif paddr == (emu.l3_table - 0x1000): add_segment(vaddr, size, '.l2_table', 'DATA') elif paddr == pk2ldr_group[1]: add_segment(vaddr, size, '.reused_stack0', 'DATA') elif paddr == (pk2ldr_group[1] + 0x1000): add_segment(vaddr, size, '.reused_stack1', 'DATA') elif vaddr == emu.phys_to_virt[ emu.ttbr & ~0xFFF][0] or vaddr == emu.core0_stack_page: add_segment(vaddr, size, '.shared_data', 'DATA') else: print 'Unknown Group' for m in group: print ' %x %x %x %x' % m assert False else: print 'Unknown Group' for m in group: print ' %x %x %x %x' % m assert False # Set vector types as code. for i, ctx in enumerate(['sp0', 'spx', 'a64', 'a32']): for j, kind in enumerate(['synch', 'irq', 'fiq', 'serror']): addr = emu.vbar + 0x200 * i + 0x80 * j name = '%s_%s_exception' % (ctx, kind) idc.create_insn(addr) idc.set_name(addr, name) # Set coldboot crt0 idc.create_insn(emu.entrypoint) idc.set_name(emu.entrypoint, 'coldboot_crt0') # Add SMC list entries assert len(emu.smc_lists) == 2 idc.set_name(emu.smc_lists_addr, 'g_smc_lists') for i, name in enumerate(['user', 'priv']): addr, num_entries, pad = emu.smc_lists[i] idc.set_name(addr, 'g_smc_list_%s' % name) for n in xrange(num_entries): id, access, func = up('<IIQ', emu.read_mem(addr + 0x10 * n, 0x10)) if func == 0: continue smc_name = get_smc_name(name == 'user', id) process_smc(func, smc_name) # We're done return 1
def load_file(li, neflags, format): # ensure we are not wrongly called if not format.startswith("Accessory Firmware Update"): return 0 li.seek(0) data = li.read(0x14) (magic, xxx1, fw_type, fw_ver, fw_len, unk1, product_id, hw_rev_id) = struct.unpack("<HHHHIIHH", data) li.seek(0x20) AFU_signature_header_data = li.read(24) (sig_magic, unknown1, unknown2, digest_type, digest_len, digest_offset, sig_type, sig_len, sig_offset) = struct.unpack("<IHHHHIHHI", AFU_signature_header_data) idaapi.set_processor_type("ARM:ARMv7-M", ida_idp.SETPROC_ALL) if product_id == 0x312: # Apple Pencil fw_base = 0x8006080 msp_base = fw_base elif product_id == 0x14c: # Apple Pencil 2 if fw_type == 1: fw_base = 0x08000980 msp_base = fw_base + 0x180 if fw_type == 0x20: fw_base = 0x0 msp_base = fw_base if fw_type == 0x30: fw_base = 0x0 msp_base = fw_base if fw_type == 0x50: fw_base = 0x08000000 msp_base = fw_base elif product_id == 0x26d: # Siri Remote 2 if fw_type == 1: fw_base = 0x8008080 msp_base = fw_base + 0x180 if fw_type == 0xb0: fw_base = 0x280 msp_base = fw_base + 0x180 elif product_id == 0x268: # Smart Keyboard 12.9" fw_base = 0x08002600 msp_base = fw_base elif product_id == 0x26A: # Smart Keyboard 9.7" fw_base = 0x08002600 msp_base = fw_base elif product_id == 0x26B: # Smart Keyboard 10.5" fw_base = 0x08002600 # don't really know, haven't seen an OTA so far msp_base = fw_base elif product_id == 0x292: # Smart Keyboard Folio 11" fw_base = 0x08000980 # seems to work msp_base = fw_base + 0x180 elif product_id == 0x293: # Smart Keyboard Folio 12.9" fw_base = 0x08000980 # seems to work msp_base = fw_base + 0x180 else: return 0 # for now a heuristic show_header = True if fw_type != 1 or fw_base == 0: show_header = False if show_header: li.file2base(0, fw_base - 0x80, fw_base, 1) li.file2base(0x80, fw_base, fw_base + fw_len, 1) if show_header: idaapi.add_segm(0, fw_base - 0x80, fw_base, "HEADER", "DATA") idaapi.add_segm(0, fw_base, fw_base + fw_len, "__TEXT", "CODE") idaapi.add_segm(0, 0xE000E000, 0xE000F000, "__SYSREG", "DATA") idaapi.add_segm(0, SRAM_BASE, SRAM_BASE + SRAM_SIZE, "__SRAM", "DATA") if show_header: idc.split_sreg_range(fw_base - 0x80, "T", 1) idc.split_sreg_range(fw_base, "T", 1) # register the structures register_structs() # apply the structure if show_header: idc.set_name(fw_base - 0x80, "AFU_HEADER") idc.create_struct(fw_base - 0x80, -1, "afu_full_header") ida_nalt.unhide_item(fw_base - 0x80 + 1) # handle the digest and signature if sig_magic == 0x61E34724: # apply the structure if show_header: idc.set_name(fw_base - 0x80 + 0x20, "AFU_SIG_HEADER") #idc.create_struct(fw_base - 0x80 + 0x20, -1, "afu_sig_header") #ida_nalt.unhide_item(fw_base - 0x80 + 0x20 + 1) # first handle the digest base = fw_base + fw_len li.file2base(digest_offset, base, base + digest_len, 1) idaapi.add_segm(0, base, base + digest_len, "__DIGEST", "DATA") idc.create_byte(base) idc.make_array(base, digest_len) idc.set_name(base, "AFU_DIGEST") # now handle the signature base += digest_len li.file2base(sig_offset, base, base + sig_len, 1) idaapi.add_segm(0, base, base + sig_len, "__SIGNATURE", "DATA") idc.create_byte(base) idc.make_array(base, sig_len) idc.set_name(base, "AFU_SIGNATURE") # check if __TEXT starts with an SRAM address # this is the initial MSP that is followed by exception vectors initMSP = idc.Dword(msp_base) print "initMSP 0x%x" % initMSP if (initMSP >= SRAM_BASE) and initMSP <= (SRAM_BASE + SRAM_SIZE): idc.set_name(msp_base, "init_MSP") idc.create_dword(msp_base) idc.op_plain_offset(msp_base, -1, 0) idc.set_cmt(msp_base, "Initial MSP value", 0) # these are now the exception vectors # determine how many exception vectors there are cnt = 0 handlers = {} last_multi = None multi = False while cnt < 255: ptr = idc.Dword(msp_base + 4 + 4 * cnt) if ptr != 0: # must be inside __TEXT if (ptr < fw_base) or (ptr > fw_base + fw_len): break if (ptr & 1) == 0: # must be thumb mode break # convert into a dword + offset idc.create_dword(msp_base + 4 + 4 * cnt) if ptr != 0: idc.op_offset(msp_base + 4 + 4 * cnt, 0, idc.REF_OFF32, -1, 0, 0) idc.set_cmt( msp_base + 4 + 4 * cnt, "exception %d: %s" % (cnt + 1, exception_table[cnt + 1]), 0) # should only RESET vector be our entrypoint? idc.add_entry(ptr & ~1, ptr & ~1, "", 1) # remember how often we see each handler if ptr != 0: if handlers.has_key(ptr): handlers[ptr] += 1 if last_multi != None: if last_multi != ptr: multi = True last_multi = ptr else: handlers[ptr] = 1 cnt += 1 print "cnt: %d" % cnt if cnt > 0: i = 1 while i <= cnt: ptr = idc.Dword(msp_base + 4 * i) if ptr != 0: # ensure this is if handlers[ptr] == 1: idc.set_name( ptr & ~1, "%s_%s" % (EXCEPTION_PREFIX, exception_table[i])) elif not multi: idc.set_name(ptr & ~1, "%s_%s" % (EXCEPTION_PREFIX, "UNIMPL")) i += 1 return 1
def get_data_guids(self): ''' rename GUIDs in idb ''' EFI_GUID = 'EFI_GUID *' EFI_GUID_ID = idc.get_struc_id('EFI_GUID') segments = ['.text', '.data'] for segment in segments: seg_start, seg_end = 0, 0 for seg in idautils.Segments(): if idc.get_segm_name(seg) == segment: seg_start = idc.get_segm_start(seg) seg_end = idc.get_segm_end(seg) break ea = seg_start while (ea <= seg_end - 15): prot_name = '' if idc.get_name(ea, ida_name.GN_VISIBLE).find('unk_') != -1: find = False cur_guid = [] cur_guid.append(idc.get_wide_dword(ea)) cur_guid.append(idc.get_wide_word(ea + 4)) cur_guid.append(idc.get_wide_word(ea + 6)) for addr in range(ea + 8, ea + 16, 1): cur_guid.append(idc.get_wide_byte(addr)) if cur_guid == [0] * 11: ea += 1 continue for name in self.Protocols['Edk2Guids']: if self.Protocols['Edk2Guids'][name] == cur_guid: prot_name = name + '_' + '{addr:#x}'.format( addr=ea) record = { 'address': ea, 'service': 'unknown', 'guid': cur_guid, 'protocol_name': name, 'protocol_place': 'edk2_guids' } find = True break for name in self.Protocols['EdkGuids']: if self.Protocols['EdkGuids'][name] == cur_guid: prot_name = name + '_' + '{addr:#x}'.format( addr=ea) prot_name = name + '_' + '{addr:#x}'.format( addr=ea) record = { 'address': ea, 'service': 'unknown', 'guid': cur_guid, 'protocol_name': name, 'protocol_place': 'edk_guids' } find = True break for name in self.Protocols['AmiGuids']: if self.Protocols['AmiGuids'][name] == cur_guid: prot_name = name + '_' + '{addr:#x}'.format( addr=ea) prot_name = name + '_' + '{addr:#x}'.format( addr=ea) record = { 'address': ea, 'service': 'unknown', 'guid': cur_guid, 'protocol_name': name, 'protocol_place': 'ami_guids' } find = True break if find and (idc.get_name(ea, ida_name.GN_VISIBLE) != prot_name): idc.SetType(ea, EFI_GUID) self.apply_struct(ea, 16, EFI_GUID_ID) idc.set_name(ea, prot_name) self.Protocols['Data'].append(record) ea += 1
def cb_btn_run(self): if self.dotnet_version_full == "unknown": ida_kernwin.warning(".NET Native framework could not be identified.\n"\ ".NIET needs it to work properly.") return # self.dotnet_version_full[:3] is "major.minor" if not self.dotnet_version_full[:3] in dotnet_versions_offsets: ida_kernwin.warning(".NIET currently does not support %s, please "\ "create an issue.") return instance = dotNIET(self.dotnet_version_full[:3]) instance.get_modules_info() # if "restore" is checked, everything else is greyed out if self.cb_restore.checkState() == QtCore.Qt.Checked: ida_kernwin.show_wait_box("HIDECANCEL\nClearing symbol names...") for i in range(instance.nb_symbols): # unset name of imports idc.set_name(instance.ordinals + i * 8, "") idaapi.msg("%d symbols removed!\n" % instance.nb_symbols) else: if self.dll_input_path.text() == "": idaapi.msg( "Error: \"SharedLibrary.dll\" path must be selected\n") del instance return # target SharedLibrary.dll .NET framework version is asked to be checked if self.cb_verify.checkState() == QtCore.Qt.Checked: ida_kernwin.show_wait_box("HIDECANCEL\nVerifying target dll "\ ".NET Native framework version...") dll_dotnet_version_full = utils.get_NET_Native_version( self.dll_input_path.text()) ida_kernwin.hide_wait_box() if dll_dotnet_version_full == "unknown" \ or dll_dotnet_version_full != self.dotnet_version_full: answer = ida_kernwin.ask_buttons("", "","", 1, "HIDECANCEL\n"\ "Target dll .NET Native "\ "framework version is '%s' "\ "whereas current binary one "\ "is '%s'.\nProceed anyway?" \ % (dll_dotnet_version_full,\ self.dotnet_version_full)) # "No" or "cancel/escape" if not answer: return # getting target SharedLibrary.dll GUID to verify that the pdb does # exist and is the right one ida_kernwin.show_wait_box("HIDECANCEL\nGetting pdb information...") if not utils.find_pdb(self.dll_input_path.text()): ida_kernwin.hide_wait_box() del instance return # everything is okay, ready to import ida_kernwin.replace_wait_box("HIDECANCEL\nImporting symbols...") instance.resolve_symbols(self.dll_input_path.text()) idaapi.msg("%d symbols imported at 0x%x\n" % (instance.nb_symbols, instance.ordinals)) ida_kernwin.hide_wait_box() del instance
z+=1 offsets.append(notimpladdr) tbl={} x=0 for i in range(0,0x20000,ssize): vea=ea+i idv=ida_bytes.get_dword(vea) if idv==0x660066: break cmdid=ida_bytes.get_dword(vea) eaaddr=ida_bytes.get_dword(vea+4) ida_bytes.del_items(eaaddr, ida_bytes.DELIT_DELNAMES, ssize) ida_funcs.add_func(eaaddr) info="%08X" % eaaddr if x<len(names): if eaaddr in badoffsets: name=badoffsets[eaaddr] else: if cmdid in names: name="atcmd_"+names[cmdid][1:] print(info+" AT"+names[cmdid]+":"+str(x)) idc.set_name(eaaddr, name, idc.SN_NOWARN) ida_bytes.del_items(vea, ida_bytes.DELIT_DELNAMES,ssize) ida_bytes.create_struct(vea, ssize, sid) if cmdid in names: idc.set_cmt(vea, "AT"+names[cmdid],0) x+=1
def run(self, arg): apiPurposeDict = { 'socket': 'netwB', 'WSAStartup': 'netwC', 'connect': 'netwC', 'InternetOpen': 'netwC', 'InternetConnect': 'netwC', 'InternetOpenURL': 'netwC', 'HttpOpenRequest': 'netwC', 'WinHttpConnect': 'netwC', 'WinHttpOpenRequest': 'netwC', 'bind': 'netwL', 'listen': 'netwL', 'accept': 'netwL', 'send': 'netwS', 'sendto': 'netwS', 'InternetWriteFile': 'netwS', 'HttpSendRequest': 'netwS', 'WSASend': 'netwS', 'WSASendTo': 'netwS', 'WinHttpSendRequest': 'netwS', 'WinHttpWriteData': 'netwS', 'recv': 'netwR', 'recvfrom': 'netwR', 'InternetReadFile': 'netwR', 'HttpReceiveHttpRequest': 'netwR', 'WSARecv': 'netwR', 'WSARecvFrom': 'netwR', 'WinHttpReceiveResponse': 'netwR', 'WinHttpReadData': 'netwR', 'URLDownloadToFile': 'netwR', 'inet_addr': 'netwM', 'htons': 'netwM', 'htonl': 'netwM', 'ntohs': 'netwM', 'ntohl': 'netwM', 'RegOpenKey': 'regH', 'RegQueryValue': 'regR', 'RegGetValue': 'regR', 'RegEnumValue': 'regR', 'RegSetValue': 'regW', 'RegSetKeyValue': 'regW', 'RegDeleteValue': 'regD', 'RegDeleteKey': 'regD', 'RegDeleteKeyValue': 'regD', 'RegCreateKey': 'regC', 'CreateFile': 'fileH', 'fopen': 'fileH', 'fscan': 'fileR', 'fgetc': 'fileR', 'fgets': 'fileR', 'fread': 'fileR', 'ReadFile': 'fileR', 'flushfilebuffers': 'fileW', 'fprintf': 'fileW', 'fputc': 'fileW', 'fputs': 'fileW', 'fwrite': 'fileW', 'WriteFile': 'fileW', 'DeleteFile': 'fileD', 'CopyFile': 'fileC', 'MoveFile': 'fileM', 'FindFirstFile': 'fileE', 'FindNextFile': 'fileE', 'strcmp': 'strC', 'strncmp': 'strC', 'stricmp': 'strC', 'wcsicmp': 'strC', 'mbsicmp': 'strC', 'lstrcmp': 'strC', 'lstrcmpi': 'strC', 'OpenService': 'servH', 'QueryServiceStatus': 'servR', 'QueryServiceConfig': 'servR', 'ChangeServiceConfig': 'servW', 'ChangeServiceConfig2': 'servW', 'CreateService': 'servC', 'DeleteService': 'servD', 'StartService': 'servS', 'CreateToolhelp32Snapshot': 'procE', 'Process32First': 'procE', 'Process32Next': 'procE', 'OpenProcess': 'procH', 'CreateProcess': 'procC', 'CreateProcessAsUser': '******', 'CreateProcessWithLogon': 'procC', 'CreateProcessWithToken': 'procC', 'ShellExecute': 'procC', 'ReadProcessMemory': 'procR', 'WriteProcessMemory': 'procW', 'CreateThread': 'threadC', 'beginthread': 'threadC', 'OpenThread': 'threadO', 'SuspendThread': 'threadS', 'ResumeThread': 'threadR', } for function in idautils.Functions(): function_name = idc.get_func_name(function) if function_name.startswith("sub"): function_start = idc.get_func_attr(function, idc.FUNCATTR_START) function_end = idc.get_func_attr(function, idc.FUNCATTR_END) function_name_new = "" functions_error = set() #idaapi.msg(f"{function_name} - {hex(function_start)} - {hex(function_end)}\n") for i in range(function_start, function_end): if idc.print_insn_mnem(i) == "call" and not "word" in str( idc.print_operand(i, 0)) and not "sub" in str( idc.print_operand(i, 0)): #idaapi.msg(f"{idc.print_insn_mnem(i)} - {idc.print_operand(i, 0)}\n") try: #idaapi.msg(str(idc.print_operand(i, 0)).replace("Ex","").replace("_","").replace("cs:","").replace("A","").replace("W","")+"\n") key = str(idc.print_operand(i, 0)).replace( "Ex", "").replace("_", "").replace("cs:", "").replace("ds:", "") if key[-1] == "W" or key[-1] == "A": key = key[:-1] if apiPurposeDict[key]: function_name_new += "_" + apiPurposeDict[str( idc.print_operand(i, 0)).replace( "Ex", "").replace("_", "").replace( "cs:", "").replace("ds:", "")] except KeyError: idaapi.msg(f' Key Error for {key}\n') open("functions_error.txt", "a").write("'" + key + "'" + ":" + "'" + key.lower() + "',") idc.set_name(function_start, function_name_new, idc.SN_NOWARN) idaapi.msg(f"{function_name} -> {function_name_new}\n")
def refresh(self): if self.ea != idc.BADADDR: mangled = self.get_mangled() idc.set_name(self.ea, mangled, idc.SN_CHECK) self.refresh_comments()
def prep_vtable(linuxtable, key, wintable, winv): if not linuxtable.get(key): return None funclist = linuxtable[key] # Compat for 2.7, strings are in unicode if version_info[0] < 3: funclist = [ i if isinstance(i, (int, long)) else str(i) for i in linuxtable[key] ] thunks, thunklist = get_thunks(winv, key, funclist) # We've got the thunks, now we don't need anything beyond another typeinfo instance = (int, long) if version_info[0] < 3 else int for i, v in enumerate(funclist): if isinstance(v, instance): funclist = funclist[:i] # Skipping thisoffs break # Get rid of extra destructor for linux for i, n in enumerate(funclist): name = idc.demangle_name(n, idc.get_inf_attr(idc.INF_SHORT_DN)) if name: if "::~" in name: del funclist[i] break # Windows does overloads backwards, reverse them # Also check for thunks while we're at it i = 0 funcoverloads = {} while i < len(funclist): # and i < len(wintable): n = funclist[i] if n.startswith("__cxa"): i += 1 continue # I shouldn't need to do this, but destructors are wonky if i == 0: demangled = idc.demangle_name(n, idc.get_inf_attr(idc.INF_SHORT_DN)) if demangled and "::~" in demangled: i += 1 continue overloadname = get_func_sname(n) shortname = get_func_postname(n) if not shortname: i += 1 continue # Windows skips the vtable function if it exists in the thunks and # the thunk does not jmp into it (because the thunk is the function) try: thunkidx = thunklist.index(shortname) delete = 1 except: thunkidx = -1 delete = 0 if i < len(wintable): if thunkidx != -1 and thunkidx < len(thunks): if not isinthunk(wintable[i], thunks[thunkidx]): currname = idc.get_name(thunks[thunkidx][0], ida_name.GN_VISIBLE) if currname and currname != funclist[ i] and EXPORT_MODE != Export_YesOnly: nameflags = ida_name.SN_FORCE if not currname.startswith("sub_"): if not USE_WEAK_NAMES: del funclist[i] continue nameflags |= ida_name.SN_WEAK elif USE_WEAK_NAMES: global FUNCS FUNCS += 1 idc.set_name(thunks[thunkidx][0], funclist[i], nameflags) del funclist[i] continue else: # Class has thunks at the end of the vtable # This doesn't change anything but it should link up the lengths of both tables if delete: del funclist[i] continue node = funcoverloads.get(overloadname, []) # Is this a half-ass decent overload go = 1 for loadnode in range(len(node)): if not any( [i - funclist.index(val) > F**K for val in node[loadnode]]): node[loadnode].append(n) go = 0 break if go: node.append([n]) funcoverloads[overloadname] = node i += 1 for k, value in get_bcompat_items(funcoverloads): # if len(value) <= 1: # continue # split = [] # # # Since subclass overloads shouldn't scoot up next to their baseclass brethren # # hackily separate overloads by classname # for mname in value: # found = 0 # # name = idc.demangle_name(mname, idc.get_inf_attr(idc.INF_SHORT_DN)) # typename = name[:name.find("::")] # # for i2 in range(len(split)): # for othermname in split[i2]: # name = idc.demangle_name(othermname, idc.get_inf_attr(idc.INF_SHORT_DN)) # othertypename = name[:name.find("::")] # # if typename == othertypename: # found = 1 # split[i2].append(mname) # break # # if found: # break # # if not found: # split.append([mname]) for v in value: if len(v) <= 1: continue lowestidx = len(funclist) for func in v: temp = funclist.index(func) if lowestidx > temp: lowestidx = temp count = 0 while len(v): k = v.pop() funclist.insert(lowestidx + count, funclist.pop(funclist.index(k))) count += 1 diff = len(funclist) - len(wintable) if diff: print("WARNING: {} vtable may be wrong! L{} - W{} = {}".format( key, len(funclist), len(wintable), diff)) return funclist
def lvar_type_changed(self, vu, v, tif): if (vu.cfunc): func_tif = ida_typeinf.tinfo_t() vu.cfunc.get_func_type(func_tif) funcdata = idaapi.func_type_data_t() got_data = func_tif.get_func_details(funcdata) if (not got_data): # self._log("Didnt get the data") pass lvars = vu.cfunc.get_lvars() for j in range(len(vu.cfunc.argidx)): # for i in vu.cfunc.argidx: i = vu.cfunc.argidx[j] if (lvars[i].name == v.name): #self._log("lvar_type_changed: function argument changed = %s, index = %s, atype = %s" % (lvars[i].name, i, funcdata[j].argloc.atype())) if (funcdata[i].argloc.atype() == 3): # self._log("lvar_type_changed: reg is : %s" %(funcdata[i].argloc.reg1())) pass if (funcdata[i].argloc.atype() != 3 or funcdata[i].argloc.reg1() != RCX_REG): break #self._log("applyName = %s" % (applyName)) firstPtrRemove = ida_typeinf.remove_pointer(tif) #self._log("type name = %s" % (firstPtrRemove._print())) #self._log("remove_pointer.is_ptr = %s" % (firstPtrRemove.is_ptr())) #self._log("remove_pointer.is_struct = %s" % (firstPtrRemove.is_struct())) if (firstPtrRemove.is_struct() and not firstPtrRemove.is_ptr()): currentFuncName = ida_name.get_ea_name( vu.cfunc.entry_ea) # self._log("before demangle current func name = %s" % (currentFuncName)) demangled = idc.demangle_name( currentFuncName, idc.get_inf_attr(idc.INF_SHORT_DN)) if (demangled != None): self._log("Overriding mangled name = %s" % (currentFuncName)) currentFuncName = demangled # self._log("after demangle current func name = %s" % (currentFuncName)) tokens = currentFuncName.split("::") if len(tokens) > 1: currentFuncName = tokens[1] currentFuncName = currentFuncName.split("(")[0] # self._log("current func name = %s" % (currentFuncName)) idc.set_name( vu.cfunc.entry_ea, firstPtrRemove._print() + "::" + currentFuncName, idc.SN_NOWARN) idaapi.auto_wait() # self._log("Decomp Res : %s" % idaapi.decompile(vu.cfunc.entry_ea)) idaapi.refresh_idaview_anyway() vu.refresh_ctext() idaapi.refresh_idaview_anyway() vu.refresh_ctext() vu.refresh_view(True) current_widget = idaapi.get_current_widget() vu1 = idaapi.get_widget_vdui(current_widget) if vu1: vu1.refresh_ctext() break #self._log("lvar_type_changed: vu=%s, v=%s, tinfo=%s" % (vu, self._format_lvar(v), tif._print())) return 1
def resolve(self, function): if 'Function' in self.info() and self.VALUE > 0: idc.set_name(self.VALUE, function, SN_NOCHECK | SN_NOWARN)
def io_naming(): idc.set_name(0x04000000, "LCDControl", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000000, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000002, "Undocumented-GreenSwap", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000002, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000004, "GeneralLCDStatus(STAT,LYC)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000004, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000006, "VerticalCounter(LY)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000006, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000008, "BG0Control", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000008, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400000A, "BG1Control", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x0400000A, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400000C, "BG2Control", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x0400000C, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400000E, "BG3Control", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x0400000E, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000010, "BG0X-Offset", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000010, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000012, "BG0Y-Offset", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000012, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000014, "BG1X-Offset", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000014, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000016, "BG1Y-Offset", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000016, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000018, "BG2X-Offset", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000018, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400001A, "BG2Y-Offset", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x0400001A, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400001C, "BG3X-Offset", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x0400001C, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400001E, "BG3Y-Offset", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x0400001E, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000020, "BG2Rotation/ScalingParameterA(dx)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000020, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000022, "BG2Rotation/ScalingParameterB(dmx)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000022, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000024, "BG2Rotation/ScalingParameterC(dy)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000024, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000026, "BG2Rotation/ScalingParameterD(dmy)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000026, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000028, "BG2ReferencePointX-Coordinate", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000028, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x0400002C, "BG2ReferencePointY-Coordinate", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x0400002C, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x04000030, "BG3Rotation/ScalingParameterA(dx)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000030, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000032, "BG3Rotation/ScalingParameterB(dmx)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000032, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000034, "BG3Rotation/ScalingParameterC(dy)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000034, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000036, "BG3Rotation/ScalingParameterD(dmy)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000036, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000038, "BG3ReferencePointX-Coordinate", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000038, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x0400003C, "BG3ReferencePointY-Coordinate", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x0400003C, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x04000040, "Window0HorizontalDimensions", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000040, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000042, "Window1HorizontalDimensions", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000042, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000044, "Window0VerticalDimensions", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000044, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000046, "Window1VerticalDimensions", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000046, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000048, "InsideofWindow0and1", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000048, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400004A, "InsideofOBJWindow&OutsideofWindows", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x0400004A, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400004C, "MosaicSize", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x0400004C, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400004E, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000050, "ColorSpecialEffectsSelection", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000050, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000052, "AlphaBlendingCoefficients", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000052, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000054, "Brightness(Fade-In/Out)Coefficient", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000054, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000056, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000060, "Channel1Sweepregister(NR10)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000060, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000062, "Channel1Duty/Length/Envelope(NR11,NR12)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000062, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000064, "Channel1Frequency/Control(NR13,NR14)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000064, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000066, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000068, "Channel2Duty/Length/Envelope(NR21,NR22)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000068, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400006A, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x0400006C, "Channel2Frequency/Control(NR23,NR24)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x0400006C, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400006E, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000070, "Channel3Stop/WaveRAMselect(NR30)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000070, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000072, "Channel3Length/Volume(NR31,NR32)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000072, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000074, "Channel3Frequency/Control(NR33,NR34)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000074, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000076, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000078, "Channel4Length/Envelope(NR41,NR42)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000078, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400007A, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x0400007C, "Channel4Frequency/Control(NR43,NR44)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x0400007C, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400007E, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000080, "ControlStereo/Volume/Enable(NR50,NR51)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000080, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000082, "ControlMixing/DMAControl", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000082, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000084, "ControlSoundon/off(NR52)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000084, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000086, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000088, "SoundPWMControl", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000088, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400008A, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000090, "Channel3WavePatternRAM(2banks!!)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x040000A0, "ChannelAFIFO,Data0-3", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000A0, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x040000A4, "ChannelBFIFO,Data0-3", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000A4, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x040000A8, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x040000B0, "DMA0SourceAddress", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000B0, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x040000B4, "DMA0DestinationAddress", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000B4, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x040000B8, "DMA0WordCount", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000B8, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x040000BA, "DMA0Control", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000BA, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x040000BC, "DMA1SourceAddress", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000BC, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x040000C0, "DMA1DestinationAddress", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000C0, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x040000C4, "DMA1WordCount", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000C4, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x040000C6, "DMA1Control", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000C6, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x040000C8, "DMA2SourceAddress", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000C8, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x040000CC, "DMA2DestinationAddress", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000CC, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x040000D0, "DMA2WordCount", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000D0, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x040000D2, "DMA2Control", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000D2, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x040000D4, "DMA3SourceAddress", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000D4, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x040000D8, "DMA3DestinationAddress", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000D8, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x040000DC, "DMA3WordCount", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000DC, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x040000DE, "DMA3Control", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000DE, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x040000E0, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000100, "Timer0Counter/Reload", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000100, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000102, "Timer0Control", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000102, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000104, "Timer1Counter/Reload", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000104, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000106, "Timer1Control", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000106, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000108, "Timer2Counter/Reload", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000108, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400010A, "Timer2Control", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x0400010A, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400010C, "Timer3Counter/Reload", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x0400010C, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400010E, "Timer3Control", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x0400010E, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000110, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000120, "SIOData(Normal-32bitMode)(sharedwithbelow!)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000120, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x04000120, "SIOData0(Parent)(Multi-PlayerMode)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000120, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000122, "SIOData1(1stChild)(Multi-PlayerMode)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000122, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000124, "SIOData2(2ndChild)(Multi-PlayerMode)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000124, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000126, "SIOData3(3rdChild)(Multi-PlayerMode)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000126, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000128, "SIOControlRegister", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000128, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400012A, "SIOData(LocalofMulti-Player)(sharedbelow)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x0400012A, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400012A, "SIOData(Normal-8bitandUARTMode)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x0400012A, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400012C, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000130, "KeyStatus", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000130, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000132, "KeyInterruptControl", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000132, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000134, "SIOModeSelect/GeneralPurposeData", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000134, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000136, "IRAncient-InfraredRegister(Prototypesonly)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000138, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000140, "SIOJOYBusControl", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000140, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000142, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000150, "SIOJOYBusReceiveData", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000150, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x04000154, "SIOJOYBusTransmitData", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000154, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x04000158, "SIOJOYBusReceiveStatus", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000158, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400015A, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000200, "InterruptEnableRegister", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000200, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000202, "InterruptRequestFlags/IRQAcknowledge", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000202, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000204, "GamePakWaitstateControl", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000204, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000206, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000208, "InterruptMasterEnableRegister", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000208, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400020A, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000300, "Undocumented-PostBootFlag", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000300, idc.FF_BYTE, 1, idaapi.BADADDR) idc.set_name(0x04000301, "Undocumented-PowerDownControl", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000301, idc.FF_BYTE, 1, idaapi.BADADDR) idc.set_name(0x04000302, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000411, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000800, "Undocumented-InternalMemoryControl(R/W)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000800, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x04000804, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN)
print key tmp = addr for i in range(0, size * 2): tmp = idc.prev_head(tmp) plain = '' ctaddr = idc.GetOperandValue(tmp, 1) varaddr = ctaddr byte = Byte(ctaddr) while byte != 0x00: plain += chr(byte ^ key) ctaddr += 1 byte = Byte(ctaddr) print plain addr = idc.prev_head(idc.prev_head(addr)) idc.set_name(varaddr, "_a{}".format(plain)) addr_array = [0x403731, 0x40373C, 0x403747, 0x403752, 0x40375D, 0x403768] for addr in addr_array: plain = "" text = idc.GetOperandValue(addr, 1) tmp = text key = idc.GetOperandValue(0x403F67, 1) byte = Byte(text) while byte != 0x00: plain += chr(byte ^ key) text += 1 byte = Byte(text) print plain plain = plain.replace(' ', '_')
def set_symbol_name(ea, name): global _FORCED_NAMES flags = idaapi.SN_PUBLIC | idaapi.SN_NOCHECK | idaapi.SN_NON_AUTO | idaapi.SN_NOWARN _FORCED_NAMES[ea] = name idc.set_name(ea, name, flags)
def __call__(self): flags = ida_name.SN_LOCAL if self.local_name else 0 idc.set_name(self.ea, self.new_name, flags | ida_name.SN_NOWARN)
def load_file(li, neflags, fmt): idaapi.set_processor_type( "arm", idaapi.SETPROC_LOADER_NON_FATAL | idaapi.SETPROC_LOADER) idc.set_inf_attr(idc.INF_LFLAGS, idc.get_inf_attr(idc.INF_LFLAGS) | idc.LFLG_64BIT) idc.set_inf_attr(idc.INF_DEMNAMES, idaapi.DEMNAM_GCC3) idaapi.set_compiler_id(idaapi.COMP_GNU) idaapi.add_til('gnulnx_arm64', 1) # Get the meta offset meta_ofs = find_kernel_meta(li) assert meta_ofs != -1 # Read important offsets. li.seek(meta_ofs + 0x40) text_base, init_base, init_base2, kernel_end = struct.unpack( '<QQQQ', li.read(0x20)) # Load the init segment. li.seek(0) init_data = li.read(KERNEL_INIT_SIZE) idaapi.mem2base(init_data, init_base) # Emulate the kernel init segment to determine interesting extents emu = Emulator() emu.run_emulator(init_base, init_data) builder = SegmentBuilder() builder.add_segment(init_base, KERNEL_INIT_SIZE, '.init', 'RWX') text_phys = 0 text_size = 0 ro_size = 0 rw_size = 0 core_dram_mappings = [] for (virt_addr, size, phys_addr, attr) in emu.mappings: print('%x, %x, %x, %x' % (virt_addr, size, phys_addr, attr)) assert attr in [ 0x4000000000078B, 0x78B, 0x6000000000078B, 0x6000000000070B, 0x60000000000607, 0x60000000000709 ] if attr == 0x78B or attr == 0x4000000000078B: # .text assert virt_addr == text_base builder.add_segment(virt_addr, size, '.text', 'CODE') li.seek(phys_addr - init_base) idaapi.mem2base(li.read(size), virt_addr) text_phys = phys_addr text_size = size elif attr == 0x6000000000078B: # .rodata assert text_size != 0 assert virt_addr == text_base + text_size builder.add_segment(virt_addr, size, '.rodata', 'CONST') li.seek(phys_addr - init_base) idaapi.mem2base(li.read(size), virt_addr) ro_size = size elif attr == 0x6000000000070B and virt_addr == text_base + text_size + ro_size: assert text_size != 0 assert ro_size != 0 # .rwdata builder.add_segment(virt_addr, size, '.rwdata', 'DATA') li.seek(phys_addr - init_base) idaapi.mem2base(li.read(size), virt_addr) rw_size = size elif attr == 0x60000000000607: # IO DEVICES = { (0x40000000, 0x40000): '.iram', (0x50041000, 0x01000): '.gicd', (0x50042000, 0x01000): '.gicc', (0x60001000, 0x01000): '.semaphore', (0x60004000, 0x01000): '.primary_ictlr', (0x60006000, 0x01000): '.clkrst', (0x60007000, 0x01000): '.flow_ctlr', (0x6000F000, 0x01000): '.evp', (0x70006000, 0x01000): '.uart', (0x7000E000, 0x01000): '.rtc_pmc', (0x70016000, 0x02000): '.atomics', (0x70019000, 0x01000): '.mc', (0x7001C000, 0x01000): '.mc0', (0x7001D000, 0x01000): '.mc1', } assert (phys_addr, size) in DEVICES.keys() name = DEVICES[(phys_addr, size)] builder.add_segment(virt_addr, size, name, 'IO') elif attr == 0x6000000000070B: # Kernel DRAM if phys_addr == (emu.ttbr & ~0xFFF) and size == 0x1000: builder.add_segment(virt_addr, size, '.ttbr1', 'DATA') else: core_dram_mappings.append( (virt_addr, size, phys_addr, attr)) else: # Linear DRAM assert attr == 0x60000000000709 idaapi.add_segm(0, virt_addr, virt_addr + size, '.linear_dram', 'DATA', idaapi.ADDSEG_SPARSE) segm = idaapi.get_segm_by_name('.linear_dram') segm.perm = idaapi.SEGPERM_READ | idaapi.SEGPERM_WRITE idaapi.update_segm(segm) idaapi.set_segm_addressing(segm, 2) assert len(core_dram_mappings) % 5 == 0 if len(core_dram_mappings) // 5 == 3: # 1.0.0-style core local mappings assert core_dram_mappings[ 0 + 0][2] == core_dram_mappings[0 + 3][2] - 0x2000 assert core_dram_mappings[ 0 + 3][2] == core_dram_mappings[0 + 6][2] - 0x2000 assert core_dram_mappings[ 0 + 6][2] == core_dram_mappings[0 + 9][2] - 0x2000 assert core_dram_mappings[0 + 0][2] == core_dram_mappings[0 + 12][2] assert core_dram_mappings[ 1 + 0][2] == core_dram_mappings[1 + 3][2] - 0x2000 assert core_dram_mappings[ 1 + 3][2] == core_dram_mappings[1 + 6][2] - 0x2000 assert core_dram_mappings[ 1 + 6][2] == core_dram_mappings[1 + 9][2] - 0x2000 assert core_dram_mappings[1 + 0][2] == core_dram_mappings[1 + 12][2] assert core_dram_mappings[ 2 + 0][2] == core_dram_mappings[2 + 3][2] - 0x1000 assert core_dram_mappings[ 2 + 3][2] == core_dram_mappings[2 + 6][2] - 0x1000 assert core_dram_mappings[ 2 + 6][2] == core_dram_mappings[2 + 9][2] - 0x1000 assert core_dram_mappings[2 + 0][2] == core_dram_mappings[2 + 12][2] builder.add_segment(core_dram_mappings[0][0], 0xA000 * 4, '.core_local_regions', 'DATA') builder.add_segment(core_dram_mappings[3 * 4 + 0][0], core_dram_mappings[3 * 4 + 0][1], '.current_common_stack', 'DATA') builder.add_segment(core_dram_mappings[3 * 4 + 1][0], core_dram_mappings[3 * 4 + 1][1], '.current_main_stack', 'DATA') builder.add_segment(core_dram_mappings[3 * 4 + 2][0], core_dram_mappings[3 * 4 + 2][1], '.current_context', 'DATA') elif len(core_dram_mappings) // 5 == 4: # 3.0.0-style core local mappings assert core_dram_mappings[ 0 + 0][2] == core_dram_mappings[0 + 4][2] - 0x2000 assert core_dram_mappings[ 0 + 4][2] == core_dram_mappings[0 + 8][2] - 0x2000 assert core_dram_mappings[ 0 + 8][2] == core_dram_mappings[0 + 12][2] - 0x2000 assert core_dram_mappings[0 + 0][2] == core_dram_mappings[0 + 16][2] assert core_dram_mappings[ 1 + 0][2] == core_dram_mappings[1 + 4][2] - 0x2000 assert core_dram_mappings[ 1 + 4][2] == core_dram_mappings[1 + 8][2] - 0x2000 assert core_dram_mappings[ 1 + 8][2] == core_dram_mappings[1 + 12][2] - 0x2000 assert core_dram_mappings[1 + 0][2] == core_dram_mappings[1 + 16][2] assert core_dram_mappings[ 2 + 0][2] == core_dram_mappings[2 + 4][2] - 0x2000 assert core_dram_mappings[ 2 + 4][2] == core_dram_mappings[2 + 8][2] - 0x2000 assert core_dram_mappings[ 2 + 8][2] == core_dram_mappings[2 + 12][2] - 0x2000 assert core_dram_mappings[2 + 0][2] == core_dram_mappings[2 + 16][2] assert core_dram_mappings[ 3 + 0][2] == core_dram_mappings[3 + 4][2] - 0x1000 assert core_dram_mappings[ 3 + 4][2] == core_dram_mappings[3 + 8][2] - 0x1000 assert core_dram_mappings[ 3 + 8][2] == core_dram_mappings[3 + 12][2] - 0x1000 assert core_dram_mappings[3 + 0][2] == core_dram_mappings[3 + 16][2] builder.add_segment(core_dram_mappings[0][0], 0xE000 * 4, '.core_local_regions', 'DATA') builder.add_segment(core_dram_mappings[4 * 4 + 0][0], core_dram_mappings[4 * 4 + 0][1], '.current_common_stack', 'DATA') builder.add_segment(core_dram_mappings[4 * 4 + 1][0], core_dram_mappings[4 * 4 + 1][1], '.current_main_stack', 'DATA') builder.add_segment(core_dram_mappings[4 * 4 + 2][0], core_dram_mappings[4 * 4 + 2][1], '.current_idle_stack', 'DATA') builder.add_segment(core_dram_mappings[4 * 4 + 3][0], core_dram_mappings[4 * 4 + 3][1], '.current_context', 'DATA') seg_prefix = '' for start, end, name, kind in builder.flatten(): idaapi.add_segm(0, start, end, seg_prefix + name, kind) segm = idaapi.get_segm_by_name(seg_prefix + name) if kind == 'CONST': segm.perm = idaapi.SEGPERM_READ elif kind == 'CODE': segm.perm = idaapi.SEGPERM_READ | idaapi.SEGPERM_EXEC elif kind == 'DATA': segm.perm = idaapi.SEGPERM_READ | idaapi.SEGPERM_WRITE elif kind == 'BSS': segm.perm = idaapi.SEGPERM_READ | idaapi.SEGPERM_WRITE elif kind == 'RWX': segm.perm = idaapi.SEGPERM_READ | idaapi.SEGPERM_WRITE | idaapi.SEGPERM_EXEC elif kind == 'IO': segm.perm = idaapi.SEGPERM_READ | idaapi.SEGPERM_WRITE idaapi.update_segm(segm) idaapi.set_segm_addressing(segm, 2) # Set vector types as code. for i, ctx in enumerate(['sp0', 'spx', 'a64', 'a32']): for j, kind in enumerate(['synch', 'irq', 'fiq', 'serror']): addr = emu.vbar + 0x200 * i + 0x80 * j name = '%s_%s_exception' % (kind, ctx) idc.create_insn(addr) idc.set_name(addr, name) # Set .init as code. idc.create_insn(init_base) idc.set_name(init_base, 'crt0') # Set text start as code. idc.create_insn(text_base) idc.set_name(text_base, 'HorizonKernelMain') # Patch movk instructions to be better understandable by ida. li.seek(text_phys - init_base) text = li.read(text_size) ro_rw = li.read(ro_size + rw_size) patch_movk_to_adrp(text_base, text, ro_rw, emu.mappings) return 1
def writeAddrName(addr, name): idc.set_name(addr, name + "Entrypoint", SN_NOCHECK) idc.set_name(addr + getBranchOffset(ida_bytes.get_dword(addr)), name, SN_NOCHECK) print hex(addr + getBranchOffset(ida_bytes.get_dword(addr)))
def setName(self, addr, name, size=0): idc.set_name(addr, name, idc.SN_NOCHECK)
def make_name(self, offset, name, flags=0): """Name the given offset in the IDB""" self.ret = idc.set_name(offset, str(name), idc.SN_NOCHECK | idc.SN_NOWARN | 0x800) return self.ret
def rename_symbol(self): """ Rename the symbol "symbol" with the new name provided by the user in the Pop-Up """ # Get the symbol symbol = None ret = ida_kernwin.get_highlight(ida_kernwin.get_current_viewer()) if ret and ret[1]: symbol = ret[0] if not symbol: idaapi.warning("Select a symbol") return False # Get the address address = gl.get_address_for_symbol(symbol) if not address: print("GhIDA:: [!] Symbol %s not found" % symbol) return False # Display a Pop-up to get the new name new_name = gl.display_rename_form(address, symbol) if not new_name or len(new_name) == 0: return # Check for white_spaces in the new symbol name for letter in new_name: if not (letter.isdigit() or letter.isalpha() or letter == '_'): print("GhIDA:: [!] symbol name contains invalid char") return # Check if new_name is already used if gl.check_if_symbol_is_used(new_name): print("GhIDA:: [!] symble name already used") return # Update symbol name in SYMBLE DICT: gl.updated_symbol_name_for_address(symbol, address, new_name) # Update symbol name in IDA DISASM view. # print("GhIDA:: [DEBUG] New symbol name: %s" % new_name) # Update symbol name in the decompiled view new_code = gl.rename_variable_in_text(self.__decompiled, symbol, new_name) self.update(self.__ea, new_code) # Add comments comment_list = COMMENTS_CACHE.get_comments_cache(self.__ea) if comment_list: self.add_comments(comment_list) print("GhIDA:: [INFO] Symbol name updated in IDA DECOMP view.") if idc.set_name(address, new_name): # Refresh the view idaapi.request_refresh(idaapi.IWID_DISASMS) # Highlight the new identifier gl.highlight_symbol_in_DISASM() print("GhIDA:: [INFO] Symbol name updated in IDA DISASM view.") return print("GhIDA:: [!] IDA DISASM rename error") return
def MakeName(self, ea, name): if idaapi.IDA_SDK_VERSION < 700: return idc.MakeNameEx(ea, name, 256) else: return idc.set_name(ea, name, 256)
def setFunctionName(self, start: int, func_name: str) -> bool: flags = idaapi.SN_NOWARN | idaapi.SN_NOCHECK if idc.set_name(start, func_name, flags): self.updateSignal.emit() return True return False
def find_WdfDriverCreate(): function_offset = OFFSET_WdfDriverCreate # If the XREF to wdfFunctions + function_offset exists.. then we're in case 1! try: call_pfnWdfDriverCreate = idautils.XrefsTo(g_vars["_WDFFUNCTIONS"] + function_offset).next().frm except StopIteration: # this is case 2! call_pfnWdfDriverCreate = find_wdf_callback_through_immediate( "mov", 1, function_offset) if call_pfnWdfDriverCreate != None: idc.OpStroffEx(call_pfnWdfDriverCreate, 1, (idaapi.get_struc_id("_WDFFUNCTIONS")), 0) else: call_pfnWdfDriverCreate = find_wdf_callback_through_immediate( "call", 0, function_offset) idc.OpStroffEx(call_pfnWdfDriverCreate, 0, (idaapi.get_struc_id("_WDFFUNCTIONS")), 0) if call_pfnWdfDriverCreate != None: # First identify the RealDriverEntry :) current_func = idaapi.get_func(call_pfnWdfDriverCreate) idc.set_name(current_func.startEA, "_DriverEntry_") argument_DriverConfig_addr = find_function_arg_with_operand_value( call_pfnWdfDriverCreate, "mov", "rsp", 0x20, 0) register_DriverConfig = idc.print_operand(argument_DriverConfig_addr, 1) lea_DriverConfig_addr = find_function_arg(argument_DriverConfig_addr, "lea", register_DriverConfig, 0) # Get stack and the stack operand offset current_func = idaapi.get_func(lea_DriverConfig_addr) stack_id = idc.GetFrame(current_func) opnd = idc.print_operand(lea_DriverConfig_addr, 1) if "rsp" in opnd: stack_member_offset = idc.get_operand_value( lea_DriverConfig_addr, 1) elif "rbp" in opnd: var_x = opnd.split("+")[-1][:-1] # [rbp+57h+var_80] -> var_80 members, _ = retrieve_stack_members(current_func) inverted_members = {v: k for k, v in members.items()} try: stack_member_offset = inverted_members[var_x] except KeyError as msg: print(msg) return else: print("+] WdfDriverCreate() Unidentified register stack layout") return #idc.SetMemberName(stack_id, stack_member_offset, "_DriverConfig") struct_id = idaapi.get_struc_id("_WDF_DRIVER_CONFIG") struct_size = idc.GetStrucSize(struct_id) # First check if we have already touch this function stack before #if function_stack_erased(current_func): # need to take care of the already defined structs # pass #else: delete_all_function_stack_members(current_func, force=True) idc.AddStrucMember(stack_id, "driver_config", stack_member_offset, idc.FF_BYTE | idc.FF_DATA, -1, struct_size) idc.SetMemberType(stack_id, stack_member_offset, idc.FF_STRU | idc.FF_DATA, struct_id, 1)
def set_addr_name(self, ea, name): result = idc.set_name(ea, name) return bool(result)
def set_func_name(func_ea, new_name): if not idc.set_name(func_ea, new_name, ida_name.SN_CHECK | ida_name.SN_FORCE): log.warn("%08X Couldn't set func name '%s'", func_ea, new_name) return idc.get_name(func_ea)
def process_smc(func, smc_name): idc.create_insn(func) idc.set_name(func, 'smc_%s' % smc_name) disasm = get_disasm(func) if disasm[:2] == ['adrp', 'x1']: d = [ get_disasm(ea) for ea in [func, func + 4, func + 8, func + 12, func + 16] ] if not d[1][:2] == ['adrp', 'x2']: return if not d[2][:3] == ['add', 'x1', 'x1']: return if not d[3][:3] == ['add', 'x2', 'x2']: return if not d[4][0] == 'b': return func_impl = parse_adr_op(d[0][2]) + parse_adr_op(d[2][3]) gr_impl = parse_adr_op(d[1][2]) + parse_adr_op(d[3][3]) gr_name = '%s_get_result' % smc_name if smc_name == 'unwrap_titlekey': gr_name += '_data' idc.create_insn(func_impl) idc.set_name(func_impl, smc_name) idc.create_insn(gr_impl) idc.set_name(gr_impl, gr_name) if d[4][1].startswith('unk_'): async_smc = parse_adr_op(d[4][1]) idc.create_insn(async_smc) idc.set_name(async_smc, 'handle_asynchronous_smc') elif disasm[:2] == ['adrl', 'x1']: branch_d = get_disasm(func + 8) if branch_d[0] == 'b': func_impl = parse_adr_op(disasm[2]) idc.create_insn(func_impl) idc.set_name(func_impl, smc_name) if branch_d[1].startswith('unk_'): sync_smc = parse_adr_op(branch_d[1]) idc.create_insn(sync_smc) idc.set_name(sync_smc, 'handle_synchronous_smc')
def main(): print("[*] loading crypto constants") for const in non_sparse_consts: const["byte_array"] = convert_to_byte_array(const) for start in idautils.Segments(): print("[*] searching for crypto constants in %s" % idc.get_segm_name(start)) ea = start while ea < idc.get_segm_end(start): bbbb = list(struct.unpack("BBBB", idc.get_bytes(ea, 4))) for const in non_sparse_consts: if bbbb != const["byte_array"][:4]: continue if list( map(lambda x: x if type(x) == int else ord(x), idc.get_bytes(ea, len( const["byte_array"])))) == const["byte_array"]: print(("0x%0" + str(digits) + "X: found const array %s (used in %s)") % (ea, const["name"], const["algorithm"])) idc.set_name(ea, g_fc_prefix_var + const["name"], ida_name.SN_FORCE) if const["size"] == "B": ida_bytes.del_items(ea, 0, len(const["array"])) idc.create_byte(ea) elif const["size"] == "L": ida_bytes.del_items(ea, 0, len(const["array"]) * 4) idc.create_dword(ea) elif const["size"] == "Q": ida_bytes.del_items(ea, 0, len(const["array"]) * 8) idc.create_qword(ea) idc.make_array(ea, len(const["array"])) ea += len(const["byte_array"]) - 4 break ea += 4 ea = start if idc.get_segm_attr(ea, idc.SEGATTR_TYPE) == idc.SEG_CODE: while ea < idc.get_segm_end(start): d = ida_bytes.get_dword(ea) for const in sparse_consts: if d != const["array"][0]: continue tmp = ea + 4 for val in const["array"][1:]: for i in range(8): if ida_bytes.get_dword(tmp + i) == val: tmp = tmp + i + 4 break else: break else: print(("0x%0" + str(digits) + "X: found sparse constants for %s") % (ea, const["algorithm"])) cmt = idc.get_cmt(idc.prev_head(ea), 0) if cmt: idc.set_cmt( idc.prev_head(ea), cmt + ' ' + g_fc_prefix_cmt + const["name"], 0) else: idc.set_cmt(idc.prev_head(ea), g_fc_prefix_cmt + const["name"], 0) ea = tmp break ea += 1 print("[*] searching for crypto constants in immediate operand") funcs = idautils.Functions() for f in funcs: flags = idc.get_func_flags(f) if (not flags & (idc.FUNC_LIB | idc.FUNC_THUNK)): ea = f f_end = idc.get_func_attr(f, idc.FUNCATTR_END) while (ea < f_end): imm_operands = [] insn = ida_ua.insn_t() ida_ua.decode_insn(insn, ea) for i in range(len(insn.ops)): if insn.ops[i].type == ida_ua.o_void: break if insn.ops[i].type == ida_ua.o_imm: imm_operands.append(insn.ops[i].value) if len(imm_operands) == 0: ea = idc.find_code(ea, idc.SEARCH_DOWN) continue for const in operand_consts: if const["value"] in imm_operands: print(("0x%0" + str(digits) + "X: found immediate operand constants for %s") % (ea, const["algorithm"])) cmt = idc.get_cmt(ea, 0) if cmt: idc.set_cmt( ea, cmt + ' ' + g_fc_prefix_cmt + const["name"], 0) else: idc.set_cmt(ea, g_fc_prefix_cmt + const["name"], 0) break ea = idc.find_code(ea, idc.SEARCH_DOWN) print("[*] finished")
def rename(offset, name): res = idc.set_name(offset, name, idc.SN_NOWARN) if res == 0: name = name+"_autogen_"+id_generator() idc.set_name(offset, name, idc.SN_NOWARN)
def set_addr_name(self, ea, name): # print("{0} {1}".format(ea, name)) result = idc.set_name(ea, name) return bool(result)
# IDAPython script # author: weizi # # written in python3, tested on IDA Pro 7.4 """ auto rename functions in .init_array segment to init_{XXXXXXXX} """ import idc import idaapi import idautils init_array_segm = idaapi.get_segm_by_name('.init_array') segm_start_ea = init_array_segm.start_ea segm_end_ea = init_array_segm.end_ea print(f"segm: start_ea={segm_start_ea:#x}, end_ea={segm_end_ea:#x}") info = idaapi.get_inf_structure() if info.is_64bit(): size = 8 get_ptr = idaapi.get_qword else: size = 4 get_ptr = idaapi.get_dword for addr in range(segm_start_ea, segm_end_ea, size): func_addr = get_ptr(addr) idc.set_name(func_addr, f"init_{func_addr:X}")
def implement(self): idc.set_name(self._linear_address, self._new_name, ida_name.SN_PUBLIC if self._is_public else ida_name.SN_LOCAL)