def get_data_symbols(): idata_seg_selector = idc.selector_by_name(".bss") idata_seg_startea = idc.get_segm_by_sel(idata_seg_selector) idata_seg_endea = idc.get_segm_end(idata_seg_startea) for seg_ea in range(idata_seg_startea, idata_seg_endea): if idc.get_name(seg_ea): address = format(seg_ea, 'x') name = ".global"+"_"+idc.get_name(seg_ea) size = idc.get_item_size(seg_ea) dtype = ida_bytes.get_data_elsize(seg_ea, idc.get_full_flags(seg_ea)) if size == dtype == 8: ownertype = "pointer" elif size == dtype != 8: ownertype = "scalar" elif size > dtype: ownertype = "array" else: continue for xref in idautils.XrefsTo(seg_ea): # print(format(xref.frm, 'x')) function = idc.get_func_name(xref.frm) # print(function) if function not in functions: continue # print(function) if str(function) not in instruction_map: instruction_map[str(function)] = {} instruction_map[str(function)][format(xref.frm, 'x')]=name,ownertype # print("Found a cross reference {}: from {:x} to variable {}".format(xref, xref.frm, name)) metadata[".global"].append({"owner":name,"datatype":ownertype, "address":address, "size":size})
def __PltResolver(jmprel, strtab, symtab, pltgot): seg_sec = idc.selector_by_name('.plt.sec') sec_start = idc.get_segm_by_sel(seg_sec) sec_end = idc.get_segm_end(sec_start) if sec_start == idaapi.BADADDR: print("[-] can't find .plt.sec segment") return idx = 0 while True: r_off = idc.get_wide_dword(jmprel + 0x8 * idx) r_info1 = idc.get_wide_byte(jmprel + 0x8 * idx + 0x4) r_info2 = idc.get_wide_byte(jmprel + 0x8 * idx + 0x5) if r_off > 0x7fffffff: return if r_info1 == 7: st_name = idc.get_wide_dword(symtab + r_info2 * 0x10) name = idc.get_strlit_contents(strtab + st_name) # rename got idc.set_name(r_off, name.decode("ascii") + '_ptr') plt_func = idc.get_wide_dword(r_off) # rename plt idc.set_name(plt_func, 'j_' + name.decode("ascii")) SetFuncFlags(plt_func) # rename plt.sec for addr in idautils.DataRefsTo(r_off): plt_sec_func = idaapi.get_func(addr) if plt_sec_func: plt_sec_func_addr = plt_sec_func.start_ea idc.set_name(plt_sec_func_addr, '_' + name.decode("ascii")) SetFuncFlags(plt_sec_func_addr) else: print("[!] idaapi.get_func({}) failed".format( hex(addr))) got_off = r_off - pltgot target = '+{}h'.format( hex(got_off).lower().replace('0x', '').replace('l', '').rjust(2, '0')) for func_ea in idautils.Functions(sec_start, sec_end): func = idaapi.get_func(func_ea) cur = func.start_ea end = func.endEA find = False while cur <= end: code = idc.GetDisasm(cur).lower().replace(' ', '') if target in code: find = True break cur = idc.NextHead(cur, end) if find: idc.set_name(func_ea, '_' + name) SetFuncFlags(func_ea) idx += 1
def make_segment(base, size, name): s = idc.get_segm_by_sel(base) if not s == 0xffffffff: return s = idaapi.segment_t() s.startEA = base s.endEA = base+size s.sel = 0 s.bitness = 1 s.comb = idaapi.scPub idaapi.add_segm_ex(s, name.strip('.').upper(), "", idaapi.ADDSEG_NOSREG|idaapi.ADDSEG_SPARSE)
def get_list_of_functions(self): ''' Gets all functions list. ''' functions_list = {} seg_ea = idc.get_segm_by_sel(idc.SEG_NORM) for func_ea in idautils.Functions(idc.get_segm_start(seg_ea), idc.get_segm_end(seg_ea)): function_name = idc.get_func_name(func_ea) functions_list[function_name] = func_ea return functions_list
def _initialize_kext_regions(): """Get region information for each kext based on iOS 12's __PRELINK_INFO.__kmod_start. NOTE: This only accounts for __TEXT_EXEC, not the other segments.""" kmod_start = idc.get_segm_by_sel( idc.selector_by_name('__PRELINK_INFO.__kmod_start')) if kmod_start == idc.BADADDR: return for kmod in idau.ReadWords(kmod_start, idc.get_segm_end(kmod_start)): _log(1, 'Found kmod {:x}', kmod) segments = list(_macho_segments_and_sections(kmod)) if len(segments) != 1: _log(0, 'Skipping unrecognized kmod {:x}', kmod) continue segname, segstart, segend, sects = segments[0] if segname != '__TEXT_EXEC' or len(sects) != 1: _log(0, 'Skipping unrecognized kmod {:x}', kmod) continue kmod_name = 'kext.{:x}'.format(kmod) _log(1, 'Adding module: {:x} - {:x} {}', segstart, segend, kmod_name) _kext_regions.append((segstart, segend, kmod_name))
elif number == 1: # ok return (0x71, 10) elif number == 0: # ok < no conditional return (0x90, 0x90) elif number == 4: # ok return (0x78, 10) elif number == 2: # ok return (0x70, 10) else: return (0x00, 0x00) align = lambda size, alignment: ((size // alignment) + 1) * alignment if __name__ == "__main__": start = idc.get_segm_by_sel(0) end = idc.get_segm_end(start) data = idaapi.get_many_bytes(start + fnc_start, fnc_end - fnc_start + 2) matches = yara.compile(source=rules).match(data=data) count = 0 match = list() for hit in matches: if hit.rule == 'nanomite': match = hit.strings for hit in match: (offset, name, pattern) = hit number = data[offset + 1] encoded = data[offset + 2:offset + 2 + 8] jmp_addr = encode(encoded) jmp_addr_off = (jmp_addr - (start + fnc_start + offset + 2) & 0xffffffff) & 0xffffffff ins, jmp_off = nanomite(number)
def get_segm_by_name(name): return idc.get_segm_by_sel(idc.selector_by_name(name))