private Il2CppTypeDefinition FindClassEntry(Metadata metadata, Il2CppExecutor executor, string className, out int typeDefIndex) { typeDefIndex = 0; foreach (var imageDef in metadata.imageDefs) { var imageName = metadata.GetStringFromIndex(imageDef.nameIndex); var typeEnd = imageDef.typeStart + imageDef.typeCount; for (typeDefIndex = imageDef.typeStart; typeDefIndex < typeEnd; typeDefIndex++) { var typeDef = metadata.typeDefs[typeDefIndex]; // Ignore if the class is sealed. if (!typeDef.IsValueType && !typeDef.IsEnum && (typeDef.flags & TYPE_ATTRIBUTE_SEALED) != 0) { continue; } var typeName = executor.GetTypeDefName(typeDef, false, true); if (typeName == className) { return(typeDef); } } } throw new Exception("Class " + className + " not found."); }
private int GetFieldOffset(Il2Cpp il2Cpp, Metadata metadata, Il2CppExecutor executor, string classname, string membername) { int typeDefIndex = 0; Il2CppTypeDefinition typeDef = FindClassEntry(metadata, executor, classname, out typeDefIndex); if (typeDef == null) { return(0); } var fieldEnd = typeDef.fieldStart + typeDef.field_count; for (var i = typeDef.fieldStart; i < fieldEnd; ++i) { var isStatic = false; var fieldDef = metadata.fieldDefs[i]; var fieldType = il2Cpp.types[fieldDef.typeIndex]; if ((fieldType.attrs & FIELD_ATTRIBUTE_STATIC) != 0) { isStatic = true; } string memberName = metadata.GetStringFromIndex(fieldDef.nameIndex); if (memberName == membername) { return(il2Cpp.GetFieldOffsetFromIndex(typeDefIndex, i - typeDef.fieldStart, i, typeDef.IsValueType, isStatic)); } } throw new Exception("Field " + membername + " not found in " + classname); }
private int GetMethodAddress(Il2Cpp il2Cpp, Metadata metadata, Il2CppExecutor executor, string methodType, string methodName) { if (il2Cpp.Version >= 27) { var sectionHelper = executor.GetSectionHelper(); foreach (var sec in sectionHelper.data) { il2Cpp.Position = sec.offset; while (il2Cpp.Position < sec.offsetEnd - il2Cpp.PointerSize) { var addr = il2Cpp.Position; var metadataValue = il2Cpp.ReadUIntPtr(); var position = il2Cpp.Position; if (metadataValue < uint.MaxValue) { var encodedToken = (uint)metadataValue; var usage = metadata.GetEncodedIndexType(encodedToken); if (usage > 0 && usage <= 6) { var decodedIndex = metadata.GetDecodedMethodIndex(encodedToken); if (metadataValue == ((usage << 29) | (decodedIndex << 1)) + 1) { var va = il2Cpp.MapRTVA(addr); if (va > 0) { switch ((Il2CppMetadataUsage)usage) { case Il2CppMetadataUsage.kIl2CppMetadataUsageMethodRef: if (decodedIndex < il2Cpp.methodSpecs.Length) { var methodSpec = il2Cpp.methodSpecs[decodedIndex]; (var methodSpecTypeName, var methodSpecMethodName) = executor.GetMethodSpecName(methodSpec, true); if (methodSpecTypeName == methodType && methodSpecMethodName == methodName) { return((int)il2Cpp.GetRVA(va)); } ; } break; } if (il2Cpp.Position != position) { il2Cpp.Position = position; } } } } } } } } return(0); }
private int GetTypeInfoAddress(Il2Cpp il2Cpp, Metadata metadata, Il2CppExecutor executor, string typeToFind) { if (il2Cpp.Version >= 27) { var sectionHelper = executor.GetSectionHelper(); foreach (var sec in sectionHelper.data) { il2Cpp.Position = sec.offset; while (il2Cpp.Position < sec.offsetEnd - il2Cpp.PointerSize) { var addr = il2Cpp.Position; var metadataValue = il2Cpp.ReadUIntPtr(); var position = il2Cpp.Position; if (metadataValue < uint.MaxValue) { var encodedToken = (uint)metadataValue; var usage = metadata.GetEncodedIndexType(encodedToken); if (usage > 0 && usage <= 6) { var decodedIndex = metadata.GetDecodedMethodIndex(encodedToken); if (metadataValue == ((usage << 29) | (decodedIndex << 1)) + 1) { var va = il2Cpp.MapRTVA(addr); if (va > 0) { switch ((Il2CppMetadataUsage)usage) { case Il2CppMetadataUsage.kIl2CppMetadataUsageTypeInfo: if (decodedIndex < il2Cpp.types.Length) { var type = il2Cpp.types[decodedIndex]; var typeName = executor.GetTypeName(type, true, false); if (typeName.Contains(typeToFind)) { return((int)il2Cpp.GetRVA(va)); } } break; } if (il2Cpp.Position != position) { il2Cpp.Position = position; } } } } } } } } return(0); }
private int GetTypeInfoAddress(Il2Cpp il2Cpp, Metadata metadata, Il2CppExecutor executor, string typeToFind) { foreach (var i in metadata.metadataUsageDic[Il2CppMetadataUsage.kIl2CppMetadataUsageTypeInfo]) { var type = il2Cpp.types[i.Value]; var typeName = executor.GetTypeName(type, true, false); if (typeName.Contains(typeToFind)) { return((int)il2Cpp.GetRVA(il2Cpp.metadataUsages[i.Key])); } } return(0); }
private int GetMethodAddress(Il2Cpp il2Cpp, Metadata metadata, Il2CppExecutor executor, string methodType, string methodName) { foreach (var i in metadata.metadataUsageDic[Il2CppMetadataUsage.kIl2CppMetadataUsageMethodRef]) { var methodSpec = il2Cpp.methodSpecs[i.Value]; (var methodSpecTypeName, var methodSpecMethodName) = executor.GetMethodSpecName(methodSpec, true); if (methodSpecTypeName == methodType && methodSpecMethodName == methodName) { return((int)il2Cpp.GetRVA(il2Cpp.metadataUsages[i.Key])); } } return(0); }
public static bool InitializeIl2Cpp(Process program) { string programPath = Path.GetDirectoryName(program.MainModule.FileName); string metaFile = Path.Combine(programPath, @"oriwotw_Data\il2cpp_data\Metadata\global-metadata.dat"); string ilFile = Path.Combine(programPath, @"GameAssembly.dll"); if (!File.Exists(metaFile) || !File.Exists(ilFile)) { return(false); } byte[] metaDataBytes = File.ReadAllBytes(metaFile); byte[] il2CppBytes = File.ReadAllBytes(ilFile); Il2CppReader.Init(il2CppBytes, metaDataBytes, out Metadata metaData, out Il2CppData il2Cpp); Il2CppExecutor executor = new Il2CppExecutor(metaData, il2Cpp); Decompiler = new Il2CppDecompiler(executor); return(true); }
private void Dump(Metadata metadata, Il2Cpp il2Cpp, string outputDir) { WriteOutput("Dumping..."); var executor = new Il2CppExecutor(metadata, il2Cpp); var decompiler = new Il2CppDecompiler(executor); decompiler.Decompile(_config, outputDir, 1); WriteOutput("Done!"); if (_config.GenerateStruct) { WriteOutput("Generate struct..."); var scriptGenerator = new StructGenerator(executor); scriptGenerator.WriteScript(outputDir, 1); WriteOutput("Done!"); } if (_config.GenerateDummyDll) { WriteOutput("Generate dummy dll..."); DummyAssemblyExporter.Export(executor, outputDir, _config.DummyDllAddToken); WriteOutput("Done!"); Directory.SetCurrentDirectory(realPath); //Fix read-only directory permission } }
public IntPtr FindPointer(Process program, string asmName) { if (il2Cpp == null || lastPID != program.Id) { lastPID = program.Id; BasePtr = IntPtr.Zero; string programPath = Path.GetDirectoryName(program.MainModule.FileName); string metaFile = Path.Combine(programPath, @"oriwotw_Data\il2cpp_data\Metadata\global-metadata.dat"); string ilFile = Path.Combine(programPath, @"GameAssembly.dll"); if (!File.Exists(metaFile) || !File.Exists(ilFile)) { return(IntPtr.Zero); } byte[] metaDataBytes = File.ReadAllBytes(metaFile); byte[] il2CppBytes = File.ReadAllBytes(ilFile); Il2CppReader.Init(il2CppBytes, metaDataBytes, out metaData, out il2Cpp); executor = new Il2CppExecutor(metaData, il2Cpp); decompiler = new Il2CppDecompiler(executor); } return(ProgramPointer.DerefPointer(program, GetPointer(program, asmName), AutoDeref)); }
private bool ExtractCurrentData(string il2cppPath, string metadataPath, out Il2Cpp il2Cpp, out Il2CppExecutor executor, out Metadata metadata) { il2Cpp = null; executor = null; metadata = null; var metadataBytes = File.ReadAllBytes(metadataPath); metadata = new Metadata(new MemoryStream(metadataBytes)); var il2cppBytes = File.ReadAllBytes(il2cppPath); var il2cppMagic = BitConverter.ToUInt32(il2cppBytes, 0); var il2CppMemory = new MemoryStream(il2cppBytes); if (il2cppMagic != IL2CPPMAGIC_PE) { throw new Exception("Unexpected il2cpp magic number."); } il2Cpp = new PE(il2CppMemory); il2Cpp.SetProperties(metadata.Version, metadata.maxMetadataUsages); if (il2Cpp.Version >= 27 && il2Cpp is ElfBase elf && elf.IsDumped) { metadata.Address = Convert.ToUInt64(Console.ReadLine(), 16); } try { var flag = il2Cpp.PlusSearch(metadata.methodDefs.Count(x => x.methodIndex >= 0), metadata.typeDefs.Length, metadata.imageDefs.Length); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { if (!flag && il2Cpp is PE) { il2Cpp = PELoader.Load(il2cppPath); il2Cpp.SetProperties(metadata.Version, metadata.maxMetadataUsages); flag = il2Cpp.PlusSearch(metadata.methodDefs.Count(x => x.methodIndex >= 0), metadata.typeDefs.Length, metadata.imageDefs.Length); } } if (!flag) { flag = il2Cpp.Search(); } if (!flag) { flag = il2Cpp.SymbolSearch(); } if (!flag) { var codeRegistration = Convert.ToUInt64(Console.ReadLine(), 16); var metadataRegistration = Convert.ToUInt64(Console.ReadLine(), 16); il2Cpp.Init(codeRegistration, metadataRegistration); } } catch { throw new Exception("ERROR: An error occurred while processing."); } executor = new Il2CppExecutor(metadata, il2Cpp); return(true); }