def findCodeCavez(self, segment=".text"): start = idc.SegByBase(idc.SegByName(segment)) if start == idc.BADADDR: print "Can't find segment %s" % (segment) return end = idc.SegEnd(start) curr_addr = start curr_size = 0 biggest_addr = idc.BADADDR biggest_size = 0 results = [] while start < end: new_addr = idc.FindText(start + curr_size, idc.SEARCH_DOWN, 0, 0, "align") if start == new_addr: break curr_size = idc.ItemSize(new_addr) if curr_size > biggest_size: biggest_addr = new_addr biggest_size = curr_size start = new_addr results.append((new_addr, curr_size)) return results return biggest_addr, biggest_size
def analyze_init_array(): print('analyze_init_array') seg = idc.SegByName('.init_array') addr = idc.SegByBase(seg) seg_st = idc.GetSegmentAttr(addr, idc.SEGATTR_START) seg_en = idc.GetSegmentAttr(addr, idc.SEGATTR_END) print(' .init_array = %08X - %08X' % (seg_st, seg_en)) if addr == idc.BADADDR: return while addr < seg_en: funcaddr = idc.Dword(addr) if funcaddr > 0: name = idc.Name(funcaddr) if name is None or name.startswith('sub_'): idc.MakeName(funcaddr, 'INIT_%X' % funcaddr) print(' %08X: %s' % (funcaddr, idc.Name(funcaddr))) addr += 4 return seg_st
def SegByName(n): start = idc.SegByBase(idc.SegByName(n)) if (start != idc.BADADDR): end = idc.SegEnd(start) else: start = idc.BADADDR end = idc.BADADDR return (start,end)
def make_offsets(segname): segea = idc.SegByBase(idc.SegByName(segname)) segend = idc.SegEnd(segea) while segea < segend: idc.OpOffset(segea, 0) ptr = idc.Dword(segea) idc.OpOffset(ptr, 0) segea += 4
def main(): objc_data_seg = idc.SegByBase(idc.SegByName('__objc_data')) if objc_data_seg == idc.BADADDR: print 'Cannot locate objc_data segment' return ea = objc_data_seg while ea < idc.SegEnd(objc_data_seg): objc_class = ObjcClass(ea) objc_class.dump() ea = ea + 0x14
def make_offsets(segname): ''' change the segment's data value into offset by class name ''' segea = idc.SegByBase(idc.SegByName(segname)) segend = idc.SegEnd(segea) while segea < segend: idc.OpOffset(segea, 0) ptr = idc.Dword(segea) idc.OpOffset(ptr, 0) segea += 4
def __PltResolver(jmprel,strtab,symtab,pltgot): seg_sec = idc.SegByName('.plt.sec') sec_start = idc.SegByBase(seg_sec) sec_end = idc.SegEnd(sec_start) if sec_start == idaapi.BADADDR: print "[-] can't find .plt.sec segment" return idx=0 while True: r_off = idc.Dword(jmprel+0x8*idx) r_info1 = idc.Byte(jmprel+0x8*idx+0x4) r_info2 = idc.Byte(jmprel+0x8*idx+0x5) if r_off > 0x7fffffff: return if r_info1 == 7: st_name = idc.Dword(symtab+r_info2*0x10) name = idc.GetString(strtab+st_name) # rename got idc.set_name(r_off,name+'_ptr') plt_func = idc.Dword(r_off) # rename plt idc.set_name(plt_func,'j_'+name) 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.startEA idc.set_name(plt_sec_func_addr,'_'+name) 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.startEA 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 main(): CFLString_sid = create_CFLString_struct() # limit search to .rodata seg_sel = idc.SegByName(".rodata") ea = idc.SegByBase(seg_sel) end_ea = idc.SegEnd(ea) while ea < end_ea: #find all instances of magic==0x756 and unk4==0x7FFFFFFF if (idc.Dword(ea), idc.Dword(ea + 4)) == (0x756, 0x7FFFFFFF): # read bytes until NULL is found index = 0 cstr = "" while True: char = chr(idc.Byte(ea + 8 + index)) if char == "\x00": break index += 1 cstr += char name_str = cstr for bad_char in [ "-", ":", ";", "=", "(", ")", " ", "/", "\\", "<", ">" ]: name_str = name_str.replace(bad_char, "_") #XXX: lazy/unreliable way to deal with name collisions suffix = 0 while not idc.MakeNameEx( ea, "cflstr_{0}__{1}".format(name_str, suffix), idc.SN_CHECK | idc.SN_NOWARN): suffix += 1 # something probably went horribly wrong if suffix > 100: print "error creating name at address {0}".format(hex(ea)) sys.exit(1) # size = magic + unk4 + string_length + NULL_byte print "applying at {0}".format(hex(ea)) struct_size = apply_struct(ea, CFLString_sid, 8 + len(cstr) + 1) # preserve alignment ea += (struct_size & ~3) else: ea += 4
def __init__(self, ea): self.class_info = dict() objc_const_seg = idc.SegByBase(idc.SegByName('__objc_const')) objc_const_end = idc.SegEnd(objc_const_seg) self.class_info['meta_class'] = idc.Dword(ea) self.class_info['super_class'] = idc.Dword(ea + 4) self.class_info['cache'] = idc.Dword(ea + 8) self.class_info['vtable'] = idc.Dword(ea + 0xC) _class_def = idc.Dword(ea + 0x10) if _class_def < objc_const_seg or _class_def > objc_const_end: return self.class_info['top_class'] = idc.Dword(_class_def) self.class_info['instance_size'] = idc.Dword(_class_def + 8) name_off = idc.Dword(_class_def + 0x10) class_name = idc.GetString(name_off, -1, idc.ASCSTR_C) if not class_name: class_name = '[UNKNOWN]' self.class_info['name'] = class_name self.class_info['methods'] = list() self.class_info['protocols'] = list() self.class_info['ivars'] = list() self.class_info['properties'] = list() if idc.Dword(_class_def + 0x14): self.class_info['methods'] = ObjcMethods( idc.Dword(_class_def + 0x14)) if idc.Dword(_class_def + 0x18): self.class_info['protocols'] = ObjcProtocols( idc.Dword(_class_def + 0x18)) if idc.Dword(_class_def + 0x1C): self.class_info['ivars'] = ObjcIvars(idc.Dword(_class_def + 0x1C)) if idc.Dword(_class_def + 0x24): self.class_info['properties'] = ObjcProperties( idc.Dword(_class_def + 0x24)) return
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.SegByBase(idc.SegByName('__PRELINK_INFO.__kmod_start')) if kmod_start == idc.BADADDR: return for kmod in idau.ReadWords(kmod_start, idc.SegEnd(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))
def rename_dwords(): f = open('C:\Users\mrT4ntr4\Downloads\idascripts\method_map.json') method_map = json.load(f) token_list = [int(x, 16) for x in method_map.keys()] data_seg_selector = idc.SegByName('.data') data_seg_startea = idc.SegByBase(data_seg_selector) data_seg_endea = idc.SegEnd(data_seg_startea) #maybe compability issue SN_FORCE = 0x800 for ea in range(data_seg_startea, data_seg_endea): var_name = Name(ea) if 'dword' in var_name: dword_val = Dword(ea) if dword_val in token_list: formatted_token = "0x0%X" % dword_val new_name = str(method_map[formatted_token]) idc.set_name(ea, new_name, SN_NOCHECK | SN_FORCE) print "done renaming " + var_name + " to " + new_name
"""Returns the first eighteen bytes of a function as ASCII.""" B = bytearray(idc.GetManyBytes(adr, Symgrate2.SEARCHLEN)) bstr = "" for b in B: bstr += "%02x" % (0x00FF & b) return bstr # Iterate over all the functions, querying from the database and printing them. fnhandled = 0 qstr = "" start = 0 end = 0 start = idc.SegByBase(idc.SegByName(".text")) if (start != idc.BADADDR): end = idc.SegEnd(start) else: start = idc.NextFunction(0) end = idc.BADADDR f = start while (f != idc.BADADDR) and (f <= end): iname = idc.GetFunctionName(f) adr = f adrstr = "%x" % f res = None bstr = ida_functionprefix(f)
def segByBase(self, selector): return idc.SegByBase(selector)
import idautils import idc import idaapi import datetime now = datetime.datetime.now() idata_seg_selector = idc.SegByName('.rdata') idata_seg_startea = idc.SegByBase(idata_seg_selector) idata_seg_endea = idc.SegEnd(idata_seg_startea) print "# AUTO GENERATED VIA IDA SCRIPT " + now.strftime("%Y-%m-%d %I:%M %p") def print_vtables(prefix): for seg_ea in range(idata_seg_startea, idata_seg_endea): name = Name(seg_ea) if name.lower().startswith( prefix) and not name.lower().startswith("vtbl_class_"): print hex(seg_ea) + "=" + name + "," + name.split('_')[1] print_vtables("vtbl_") print_vtables("gvtbl_") print "# END VTABLE DEFINITION"