添加PE Plus模式支持

一些细节调整
This commit is contained in:
Perfare 2018-07-11 05:08:49 +08:00
parent af667aed63
commit 9d5a03463d
10 changed files with 627 additions and 385 deletions

View file

@ -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)
{

View file

@ -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;
}
}

View file

@ -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)

View file

@ -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>

View file

@ -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;
}
}
}

View file

@ -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;
}
}
}

View file

@ -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
View 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
View 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;
}
}

View file

@ -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();
}