Cpp2IL
Cpp2IL copied to clipboard
Support dumped il2cpp files from memory (Android)
It seems Cpp2IL doesn't have option to input base address. I needed to dump binary and metadata from memory in order to obtain decrypted blocks. I tried to input command but getting an error Cpp2IL.Core.SoftException: Invalid force option configuration ./Cpp2IL --game-path "path to apk file" --force-binary-path "libil2cpp-b6bf7000-bdc3d000.bin" --force-metadata-path "global-metadata.dat-a98f0000-aab42000.bin"
https://anonfiles.com/X4UbGe1by0/dumped_il2cpp_files_zip
Perfare refuse to fix the issue for 32-bit files (See https://github.com/Perfare/Il2CppDumper/issues/552), that's why I open issue here hoping you will support it. 32-bit is not dead yet, many games are still using it
The only thing you're missing in that is the unity version. Try and see if that works.
Is that correct?
./Cpp2IL --game-path "path to apk file" --force-binary-path "libil2cpp-b6bf7000-bdc3d000.bin" --force-metadata-path "global-metadata.dat-a98f0000-aab42000.bin" --force-unity-version 2020.3.30f1
also tried --force-unity-version "2020.3.30f1"
===Cpp2IL by Samboy063===
A Tool to Reverse Unity's "il2cpp" Build Process.
[Info] [Program] Running on Win32NT
[Warn] [Program] Using force options, I sure hope you know what you're doing!
Unhandled Exception: System.FormatException: The input string was not in a correct format.
ved System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
ved System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
ved System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
ved System.Linq.Buffer`1..ctor(IEnumerable`1 source)
ved System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
ved Cpp2IL.Program.GetRuntimeOptionsFromCommandLine(String[] commandLine) i E:\Github\Cpp2IL\Cpp2IL\Program.cs:linje 271
ved Cpp2IL.Program.Main(String[] args) i E:\Github\Cpp2IL\Cpp2IL\Program.cs:linje 331
Remove the f1
Alright, the forcing args works now but i'm getting an error regarding binary reader. Since the binary was dumped from memory, I'm pretty sure it is needed to input base address like original Il2CppDumper
[Info] [Program] Running on Win32NT
[Warn] [Program] Using force options, I sure hope you know what you're doing!
[Info] [Library] Initializing Metadata...
[Info] [Library] Using actual IL2CPP Metadata version 27,1
[Info] [Library] Initialized Metadata in 1626ms
[Info] [Library] Searching Binary for Required Data...
Unhandled Exception: System.ArgumentOutOfRangeException: The length of the stream must not be negative and must be less than 2^31 - 1 - origin.
Parameter name: value
ved System.IO.MemoryStream.set_Position(Int64 value)
ved LibCpp2IL.ClassReadingBinaryReader.set_Position(Int64 value) i E:\Github\Cpp2IL\LibCpp2IL\ClassReadingBinaryReader.cs:linje 30
ved LibCpp2IL.ClassReadingBinaryReader.ReadStringToNull(Int64 offset) i E:\Github\Cpp2IL\LibCpp2IL\ClassReadingBinaryReader.cs:linje 277
ved LibCpp2IL.ClassReadingBinaryReader.ReadStringToNull(UInt64 offset) i E:\Github\Cpp2IL\LibCpp2IL\ClassReadingBinaryReader.cs:linje 263
ved LibCpp2IL.Elf.ElfFile..ctor(MemoryStream input, Int64 maxMetadataUsages) i E:\Github\Cpp2IL\LibCpp2IL\Elf\ElfFile.cs:linje 70
ved LibCpp2IL.LibCpp2IlMain.Initialize(Byte[] binaryBytes, Byte[] metadataBytes, Int32[] unityVersion) i E:\Github\Cpp2IL\LibCpp2IL\LibCpp2IlMain.cs:linje 169
ved LibCpp2IL.LibCpp2IlMain.LoadFromFile(String pePath, String metadataPath, Int32[] unityVersion) i E:\Github\Cpp2IL\LibCpp2IL\LibCpp2IlMain.cs:linje 248
ved Cpp2IL.Core.Cpp2IlApi.InitializeLibCpp2Il(String assemblyPath, String metadataPath, Int32[] unityVersion, Boolean allowUserToInputAddresses) i E:\Github\Cpp2IL\Cpp2IL.Core\Cpp2IlApi.cs:linje 182
ved Cpp2IL.Program.MainWithArgs(Cpp2IlRuntimeArgs runtimeArgs) i E:\Github\Cpp2IL\Cpp2IL\Program.cs:linje 385
ved Cpp2IL.Program.Main(String[] args) i E:\Github\Cpp2IL\Cpp2IL\Program.cs:linje 333
Alright, the forcing args works now but i'm getting an error regarding binary reader. Since the binary was dumped from memory, I'm pretty sure it is needed to input base address like original Il2CppDumper
[Info] [Program] Running on Win32NT [Warn] [Program] Using force options, I sure hope you know what you're doing! [Info] [Library] Initializing Metadata... [Info] [Library] Using actual IL2CPP Metadata version 27,1 [Info] [Library] Initialized Metadata in 1626ms [Info] [Library] Searching Binary for Required Data... Unhandled Exception: System.ArgumentOutOfRangeException: The length of the stream must not be negative and must be less than 2^31 - 1 - origin. Parameter name: value ved System.IO.MemoryStream.set_Position(Int64 value) ved LibCpp2IL.ClassReadingBinaryReader.set_Position(Int64 value) i E:\Github\Cpp2IL\LibCpp2IL\ClassReadingBinaryReader.cs:linje 30 ved LibCpp2IL.ClassReadingBinaryReader.ReadStringToNull(Int64 offset) i E:\Github\Cpp2IL\LibCpp2IL\ClassReadingBinaryReader.cs:linje 277 ved LibCpp2IL.ClassReadingBinaryReader.ReadStringToNull(UInt64 offset) i E:\Github\Cpp2IL\LibCpp2IL\ClassReadingBinaryReader.cs:linje 263 ved LibCpp2IL.Elf.ElfFile..ctor(MemoryStream input, Int64 maxMetadataUsages) i E:\Github\Cpp2IL\LibCpp2IL\Elf\ElfFile.cs:linje 70 ved LibCpp2IL.LibCpp2IlMain.Initialize(Byte[] binaryBytes, Byte[] metadataBytes, Int32[] unityVersion) i E:\Github\Cpp2IL\LibCpp2IL\LibCpp2IlMain.cs:linje 169 ved LibCpp2IL.LibCpp2IlMain.LoadFromFile(String pePath, String metadataPath, Int32[] unityVersion) i E:\Github\Cpp2IL\LibCpp2IL\LibCpp2IlMain.cs:linje 248 ved Cpp2IL.Core.Cpp2IlApi.InitializeLibCpp2Il(String assemblyPath, String metadataPath, Int32[] unityVersion, Boolean allowUserToInputAddresses) i E:\Github\Cpp2IL\Cpp2IL.Core\Cpp2IlApi.cs:linje 182 ved Cpp2IL.Program.MainWithArgs(Cpp2IlRuntimeArgs runtimeArgs) i E:\Github\Cpp2IL\Cpp2IL\Program.cs:linje 385 ved Cpp2IL.Program.Main(String[] args) i E:\Github\Cpp2IL\Cpp2IL\Program.cs:linje 333
After modifying the constructor of ELF file class, I successfully dumped the il2cpp file from memory (unity 2017.4.39f1, il2cpp version 24, x86, Android)
The main modifications I made are as follows:
Manually set the value of _globalOffsett
to the dump position, and set a bool called _isDump
to true
In after _globaloffset
is assigned, add (You need to modify the access permissions of IElfProgramHeaderEntry
's attribute)
if (_isDump)
{
for (int i = 0; i < _elfProgramHeaderEntries!.Count; i++)
{
Position = _elfHeader!.pProgramHeader + (is32Bit ? i * 32u + 4u : i * 56u + 8u);
var phdr = _elfProgramHeaderEntries[i];
phdr.RawAddress = phdr.VirtualAddress;
phdr.VirtualAddress += (ulong)_globalOffset;
Position += is32Bit ? 4 : 8;
phdr.RawSize = phdr.VirtualSize;
}
}
In after dynamicsection
is assigned, add
if (_isDump)
{
for (int i = 0; i < _dynamicSection.Count; i++)
{
Position = (long)dynamicSegment.RawAddress + (is32Bit ? i * 8 + 4 : i * 16 + 8);
var dyn = _dynamicSection[i];
switch (dyn.Tag)
{
case ElfDynamicType.DT_PLTGOT:
case ElfDynamicType.DT_HASH:
case ElfDynamicType.DT_STRTAB:
case ElfDynamicType.DT_SYMTAB:
case ElfDynamicType.DT_RELA:
case ElfDynamicType.DT_INIT:
case ElfDynamicType.DT_FINI:
case ElfDynamicType.DT_REL:
case ElfDynamicType.DT_JMPREL:
case ElfDynamicType.DT_INIT_ARRAY:
case ElfDynamicType.DT_FINI_ARRAY:
dyn.Value += (ulong)_globalOffset;
break;
}
}
}
and modified ProcessRelocations
if (!_isDump)
{
LibLogger.VerboseNewline("\tFinding Relocations...");
start = DateTime.Now;
ProcessRelocations();
LibLogger.VerboseNewline($"OK ({(DateTime.Now - start).TotalMilliseconds} ms)");
}
In fact, because il2cpp files are encrypted, I also made some other modifications. Finally, it worked. I hope it will help you.
Glad you got it working
@jxr2006 Thanks, i'll see what I can do with this. Do you mind making pull request of this changes?
Alright, the forcing args works now but i'm getting an error regarding binary reader. Since the binary was dumped from memory, I'm pretty sure it is needed to input base address like original Il2CppDumper
[Info] [Program] Running on Win32NT [Warn] [Program] Using force options, I sure hope you know what you're doing! [Info] [Library] Initializing Metadata... [Info] [Library] Using actual IL2CPP Metadata version 27,1 [Info] [Library] Initialized Metadata in 1626ms [Info] [Library] Searching Binary for Required Data... Unhandled Exception: System.ArgumentOutOfRangeException: The length of the stream must not be negative and must be less than 2^31 - 1 - origin. Parameter name: value ved System.IO.MemoryStream.set_Position(Int64 value) ved LibCpp2IL.ClassReadingBinaryReader.set_Position(Int64 value) i E:\Github\Cpp2IL\LibCpp2IL\ClassReadingBinaryReader.cs:linje 30 ved LibCpp2IL.ClassReadingBinaryReader.ReadStringToNull(Int64 offset) i E:\Github\Cpp2IL\LibCpp2IL\ClassReadingBinaryReader.cs:linje 277 ved LibCpp2IL.ClassReadingBinaryReader.ReadStringToNull(UInt64 offset) i E:\Github\Cpp2IL\LibCpp2IL\ClassReadingBinaryReader.cs:linje 263 ved LibCpp2IL.Elf.ElfFile..ctor(MemoryStream input, Int64 maxMetadataUsages) i E:\Github\Cpp2IL\LibCpp2IL\Elf\ElfFile.cs:linje 70 ved LibCpp2IL.LibCpp2IlMain.Initialize(Byte[] binaryBytes, Byte[] metadataBytes, Int32[] unityVersion) i E:\Github\Cpp2IL\LibCpp2IL\LibCpp2IlMain.cs:linje 169 ved LibCpp2IL.LibCpp2IlMain.LoadFromFile(String pePath, String metadataPath, Int32[] unityVersion) i E:\Github\Cpp2IL\LibCpp2IL\LibCpp2IlMain.cs:linje 248 ved Cpp2IL.Core.Cpp2IlApi.InitializeLibCpp2Il(String assemblyPath, String metadataPath, Int32[] unityVersion, Boolean allowUserToInputAddresses) i E:\Github\Cpp2IL\Cpp2IL.Core\Cpp2IlApi.cs:linje 182 ved Cpp2IL.Program.MainWithArgs(Cpp2IlRuntimeArgs runtimeArgs) i E:\Github\Cpp2IL\Cpp2IL\Program.cs:linje 385 ved Cpp2IL.Program.Main(String[] args) i E:\Github\Cpp2IL\Cpp2IL\Program.cs:linje 333
After modifying the constructor of ELF file class, I successfully dumped the il2cpp file from memory (unity 2017.4.39f1, il2cpp version 24, x86, Android)
The main modifications I made are as follows:
Manually set the value of
_globalOffsett
to the dump position, and set a bool called_isDump
to trueIn after
_globaloffset
is assigned, add (You need to modify the access permissions ofIElfProgramHeaderEntry
's attribute)if (_isDump) { for (int i = 0; i < _elfProgramHeaderEntries!.Count; i++) { Position = _elfHeader!.pProgramHeader + (is32Bit ? i * 32u + 4u : i * 56u + 8u); var phdr = _elfProgramHeaderEntries[i]; phdr.RawAddress = phdr.VirtualAddress; phdr.VirtualAddress += (ulong)_globalOffset; Position += is32Bit ? 4 : 8; phdr.RawSize = phdr.VirtualSize; } }
In after
dynamicsection
is assigned, addif (_isDump) { for (int i = 0; i < _dynamicSection.Count; i++) { Position = (long)dynamicSegment.RawAddress + (is32Bit ? i * 8 + 4 : i * 16 + 8); var dyn = _dynamicSection[i]; switch (dyn.Tag) { case ElfDynamicType.DT_PLTGOT: case ElfDynamicType.DT_HASH: case ElfDynamicType.DT_STRTAB: case ElfDynamicType.DT_SYMTAB: case ElfDynamicType.DT_RELA: case ElfDynamicType.DT_INIT: case ElfDynamicType.DT_FINI: case ElfDynamicType.DT_REL: case ElfDynamicType.DT_JMPREL: case ElfDynamicType.DT_INIT_ARRAY: case ElfDynamicType.DT_FINI_ARRAY: dyn.Value += (ulong)_globalOffset; break; } } }
and modified ProcessRelocations
if (!_isDump) { LibLogger.VerboseNewline("\tFinding Relocations..."); start = DateTime.Now; ProcessRelocations(); LibLogger.VerboseNewline($"OK ({(DateTime.Now - start).TotalMilliseconds} ms)"); }
In fact, because il2cpp files are encrypted, I also made some other modifications. Finally, it worked. I hope it will help you.
能不能push一下这个到独立的fork?