def LastSegEnd(): start = idc.NextSeg(0) end = idc.SegEnd(start) while idc.NextSeg(start + 1) != idc.BADADDR: start = idc.NextSeg(end - 1) end = idc.SegEnd(start) return end
def get_all_segments(): segments = [] seg = idc.FirstSeg() while seg != idc.BADADDR: segments.append((seg, idc.SegEnd(seg))) seg = idc.NextSeg(seg) return segments
def LocatePointerLists(): seg = idc.FirstSeg() initArrayAddr = 0 while seg != idc.BADADDR: seg = idc.NextSeg(seg) segName = idc.SegName(seg) if segName == ".init_array": initArrayAddr = idc.SegStart(seg) break # find Il2CppCodeRegistrationOffset from init_array Il2CppCodeRegistrationOffset = initArrayAddr + 30 * (BITS / 8) print "find Il2CppCodeRegistrationOffset %x" % Il2CppCodeRegistrationOffset Il2CppCodeRegistrationCpp = GetVarFromAddr(Il2CppCodeRegistrationOffset) print "Il2CppCodeRegistrationCpp: %x" % Il2CppCodeRegistrationCpp idc.MakeName(Il2CppCodeRegistrationCpp, "Il2CppCodeRegistrationCpp") #Il2CppCodegenRegistration = 0 #for r in idautils.XrefsFrom(Il2CppCodeRegistrationAddr + 0x14, 0): # Il2CppCodegenRegistration = hex(r.to) #g_CodeRegistration = 0 #for r in idautils.XrefsFrom(Il2CppCodegenRegistration + 0x18, 0): # g_CodeRegistration = hex(r.to) opndValue = idc.GetOperandValue(Il2CppCodeRegistrationCpp + 0x8, 1) offset = GetVarFromAddr(opndValue) _GLOBAL_OFFSET_TABLE_ = idc.LocByName("_GLOBAL_OFFSET_TABLE_") print "_GLOBAL_OFFSET_TABLE_ %x" % _GLOBAL_OFFSET_TABLE_ Il2CppCodegenRegistration = (_GLOBAL_OFFSET_TABLE_ + offset) & 0xFFFFFFFF idc.MakeName(Il2CppCodegenRegistration, "Il2CppCodegenRegistration") print "Il2CppCodegenRegistration %x" % Il2CppCodegenRegistration opndValue = idc.GetOperandValue(Il2CppCodegenRegistration + 0xC, 1) offset = GetVarFromAddr(opndValue) g_CodeRegistration = (_GLOBAL_OFFSET_TABLE_ + offset) & 0xFFFFFFFF idc.MakeName(g_CodeRegistration, "g_CodeRegistration") print "g_CodeRegistration %x" % g_CodeRegistration g_MethodPointers = GetVarFromAddr(g_CodeRegistration + 0x4) idc.MakeName(g_MethodPointers, "g_MethodPointers") print "g_MethodPointers %x" % g_MethodPointers opndValue = idc.GetOperandValue(Il2CppCodegenRegistration + 0x04, 1) offset = GetVarFromAddr(opndValue) g_MetadataRegistration = GetVarFromAddr((_GLOBAL_OFFSET_TABLE_ + offset) & 0xFFFFFFFF) idc.MakeName(g_MetadataRegistration, "g_MetadataRegistration") print "g_MetadataRegistration %x" % g_MetadataRegistration g_MetadataUsages = GetVarFromAddr(g_MetadataRegistration + 0x3C) idc.MakeName(g_MetadataUsages, "g_MetadataUsages") print "g_MetadataUsages %x" % g_MetadataUsages return (g_MethodPointers, g_MetadataUsages)
def getSegBoundaries(segName) : s = idc.FirstSeg(); while s != idc.BADADDR : if idc.SegName(s) == segName : return (s, idc.SegEnd(s)) s = idc.NextSeg(s) return None
def LocateStringLiterals(): seg = idc.FirstSeg() initArrayAddr = 0 while seg != idc.BADADDR: seg = idc.NextSeg(seg) segName = idc.SegName(seg) if segName == ".data.rel.ro": data_rel_ro = idc.SegStart(seg) break addr = data_rel_ro referedVars = [] while idc.SegName(addr) == ".data.rel.ro": for r in idautils.XrefsTo(addr, 0): referedVars.append(addr) break addr += 4 candidateMetadaUsages = [] for idx, var in enumerate(referedVars): if idx < (len(referedVars) - 1) and (referedVars[idx + 1] - referedVars[idx]) >= 1024: if idc.Dword(var) == 0x0: continue if IsDataFollowing(var) and idc.SegName(idc.Dword(var)) == '.bss': candidateMetadaUsages.append(var) for candidate in candidateMetadaUsages: for referedVar in referedVars: if referedVar == candidate: nextVar = referedVars[referedVars.index(referedVar) + 1] print "candidate: 0x%x, candidate end: 0x%x, data numbers: %d" % ( candidate, nextVar, (nextVar - candidate) / 4) break
def LocateMethodPointers(): seg = idc.FirstSeg() initArrayAddr = 0 while seg != idc.BADADDR: seg = idc.NextSeg(seg) segName = idc.SegName(seg) if segName == ".data.rel.ro": data_rel_ro = idc.SegStart(seg) break addr = data_rel_ro referedVars = [] while idc.SegName(addr) == ".data.rel.ro": for r in idautils.XrefsTo(addr, 0): #print "is refered: 0x%x" % addr referedVars.append(addr) break addr += 4 candidateMethodPointers = [] for var in referedVars: if IsSubFollowing(var): candidateMethodPointers.append(var) for candidate in candidateMethodPointers: for referedVar in referedVars: if referedVar == candidate: nextVar = referedVars[referedVars.index(referedVar) + 1] print "candidate: 0x%x, candidate end: 0x%x, method numbers: %d" % ( candidate, nextVar, (nextVar - candidate) / 4) break
def resolve_unknown_functions(): proc_name = get_proc_name() if proc_name.startswith("mips"): prolog_pattern = FUNCTION_PROLOGS.get(proc_name, "BAD ARCH") elif proc_name.startswith("ARM"): prolog_pattern = FUNCTION_PROLOGS.get(proc_name, "BAD ARCH") else: # TODO: support another arch return ea = get_start_ea(idaapi.SEG_CODE) if ea == idc.BADADDR: ea = idc.FirstSeg() cur_seg_end = idc.SegEnd(ea) while ea != idc.BADADDR: if ea < cur_seg_end and idc.GetSegmentAttr(ea, idc.SEGATTR_TYPE) == idaapi.SEG_CODE: if idc.GetFunctionFlags(ea) == -1: # not function raw_data_hex = read_addr(ea) if re.match(prolog_pattern, raw_data_hex.decode('hex')): idc.MakeFunction(ea) ea = ea + 4 else: ea = idc.NextSeg(ea) cur_seg_end = idc.SegEnd(ea)
def get_start_ea(self, attr): ea = idc.BADADDR seg = idc.FirstSeg() while seg != idc.BADADDR: if idc.GetSegmentAttr(seg, idc.SEGATTR_TYPE) == attr: ea = seg break else: seg = idc.NextSeg(seg) return ea
def get_data_section(self): ea = idc.BADADDR seg = idc.FirstSeg() while seg != idc.BADADDR: if ea == idc.BADADDR and idc.GetSegmentAttr(seg, idc.SEGATTR_TYPE) == 2: ea = seg stop = idc.SegEnd(seg) seg = idc.NextSeg(seg) return (ea, stop)
def get_seg_range_by_name(self, seg_name): ''' 获取指定名字的seg的范围 ''' start_addr = idc.FirstSeg() while start_addr != idaapi.BADADDR: end_addr = idc.SegEnd(start_addr) name = idc.SegName(start_addr) #print '%s : 0x%08x - 0x%08x'%(seg_name, start_addr, seg_end_addr) if name.lower() == seg_name.lower(): return [start_addr, end_addr] start_addr = idc.NextSeg(start_addr) return None
def _get_segments(self, attr): segments = [] start = idc.BADADDR end = idc.BADADDR seg = idc.FirstSeg() while seg != idc.BADADDR: if idc.GetSegmentAttr(seg, idc.SEGATTR_TYPE) == attr: start = idc.SegStart(seg) end = idc.SegEnd(seg) segments.append((start, end)) seg = idc.NextSeg(seg) return segments
def get_segments(): """ Returns a set of of (segment name, segment start, segment end). The end is exclusive - last byte of segment is one byte before. """ segments = set() segment_start = idc.FirstSeg() while segment_start != idc.BADADDR: segment_name = idc.SegName(segment_start) segment_end = idc.SegEnd(segment_start) segments.add((segment_name, segment_start, segment_end)) segment_start = idc.NextSeg(segment_start) return segments
def _detect_membase(self): ''' Attempts to locate a section of memory for IDBMMU's internal memory allocation. For internal use only. ''' if self.BASE_MP == idc.BADADDR: # Look for the MMU segment ea = idc.SegByName(self.SEGNAME) # No MMU segment? if ea == idc.BADADDR: ea = 0 # Find the very last defined segment while True: segea = idc.NextSeg(ea) if segea == idc.BADADDR: break else: ea = segea # Is it not a memory segment? if idc.SegName(ea) not in self.LAST_SEGNAME: try: # Find the start of the stack ea = idc.SegStart(self.cpu.StackPointer()) # Still nothing? Use the default. if ea == idc.BADADDR: ea = self.DEFAULT_MP except: if not self.use_native_malloc: raise Exception( "No available segments for memory allocation! Try defining segment %s." % self.SEGNAME) self.BASE_MP = ea if self.MP == idc.BADADDR: self.MP = self.BASE_MP return self.BASE_MP
def analyze(cu): objc_meth_map = {} methnamebegin = 0 methnameend = 0 forbitmeth = [ "alloc", "allocWithZone:", "allowsWeakReference", "autorelease", "class", "conformsToProtocol:", "copy", "copyWithZone:", "dealloc", "debugDescription", "description", "doesNotRecognizeSelector:", "finalize", "forwardingTargetForSelector:", "forwardInvocation:", "hash", "init", "initialize", "instanceMethodForSelector:" "instanceMethodSignatureForSelector:", "instancesRespondToSelector:", "isEqual", "isKindOfClass:", "isMemberOfClass:", "isProxy", "isSubclassOfClass:", "load", "methodForSelector:", "methodSignatureForSelector:", "mutableCopy", "mutableCopyWithZone:", "performSelector:", "performSelector:withObject:", "performSelector:withObject:withObject:", "respondsToSelector:", "release", "resolveClassMethod:", "resolveInstanceMethod:", "retain", "retainCount", "retainWeakReference", "superclass", "zone", ".cxx_construct", ".cxx_destruct", ] # find the segment which contains objc method names curseg = idc.FirstSeg() while curseg != 0xffffffff: if "__objc_methname" == idc.SegName(curseg): methnamebegin = idc.SegStart(curseg) methnameend = idc.SegEnd(curseg) break curseg = idc.NextSeg(curseg) # get objc method names if methnamebegin != 0: while methnamebegin < methnameend: funcname = idc.GetString(methnamebegin) objc_meth_map[funcname] = methnamebegin methnamebegin = methnamebegin + len(funcname) + 1 # get objc func table funcmap = {} addr = idc.PrevFunction(-1) while addr != 0xffffffff: curname = idc.GetFunctionName(addr) if -1 != curname.find('['): curname = curname.replace("[", "").replace("]", "") curname = curname.split(" ")[1] # may be more than one function with same sel but differenct class if curname not in funcmap: funcmap[curname] = [] funcmap[curname].append(addr) addr = idc.PrevFunction(addr) # make xref result = [] indx = 0 for (k, v) in objc_meth_map.items(): # find corresponding func addr if k in funcmap and k not in forbitmeth: farr = funcmap[k] # find xref to code and make xref for each curref = idc.DfirstB(v) while curref != 0xffffffff: for f in farr: cu.execute('insert into xref values (?,?,?,?,?)', [indx, curref, f, v, k]) indx += 1 curref = idc.DnextB(v, curref) return result
#coding=utf-8 import idautils import idc #遍历区段 for seg in idautils.Segments(): print idc.SegName(seg), hex(idc.SegStart(seg)), hex(idc.SegEnd(seg)) #获取当前地址所在段的下一个段的起始地址 ea = here() print hex(idc.NextSeg(ea)) #通过名称获取一个区段的起始地址 ?? print hex(idc.SegByName('.data'))
def main(): global mod_addr_min global mod_addr_max #print('INF_VERSION: %s' % (str(idc.GetLongPrm(idc.INF_VERSION)))) #print('INF_PROCNAME: %s' % (str(idc.GetLongPrm(idc.INF_PROCNAME)))) #print('INF_COMPILER: %s' % (str(idc.GetLongPrm(idc.INF_COMPILER)))) #print('INF_FILETYPE: %s' % (str(idc.GetLongPrm(idc.INF_FILETYPE)))) processor = str(idc.GetLongPrm(idc.INF_PROCNAME)) is_x86 = processor == 'metapc' is_ARM = processor == 'ARM' #if not is_x86: # idc.Message('*** Sorry, currently only supported x86.\n') # return addr = idc.MinEA() while True: seg = idc.NextSeg(addr) if seg == idc.BADADDR: break name = idc.SegName(addr) seg_st = idc.GetSegmentAttr(seg, idc.SEGATTR_START) seg_en = idc.GetSegmentAttr(seg, idc.SEGATTR_END) print('%08X-%08X: %s' % (seg_st, seg_en, name)) if name.startswith('.'): if seg_st < mod_addr_min: mod_addr_min = seg_st if seg_en > mod_addr_max: mod_addr_max = seg_en addr = seg_en - 4 print('module range = %08X-%08X' % (mod_addr_min, mod_addr_max)) init_array = analyze_init_array() load_metadata() code_reg, meta_reg = search_reg() if code_reg != idc.BADADDR: analyze_code_reg(code_reg) if meta_reg != idc.BADADDR: analyze_meta_reg(meta_reg, code_reg) analyze_invoke_unityengine() analyze_invoke_library() print('%X: INIT_IL2CPP' % (idc.LocByName('INIT_IL2CPP'))) print('%X: %s' % (code_reg, idc.Name(code_reg))) print('%X: %s' % (meta_reg, idc.Name(meta_reg))) print('%X: .init_array' % (init_array))