def next(self): """Get the next segment.""" seg = Segment(segment_t=idaapi.get_next_seg(self.ea)) if seg.ea <= self.ea: raise exceptions.NoMoreSegments("This is the last segment. No segments exist after it.") return seg
def enum_all_segments(): segm = idaapi.get_first_seg() segments = list() while segm is not None: segments.append(segm) segm = idaapi.get_next_seg(segm.start_ea) return segments
def end_address(): last_ea = idc.BADADDR seg = idaapi.get_first_seg() while seg: last_ea = seg.endEA seg = idaapi.get_next_seg(last_ea) return last_ea
def ida_iter_segments(): seg = idaapi.get_first_seg() while seg: # TODO: CRITICAL!! Figure out how to calculate segment file size yield SegmentTuple(name=idaapi.get_segm_name(seg), perm=seg.perm, startEA=seg.startEA, endEA=seg.endEA, offset=ida_loader.get_fileregion_offset( seg.startEA)) seg = idaapi.get_next_seg(seg.startEA)
def next(self): return Segment(idaapi.get_next_seg())
def get_next_segment_addr(addr): return idaapi.get_next_seg(addr).start_ea
def findAllKEXT(): """ findAllKEXT: Finds all KEXT contained in the kernelcache file. The mach-o headers will be converted into the appropiate structs, the new sections will be defined and the name and version number of the KEXT are extracted. In the end a window is shown that shows all contained KEXT. """ # Ask the user if he wants to add all the KEXT sections # to the IDA database. answer = idc.AskYN(0, """Do you want to add all the KEXT sections to the IDA database? If this was already done before or there was already code or data in the same place in the IDA database, IDA might react very slow, crash or just stop to work.""") # KEXT cache starts behind the __LINKEDIT segment # NOTE: IDA calls the segment __LINKEDIT_hidden linkedit = idaapi.get_segm_by_name("__LINKEDIT_hidden") if not linkedit: print "[-] cannot find KEXTCACHE: __LINKEDIT segment not found" return kextcache = idaapi.get_next_seg(linkedit.endEA) if not kextcache: print "[-] cannot find KEXTCACHE: __LINKEDIT not followed by any segment" return dummyName = idaapi.get_segm_name(kextcache) if dummyName != "__text": print "[-] cannot find KEXTCACHE: __LINKEDIT not followed by __text segment" return if answer == 1: # Destroy everything in the kextcache area idaapi.do_unknown_range(kextcache.startEA, kextcache.endEA-kextcache.startEA, DOUNK_DELNAMES) startEA = kextcache.startEA kextlist = [] while True: sig = idc.Dword(startEA) if sig != 0xfeedface: "[-] expected the next KEXT but did not find correct signature" break seg_lc = None sections = [] added = 0 next = forceStruct(startEA, "mach_header") ncmds = get_member_from_struct(startEA, "mach_header", "ncmds") for i in range(ncmds): lc_addr = next cmd = get_member_from_struct(next, "load_command", "cmd") if cmd == 1: seg_lc = next next = forceStruct(seg_lc, "segment_command") nsecs = get_member_from_struct(seg_lc, "segment_command", "nsects") for j in range(nsecs): section = next next = forceStruct(section, "section") # Get basic information about segment (needed for ALL the code below) secStart = get_member_from_struct(section, "section", "addr") secEnd = secStart + get_member_from_struct(section, "section", "size") secname = idc.GetString(section) # We should tell IDA about what this section is s = idaapi.segment_t() s.startEA = secStart s.endEA = secEnd s.sel = idaapi.setup_selector(0) if secname == "__text": s.bitness = 0 else: s.bitness = 1 s.align = get_member_from_struct(section, "section", "align") s.comb = 0 # ??? if secname == "__text" or secname == "stubs": sclass = "CODE" elif secname == "__bss": sclass = "BSS" else: sclass = "DATA" if len(sections) == 0: sec = {} sec["name"] = "MACH-O HEADER" sec["start"] = "%08X" % (startEA) sec["end"] = "%08X" % (secStart-1) sections.append(sec) sec = {} sec["name"] = secname sec["start"] = "%08X" % (secStart) sec["end"] = "%08X" % (secEnd-1) sections.append(sec) if answer == 1: # Destroy everything inside the segment idaapi.do_unknown_range(secStart, secEnd-secStart, DOUNK_DELNAMES) # Ensure that the whole section is undefined idaapi.add_segm_ex(s, secname, sclass, idaapi.ADDSEG_NOSREG|idaapi.ADDSEG_QUIET) if secname == "__text": idc.SetRegEx(secStart, "T", 1, 0) # special handling of constructor and destructor if secname == "__constructor" or secname == "__destructor": for z in range(secStart, secEnd, 4): idc.OpOffEx(z, -1, REF_OFF32, 0xFFFFFFFF, 0, 0) # We have to check for __data section because we want # to find the kmod_info structure if secname != "__data": continue kextName = None for z in range(secStart, secEnd, 4): k = z # We assume that all KEXT name start with "com." kextNameSig = idc.Dword(k) if kextNameSig == 0x2e6d6f63: forceStruct(k-12, "kmod_info") kextName = idc.GetString(k) kextVersion = idc.GetString(k+64) #print "-> %s - version: %s" % (kextName, kextVersion) dic = {} dic["addr"] = "%08X" % (startEA) dic["name"] = kextName dic["version"] = kextVersion kextlist.append(dic) added = 1 break if kextName == None: print "ERROR COULD NOT FIND NAME" elif cmd == 0x1b: next = forceStruct(lc_addr, "uuid_command") elif cmd == 0x2: next = forceStruct(lc_addr, "symtab_command") #print "Found symbol table KEXT at %08x" % (startEA) else: print "Unknown load command %08x" % (cmd) if added: kextlist[len(kextlist)-1]["sections"] = sections next = lc_addr + get_member_from_struct(lc_addr, "load_command", "cmdsize") if seg_lc == None: startEA += 4 while idc.Dword(startEA) != 0xfeedface: startEA += 4 continue startEA = get_member_from_struct(seg_lc, "segment_command", "vmaddr") startEA += get_member_from_struct(seg_lc, "segment_command", "vmsize") c = MySelectionDialog("Retrieved KEXT", [ ["Address", 10], [ "Name", 65 ], ["Version", 65] ], formatKEXTresults(kextlist)) selected_row = c.Show(True) if selected_row >= 0: sel = kextlist[selected_row] c = MySelectionDialog("Sections inside " + sel["name"], [ ["Name", 16], [ "Start", 10 ], ["End", 10] ], formatSECTIONresults(sel["sections"])) selected_row = c.Show(True) if selected_row >= 0: sel = sel["sections"][selected_row] idc.Jump(int(sel["start"], 16))