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)
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)
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])
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)