def make_data(addr, index, name, classname):
    if index == 0:
        print('    %s[%d] = %X' % (name, index, addr))
        print('      :')

    if addr == 0:
        return

    if classname == 'int':
        idc.MakeDword(addr)
    else:
        idc.MakeStruct(addr, classname)

    idc.MakeNameEx(addr, 'g_%s_%X' % (name, addr), idc.SN_NOWARN | idc.SN_AUTO)
Example #2
0
def dump_memory_region(ea):

    idc.MakeStruct(ea, "MEMORY_REGION")

    id = idc.Dword(ea)
    low = idc.Dword(ea + 8)
    high = idc.Dword(ea + 0xC)
    intv = idc.Dword(ea + 0x14)
    name = idc.Dword(ea + 0x20)
    memory_region = idc.GetString(name, -1, idc.ASCSTR_C)
    print "    flags: 0x%04x - int 0x%x- reg: %10s - low 0x%08x / high 0x%08x" % (
        id, intv, memory_region, low, high)

    if memory_region.startswith("MR"):
        idc.set_name(ea, memory_region, idc.SN_PUBLIC)
Example #3
0
def dump_memory_region(ea):

    idc.MakeStruct(ea,"MEMORY_REGION");

    id = idc.Dword(ea)
    flag1 = idc.Dword(ea+0x18)
    flag2 = idc.Dword(ea+0x1C)
    low = idc.Dword(ea+0x8)
    high = idc.Dword(ea+0x10)
    mask_low = idc.Dword(ea+0x20)
    mask_high = idc.Dword(ea+0x28)
    name = idc.Dword(ea+0x30)
    memory_region = idc.GetString(name, -1, idc.ASCSTR_C)
    print "    id: 0x%04x - flags 0x%x 0x%x - reg: %10s - low 0x%08x / high 0x%08x - mask 0x%08x / 0x%08x" % (id, flag1, flag2, memory_region, low, high, mask_low, mask_high)

    if memory_region.startswith("MR"):
        idc.set_name(ea, memory_region, idc.SN_PUBLIC)
    else:
        idc.set_name(ea, "MR_" + memory_region, idc.SN_PUBLIC)
def analyze_code_reg(code_reg):
    global metadata

    print('analyze_code_reg')

    names = [
        'methodPointers',
        'delegateWrappersFromNativeToManaged',
        'delegateWrappersFromManagedToNative',
        'marshalingFunctions',
        'ccwMarshalingFunctions',
        'genericMethodPointers',
        'invokerPointers',
        'customAttributeGenerators',
        #'guids',
    ]
    defaddr = code_reg

    idc.MakeNameEx(code_reg, 'g_code_reg', idc.SN_NOWARN | idc.SN_AUTO)
    idc.MakeStruct(code_reg, 'CodeRegistration')

    for i in range(len(names)):
        defaddr = make_func_table(True, defaddr, names[i])
Example #5
0
def apply_struct(objname, address):
    """Apply a Structure to an address."""
    structure = _struct_by_name(objname)
    size = ctypes.sizeof(structure)

    # it is known
    idc.MakeUnknown(address, size, idc.DOUNK_SIMPLE)
    idc.MakeStruct(address, objname)

    # read the structure and return that data
    data = (idc.GetOriginalByte(x) for x in xrange(address, address + size))
    _ret = structure.from_buffer_copy(''.join(chr(x) for x in data))

    class _Structure:
        pass

    ret = _Structure()
    offset = 0
    for name, typ in structure._fields_:
        # pointer to an ascii string
        if typ == ctypes.c_char_p:
            value = idc.Dword(address + offset)
            setattr(ret, name, make_str(value))
        # pointer to an unicode string
        elif typ == ctypes.c_wchar_p:
            # TODO implement unicode string stuff
            pass
        # this is a pointer to another structure
        elif hasattr(typ, 'contents'):
            _name = _registered_structures[typ._type_][0]
            _addr = idc.Dword(address + offset)
            setattr(ret, name, apply_struct(_name, _addr))
        else:
            setattr(ret, name, getattr(_ret, name))
        offset += ctypes.sizeof(typ)
    return ret
def map_metadata(file, addr):
    flags = 0
    flags |= 0x0001  # NEF_SEGS
    size = os.stat(file).st_size

    li = idaapi.open_linput(file, False)

    #print('li = %s' % str(li))

    rc = idaapi.load_binary_file(file, li, flags, 0, 0, addr, size)

    #print('rc = %d' % rc)

    names = [
        'stringLiteral',
        'stringLiteralData',
        'strings',
        'events',
        'properties',
        'methods',
        'parameterDefaultValues',
        'fieldDefaultValues',
        'fieldAndParameterDefaultValueData',
        'fieldMarshaledSizes',
        'parameters',
        'fields',
        'genericParameters',
        'genericParameterConstraints',
        'genericContainers',
        'nestedTypes',
        'interfaces',
        'vtableMethods',
        'interfaceOffsets',
        'typeDefinitions',
        'rgctxEntries',
        'images',
        'assemblies',
        'metadataUsageLists',
        'metadataUsagePairs',
        'fieldRefs',
        'referencedAssemblies',
        'attributesInfo',
        'attributeTypes',
    ]

    baseaddr = addr

    idc.MakeDword(addr + 0)
    idc.MakeNameEx(addr + 0, 'META_Sig', idc.SN_NOWARN | idc.SN_AUTO)
    idc.MakeDword(addr + 4)
    idc.MakeNameEx(addr + 0, 'META_Version', idc.SN_NOWARN | idc.SN_AUTO)

    for i in range(len(names)):
        descaddr = baseaddr + 8 + i * 8

        idc.MakeStruct(descaddr, 'OffsetAndCount')
        idc.MakeNameEx(descaddr, 'META_%sDesc' % names[i],
                       idc.SN_NOWARN | idc.SN_AUTO)

        dataaddr = baseaddr + idc.Dword(descaddr + 0)
        datasize = idc.Dword(descaddr + 4)

        idc.MakeNameEx(dataaddr, 'META_%s' % names[i],
                       idc.SN_NOWARN | idc.SN_AUTO)

    # string literal
    descaddr = idc.LocByName('META_stringLiteralDesc')
    size1 = idc.Dword(descaddr + 4)
    addr1 = idc.LocByName('META_stringLiteral')
    addr1end = addr1 + size1
    addr2 = idc.LocByName('META_stringLiteralData')

    #print('addr1: %X' % (addr1))
    #print('addr2: %X' % (addr2))

    while addr1 < addr1end:
        strsize = idc.Dword(addr1 + 0)
        stroff = idc.Dword(addr1 + 4)

        #print('%X - %X' % (addr2 + stroff, addr2 + stroff + strsize))

        idc.MakeStr(addr2 + stroff, addr2 + stroff + strsize)

        addr1 += 8

    idc.Jump(baseaddr)
def analyze_meta_reg(meta_reg, code_reg):
    global metadata

    print('analyze_meta_reg')

    defs = [
        (0, 'GenericClasses', 'genclass', 'Il2CppGenericClass'),
        (0, 'GenericInsts', 'geninst', 'Il2CppGenericInst'),
        (12, 'GenericMethodTable', 'genmethodtbl',
         'Il2CppGenericMethodFunctionsDefinitions'),
        (0, 'Types', 'type', 'Il2CppType'),
        (12, 'MethodSpec', 'methodspec', 'Il2CppMethodSpec'),
        (0, 'FieldOffsets', 'fieldoff', 'int'),
        (0, 'TypeDefinitionsSizes', 'typedefsize',
         'Il2CppTypeDefinitionSizes'),
        (0, 'MetadataUsages', 'metausage', 'int'),
    ]
    defaddr = meta_reg

    idc.MakeNameEx(meta_reg, 'g_meta_reg', idc.SN_NOWARN | idc.SN_AUTO)
    idc.MakeStruct(meta_reg, 'MetaRegistration')

    for i in defs:
        if i[0] == 0:
            defaddr = make_ref_table(True, defaddr, i[1], i[2], i[3])
        else:
            defaddr = make_table(True, defaddr, i[1], i[2], i[3], i[0])

    # metadata matching
    typecount = 0

    for i in metadata.images:
        """
    print('%s' % (i.name))
    print('  typeStart:       %d' % (i.typeStart))
    print('  typeCount:       %d' % (i.typeCount))
    print('  entryPointIndex: %d' % (i.entryPointIndex))
    print('  token:           %X' % (i.token))
    """
        typecount += i.typeCount

    # type
    count_type = idc.Dword(meta_reg + 8 * 3 + 0)
    addr_type = idc.Dword(meta_reg + 8 * 3 + 4)
    count_fieldoff = idc.Dword(meta_reg + 8 * 5 + 0)
    addr_fieldoff = idc.Dword(meta_reg + 8 * 5 + 4)
    count_typedefsize = idc.Dword(meta_reg + 8 * 6 + 0)
    addr_typedefsize = idc.Dword(meta_reg + 8 * 6 + 4)
    addr_methods = idc.Dword(code_reg + 4)

    print('count_type               = %d' % (count_type))
    print('addr_type                = %X' % (addr_type))
    print('typecount                = %d' % typecount)
    print('metadata.typeDefinitions = %d' % (len(metadata.typeDefinitions)))
    print('count_fieldoff           = %d' % (count_fieldoff))
    print('count_typedefsize        = %d' % (count_typedefsize))
    print('addr_fieldoff            = %X' % (addr_fieldoff))
    print('addr_typedefsize         = %X' % (addr_typedefsize))
    print('addr_methods             = %X' % (addr_methods))

    assert count_fieldoff == len(metadata.typeDefinitions), 'ERROR'
    assert count_typedefsize == len(metadata.typeDefinitions), 'ERROR'

    for i in metadata.images:
        # image
        print('%s' % (i.name))
        print('  typeStart:       %d' % (i.typeStart))
        print('  typeCount:       %d' % (i.typeCount))
        print('  entryPointIndex: %d' % (i.entryPointIndex))
        print('  token:           %X' % (i.token))

        imgname = i.name

        for j in range(i.typeCount):
            typeindex = i.typeStart + j
            metadata_type = metadata.typeDefinitions[typeindex]
            name = metadata_type.name

            fieldoff = idc.Dword(addr_fieldoff + typeindex * 4)
            typedefsize = idc.Dword(addr_typedefsize + typeindex * 4)

            print('  Typw: %4d %08X/%08X: %s' %
                  (typeindex, fieldoff, typedefsize, name))

            # fields
            #print('metadata_type.field_count = %d' % metadata_type.field_count)
            #print('metadata_type.fieldStart  = %d' % metadata_type.fieldStart)

            if metadata_type.field_count > 0:
                print('    Fields')

                for k in range(metadata_type.field_count):
                    fieldindex = metadata_type.fieldStart + k  # metadata
                    field = metadata.fields[fieldindex]  # metadata
                    fieldtypeaddr = idc.Dword(addr_type +
                                              8 * field.typeIndex)  # mata_reg
                    is_class, fieldtypename, value1, value2, attrs, type, num_mods, byref, pinned = \
                      get_typeinfo_by_metareg(fieldtypeaddr)

                    print('      %s : %s' %
                          (field.name.ljust(32), fieldtypename))

            # methods
            #print('metadata_type.method_count = %d' % metadata_type.method_count)
            #print('metadata_type.methodStart  = %d' % metadata_type.methodStart)

            if metadata_type.method_count > 0:
                print('    Methods')

                for k in range(metadata_type.method_count):
                    methodindex = metadata_type.methodStart + k  # metadata
                    method = metadata.methods[methodindex]  # metadata
                    rettypeaddr = idc.Dword(addr_type +
                                            8 * method.returnType)  # mata_reg
                    is_class, rettypename, value1, value2, attrs, type, num_mods, byref, pinned = \
                      get_typeinfo_by_metareg(rettypeaddr)

                    codeaddr = idc.Dword(addr_methods + method.methodIndex * 4)
                    oldname = idc.Name(codeaddr)

                    print('      %08X: %s : %s' %
                          (codeaddr, method.name, rettypename))

                    if oldname.startswith('sub_'):
                        funcname = 'ctor_%s' % name if method.name == '.ctor' \
                              else '%s::%s' % (name, method.name)

                        make_name(codeaddr, funcname)