mirror of
https://github.com/Perfare/Il2CppDumper.git
synced 2025-01-10 03:27:28 -03:00
添加PE Plus模式支持
一些细节调整
This commit is contained in:
parent
af667aed63
commit
9d5a03463d
10 changed files with 627 additions and 385 deletions
|
@ -17,15 +17,8 @@ namespace Il2CppDumper
|
|||
private uint codeRegistration;
|
||||
private uint metadataRegistration;
|
||||
|
||||
public Elf(Stream stream, int version, long maxmetadataUsages) : base(stream)
|
||||
public Elf(Stream stream, int version, long maxMetadataUsages) : base(stream, version, maxMetadataUsages)
|
||||
{
|
||||
this.version = version;
|
||||
this.maxmetadataUsages = maxmetadataUsages;
|
||||
readAs32Bit = true;
|
||||
if (version < 21)
|
||||
Search = Searchv20;
|
||||
else
|
||||
Search = Searchv21;
|
||||
elf_header = new Elf32_Ehdr();
|
||||
elf_header.ei_mag = ReadUInt32();
|
||||
elf_header.ei_class = ReadByte();
|
||||
|
@ -83,14 +76,13 @@ namespace Il2CppDumper
|
|||
return uiAddr - (program_header_table.p_vaddr - program_header_table.p_offset);
|
||||
}
|
||||
|
||||
private bool Searchv20()
|
||||
public override bool Search()
|
||||
{
|
||||
if (version < 21)
|
||||
{
|
||||
Console.WriteLine("ERROR: Auto mode not support this version.");
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool Searchv21()
|
||||
{
|
||||
//取.dynamic
|
||||
var dynamic = new Elf32_Shdr();
|
||||
var PT_DYNAMIC = program_table_element.First(x => x.p_type == 2u);
|
||||
|
@ -222,9 +214,9 @@ namespace Il2CppDumper
|
|||
}
|
||||
}
|
||||
}
|
||||
var pmetadataUsages = FindPointersAsc(maxmetadataUsages, datarelro, bss);
|
||||
var pmetadataUsages = FindPointersAsc(maxMetadataUsages, datarelro, bss);
|
||||
if (pmetadataUsages == 0 && datarelrolocal != null)
|
||||
pmetadataUsages = FindPointersAsc(maxmetadataUsages, datarelrolocal, bss);
|
||||
pmetadataUsages = FindPointersAsc(maxMetadataUsages, datarelrolocal, bss);
|
||||
if (pmetadataUsages != 0)
|
||||
{
|
||||
metadataRegistration = FindReference(pmetadataUsages, datarelro);
|
||||
|
@ -232,9 +224,9 @@ namespace Il2CppDumper
|
|||
metadataRegistration = FindReference(pmetadataUsages, datarelrolocal);
|
||||
if (metadataRegistration == 0)
|
||||
{
|
||||
pmetadataUsages = FindPointersDesc(maxmetadataUsages, datarelro, bss);
|
||||
pmetadataUsages = FindPointersDesc(maxMetadataUsages, datarelro, bss);
|
||||
if (pmetadataUsages == 0 && datarelrolocal != null)
|
||||
pmetadataUsages = FindPointersDesc(maxmetadataUsages, datarelrolocal, bss);
|
||||
pmetadataUsages = FindPointersDesc(maxMetadataUsages, datarelrolocal, bss);
|
||||
if (pmetadataUsages != 0)
|
||||
{
|
||||
metadataRegistration = FindReference(pmetadataUsages, datarelro);
|
||||
|
@ -275,7 +267,7 @@ namespace Il2CppDumper
|
|||
}
|
||||
else
|
||||
{
|
||||
return search.sh_addr + (uint)add;//MapRATV
|
||||
return search.sh_addr + (uint)add; //VirtualAddress
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -296,7 +288,7 @@ namespace Il2CppDumper
|
|||
}
|
||||
else
|
||||
{
|
||||
return (uint)(search.sh_addr + search.sh_size + add - 4 * readCount);//MapRATV
|
||||
return (uint)(search.sh_addr + search.sh_size + add - 4 * readCount); //VirtualAddress
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -310,7 +302,7 @@ namespace Il2CppDumper
|
|||
{
|
||||
if (ReadUInt32() == pointer)
|
||||
{
|
||||
return (uint)Position - search.sh_offset + search.sh_addr;//MapRATV
|
||||
return (uint)Position - search.sh_offset + search.sh_addr; //VirtualAddress
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -425,7 +417,7 @@ namespace Il2CppDumper
|
|||
var r = Array.FindIndex(temp, x => x < range.sh_addr || x > rangeend);
|
||||
if (r == -1)
|
||||
{
|
||||
return (uint)add - search.sh_offset + search.sh_addr;//MapRATV
|
||||
return (uint)add - search.sh_offset + search.sh_addr; //VirtualAddress
|
||||
}
|
||||
Position = np;
|
||||
}
|
||||
|
@ -436,7 +428,7 @@ namespace Il2CppDumper
|
|||
var r = Array.FindIndex(temp, x => x < range.sh_addr || x > rangeend);
|
||||
if (r == -1)
|
||||
{
|
||||
return (uint)add - search.sh_offset + search.sh_addr;//MapRATV
|
||||
return (uint)add - search.sh_offset + search.sh_addr; //VirtualAddress
|
||||
}
|
||||
Position = np;
|
||||
}
|
||||
|
@ -468,20 +460,20 @@ namespace Il2CppDumper
|
|||
uint pointers = MapVATR(ReadUInt32());
|
||||
if (pointers >= search.sh_offset && pointers <= searchend)
|
||||
{
|
||||
var temp = ReadClassArray<uint>(pointers, maxmetadataUsages);
|
||||
var temp = ReadClassArray<uint>(pointers, maxMetadataUsages);
|
||||
var r = Array.FindIndex(temp, x => x < range.sh_addr || x > rangeend);
|
||||
if (r == -1)
|
||||
{
|
||||
return (uint)add - 48u - search.sh_offset + search.sh_addr;//MapRATV
|
||||
return (uint)add - 48u - search.sh_offset + search.sh_addr; //VirtualAddress
|
||||
}
|
||||
}
|
||||
else if (search2 != null && pointers >= search2.sh_offset && pointers <= search2end)
|
||||
{
|
||||
var temp = ReadClassArray<uint>(pointers, maxmetadataUsages);
|
||||
var temp = ReadClassArray<uint>(pointers, maxMetadataUsages);
|
||||
var r = Array.FindIndex(temp, x => x < range.sh_addr || x > rangeend);
|
||||
if (r == -1)
|
||||
{
|
||||
return (uint)add - 48u - search.sh_offset + search.sh_addr;//MapRATV
|
||||
return (uint)add - 48u - search.sh_offset + search.sh_addr; //VirtualAddress
|
||||
}
|
||||
}
|
||||
Position = np;
|
||||
|
@ -495,7 +487,7 @@ namespace Il2CppDumper
|
|||
return 0;
|
||||
}
|
||||
|
||||
public bool DetectedSymbol()
|
||||
public override bool SymbolSearch()
|
||||
{
|
||||
if (codeRegistration > 0 && metadataRegistration > 0)
|
||||
{
|
||||
|
|
|
@ -14,11 +14,8 @@ namespace Il2CppDumper
|
|||
private ulong codeRegistration;
|
||||
private ulong metadataRegistration;
|
||||
|
||||
public Elf64(Stream stream, int version, long maxmetadataUsages) : base(stream)
|
||||
public Elf64(Stream stream, int version, long maxMetadataUsages) : base(stream, version, maxMetadataUsages)
|
||||
{
|
||||
this.version = version;
|
||||
this.maxmetadataUsages = maxmetadataUsages;
|
||||
Search = SearchObsolete;
|
||||
elf_header = new Elf64_Ehdr();
|
||||
elf_header.ei_mag = ReadUInt32();
|
||||
elf_header.ei_class = ReadByte();
|
||||
|
@ -64,6 +61,140 @@ namespace Il2CppDumper
|
|||
}
|
||||
}
|
||||
|
||||
public override dynamic MapVATR(dynamic uiAddr)
|
||||
{
|
||||
var program_header_table = program_table_element.First(x => uiAddr >= x.p_vaddr && uiAddr <= x.p_vaddr + x.p_memsz);
|
||||
return uiAddr - (program_header_table.p_vaddr - program_header_table.p_offset);
|
||||
}
|
||||
|
||||
public override bool Search()
|
||||
{
|
||||
Console.WriteLine("ERROR: This mode not supported.");
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool AdvancedSearch(int methodCount)
|
||||
{
|
||||
Console.WriteLine("ERROR: This mode not supported.");
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool PlusSearch(int methodCount, int typeDefinitionsCount)
|
||||
{
|
||||
if (sectionWithName.ContainsKey(".data") && sectionWithName.ContainsKey(".text") && sectionWithName.ContainsKey(".bss"))
|
||||
{
|
||||
var datarelro = sectionWithName[".data"];
|
||||
var text = sectionWithName[".text"];
|
||||
var bss = sectionWithName[".bss"];
|
||||
codeRegistration = FindCodeRegistration(methodCount, datarelro, null, text);
|
||||
metadataRegistration = FindMetadataRegistration(typeDefinitionsCount, datarelro, null, bss);
|
||||
if (codeRegistration != 0 && metadataRegistration != 0)
|
||||
{
|
||||
Console.WriteLine("CodeRegistration : {0:x}", codeRegistration);
|
||||
Console.WriteLine("MetadataRegistration : {0:x}", metadataRegistration);
|
||||
Init64(codeRegistration, metadataRegistration);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("ERROR: The necessary section is missing.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private ulong FindCodeRegistration(int count, Elf64_Shdr search, Elf64_Shdr search2, Elf64_Shdr range)
|
||||
{
|
||||
var searchend = search.sh_offset + search.sh_size;
|
||||
var rangeend = range.sh_addr + range.sh_size;
|
||||
var search2end = search2 == null ? 0 : search2.sh_offset + search2.sh_size;
|
||||
Position = search.sh_offset;
|
||||
while ((ulong)Position < searchend)
|
||||
{
|
||||
var add = Position;
|
||||
if (ReadUInt64() == (ulong)count)
|
||||
{
|
||||
try
|
||||
{
|
||||
ulong pointers = MapVATR(ReadUInt64());
|
||||
if (pointers >= search.sh_offset && pointers <= searchend)
|
||||
{
|
||||
var np = Position;
|
||||
var temp = ReadClassArray<ulong>(pointers, count);
|
||||
var r = Array.FindIndex(temp, x => x < range.sh_addr || x > rangeend);
|
||||
if (r == -1)
|
||||
{
|
||||
return (ulong)add - search.sh_offset + search.sh_addr; //VirtualAddress
|
||||
}
|
||||
Position = np;
|
||||
}
|
||||
else if (search2 != null && pointers >= search2.sh_offset && pointers <= search2end)
|
||||
{
|
||||
var np = Position;
|
||||
var temp = ReadClassArray<ulong>(pointers, count);
|
||||
var r = Array.FindIndex(temp, x => x < range.sh_addr || x > rangeend);
|
||||
if (r == -1)
|
||||
{
|
||||
return (ulong)add - search.sh_offset + search.sh_addr; //VirtualAddress
|
||||
}
|
||||
Position = np;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private ulong FindMetadataRegistration(int typeDefinitionsCount, Elf64_Shdr search, Elf64_Shdr search2, Elf64_Shdr range)
|
||||
{
|
||||
var searchend = search.sh_offset + search.sh_size;
|
||||
var rangeend = range.sh_addr + range.sh_size;
|
||||
var search2end = search2 == null ? 0 : search2.sh_offset + search2.sh_size;
|
||||
Position = search.sh_offset;
|
||||
while ((ulong)Position < searchend)
|
||||
{
|
||||
var add = Position;
|
||||
if (ReadUInt64() == (ulong)typeDefinitionsCount)
|
||||
{
|
||||
try
|
||||
{
|
||||
var np = Position;
|
||||
Position += 16;
|
||||
ulong pointers = MapVATR(ReadUInt64());
|
||||
if (pointers >= search.sh_offset && pointers <= searchend)
|
||||
{
|
||||
var temp = ReadClassArray<ulong>(pointers, maxMetadataUsages);
|
||||
var r = Array.FindIndex(temp, x => x < range.sh_addr || x > rangeend);
|
||||
if (r == -1)
|
||||
{
|
||||
return (ulong)add - 96ul - search.sh_offset + search.sh_addr; //VirtualAddress
|
||||
}
|
||||
}
|
||||
else if (search2 != null && pointers >= search2.sh_offset && pointers <= search2end)
|
||||
{
|
||||
var temp = ReadClassArray<ulong>(pointers, maxMetadataUsages);
|
||||
var r = Array.FindIndex(temp, x => x < range.sh_addr || x > rangeend);
|
||||
if (r == -1)
|
||||
{
|
||||
return (ulong)add - 96ul - search.sh_offset + search.sh_addr; //VirtualAddress
|
||||
}
|
||||
}
|
||||
Position = np;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
private void RelocationProcessing()
|
||||
{
|
||||
//TODO
|
||||
|
@ -119,12 +250,6 @@ namespace Il2CppDumper
|
|||
}*/
|
||||
}
|
||||
|
||||
public override dynamic MapVATR(dynamic uiAddr)
|
||||
{
|
||||
var program_header_table = program_table_element.First(x => uiAddr >= x.p_vaddr && uiAddr <= x.p_vaddr + x.p_memsz);
|
||||
return uiAddr - (program_header_table.p_vaddr - program_header_table.p_offset);
|
||||
}
|
||||
|
||||
public override long GetFieldOffsetFromIndex(int typeIndex, int fieldIndexInType, int fieldIndex)
|
||||
{
|
||||
if (isNew21)
|
||||
|
@ -146,136 +271,9 @@ namespace Il2CppDumper
|
|||
return pointers;
|
||||
}
|
||||
|
||||
private bool SearchObsolete()
|
||||
public override bool SymbolSearch()
|
||||
{
|
||||
Console.WriteLine("ERROR: This mode not supported Elf64.");
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool AdvancedSearch(int methodCount)
|
||||
{
|
||||
Console.WriteLine("ERROR: This mode not supported Elf64.");
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool PlusSearch(int methodCount, int typeDefinitionsCount)
|
||||
{
|
||||
if (sectionWithName.ContainsKey(".data") && sectionWithName.ContainsKey(".text") && sectionWithName.ContainsKey(".bss"))
|
||||
{
|
||||
var datarelro = sectionWithName[".data"];
|
||||
var text = sectionWithName[".text"];
|
||||
var bss = sectionWithName[".bss"];
|
||||
codeRegistration = FindCodeRegistration(methodCount, datarelro, null, text);
|
||||
metadataRegistration = FindMetadataRegistration(typeDefinitionsCount, datarelro, null, bss);
|
||||
if (codeRegistration != 0 && metadataRegistration != 0)
|
||||
{
|
||||
Console.WriteLine("CodeRegistration : {0:x}", codeRegistration);
|
||||
Console.WriteLine("MetadataRegistration : {0:x}", metadataRegistration);
|
||||
Init64(codeRegistration, metadataRegistration);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("ERROR: The necessary section is missing.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private ulong FindCodeRegistration(int count, Elf64_Shdr search, Elf64_Shdr search2, Elf64_Shdr range)
|
||||
{
|
||||
var searchend = search.sh_offset + search.sh_size;
|
||||
var rangeend = range.sh_addr + range.sh_size;
|
||||
var search2end = search2 == null ? 0 : search2.sh_offset + search2.sh_size;
|
||||
Position = search.sh_offset;
|
||||
while ((ulong)Position < searchend)
|
||||
{
|
||||
var add = Position;
|
||||
if (ReadUInt64() == (ulong)count)
|
||||
{
|
||||
try
|
||||
{
|
||||
ulong pointers = MapVATR(ReadUInt64());
|
||||
if (pointers >= search.sh_offset && pointers <= searchend)
|
||||
{
|
||||
var np = Position;
|
||||
var temp = ReadClassArray<ulong>(pointers, count);
|
||||
var r = Array.FindIndex(temp, x => x < range.sh_addr || x > rangeend);
|
||||
if (r == -1)
|
||||
{
|
||||
return (ulong)add - search.sh_offset + search.sh_addr;//MapRATV
|
||||
}
|
||||
Position = np;
|
||||
}
|
||||
else if (search2 != null && pointers >= search2.sh_offset && pointers <= search2end)
|
||||
{
|
||||
var np = Position;
|
||||
var temp = ReadClassArray<ulong>(pointers, count);
|
||||
var r = Array.FindIndex(temp, x => x < range.sh_addr || x > rangeend);
|
||||
if (r == -1)
|
||||
{
|
||||
return (ulong)add - search.sh_offset + search.sh_addr;//MapRATV
|
||||
}
|
||||
Position = np;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private ulong FindMetadataRegistration(int typeDefinitionsCount, Elf64_Shdr search, Elf64_Shdr search2, Elf64_Shdr range)
|
||||
{
|
||||
var searchend = search.sh_offset + search.sh_size;
|
||||
var rangeend = range.sh_addr + range.sh_size;
|
||||
var search2end = search2 == null ? 0 : search2.sh_offset + search2.sh_size;
|
||||
Position = search.sh_offset;
|
||||
while ((ulong)Position < searchend)
|
||||
{
|
||||
var add = Position;
|
||||
if (ReadUInt64() == (ulong)typeDefinitionsCount)
|
||||
{
|
||||
try
|
||||
{
|
||||
var np = Position;
|
||||
Position += 16;
|
||||
ulong pointers = MapVATR(ReadUInt64());
|
||||
if (pointers >= search.sh_offset && pointers <= searchend)
|
||||
{
|
||||
var temp = ReadClassArray<ulong>(pointers, maxmetadataUsages);
|
||||
var r = Array.FindIndex(temp, x => x < range.sh_addr || x > rangeend);
|
||||
if (r == -1)
|
||||
{
|
||||
return (ulong)add - 96ul - search.sh_offset + search.sh_addr;//MapRATV
|
||||
}
|
||||
}
|
||||
else if (search2 != null && pointers >= search2.sh_offset && pointers <= search2end)
|
||||
{
|
||||
var temp = ReadClassArray<ulong>(pointers, maxmetadataUsages);
|
||||
var r = Array.FindIndex(temp, x => x < range.sh_addr || x > rangeend);
|
||||
if (r == -1)
|
||||
{
|
||||
return (ulong)add - 96ul - search.sh_offset + search.sh_addr;//MapRATV
|
||||
}
|
||||
}
|
||||
Position = np;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public bool DetectedSymbol()
|
||||
{
|
||||
Console.WriteLine("ERROR: This mode not supported Elf64.");
|
||||
Console.WriteLine("ERROR: This mode not supported.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,18 +18,24 @@ namespace Il2CppDumper
|
|||
private Dictionary<ulong, Il2CppType> typesdic = new Dictionary<ulong, Il2CppType>();
|
||||
public ulong[] metadataUsages;
|
||||
protected bool isNew21;
|
||||
protected long maxmetadataUsages;
|
||||
|
||||
public Func<bool> Search;
|
||||
public abstract bool AdvancedSearch(int methodCount);
|
||||
public abstract bool PlusSearch(int methodCount, int typeDefinitionsCount);
|
||||
protected long maxMetadataUsages;
|
||||
|
||||
public abstract dynamic MapVATR(dynamic uiAddr);
|
||||
|
||||
protected Il2Cpp(Stream stream) : base(stream) { }
|
||||
public abstract bool Search();
|
||||
public abstract bool AdvancedSearch(int methodCount);
|
||||
public abstract bool PlusSearch(int methodCount, int typeDefinitionsCount);
|
||||
public abstract bool SymbolSearch();
|
||||
|
||||
protected Il2Cpp(Stream stream, int version, long maxMetadataUsages) : base(stream)
|
||||
{
|
||||
this.version = version;
|
||||
this.maxMetadataUsages = maxMetadataUsages;
|
||||
}
|
||||
|
||||
public virtual void Init(ulong codeRegistration, ulong metadataRegistration)
|
||||
{
|
||||
readAs32Bit = true;
|
||||
pCodeRegistration = MapVATR<Il2CppCodeRegistration>(codeRegistration);
|
||||
pMetadataRegistration = MapVATR<Il2CppMetadataRegistration>(metadataRegistration);
|
||||
methodPointers = Array.ConvertAll(MapVATR<uint>(pCodeRegistration.methodPointers, (long)pCodeRegistration.methodPointersCount), x => (ulong)x);
|
||||
|
@ -48,7 +54,7 @@ namespace Il2CppDumper
|
|||
typesdic.Add(ptypes[i], types[i]);
|
||||
}
|
||||
if (version > 16)
|
||||
metadataUsages = Array.ConvertAll(MapVATR<uint>(pMetadataRegistration.metadataUsages, maxmetadataUsages), x => (ulong)x);
|
||||
metadataUsages = Array.ConvertAll(MapVATR<uint>(pMetadataRegistration.metadataUsages, maxMetadataUsages), x => (ulong)x);
|
||||
}
|
||||
|
||||
public void Init64(ulong codeRegistration, ulong metadataRegistration)
|
||||
|
@ -73,7 +79,7 @@ namespace Il2CppDumper
|
|||
typesdic.Add(ptypes[i], types[i]);
|
||||
}
|
||||
if (version > 16)
|
||||
metadataUsages = MapVATR<ulong>(pMetadataRegistration.metadataUsages, maxmetadataUsages);
|
||||
metadataUsages = MapVATR<ulong>(pMetadataRegistration.metadataUsages, maxMetadataUsages);
|
||||
}
|
||||
|
||||
public virtual long GetFieldOffsetFromIndex(int typeIndex, int fieldIndexInType, int fieldIndex)
|
||||
|
|
|
@ -58,6 +58,8 @@
|
|||
<Compile Include="Macho.cs" />
|
||||
<Compile Include="Metadata.cs" />
|
||||
<Compile Include="MetadataClass.cs" />
|
||||
<Compile Include="PE.cs" />
|
||||
<Compile Include="PEClass.cs" />
|
||||
<Compile Include="Resource1.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
|
|
|
@ -14,15 +14,8 @@ namespace Il2CppDumper
|
|||
private static byte[] FeatureBytes2 = { 0x78, 0x44, 0x79, 0x44 };//ADD R0, PC and ADD R1, PC
|
||||
|
||||
|
||||
public Macho(Stream stream, int version, long maxmetadataUsages) : base(stream)
|
||||
public Macho(Stream stream, int version, long maxMetadataUsages) : base(stream, version, maxMetadataUsages)
|
||||
{
|
||||
this.version = version;
|
||||
this.maxmetadataUsages = maxmetadataUsages;
|
||||
readAs32Bit = true;
|
||||
if (version < 21)
|
||||
Search = Searchv16;
|
||||
else
|
||||
Search = Searchv21;
|
||||
Position += 16;//skip
|
||||
var ncmds = ReadUInt32();
|
||||
Position += 8;//skip
|
||||
|
@ -56,12 +49,6 @@ namespace Il2CppDumper
|
|||
}
|
||||
}
|
||||
|
||||
public override dynamic MapVATR(dynamic uiAddr)
|
||||
{
|
||||
var section = sections.First(x => uiAddr >= x.address && uiAddr <= x.end);
|
||||
return uiAddr - (section.address - section.offset);
|
||||
}
|
||||
|
||||
public override void Init(ulong codeRegistration, ulong metadataRegistration)
|
||||
{
|
||||
base.Init(codeRegistration, metadataRegistration);
|
||||
|
@ -69,48 +56,15 @@ namespace Il2CppDumper
|
|||
customAttributeGenerators = customAttributeGenerators.Select(x => x - 1).ToArray();
|
||||
}
|
||||
|
||||
private bool Searchv21()
|
||||
public override dynamic MapVATR(dynamic uiAddr)
|
||||
{
|
||||
var __mod_init_func = sections.First(x => x.section_name == "__mod_init_func");
|
||||
var addrs = ReadClassArray<uint>(__mod_init_func.offset, __mod_init_func.size / 4u);
|
||||
foreach (var a in addrs)
|
||||
{
|
||||
if (a > 0)
|
||||
{
|
||||
var i = a - 1;
|
||||
Position = MapVATR(i);
|
||||
Position += 4;
|
||||
var buff = ReadBytes(2);
|
||||
if (FeatureBytes1.SequenceEqual(buff))
|
||||
{
|
||||
Position += 12;
|
||||
buff = ReadBytes(4);
|
||||
if (FeatureBytes2.SequenceEqual(buff))
|
||||
{
|
||||
Position = MapVATR(i) + 10;
|
||||
var subaddr = DecodeMov(ReadBytes(8)) + i + 24u - 1u;
|
||||
var rsubaddr = MapVATR(subaddr);
|
||||
Position = rsubaddr;
|
||||
var ptr = DecodeMov(ReadBytes(8)) + subaddr + 16u;
|
||||
Position = MapVATR(ptr);
|
||||
var metadataRegistration = ReadUInt32();
|
||||
Position = rsubaddr + 8;
|
||||
buff = ReadBytes(4);
|
||||
Position = rsubaddr + 14;
|
||||
buff = buff.Concat(ReadBytes(4)).ToArray();
|
||||
var codeRegistration = DecodeMov(buff) + subaddr + 26u;
|
||||
Console.WriteLine("CodeRegistration : {0:x}", codeRegistration);
|
||||
Console.WriteLine("MetadataRegistration : {0:x}", metadataRegistration);
|
||||
Init(codeRegistration, metadataRegistration);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
var section = sections.First(x => uiAddr >= x.address && uiAddr <= x.end);
|
||||
return uiAddr - (section.address - section.offset);
|
||||
}
|
||||
|
||||
private bool Searchv16()
|
||||
public override bool Search()
|
||||
{
|
||||
if (version < 21)
|
||||
{
|
||||
var __mod_init_func = sections.First(x => x.section_name == "__mod_init_func");
|
||||
var addrs = ReadClassArray<uint>(__mod_init_func.offset, __mod_init_func.size / 4u);
|
||||
|
@ -150,6 +104,47 @@ namespace Il2CppDumper
|
|||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
var __mod_init_func = sections.First(x => x.section_name == "__mod_init_func");
|
||||
var addrs = ReadClassArray<uint>(__mod_init_func.offset, __mod_init_func.size / 4u);
|
||||
foreach (var a in addrs)
|
||||
{
|
||||
if (a > 0)
|
||||
{
|
||||
var i = a - 1;
|
||||
Position = MapVATR(i);
|
||||
Position += 4;
|
||||
var buff = ReadBytes(2);
|
||||
if (FeatureBytes1.SequenceEqual(buff))
|
||||
{
|
||||
Position += 12;
|
||||
buff = ReadBytes(4);
|
||||
if (FeatureBytes2.SequenceEqual(buff))
|
||||
{
|
||||
Position = MapVATR(i) + 10;
|
||||
var subaddr = DecodeMov(ReadBytes(8)) + i + 24u - 1u;
|
||||
var rsubaddr = MapVATR(subaddr);
|
||||
Position = rsubaddr;
|
||||
var ptr = DecodeMov(ReadBytes(8)) + subaddr + 16u;
|
||||
Position = MapVATR(ptr);
|
||||
var metadataRegistration = ReadUInt32();
|
||||
Position = rsubaddr + 8;
|
||||
buff = ReadBytes(4);
|
||||
Position = rsubaddr + 14;
|
||||
buff = buff.Concat(ReadBytes(4)).ToArray();
|
||||
var codeRegistration = DecodeMov(buff) + subaddr + 26u;
|
||||
Console.WriteLine("CodeRegistration : {0:x}", codeRegistration);
|
||||
Console.WriteLine("MetadataRegistration : {0:x}", metadataRegistration);
|
||||
Init(codeRegistration, metadataRegistration);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool AdvancedSearch(int methodCount)
|
||||
{
|
||||
|
@ -187,9 +182,9 @@ namespace Il2CppDumper
|
|||
Console.WriteLine("CodeRegistration : {0:x}", codeRegistration);
|
||||
return false;
|
||||
}
|
||||
var pmetadataUsages = FindPointersAsc(maxmetadataUsages, __const, __common);
|
||||
var pmetadataUsages = FindPointersAsc(maxMetadataUsages, __const, __common);
|
||||
if (pmetadataUsages == 0)
|
||||
pmetadataUsages = FindPointersAsc(maxmetadataUsages, __const2, __common);
|
||||
pmetadataUsages = FindPointersAsc(maxMetadataUsages, __const2, __common);
|
||||
if (pmetadataUsages != 0)
|
||||
{
|
||||
metadataRegistration = FindReference(pmetadataUsages, __const);
|
||||
|
@ -197,9 +192,9 @@ namespace Il2CppDumper
|
|||
metadataRegistration = FindReference(pmetadataUsages, __const2);
|
||||
if (metadataRegistration == 0)
|
||||
{
|
||||
pmetadataUsages = FindPointersDesc(maxmetadataUsages, __const, __common);
|
||||
pmetadataUsages = FindPointersDesc(maxMetadataUsages, __const, __common);
|
||||
if (pmetadataUsages == 0)
|
||||
pmetadataUsages = FindPointersDesc(maxmetadataUsages, __const2, __common);
|
||||
pmetadataUsages = FindPointersDesc(maxMetadataUsages, __const2, __common);
|
||||
if (pmetadataUsages != 0)
|
||||
{
|
||||
metadataRegistration = FindReference(pmetadataUsages, __const);
|
||||
|
@ -235,7 +230,7 @@ namespace Il2CppDumper
|
|||
}
|
||||
else
|
||||
{
|
||||
return search.address + (uint)add;//MapRATV
|
||||
return search.address + (uint)add; //VirtualAddress
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -256,7 +251,7 @@ namespace Il2CppDumper
|
|||
}
|
||||
else
|
||||
{
|
||||
return (uint)(search.address + search.size + add - 4 * readCount);//MapRATV
|
||||
return (uint)(search.address + search.size + add - 4 * readCount); //VirtualAddress
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -270,7 +265,7 @@ namespace Il2CppDumper
|
|||
{
|
||||
if (ReadUInt32() == pointer)
|
||||
{
|
||||
return (uint)Position - search.offset + search.address;//MapRATV
|
||||
return (uint)Position - search.offset + search.address; //VirtualAddress
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -329,7 +324,7 @@ namespace Il2CppDumper
|
|||
var r = Array.FindIndex(temp, x => x < range.address || x > rangeend);
|
||||
if (r == -1)
|
||||
{
|
||||
return (uint)add - search.offset + search.address;//MapRATV
|
||||
return (uint)add - search.offset + search.address; //VirtualAddress
|
||||
}
|
||||
Position = np;
|
||||
}
|
||||
|
@ -340,7 +335,7 @@ namespace Il2CppDumper
|
|||
var r = Array.FindIndex(temp, x => x < range.address || x > rangeend);
|
||||
if (r == -1)
|
||||
{
|
||||
return (uint)add - search.offset + search.address;//MapRATV
|
||||
return (uint)add - search.offset + search.address; //VirtualAddress
|
||||
}
|
||||
Position = np;
|
||||
}
|
||||
|
@ -372,20 +367,20 @@ namespace Il2CppDumper
|
|||
uint pointers = MapVATR(ReadUInt32());
|
||||
if (pointers >= search.offset && pointers <= searchend)
|
||||
{
|
||||
var temp = ReadClassArray<uint>(pointers, maxmetadataUsages);
|
||||
var temp = ReadClassArray<uint>(pointers, maxMetadataUsages);
|
||||
var r = Array.FindIndex(temp, x => x < range.address || x > rangeend);
|
||||
if (r == -1)
|
||||
{
|
||||
return (uint)add - 48u - search.offset + search.address;//MapRATV
|
||||
return (uint)add - 48u - search.offset + search.address; //VirtualAddress
|
||||
}
|
||||
}
|
||||
else if (search2 != null && pointers >= search2.offset && pointers <= search2end)
|
||||
{
|
||||
var temp = ReadClassArray<uint>(pointers, maxmetadataUsages);
|
||||
var temp = ReadClassArray<uint>(pointers, maxMetadataUsages);
|
||||
var r = Array.FindIndex(temp, x => x < range.address || x > rangeend);
|
||||
if (r == -1)
|
||||
{
|
||||
return (uint)add - 48u - search.offset + search.address;//MapRATV
|
||||
return (uint)add - 48u - search.offset + search.address; //VirtualAddress
|
||||
}
|
||||
}
|
||||
Position = np;
|
||||
|
@ -398,5 +393,11 @@ namespace Il2CppDumper
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override bool SymbolSearch()
|
||||
{
|
||||
Console.WriteLine("ERROR: This mode not supported.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,14 +14,8 @@ namespace Il2CppDumper
|
|||
private static byte[] FeatureBytes2 = { 0x3, 0x0, 0x80, 0x52 };//MOV W3, #0
|
||||
|
||||
|
||||
public Macho64(Stream stream, int version, long maxmetadataUsages) : base(stream)
|
||||
public Macho64(Stream stream, int version, long maxMetadataUsages) : base(stream, version, maxMetadataUsages)
|
||||
{
|
||||
this.version = version;
|
||||
this.maxmetadataUsages = maxmetadataUsages;
|
||||
if (version < 23)
|
||||
Search = Searchv16_22;
|
||||
else
|
||||
Search = Searchv23;
|
||||
Position += 16;//skip
|
||||
var ncmds = ReadUInt32();
|
||||
Position += 12;//skip
|
||||
|
@ -61,28 +55,9 @@ namespace Il2CppDumper
|
|||
return uiAddr - (section.address - section.offset);
|
||||
}
|
||||
|
||||
public override long GetFieldOffsetFromIndex(int typeIndex, int fieldIndexInType, int fieldIndex)
|
||||
public override bool Search()
|
||||
{
|
||||
if (isNew21)
|
||||
{
|
||||
var ptr = fieldOffsets[typeIndex];
|
||||
if (ptr >= 0)
|
||||
{
|
||||
Position = MapVATR((ulong)ptr) + 4ul * (ulong)fieldIndexInType;
|
||||
return ReadInt32();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return fieldOffsets[fieldIndex];
|
||||
}
|
||||
|
||||
public override ulong[] GetPointers(ulong pointer, long count)
|
||||
{
|
||||
var pointers = MapVATR<ulong>(pointer, count);
|
||||
return pointers;
|
||||
}
|
||||
|
||||
private bool Searchv16_22()
|
||||
if (version < 23)
|
||||
{
|
||||
var __mod_init_func = sections.First(x => x.section_name == "__mod_init_func");
|
||||
var addrs = ReadClassArray<ulong>(__mod_init_func.offset, (long)__mod_init_func.size / 8);
|
||||
|
@ -116,8 +91,7 @@ namespace Il2CppDumper
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool Searchv23()
|
||||
else
|
||||
{
|
||||
var __mod_init_func = sections.First(x => x.section_name == "__mod_init_func");
|
||||
var addrs = ReadClassArray<ulong>(__mod_init_func.offset, (long)__mod_init_func.size / 8);
|
||||
|
@ -151,6 +125,7 @@ namespace Il2CppDumper
|
|||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool AdvancedSearch(int methodCount)
|
||||
{
|
||||
|
@ -189,9 +164,9 @@ namespace Il2CppDumper
|
|||
Console.WriteLine("CodeRegistration : {0:x}", codeRegistration);
|
||||
return false;
|
||||
}
|
||||
var pmetadataUsages = FindPointersAsc(maxmetadataUsages, __const, __common);
|
||||
var pmetadataUsages = FindPointersAsc(maxMetadataUsages, __const, __common);
|
||||
if (pmetadataUsages == 0)
|
||||
pmetadataUsages = FindPointersAsc(maxmetadataUsages, __const2, __common);
|
||||
pmetadataUsages = FindPointersAsc(maxMetadataUsages, __const2, __common);
|
||||
if (pmetadataUsages != 0)
|
||||
{
|
||||
metadataRegistration = FindReference(pmetadataUsages, __const);
|
||||
|
@ -199,9 +174,9 @@ namespace Il2CppDumper
|
|||
metadataRegistration = FindReference(pmetadataUsages, __const2);
|
||||
if (metadataRegistration == 0)
|
||||
{
|
||||
pmetadataUsages = FindPointersDesc(maxmetadataUsages, __const, __common);
|
||||
pmetadataUsages = FindPointersDesc(maxMetadataUsages, __const, __common);
|
||||
if (pmetadataUsages == 0)
|
||||
pmetadataUsages = FindPointersDesc(maxmetadataUsages, __const2, __common);
|
||||
pmetadataUsages = FindPointersDesc(maxMetadataUsages, __const2, __common);
|
||||
if (pmetadataUsages != 0)
|
||||
{
|
||||
metadataRegistration = FindReference(pmetadataUsages, __const);
|
||||
|
@ -237,7 +212,7 @@ namespace Il2CppDumper
|
|||
}
|
||||
else
|
||||
{
|
||||
return search.address + add;//MapRATV
|
||||
return search.address + add; //VirtualAddress
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -258,7 +233,7 @@ namespace Il2CppDumper
|
|||
}
|
||||
else
|
||||
{
|
||||
return search.address + search.size + (ulong)add - 8ul * (ulong)readCount;//MapRATV
|
||||
return search.address + search.size + (ulong)add - 8ul * (ulong)readCount; //VirtualAddress
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -272,7 +247,7 @@ namespace Il2CppDumper
|
|||
{
|
||||
if (ReadUInt64() == pointer)
|
||||
{
|
||||
return (ulong)Position - search.offset + search.address;//MapRATV
|
||||
return (ulong)Position - search.offset + search.address; //VirtualAddress
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -332,7 +307,7 @@ namespace Il2CppDumper
|
|||
var r = Array.FindIndex(temp, x => x < range.address || x > rangeend);
|
||||
if (r == -1)
|
||||
{
|
||||
return (ulong)add - search.offset + search.address;//MapRATV
|
||||
return (ulong)add - search.offset + search.address; //VirtualAddress
|
||||
}
|
||||
Position = np;
|
||||
}
|
||||
|
@ -343,7 +318,7 @@ namespace Il2CppDumper
|
|||
var r = Array.FindIndex(temp, x => x < range.address || x > rangeend);
|
||||
if (r == -1)
|
||||
{
|
||||
return (ulong)add - search.offset + search.address;//MapRATV
|
||||
return (ulong)add - search.offset + search.address; //VirtualAddress
|
||||
}
|
||||
Position = np;
|
||||
}
|
||||
|
@ -375,20 +350,20 @@ namespace Il2CppDumper
|
|||
ulong pointers = MapVATR(ReadUInt64());
|
||||
if (pointers >= search.offset && pointers <= searchend)
|
||||
{
|
||||
var temp = ReadClassArray<ulong>(pointers, maxmetadataUsages);
|
||||
var temp = ReadClassArray<ulong>(pointers, maxMetadataUsages);
|
||||
var r = Array.FindIndex(temp, x => x < range.address || x > rangeend);
|
||||
if (r == -1)
|
||||
{
|
||||
return (ulong)add - 96ul - search.offset + search.address;//MapRATV
|
||||
return (ulong)add - 96ul - search.offset + search.address; //VirtualAddress
|
||||
}
|
||||
}
|
||||
else if (search2 != null && pointers >= search2.offset && pointers <= search2end)
|
||||
{
|
||||
var temp = ReadClassArray<ulong>(pointers, maxmetadataUsages);
|
||||
var temp = ReadClassArray<ulong>(pointers, maxMetadataUsages);
|
||||
var r = Array.FindIndex(temp, x => x < range.address || x > rangeend);
|
||||
if (r == -1)
|
||||
{
|
||||
return (ulong)add - 96ul - search.offset + search.address;//MapRATV
|
||||
return (ulong)add - 96ul - search.offset + search.address; //VirtualAddress
|
||||
}
|
||||
}
|
||||
Position = np;
|
||||
|
@ -401,5 +376,32 @@ namespace Il2CppDumper
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override bool SymbolSearch()
|
||||
{
|
||||
Console.WriteLine("ERROR: This mode not supported.");
|
||||
return false;
|
||||
}
|
||||
|
||||
public override long GetFieldOffsetFromIndex(int typeIndex, int fieldIndexInType, int fieldIndex)
|
||||
{
|
||||
if (isNew21)
|
||||
{
|
||||
var ptr = fieldOffsets[typeIndex];
|
||||
if (ptr >= 0)
|
||||
{
|
||||
Position = MapVATR((ulong)ptr) + 4ul * (ulong)fieldIndexInType;
|
||||
return ReadInt32();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return fieldOffsets[fieldIndex];
|
||||
}
|
||||
|
||||
public override ulong[] GetPointers(ulong pointer, long count)
|
||||
{
|
||||
var pointers = MapVATR<ulong>(pointer, count);
|
||||
return pointers;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,9 +92,8 @@ namespace Il2CppDumper
|
|||
}
|
||||
}
|
||||
|
||||
public T[] ReadClassArray<T>(dynamic addr, long count) where T : new()
|
||||
public T[] ReadClassArray<T>(long count) where T : new()
|
||||
{
|
||||
Position = addr;
|
||||
var t = new T[count];
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
|
@ -103,6 +102,12 @@ namespace Il2CppDumper
|
|||
return t;
|
||||
}
|
||||
|
||||
public T[] ReadClassArray<T>(dynamic addr, long count) where T : new()
|
||||
{
|
||||
Position = addr;
|
||||
return ReadClassArray<T>(count);
|
||||
}
|
||||
|
||||
public string ReadStringToNull(dynamic addr)
|
||||
{
|
||||
Position = addr;
|
||||
|
|
167
Il2CppDumper/PE.cs
Normal file
167
Il2CppDumper/PE.cs
Normal file
|
@ -0,0 +1,167 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Il2CppDumper
|
||||
{
|
||||
public sealed class PE : Il2Cpp
|
||||
{
|
||||
private FileHeader fileHeader;
|
||||
private OptionalHeader optionalHeader;
|
||||
private SectionHeader[] sections;
|
||||
private uint imageBase;
|
||||
|
||||
public PE(Stream stream, int version, long maxMetadataUsages) : base(stream, version, maxMetadataUsages)
|
||||
{
|
||||
if (ReadUInt16() != 0x5A4D)//e_magic
|
||||
throw new Exception("ERROR: Invalid PE file");
|
||||
Position = 0x3C;//e_lfanew
|
||||
Position = ReadUInt32();
|
||||
if (ReadUInt32() != 0x00004550)//Signature
|
||||
throw new Exception("ERROR: Invalid PE file");
|
||||
fileHeader = ReadClass<FileHeader>();
|
||||
optionalHeader = ReadClass<OptionalHeader>();
|
||||
optionalHeader.DataDirectory = ReadClassArray<DataDirectory>(optionalHeader.NumberOfRvaAndSizes);
|
||||
imageBase = optionalHeader.ImageBase;
|
||||
var IATVirtualAddress = optionalHeader.DataDirectory[12].VirtualAddress;
|
||||
var IATSize = optionalHeader.DataDirectory[12].Size;
|
||||
sections = new SectionHeader[fileHeader.NumberOfSections];
|
||||
for (int i = 0; i < fileHeader.NumberOfSections; i++)
|
||||
{
|
||||
sections[i] = new SectionHeader
|
||||
{
|
||||
Name = Encoding.UTF8.GetString(ReadBytes(8)).Trim('\0'),
|
||||
VirtualSize = ReadUInt32(),
|
||||
VirtualAddress = ReadUInt32(),
|
||||
SizeOfRawData = ReadUInt32(),
|
||||
PointerToRawData = ReadUInt32(),
|
||||
PointerToRelocations = ReadUInt32(),
|
||||
PointerToLinenumbers = ReadUInt32(),
|
||||
NumberOfRelocations = ReadUInt16(),
|
||||
NumberOfLinenumbers = ReadUInt16(),
|
||||
Characteristics = ReadUInt32()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public override dynamic MapVATR(dynamic uiAddr)
|
||||
{
|
||||
uint addr = (uint)uiAddr - imageBase;
|
||||
var section = sections.First(x => addr >= x.VirtualAddress && addr <= x.VirtualAddress + x.VirtualSize);
|
||||
return addr - (section.VirtualAddress - section.PointerToRawData);
|
||||
}
|
||||
|
||||
public override bool Search()
|
||||
{
|
||||
Console.WriteLine("ERROR: This mode not supported.");
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool AdvancedSearch(int methodCount)
|
||||
{
|
||||
Console.WriteLine("ERROR: This mode not supported.");
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool PlusSearch(int methodCount, int typeDefinitionsCount)
|
||||
{
|
||||
if (sections.Any(x => x.Name == ".text") && sections.Any(x => x.Name == ".data") && sections.Any(x => x.Name == ".rdata"))
|
||||
{
|
||||
var text = sections.First(x => x.Name == ".text");
|
||||
var data = sections.First(x => x.Name == ".data");
|
||||
var rdata = sections.First(x => x.Name == ".rdata");
|
||||
var codeRegistration = FindCodeRegistration(methodCount, rdata, text);
|
||||
var metadataRegistration = FindMetadataRegistration(typeDefinitionsCount, rdata, data);
|
||||
if (codeRegistration != 0 && metadataRegistration != 0)
|
||||
{
|
||||
Console.WriteLine("CodeRegistration : {0:x}", codeRegistration);
|
||||
Console.WriteLine("MetadataRegistration : {0:x}", metadataRegistration);
|
||||
Init(codeRegistration, metadataRegistration);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("ERROR: The necessary section is missing.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private uint FindCodeRegistration(int count, SectionHeader search, SectionHeader range)
|
||||
{
|
||||
var searchend = search.PointerToRawData + search.SizeOfRawData;
|
||||
var rangeend = range.VirtualAddress + range.VirtualSize;
|
||||
Position = search.PointerToRawData;
|
||||
while (Position < searchend)
|
||||
{
|
||||
var add = Position;
|
||||
if (ReadUInt32() == count)
|
||||
{
|
||||
try
|
||||
{
|
||||
uint pointers = MapVATR(ReadUInt32());
|
||||
if (pointers >= search.PointerToRawData && pointers <= searchend)
|
||||
{
|
||||
var np = Position;
|
||||
var temp = ReadClassArray<uint>(pointers, count);
|
||||
var r = Array.FindIndex(temp, x => x - imageBase < range.VirtualAddress || x - imageBase > rangeend);
|
||||
if (r == -1)
|
||||
{
|
||||
return (uint)add - search.PointerToRawData + search.VirtualAddress + imageBase; //VirtualAddress
|
||||
}
|
||||
Position = np;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private uint FindMetadataRegistration(int typeDefinitionsCount, SectionHeader search, SectionHeader range)
|
||||
{
|
||||
var searchend = search.PointerToRawData + search.SizeOfRawData;
|
||||
var rangeend = range.VirtualAddress + range.VirtualSize;
|
||||
Position = search.PointerToRawData;
|
||||
while (Position < searchend)
|
||||
{
|
||||
var add = Position;
|
||||
if (ReadUInt32() == typeDefinitionsCount)
|
||||
{
|
||||
try
|
||||
{
|
||||
var np = Position;
|
||||
Position += 8;
|
||||
uint pointers = MapVATR(ReadUInt32());
|
||||
if (pointers >= search.PointerToRawData && pointers <= searchend)
|
||||
{
|
||||
var temp = ReadClassArray<uint>(pointers, maxMetadataUsages);
|
||||
var r = Array.FindIndex(temp, x => x - imageBase < range.VirtualAddress || x - imageBase > rangeend);
|
||||
if (r == -1)
|
||||
{
|
||||
return (uint)add - 48u - search.PointerToRawData + search.VirtualAddress + imageBase; //VirtualAddress
|
||||
}
|
||||
}
|
||||
Position = np;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override bool SymbolSearch()
|
||||
{
|
||||
Console.WriteLine("ERROR: This mode not supported.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
74
Il2CppDumper/PEClass.cs
Normal file
74
Il2CppDumper/PEClass.cs
Normal file
|
@ -0,0 +1,74 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Il2CppDumper
|
||||
{
|
||||
public class FileHeader
|
||||
{
|
||||
public ushort Machine;
|
||||
public ushort NumberOfSections;
|
||||
public uint TimeDateStamp;
|
||||
public uint PointerToSymbolTable;
|
||||
public uint NumberOfSymbols;
|
||||
public ushort SizeOfOptionalHeader;
|
||||
public ushort Characteristics;
|
||||
}
|
||||
|
||||
public class OptionalHeader
|
||||
{
|
||||
public ushort Magic;
|
||||
public byte MajorLinkerVersion;
|
||||
public byte MinorLinkerVersion;
|
||||
public uint SizeOfCode;
|
||||
public uint SizeOfInitializedData;
|
||||
public uint SizeOfUninitializedData;
|
||||
public uint AddressOfEntryPoint;
|
||||
public uint BaseOfCode;
|
||||
public uint BaseOfData;
|
||||
public uint ImageBase;
|
||||
public uint SectionAlignment;
|
||||
public uint FileAlignment;
|
||||
public ushort MajorOperatingSystemVersion;
|
||||
public ushort MinorOperatingSystemVersion;
|
||||
public ushort MajorImageVersion;
|
||||
public ushort MinorImageVersion;
|
||||
public ushort MajorSubsystemVersion;
|
||||
public ushort MinorSubsystemVersion;
|
||||
public uint Win32VersionValue;
|
||||
public uint SizeOfImage;
|
||||
public uint SizeOfHeaders;
|
||||
public uint CheckSum;
|
||||
public ushort Subsystem;
|
||||
public ushort DllCharacteristics;
|
||||
public uint SizeOfStackReserve;
|
||||
public uint SizeOfStackCommit;
|
||||
public uint SizeOfHeapReserve;
|
||||
public uint SizeOfHeapCommit;
|
||||
public uint LoaderFlags;
|
||||
public uint NumberOfRvaAndSizes;
|
||||
public DataDirectory[] DataDirectory { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class DataDirectory
|
||||
{
|
||||
public uint VirtualAddress;
|
||||
public uint Size;
|
||||
}
|
||||
|
||||
public class SectionHeader
|
||||
{
|
||||
public string Name;
|
||||
public uint VirtualSize;
|
||||
public uint VirtualAddress;
|
||||
public uint SizeOfRawData;
|
||||
public uint PointerToRawData;
|
||||
public uint PointerToRelocations;
|
||||
public uint PointerToLinenumbers;
|
||||
public ushort NumberOfRelocations;
|
||||
public ushort NumberOfLinenumbers;
|
||||
public uint Characteristics;
|
||||
}
|
||||
}
|
|
@ -36,11 +36,15 @@ namespace Il2CppDumper
|
|||
//判断il2cpp的magic
|
||||
var il2cppMagic = BitConverter.ToUInt32(il2cppfile, 0);
|
||||
var isElf = false;
|
||||
var isPE = false;
|
||||
var is64bit = false;
|
||||
switch (il2cppMagic)
|
||||
{
|
||||
default:
|
||||
throw new Exception("ERROR: il2cpp file not supported.");
|
||||
case 0x905A4D://PE
|
||||
isPE = true;
|
||||
goto case 0xFEEDFACE;
|
||||
case 0x464c457f://ELF
|
||||
isElf = true;
|
||||
if (il2cppfile[4] == 2)
|
||||
|
@ -70,20 +74,21 @@ namespace Il2CppDumper
|
|||
is64bit = true;
|
||||
goto case 0xFEEDFACE;
|
||||
case 0xFEEDFACE:// 32-bit mach object file
|
||||
Console.Write("Select Mode: 1.Manual 2.Auto 3.Auto(Advanced) 4.Auto(Plus)");
|
||||
if (isElf)
|
||||
{
|
||||
Console.Write(" 5.Auto(Symbol)");
|
||||
}
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Select Mode: 1.Manual 2.Auto 3.Auto(Advanced) 4.Auto(Plus) 5.Auto(Symbol)");
|
||||
key = Console.ReadKey(true);
|
||||
var version = config.ForceIl2CppVersion ? config.ForceVersion : metadata.version;
|
||||
Console.WriteLine("Initializing il2cpp file...");
|
||||
if (isElf)
|
||||
if (isPE)
|
||||
{
|
||||
il2cpp = new PE(new MemoryStream(il2cppfile), version, metadata.maxMetadataUsages);
|
||||
}
|
||||
else if (isElf)
|
||||
{
|
||||
if (is64bit)
|
||||
il2cpp = new Elf64(new MemoryStream(il2cppfile), version, metadata.maxMetadataUsages);
|
||||
else
|
||||
il2cpp = new Elf(new MemoryStream(il2cppfile), version, metadata.maxMetadataUsages);
|
||||
}
|
||||
else if (is64bit)
|
||||
il2cpp = new Macho64(new MemoryStream(il2cppfile), version, metadata.maxMetadataUsages);
|
||||
else
|
||||
|
@ -96,21 +101,11 @@ namespace Il2CppDumper
|
|||
case '5':
|
||||
try
|
||||
{
|
||||
if (key.KeyChar == '5')
|
||||
{
|
||||
dynamic elf = il2cpp;
|
||||
if (!elf.DetectedSymbol())
|
||||
{
|
||||
throw new Exception();
|
||||
}
|
||||
break;
|
||||
}
|
||||
Console.WriteLine("Searching...");
|
||||
if (key.KeyChar == '2' ?
|
||||
!il2cpp.Search() :
|
||||
key.KeyChar == '3' ?
|
||||
!il2cpp.AdvancedSearch(metadata.methodDefs.Count(x => x.methodIndex >= 0)) :
|
||||
!il2cpp.PlusSearch(metadata.methodDefs.Count(x => x.methodIndex >= 0), metadata.typeDefs.Length))
|
||||
if (key.KeyChar == '2' ? !il2cpp.Search() :
|
||||
key.KeyChar == '3' ? !il2cpp.AdvancedSearch(metadata.methodDefs.Count(x => x.methodIndex >= 0)) :
|
||||
key.KeyChar == '4' ? !il2cpp.PlusSearch(metadata.methodDefs.Count(x => x.methodIndex >= 0), metadata.typeDefs.Length) :
|
||||
!il2cpp.SymbolSearch())
|
||||
{
|
||||
throw new Exception();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue