diff --git a/Il2CppInspector/Il2CppBinary.cs b/Il2CppInspector/Il2CppBinary.cs index aabf7c8..79cb964 100644 --- a/Il2CppInspector/Il2CppBinary.cs +++ b/Il2CppInspector/Il2CppBinary.cs @@ -59,7 +59,7 @@ namespace Il2CppInspector } // Architecture-specific search function - protected abstract (ulong, ulong) ConsiderCode(uint loc, ulong globalOffset); + protected abstract (ulong, ulong) ConsiderCode(IFileFormatReader image, uint loc); // Check all search locations public bool Initialize(double version, uint imageIndex = 0) { @@ -99,7 +99,7 @@ namespace Il2CppInspector foreach (var loc in addrs) if (loc != 0) { - var (code, metadata) = ConsiderCode(loc, Image.GlobalOffset); + var (code, metadata) = ConsiderCode(subImage, loc); if (code != 0) { Console.WriteLine("Required structures acquired from code heuristics"); Configure(subImage, code, metadata); diff --git a/Il2CppInspector/Il2CppBinaryARM.cs b/Il2CppInspector/Il2CppBinaryARM.cs index 5fc5b9d..c72cee5 100644 --- a/Il2CppInspector/Il2CppBinaryARM.cs +++ b/Il2CppInspector/Il2CppBinaryARM.cs @@ -16,7 +16,7 @@ namespace Il2CppInspector public Il2CppBinaryARM(IFileFormatReader stream, uint codeRegistration, uint metadataRegistration) : base(stream, codeRegistration, metadataRegistration) { } - protected override (ulong, ulong) ConsiderCode(uint loc, ulong globalOffset) { + protected override (ulong, ulong) ConsiderCode(IFileFormatReader image, uint loc) { // Assembly bytes to search for at start of each function ulong metadataRegistration, codeRegistration; byte[] buff; @@ -24,25 +24,25 @@ namespace Il2CppInspector // ARMv7 // void Il2CppCodegenRegistration() (not available in the symbol table of later versions) var bytes = new byte[] { 0x1c, 0x0, 0x9f, 0xe5, 0x1c, 0x10, 0x9f, 0xe5, 0x1c, 0x20, 0x9f, 0xe5 }; - Image.Position = loc; - buff = Image.ReadBytes(12); + image.Position = loc; + buff = image.ReadBytes(12); if (bytes.SequenceEqual(buff)) { - Image.Position = loc + 0x2c; - var subaddr = Image.ReadUInt32() + globalOffset; - Image.Position = (uint) (subaddr + 0x28); - codeRegistration = Image.ReadUInt32() + globalOffset; - Image.Position = (uint) (subaddr + 0x2C); - var ptr = Image.ReadUInt32() + globalOffset; - Image.Position = Image.MapVATR(ptr); - metadataRegistration = Image.ReadUInt32(); + image.Position = loc + 0x2c; + var subaddr = image.ReadUInt32() + image.GlobalOffset; + image.Position = (uint) (subaddr + 0x28); + codeRegistration = image.ReadUInt32() + image.GlobalOffset; + image.Position = (uint) (subaddr + 0x2C); + var ptr = image.ReadUInt32() + image.GlobalOffset; + image.Position = image.MapVATR(ptr); + metadataRegistration = image.ReadUInt32(); return (codeRegistration, metadataRegistration); } // ARMv7 metadata v24 // void Il2CppCodeRegistration() - Image.Position = loc; + image.Position = loc; - buff = Image.ReadBytes(0x18); + buff = image.ReadBytes(0x18); // Check for ADD R0, PC, R0; ADD R1, PC, R1 near the end of the function if (new byte[] {0x00, 0x00, 0x8F, 0xE0, 0x01, 0x10, 0x8F, 0xE0}.SequenceEqual(buff.Skip(0x10)) @@ -51,38 +51,38 @@ namespace Il2CppInspector // Read offset in LDR operand plus pointer table at end of function to find pCgr var pCgr = buff[8] + loc + 0x10; - Image.Position = pCgr; - pCgr = Image.ReadUInt32() + loc + 0x1c; + image.Position = pCgr; + pCgr = image.ReadUInt32() + loc + 0x1c; // void Il2CppCodegenRegistration() // Read pointer table at end of function - Image.Position = pCgr + 0x1C; - var pMetadata = Image.ReadUInt32() + pCgr + 0x14; - codeRegistration = Image.ReadUInt32() + pCgr + 0x18; + image.Position = pCgr + 0x1C; + var pMetadata = image.ReadUInt32() + pCgr + 0x14; + codeRegistration = image.ReadUInt32() + pCgr + 0x18; - Image.Position = Image.MapVATR(pMetadata); - metadataRegistration = Image.ReadUInt32(); + image.Position = image.MapVATR(pMetadata); + metadataRegistration = image.ReadUInt32(); return (codeRegistration, metadataRegistration); } // ARMv7 Thumb (T1) metadata v23 // void Il2CppCodeRegistration() - Image.Position = loc; + image.Position = loc; // Check for ADD Rx, PC in relevant parts of function - buff = Image.ReadBytes(0x20); + buff = image.ReadBytes(0x20); if (buff[0x0C] == 0x79 && buff[0x0D] == 0x44 && // ADD R1, PC buff[0x16] == 0x78 && buff[0x17] == 0x44 && // ADD R0, PC buff[0x1E] == 0x7A && buff[0x1F] == 0x44) // ADD R2, PC { // Follow path to metadata pointer var ppMetadata = decodeMovImm32(buff) + loc + 0x10; - Image.Position = ppMetadata; - metadataRegistration = Image.ReadUInt32(); + image.Position = ppMetadata; + metadataRegistration = image.ReadUInt32(); // Follow path to code pointer var pCode = decodeMovImm32(buff.Skip(8).Take(4).Concat(buff.Skip(14).Take(4)).ToArray()); - codeRegistration = pCode + loc + 0x1A + globalOffset; + codeRegistration = pCode + loc + 0x1A + image.GlobalOffset; return (codeRegistration, metadataRegistration); } @@ -91,19 +91,19 @@ namespace Il2CppInspector // http://liris.cnrs.fr/~mmrissa/lib/exe/fetch.php?media=armv7-a-r-manual.pdf - A8.8.106 // http://armconverter.com/hextoarm/ bytes = new byte[] { 0x2d, 0xe9, 0x00, 0x48, 0xeb, 0x46 }; - Image.Position = loc; - buff = Image.ReadBytes(6); + image.Position = loc; + buff = image.ReadBytes(6); if (!bytes.SequenceEqual(buff)) return (0, 0); bytes = new byte[] { 0x00, 0x23, 0x00, 0x22, 0xbd, 0xe8, 0x00, 0x48 }; - Image.Position += 0x10; - buff = Image.ReadBytes(8); + image.Position += 0x10; + buff = image.ReadBytes(8); if (!bytes.SequenceEqual(buff)) return (0, 0); - Image.Position = loc + 6; - Image.Position = (Image.MapVATR(decodeMovImm32(Image.ReadBytes(8))) & 0xfffffffc) + 0x0e; - metadataRegistration = decodeMovImm32(Image.ReadBytes(8)); - codeRegistration = decodeMovImm32(Image.ReadBytes(8)); + image.Position = loc + 6; + image.Position = (image.MapVATR(decodeMovImm32(image.ReadBytes(8))) & 0xfffffffc) + 0x0e; + metadataRegistration = decodeMovImm32(image.ReadBytes(8)); + codeRegistration = decodeMovImm32(image.ReadBytes(8)); return (codeRegistration, metadataRegistration); } diff --git a/Il2CppInspector/Il2CppBinaryX86.cs b/Il2CppInspector/Il2CppBinaryX86.cs index 7836c2e..75d3a65 100644 --- a/Il2CppInspector/Il2CppBinaryX86.cs +++ b/Il2CppInspector/Il2CppBinaryX86.cs @@ -13,7 +13,7 @@ namespace Il2CppInspector public Il2CppBinaryX86(IFileFormatReader stream) : base(stream) { } public Il2CppBinaryX86(IFileFormatReader stream, uint codeRegistration, uint metadataRegistration) : base(stream, codeRegistration, metadataRegistration) { } - protected override (ulong, ulong) ConsiderCode(uint loc, ulong globalOffset) { + protected override (ulong, ulong) ConsiderCode(IFileFormatReader image, uint loc) { ulong metadata, code; long funcPtr; ushort opcode; @@ -22,60 +22,60 @@ namespace Il2CppInspector // Assembly bytes to search for at start of each function var bytes = new byte[] {0x6A, 0x00, 0x6A, 0x00, 0x68}; - Image.Position = loc; - var buff = Image.ReadBytes(5); + image.Position = loc; + var buff = image.ReadBytes(5); if (bytes.SequenceEqual(buff)) { // Next 4 bytes are the function pointer being pushed onto the stack - funcPtr = Image.ReadUInt32(); + funcPtr = image.ReadUInt32(); // Start of next instruction - if (Image.ReadByte() != 0xB9) + if (image.ReadByte() != 0xB9) return (0, 0); // Jump to Il2CppCodegenRegistration - Image.Position = Image.MapVATR((ulong) funcPtr + 6); - metadata = Image.ReadUInt32(); - Image.Position = Image.MapVATR((ulong) funcPtr + 11); - code = Image.ReadUInt32(); + image.Position = image.MapVATR((ulong) funcPtr + 6); + metadata = image.ReadUInt32(); + image.Position = image.MapVATR((ulong) funcPtr + 11); + code = image.ReadUInt32(); return (code, metadata); } // Variant 2 bytes = new byte[] {0x55, 0x89, 0xE5, 0x53, 0x83, 0xE4, 0xF0, 0x83, 0xEC, 0x20, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5B}; - Image.Position = loc; - buff = Image.ReadBytes(16); + image.Position = loc; + buff = image.ReadBytes(16); if (!bytes.SequenceEqual(buff)) return (0, 0); - Image.Position += 8; - funcPtr = Image.MapVATR(Image.ReadUInt32() + globalOffset); - if (funcPtr > Image.Stream.BaseStream.Length) + image.Position += 8; + funcPtr = image.MapVATR(image.ReadUInt32() + image.GlobalOffset); + if (funcPtr > image.Stream.BaseStream.Length) return (0, 0); // Extract Metadata pointer // An 0x838D opcode indicates LEA (no indirection) - Image.Position = funcPtr + 0x20; - opcode = Image.ReadUInt16(); - metadata = Image.ReadUInt32() + globalOffset; + image.Position = funcPtr + 0x20; + opcode = image.ReadUInt16(); + metadata = image.ReadUInt32() + image.GlobalOffset; // An 8x838B opcode indicates MOV (pointer indirection) if (opcode == 0x838B) { - Image.Position = Image.MapVATR(metadata); - metadata = Image.ReadUInt32(); + image.Position = image.MapVATR(metadata); + metadata = image.ReadUInt32(); } if (opcode != 0x838B && opcode != 0x838D) return (0, 0); // Repeat the same logic for extracting the Code pointer - Image.Position = funcPtr + 0x2A; - opcode = Image.ReadUInt16(); - code = Image.ReadUInt32() + globalOffset; + image.Position = funcPtr + 0x2A; + opcode = image.ReadUInt16(); + code = image.ReadUInt32() + image.GlobalOffset; if (opcode == 0x838B) { - Image.Position = Image.MapVATR(code); - code = Image.ReadUInt32(); + image.Position = image.MapVATR(code); + code = image.ReadUInt32(); } if (opcode != 0x838B && opcode != 0x838D)