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)
Example #2
0
    def codeify(self, ea=idc.BADADDR):
        func_count = 0
        code_count = 0

        if ea == idc.BADADDR:
            ea = self.get_start_ea(self.CODE)
            if ea == idc.BADADDR:
                ea = idc.FirstSeg()

        self.say("\nLooking for undefined code starting at: %s:0x%X" %
                 (idc.SegName(ea), ea))

        while ea != idc.BADADDR:
            try:
                if idc.GetSegmentAttr(ea, idc.SEGATTR_TYPE) == self.CODE:
                    if idc.GetFunctionName(ea) != '':
                        ea = idc.FindFuncEnd(ea)
                        continue
                    else:
                        if idc.MakeFunction(ea):
                            func_count += 1
                        elif idc.MakeCode(ea):
                            code_count += 1
            except:
                pass

            ea = idc.NextAddr(ea)

        self.say("Created %d new functions and %d new code blocks\n" %
                 (func_count, code_count))
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)
Example #4
0
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
Example #5
0
    def codeify(self, ea=idc.BADADDR):
        func_count = 0
        code_count = 0

        if ea == idc.BADADDR:
            ea = self.get_start_ea(self.CODE)
            if ea == idc.BADADDR:
                ea = idc.FirstSeg()

        print "\nLooking for undefined code starting at: %s:0x%X" % (
            idc.SegName(ea), ea)

        if self.get_start_ea(self.DATA) == idc.BADADDR:
            print "WARNING: No data segments defined! I don't know where the code segment ends and the data segment begins."

        while ea != idc.BADADDR:
            try:
                if idc.GetSegmentAttr(ea, idc.SEGATTR_TYPE) == self.CODE:
                    if idc.GetFunctionName(ea) != '':
                        ea = idc.FindFuncEnd(ea)
                        continue
                    else:
                        if idc.MakeFunction(ea):
                            func_count += 1
                        elif idc.MakeCode(ea):
                            code_count += 1
            except:
                pass

            ea = idc.NextAddr(ea)

        print "Created %d new functions and %d new code blocks\n" % (
            func_count, code_count)
Example #6
0
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 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
Example #9
0
def find_all_pattern(pat):
    first = idc.FirstSeg()
    last = idc.BADADDR
    result = []

    ea = idaapi.find_binary(first, last, pat, 16, idaapi.SEARCH_DOWN)
    while ea != idaapi.BADADDR and ea < last:
        result.append(ea)
        ea = idaapi.find_binary(ea, last, pat, 16,
                                idaapi.SEARCH_DOWN | idaapi.SEARCH_NEXT)

    return result
Example #10
0
    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
Example #11
0
 def makeFuncsFromPreamble(funcpreamble, startea=idc.FirstSeg(), endea = idaapi.BADADDR):
     """ This method makes functions everywhere that the sequence 'funpreamble' is found.
         NOTE: this method is generally unsafe, because it will attempt to make functions where
         there may be no function.  Use it with caution.
     """
     ea = startea
     i = 0
     while (ea != idaapi.BADADDR and ea < endea):
         ea = idc.FindBinary(ea, SEARCH_DOWN, funcpreamble)
         idc.MakeFunction(ea)
         idc.Wait()
         ea = ea + 1 # idc.FindBinary(ea) returns ea if ea matches, silly
Example #12
0
 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
Example #13
0
    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)
Example #14
0
    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
Example #15
0
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
Example #16
0
    def datify(self):
        ea = self.get_start_ea(self.DATA)
        if ea == idc.BADADDR:
            ea = idc.FirstSeg()

        print "Converting remaining data to DWORDs...",

        while ea != idc.BADADDR:
            flags = idc.GetFlags(ea)

            if idc.isUnknown(flags) or idc.isByte(flags):
                idc.MakeDword(ea)
                idc.OpOff(ea, 0, 0)

            ea = idc.NextAddr(ea)

        print "done."
Example #17
0
    def stringify(self):
        n = 0
        ea = self.get_start_ea(self.DATA)

        if ea == idc.BADADDR:
            ea = idc.FirstSeg()

        print("Looking for possible strings starting at: %s:0x%X..." %
              (idc.SegName(ea), ea)),

        for s in idautils.Strings():
            if s.ea > ea:
                if not idc.isASCII(idc.GetFlags(s.ea)) and idc.MakeStr(
                        s.ea, idc.BADADDR):
                    n += 1

        print "created %d new ASCII strings" % n
def static_breakpoint(target_type):
    try:
        base = idc.FirstSeg()
        if base == idc.BADADDR:
            print("can't find first seg")
            return
        filepath = idaapi.get_input_file_path()
        print("filename:", filepath)
        idbFile = open(filepath, "rb")
        e_phoff = get_ushort(idbFile, 0x1C)
        e_phentsize = get_ushort(idbFile, 0x2A)
        e_phnum = get_ushort(idbFile, 0x2C)
        print(e_phoff, e_phentsize, e_phnum)
        dynamic = -1
        for i in xrange(e_phnum):
            idbFile.seek(e_phoff + e_phentsize * i)
            p_type = get_ulong(idbFile, e_phoff + e_phentsize * i)
            # define PT_DYNAMIC 2
            if p_type == 2:
                dynamic = get_ulong(idbFile, e_phoff + e_phentsize * i + 4)
                break
        if dynamic == -1:
            print("\tcan't find dynamic")
            return
        dynamic_type = get_ulong(idbFile, dynamic)
        init = -1

        while dynamic_type != 0:

            dynamic += 8
            dynamic_type = get_ulong(idbFile, dynamic)

            if dynamic_type == target_type:
                init = get_ulong(idbFile, dynamic + 4)
                break
        if init == -1:
            print("\tcan't find init")
            return
        idc.AddBpt(base + init)
        print('\tbp the init on the %x' % (base + init))
        print("\nbp init finished")
    except BaseException, e:
        print(e)
Example #19
0
    def datify(self):
        ea = self.get_start_ea(self.DATA)
        if ea == idc.BADADDR:
            ea = idc.FirstSeg()

        self.say("Converting remaining data to DWORDs...", )

        while ea != idc.BADADDR:
            flags = idc.GetFlags(ea)

            if (idc.isUnknown(flags) or idc.isByte(flags)) and ((ea % 4) == 0):
                idc.MakeDword(ea)
                idc.OpOff(ea, 0, 0)

            ea = idc.NextAddr(ea)

        self.say("done.")

        self._fix_data_offsets()
Example #20
0
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