mirror of
https://github.com/Perfare/Il2CppDumper.git
synced 2025-01-09 11:17:35 -03:00
v27以上dump文件不再需要输入Metadata地址
支持dumped的pe文件
This commit is contained in:
parent
daeff2734c
commit
63c5af8d12
13 changed files with 135 additions and 89 deletions
|
@ -26,12 +26,13 @@ namespace Il2CppDumper
|
|||
public Elf(Stream stream) : base(stream)
|
||||
{
|
||||
Is32Bit = true;
|
||||
elfHeader = ReadClass<Elf32_Ehdr>();
|
||||
Load();
|
||||
}
|
||||
|
||||
protected override void Load()
|
||||
{
|
||||
elfHeader = ReadClass<Elf32_Ehdr>(0);
|
||||
programSegment = ReadClassArray<Elf32_Phdr>(elfHeader.e_phoff, elfHeader.e_phnum);
|
||||
if (!CheckSection())
|
||||
{
|
||||
GetDumpAddress();
|
||||
}
|
||||
if (IsDumped)
|
||||
{
|
||||
FixedProgramSegment();
|
||||
|
@ -53,7 +54,7 @@ namespace Il2CppDumper
|
|||
}
|
||||
}
|
||||
|
||||
public bool CheckSection()
|
||||
protected override bool CheckSection()
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -133,10 +134,10 @@ namespace Il2CppDumper
|
|||
if (elfHeader.e_machine == EM_ARM)
|
||||
{
|
||||
Position = result + 0x14;
|
||||
codeRegistration = ReadUInt32() + result + 0xcu + (uint)DumpAddr;
|
||||
codeRegistration = ReadUInt32() + result + 0xcu + (uint)ImageBase;
|
||||
Position = result + 0x10;
|
||||
var ptr = ReadUInt32() + result + 0x8;
|
||||
Position = MapVATR(ptr + DumpAddr);
|
||||
Position = MapVATR(ptr + ImageBase);
|
||||
metadataRegistration = ReadUInt32();
|
||||
}
|
||||
}
|
||||
|
@ -273,28 +274,35 @@ namespace Il2CppDumper
|
|||
|
||||
private bool CheckProtection()
|
||||
{
|
||||
//.init_proc
|
||||
if (dynamicSection.Any(x => x.d_tag == DT_INIT))
|
||||
try
|
||||
{
|
||||
Console.WriteLine("WARNING: find .init_proc");
|
||||
return true;
|
||||
}
|
||||
//JNI_OnLoad
|
||||
var dynstrOffset = MapVATR(dynamicSection.First(x => x.d_tag == DT_STRTAB).d_un);
|
||||
foreach (var symbol in symbolTable)
|
||||
{
|
||||
var name = ReadStringToNull(dynstrOffset + symbol.st_name);
|
||||
switch (name)
|
||||
//.init_proc
|
||||
if (dynamicSection.Any(x => x.d_tag == DT_INIT))
|
||||
{
|
||||
case "JNI_OnLoad":
|
||||
Console.WriteLine("WARNING: find JNI_OnLoad");
|
||||
return true;
|
||||
Console.WriteLine("WARNING: find .init_proc");
|
||||
return true;
|
||||
}
|
||||
//JNI_OnLoad
|
||||
var dynstrOffset = MapVATR(dynamicSection.First(x => x.d_tag == DT_STRTAB).d_un);
|
||||
foreach (var symbol in symbolTable)
|
||||
{
|
||||
var name = ReadStringToNull(dynstrOffset + symbol.st_name);
|
||||
switch (name)
|
||||
{
|
||||
case "JNI_OnLoad":
|
||||
Console.WriteLine("WARNING: find JNI_OnLoad");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (sectionTable != null && sectionTable.Any(x => x.sh_type == SHT_LOUSER))
|
||||
{
|
||||
Console.WriteLine("WARNING: find SHT_LOUSER section");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (sectionTable != null && sectionTable.Any(x => x.sh_type == SHT_LOUSER))
|
||||
catch
|
||||
{
|
||||
Console.WriteLine("WARNING: find SHT_LOUSER section");
|
||||
return true;
|
||||
// ignored
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -303,7 +311,7 @@ namespace Il2CppDumper
|
|||
{
|
||||
if (IsDumped)
|
||||
{
|
||||
return pointer - DumpAddr;
|
||||
return pointer - ImageBase;
|
||||
}
|
||||
return pointer;
|
||||
}
|
||||
|
@ -316,7 +324,7 @@ namespace Il2CppDumper
|
|||
var phdr = programSegment[i];
|
||||
phdr.p_offset = phdr.p_vaddr;
|
||||
Write(phdr.p_offset);
|
||||
phdr.p_vaddr += (uint)DumpAddr;
|
||||
phdr.p_vaddr += (uint)ImageBase;
|
||||
Write(phdr.p_vaddr);
|
||||
Position += 4;
|
||||
phdr.p_filesz = phdr.p_memsz;
|
||||
|
@ -343,7 +351,7 @@ namespace Il2CppDumper
|
|||
case DT_JMPREL:
|
||||
case DT_INIT_ARRAY:
|
||||
case DT_FINI_ARRAY:
|
||||
dyn.d_un += (uint)DumpAddr;
|
||||
dyn.d_un += (uint)ImageBase;
|
||||
Write(dyn.d_un);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -17,12 +17,13 @@ namespace Il2CppDumper
|
|||
|
||||
public Elf64(Stream stream) : base(stream)
|
||||
{
|
||||
elfHeader = ReadClass<Elf64_Ehdr>();
|
||||
Load();
|
||||
}
|
||||
|
||||
protected override void Load()
|
||||
{
|
||||
elfHeader = ReadClass<Elf64_Ehdr>(0);
|
||||
programSegment = ReadClassArray<Elf64_Phdr>(elfHeader.e_phoff, elfHeader.e_phnum);
|
||||
if (!CheckSection())
|
||||
{
|
||||
GetDumpAddress();
|
||||
}
|
||||
if (IsDumped)
|
||||
{
|
||||
FixedProgramSegment();
|
||||
|
@ -44,7 +45,7 @@ namespace Il2CppDumper
|
|||
}
|
||||
}
|
||||
|
||||
public bool CheckSection()
|
||||
protected override bool CheckSection()
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -217,28 +218,35 @@ namespace Il2CppDumper
|
|||
|
||||
private bool CheckProtection()
|
||||
{
|
||||
//.init_proc
|
||||
if (dynamicSection.Any(x => x.d_tag == DT_INIT))
|
||||
try
|
||||
{
|
||||
Console.WriteLine("WARNING: find .init_proc");
|
||||
return true;
|
||||
}
|
||||
//JNI_OnLoad
|
||||
ulong dynstrOffset = MapVATR(dynamicSection.First(x => x.d_tag == DT_STRTAB).d_un);
|
||||
foreach (var symbol in symbolTable)
|
||||
{
|
||||
var name = ReadStringToNull(dynstrOffset + symbol.st_name);
|
||||
switch (name)
|
||||
//.init_proc
|
||||
if (dynamicSection.Any(x => x.d_tag == DT_INIT))
|
||||
{
|
||||
case "JNI_OnLoad":
|
||||
Console.WriteLine("WARNING: find JNI_OnLoad");
|
||||
return true;
|
||||
Console.WriteLine("WARNING: find .init_proc");
|
||||
return true;
|
||||
}
|
||||
//JNI_OnLoad
|
||||
ulong dynstrOffset = MapVATR(dynamicSection.First(x => x.d_tag == DT_STRTAB).d_un);
|
||||
foreach (var symbol in symbolTable)
|
||||
{
|
||||
var name = ReadStringToNull(dynstrOffset + symbol.st_name);
|
||||
switch (name)
|
||||
{
|
||||
case "JNI_OnLoad":
|
||||
Console.WriteLine("WARNING: find JNI_OnLoad");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (sectionTable != null && sectionTable.Any(x => x.sh_type == SHT_LOUSER))
|
||||
{
|
||||
Console.WriteLine("WARNING: find SHT_LOUSER section");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (sectionTable != null && sectionTable.Any(x => x.sh_type == SHT_LOUSER))
|
||||
catch
|
||||
{
|
||||
Console.WriteLine("WARNING: find SHT_LOUSER section");
|
||||
return true;
|
||||
// ignored
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -247,7 +255,7 @@ namespace Il2CppDumper
|
|||
{
|
||||
if (IsDumped)
|
||||
{
|
||||
return pointer - DumpAddr;
|
||||
return pointer - ImageBase;
|
||||
}
|
||||
return pointer;
|
||||
}
|
||||
|
@ -260,7 +268,7 @@ namespace Il2CppDumper
|
|||
var phdr = programSegment[i];
|
||||
phdr.p_offset = phdr.p_vaddr;
|
||||
Write(phdr.p_offset);
|
||||
phdr.p_vaddr += DumpAddr;
|
||||
phdr.p_vaddr += ImageBase;
|
||||
Write(phdr.p_vaddr);
|
||||
Position += 8;
|
||||
phdr.p_filesz = phdr.p_memsz;
|
||||
|
@ -287,7 +295,7 @@ namespace Il2CppDumper
|
|||
case DT_JMPREL:
|
||||
case DT_INIT_ARRAY:
|
||||
case DT_FINI_ARRAY:
|
||||
dyn.d_un += DumpAddr;
|
||||
dyn.d_un += ImageBase;
|
||||
Write(dyn.d_un);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1,24 +1,15 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.IO;
|
||||
|
||||
namespace Il2CppDumper
|
||||
{
|
||||
public abstract class ElfBase : Il2Cpp
|
||||
{
|
||||
public bool IsDumped;
|
||||
public ulong DumpAddr;
|
||||
|
||||
protected ElfBase(Stream stream) : base(stream) { }
|
||||
protected abstract void Load();
|
||||
protected abstract bool CheckSection();
|
||||
|
||||
public void GetDumpAddress()
|
||||
{
|
||||
Console.WriteLine("Detected this may be a dump file.");
|
||||
Console.WriteLine("Input il2cpp dump address or input 0 to force continue:");
|
||||
DumpAddr = Convert.ToUInt64(Console.ReadLine(), 16);
|
||||
if (DumpAddr != 0)
|
||||
{
|
||||
IsDumped = true;
|
||||
}
|
||||
}
|
||||
public override bool CheckDump() => !CheckSection();
|
||||
|
||||
public void Reload() => Load();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -203,5 +203,7 @@ namespace Il2CppDumper
|
|||
sectionHelper.SetSection(SearchSectionType.Bss, bss);
|
||||
return sectionHelper;
|
||||
}
|
||||
|
||||
public override bool CheckDump() => false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -265,5 +265,7 @@ namespace Il2CppDumper
|
|||
sectionHelper.SetSection(SearchSectionType.Bss, bss);
|
||||
return sectionHelper;
|
||||
}
|
||||
|
||||
public override bool CheckDump() => false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -328,5 +328,7 @@ namespace Il2CppDumper
|
|||
sectionHelper.SetSection(SearchSectionType.Bss, header.BssSegment);
|
||||
return sectionHelper;
|
||||
}
|
||||
|
||||
public override bool CheckDump() => false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ namespace Il2CppDumper
|
|||
public sealed class PE : Il2Cpp
|
||||
{
|
||||
private SectionHeader[] sections;
|
||||
private ulong imageBase;
|
||||
|
||||
public PE(Stream stream) : base(stream)
|
||||
{
|
||||
|
@ -31,12 +30,12 @@ namespace Il2CppDumper
|
|||
{
|
||||
Is32Bit = true;
|
||||
var optionalHeader = ReadClass<OptionalHeader>();
|
||||
imageBase = optionalHeader.ImageBase;
|
||||
ImageBase = optionalHeader.ImageBase;
|
||||
}
|
||||
else if (magic == 0x20b)
|
||||
{
|
||||
var optionalHeader = ReadClass<OptionalHeader64>();
|
||||
imageBase = optionalHeader.ImageBase;
|
||||
ImageBase = optionalHeader.ImageBase;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -48,7 +47,7 @@ namespace Il2CppDumper
|
|||
|
||||
public void LoadFromMemory(ulong addr)
|
||||
{
|
||||
imageBase = addr;
|
||||
ImageBase = addr;
|
||||
foreach (var section in sections)
|
||||
{
|
||||
section.PointerToRawData = section.VirtualAddress;
|
||||
|
@ -58,7 +57,7 @@ namespace Il2CppDumper
|
|||
|
||||
public override ulong MapVATR(ulong absAddr)
|
||||
{
|
||||
var addr = absAddr - imageBase;
|
||||
var addr = absAddr - ImageBase;
|
||||
var section = sections.FirstOrDefault(x => addr >= x.VirtualAddress && addr <= x.VirtualAddress + x.VirtualSize);
|
||||
if (section == null)
|
||||
{
|
||||
|
@ -74,7 +73,7 @@ namespace Il2CppDumper
|
|||
{
|
||||
return 0ul;
|
||||
}
|
||||
return addr - section.PointerToRawData + section.VirtualAddress + imageBase;
|
||||
return addr - section.PointerToRawData + section.VirtualAddress + ImageBase;
|
||||
}
|
||||
|
||||
public override bool Search()
|
||||
|
@ -97,7 +96,7 @@ namespace Il2CppDumper
|
|||
|
||||
public override ulong GetRVA(ulong pointer)
|
||||
{
|
||||
return pointer - imageBase;
|
||||
return pointer - ImageBase;
|
||||
}
|
||||
|
||||
public override SectionHelper GetSectionHelper(int methodCount, int typeDefinitionsCount, int imageCount)
|
||||
|
@ -120,10 +119,22 @@ namespace Il2CppDumper
|
|||
var sectionHelper = new SectionHelper(this, methodCount, typeDefinitionsCount, maxMetadataUsages, imageCount);
|
||||
var data = dataList.ToArray();
|
||||
var exec = execList.ToArray();
|
||||
sectionHelper.SetSection(SearchSectionType.Exec, imageBase, exec);
|
||||
sectionHelper.SetSection(SearchSectionType.Data, imageBase, data);
|
||||
sectionHelper.SetSection(SearchSectionType.Bss, imageBase, data);
|
||||
sectionHelper.SetSection(SearchSectionType.Exec, ImageBase, exec);
|
||||
sectionHelper.SetSection(SearchSectionType.Data, ImageBase, data);
|
||||
sectionHelper.SetSection(SearchSectionType.Bss, ImageBase, data);
|
||||
return sectionHelper;
|
||||
}
|
||||
|
||||
public override bool CheckDump()
|
||||
{
|
||||
if (Is32Bit)
|
||||
{
|
||||
return ImageBase != 0x10000000;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ImageBase != 0x180000000;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,5 +66,7 @@ namespace Il2CppDumper
|
|||
sectionHelper.SetSection(SearchSectionType.Bss, bss);
|
||||
return sectionHelper;
|
||||
}
|
||||
|
||||
public override bool CheckDump() => false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ namespace Il2CppDumper
|
|||
{
|
||||
public double Version;
|
||||
public bool Is32Bit;
|
||||
public ulong ImageBase;
|
||||
private Stream stream;
|
||||
private BinaryReader reader;
|
||||
private BinaryWriter writer;
|
||||
|
|
|
@ -30,6 +30,7 @@ namespace Il2CppDumper
|
|||
public Dictionary<string, Il2CppCodeGenModule> codeGenModules;
|
||||
public Dictionary<string, ulong[]> codeGenModuleMethodPointers;
|
||||
public Dictionary<string, Dictionary<uint, Il2CppRGCTXDefinition[]>> rgctxsDictionary;
|
||||
public bool IsDumped;
|
||||
|
||||
public abstract ulong MapVATR(ulong addr);
|
||||
public abstract ulong MapRTVA(ulong addr);
|
||||
|
@ -37,6 +38,7 @@ namespace Il2CppDumper
|
|||
public abstract bool PlusSearch(int methodCount, int typeDefinitionsCount, int imageCount);
|
||||
public abstract bool SymbolSearch();
|
||||
public abstract SectionHelper GetSectionHelper(int methodCount, int typeDefinitionsCount, int imageCount);
|
||||
public abstract bool CheckDump();
|
||||
|
||||
protected Il2Cpp(Stream stream) : base(stream) { }
|
||||
|
||||
|
|
|
@ -39,7 +39,6 @@ namespace Il2CppDumper
|
|||
public Il2CppRGCTXDefinition[] rgctxEntries;
|
||||
|
||||
private Dictionary<uint, string> stringCache = new Dictionary<uint, string>();
|
||||
public ulong Address;
|
||||
|
||||
public Metadata(Stream stream) : base(stream)
|
||||
{
|
||||
|
|
|
@ -184,13 +184,26 @@ namespace Il2CppDumper
|
|||
var version = config.ForceIl2CppVersion ? config.ForceVersion : metadata.Version;
|
||||
il2Cpp.SetProperties(version, metadata.maxMetadataUsages);
|
||||
Console.WriteLine($"Il2Cpp Version: {il2Cpp.Version}");
|
||||
if (il2Cpp.Version >= 27 && il2Cpp is ElfBase elf && elf.IsDumped)
|
||||
if (il2Cpp.CheckDump())
|
||||
{
|
||||
Console.WriteLine("Input global-metadata.dat dump address:");
|
||||
metadata.Address = Convert.ToUInt64(Console.ReadLine(), 16);
|
||||
if (il2Cpp is ElfBase elf)
|
||||
{
|
||||
Console.WriteLine("Detected this may be a dump file.");
|
||||
Console.WriteLine("Input il2cpp dump address or input 0 to force continue:");
|
||||
var DumpAddr = Convert.ToUInt64(Console.ReadLine(), 16);
|
||||
if (DumpAddr != 0)
|
||||
{
|
||||
il2Cpp.ImageBase = DumpAddr;
|
||||
il2Cpp.IsDumped = true;
|
||||
elf.Reload();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
il2Cpp.IsDumped = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Console.WriteLine("Searching...");
|
||||
try
|
||||
{
|
||||
|
@ -221,7 +234,12 @@ namespace Il2CppDumper
|
|||
Console.Write("Input MetadataRegistration: ");
|
||||
var metadataRegistration = Convert.ToUInt64(Console.ReadLine(), 16);
|
||||
il2Cpp.Init(codeRegistration, metadataRegistration);
|
||||
return true;
|
||||
}
|
||||
if (il2Cpp.Version >= 27 && il2Cpp.IsDumped)
|
||||
{
|
||||
var typeDef = metadata.typeDefs[0];
|
||||
var il2CppType = il2Cpp.types[typeDef.byvalTypeIndex];
|
||||
metadata.ImageBase = il2CppType.data.typeHandle - metadata.header.typeDefinitionsOffset;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
|
|
|
@ -292,9 +292,9 @@ namespace Il2CppDumper
|
|||
|
||||
public Il2CppTypeDefinition GetTypeDefinitionFromIl2CppType(Il2CppType il2CppType)
|
||||
{
|
||||
if (il2Cpp.Version >= 27 && il2Cpp is ElfBase elf && elf.IsDumped)
|
||||
if (il2Cpp.Version >= 27 && il2Cpp.IsDumped)
|
||||
{
|
||||
var offset = il2CppType.data.typeHandle - metadata.Address - metadata.header.typeDefinitionsOffset;
|
||||
var offset = il2CppType.data.typeHandle - metadata.ImageBase - metadata.header.typeDefinitionsOffset;
|
||||
var index = offset / (ulong)metadata.SizeOf(typeof(Il2CppTypeDefinition));
|
||||
return metadata.typeDefs[index];
|
||||
}
|
||||
|
@ -306,9 +306,9 @@ namespace Il2CppDumper
|
|||
|
||||
public Il2CppGenericParameter GetGenericParameteFromIl2CppType(Il2CppType il2CppType)
|
||||
{
|
||||
if (il2Cpp.Version >= 27 && il2Cpp is ElfBase elf && elf.IsDumped)
|
||||
if (il2Cpp.Version >= 27 && il2Cpp.IsDumped)
|
||||
{
|
||||
var offset = il2CppType.data.genericParameterHandle - metadata.Address - metadata.header.genericParametersOffset;
|
||||
var offset = il2CppType.data.genericParameterHandle - metadata.ImageBase - metadata.header.genericParametersOffset;
|
||||
var index = offset / (ulong)metadata.SizeOf(typeof(Il2CppGenericParameter));
|
||||
return metadata.genericParameters[index];
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue