mirror of
https://github.com/Perfare/Il2CppDumper.git
synced 2025-01-25 02:03:02 -03:00
Elf64完善
Auto(Plus)完善
This commit is contained in:
parent
f1c1039d1c
commit
c45284f343
7 changed files with 153 additions and 141 deletions
|
@ -96,4 +96,24 @@ namespace Il2CppDumper
|
|||
{30,"T"},
|
||||
};
|
||||
}
|
||||
|
||||
static class ElfConstants
|
||||
{
|
||||
public const int DT_PLTGOT = 3;
|
||||
public const int DT_STRTAB = 5;
|
||||
public const int DT_SYMTAB = 6;
|
||||
public const int DT_RELA = 7;
|
||||
public const int DT_RELASZ = 8;
|
||||
public const int DT_STRSZ = 10;
|
||||
public const int DT_REL = 17;
|
||||
public const int DT_RELSZ = 18;
|
||||
public const int DT_INIT_ARRAY = 25;
|
||||
public const int DT_INIT_ARRAYSZ = 27;
|
||||
|
||||
public const int R_ARM_ABS32 = 2;
|
||||
|
||||
public const int R_386_32 = 1;
|
||||
|
||||
public const int R_AARCH64_ABS64 = 257;
|
||||
}
|
||||
}
|
|
@ -291,45 +291,40 @@ namespace Il2CppDumper
|
|||
{
|
||||
Console.WriteLine("Applying relocations...");
|
||||
|
||||
uint dynsymOffset = MapVATR(dynamic_table.First(x => x.d_tag == DT_SYMTAB).d_un);
|
||||
uint dynstrOffset = MapVATR(dynamic_table.First(x => x.d_tag == DT_STRTAB).d_un);
|
||||
var dynsymSize = dynstrOffset - dynsymOffset;
|
||||
//var dynstrSize = dynamic_table.First(x => x.d_tag == DT_STRSZ).d_un;
|
||||
uint reldynOffset = MapVATR(dynamic_table.First(x => x.d_tag == DT_REL).d_un);
|
||||
var reldynSize = dynamic_table.First(x => x.d_tag == DT_RELSZ).d_un;
|
||||
dynamic_symbol_table = ReadClassArray<Elf32_Sym>(dynsymOffset, dynsymSize / 16);
|
||||
var rel_table = ReadClassArray<Elf32_Rel>(reldynOffset, reldynSize / 8);
|
||||
var writer = new BinaryWriter(BaseStream);
|
||||
var isx86 = elf_header.e_machine == 0x3;
|
||||
foreach (var rel in rel_table)
|
||||
try
|
||||
{
|
||||
var type = rel.r_info & 0xff;
|
||||
var sym = rel.r_info >> 8;
|
||||
switch (type)
|
||||
uint dynsymOffset = MapVATR(dynamic_table.First(x => x.d_tag == DT_SYMTAB).d_un);
|
||||
uint dynstrOffset = MapVATR(dynamic_table.First(x => x.d_tag == DT_STRTAB).d_un);
|
||||
var dynsymSize = dynstrOffset - dynsymOffset;
|
||||
//var dynstrSize = dynamic_table.First(x => x.d_tag == DT_STRSZ).d_un;
|
||||
uint reldynOffset = MapVATR(dynamic_table.First(x => x.d_tag == DT_REL).d_un);
|
||||
var reldynSize = dynamic_table.First(x => x.d_tag == DT_RELSZ).d_un;
|
||||
dynamic_symbol_table = ReadClassArray<Elf32_Sym>(dynsymOffset, dynsymSize / 16);
|
||||
var rel_table = ReadClassArray<Elf32_Rel>(reldynOffset, reldynSize / 8);
|
||||
var writer = new BinaryWriter(BaseStream);
|
||||
var isx86 = elf_header.e_machine == 0x3;
|
||||
foreach (var rel in rel_table)
|
||||
{
|
||||
case R_386_32 when isx86:
|
||||
case R_ARM_ABS32 when !isx86:
|
||||
{
|
||||
var dynamic_symbol = dynamic_symbol_table[sym];
|
||||
Position = MapVATR(rel.r_offset);
|
||||
writer.Write(dynamic_symbol.st_value);
|
||||
break;
|
||||
}
|
||||
/*case R_386_RELATIVE when isDump && isx86:
|
||||
case R_ARM_RELATIVE when isDump && !isx86:
|
||||
var type = rel.r_info & 0xff;
|
||||
var sym = rel.r_info >> 8;
|
||||
switch (type)
|
||||
{
|
||||
case R_386_32 when isx86:
|
||||
case R_ARM_ABS32 when !isx86:
|
||||
{
|
||||
var dynamic_symbol = dynamic_symbol_table[sym];
|
||||
Position = MapVATR(rel.r_offset);
|
||||
var val = ReadUInt32();
|
||||
if (val == 0)
|
||||
break;
|
||||
val -= dumpAddr;
|
||||
Position = MapVATR(rel.r_offset);
|
||||
writer.Write(val);
|
||||
writer.Write(dynamic_symbol.st_value);
|
||||
break;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
writer.Flush();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
writer.Flush();
|
||||
}
|
||||
|
||||
public override bool PlusSearch(int methodCount, int typeDefinitionsCount)
|
||||
|
|
|
@ -2,14 +2,16 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using static Il2CppDumper.ElfConstants;
|
||||
|
||||
namespace Il2CppDumper
|
||||
{
|
||||
public sealed class Elf64 : Il2Cpp
|
||||
{
|
||||
private Elf64_Ehdr elf_header;
|
||||
private Elf64_Phdr[] program_table_element;
|
||||
private Elf64_Phdr[] program_table;
|
||||
private Elf64_Dyn[] dynamic_table;
|
||||
private Elf64_Sym[] dynamic_symbol_table;
|
||||
private Dictionary<string, Elf64_Shdr> sectionWithName = new Dictionary<string, Elf64_Shdr>();
|
||||
|
||||
public Elf64(Stream stream, float version, long maxMetadataUsages) : base(stream, version, maxMetadataUsages)
|
||||
|
@ -35,8 +37,10 @@ namespace Il2CppDumper
|
|||
elf_header.e_shentsize = ReadUInt16();
|
||||
elf_header.e_shnum = ReadUInt16();
|
||||
elf_header.e_shtrndx = ReadUInt16();
|
||||
program_table_element = ReadClassArray<Elf64_Phdr>(elf_header.e_phoff, elf_header.e_phnum);
|
||||
program_table = ReadClassArray<Elf64_Phdr>(elf_header.e_phoff, elf_header.e_phnum);
|
||||
GetSectionWithName();
|
||||
var pt_dynamic = program_table.First(x => x.p_type == 2u);
|
||||
dynamic_table = ReadClassArray<Elf64_Dyn>(pt_dynamic.p_offset, (long)pt_dynamic.p_filesz / 16L);
|
||||
RelocationProcessing();
|
||||
}
|
||||
|
||||
|
@ -61,7 +65,7 @@ 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);
|
||||
var program_header_table = program_table.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);
|
||||
}
|
||||
|
||||
|
@ -77,7 +81,7 @@ namespace Il2CppDumper
|
|||
|
||||
public override bool PlusSearch(int methodCount, int typeDefinitionsCount)
|
||||
{
|
||||
if (sectionWithName.ContainsKey(".data") && sectionWithName.ContainsKey(".text") && sectionWithName.ContainsKey(".bss"))
|
||||
/*if (sectionWithName.ContainsKey(".data") && sectionWithName.ContainsKey(".text") && sectionWithName.ContainsKey(".bss"))
|
||||
{
|
||||
var data = sectionWithName[".data"];
|
||||
var text = sectionWithName[".text"];
|
||||
|
@ -97,110 +101,113 @@ namespace Il2CppDumper
|
|||
Init(codeRegistration, metadataRegistration);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
}*/
|
||||
var plusSearch = new PlusSearch(this, methodCount, typeDefinitionsCount, maxMetadataUsages);
|
||||
var dataList = new List<Elf64_Phdr>();
|
||||
var execList = new List<Elf64_Phdr>();
|
||||
foreach (var phdr in program_table)
|
||||
{
|
||||
var plusSearch = new PlusSearch(this, methodCount, typeDefinitionsCount, maxMetadataUsages);
|
||||
var dataList = new List<Elf64_Phdr>();
|
||||
var execList = new List<Elf64_Phdr>();
|
||||
foreach (var phdr in program_table_element)
|
||||
if (phdr.p_memsz != 0ul)
|
||||
{
|
||||
if (phdr.p_memsz != 0ul)
|
||||
switch (phdr.p_flags)
|
||||
{
|
||||
switch (phdr.p_flags)
|
||||
{
|
||||
case 1u: //PF_X
|
||||
case 3u:
|
||||
case 5u:
|
||||
case 7u:
|
||||
execList.Add(phdr);
|
||||
break;
|
||||
case 2u: //PF_W && PF_R
|
||||
case 4u:
|
||||
case 6u:
|
||||
dataList.Add(phdr);
|
||||
break;
|
||||
}
|
||||
case 1u: //PF_X
|
||||
case 3u:
|
||||
case 5u:
|
||||
case 7u:
|
||||
execList.Add(phdr);
|
||||
break;
|
||||
case 2u: //PF_W && PF_R
|
||||
case 4u:
|
||||
case 6u:
|
||||
dataList.Add(phdr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
var data = dataList.ToArray();
|
||||
var exec = execList.ToArray();
|
||||
plusSearch.SetSearch(data);
|
||||
plusSearch.SetPointerRangeFirst(data);
|
||||
plusSearch.SetPointerRangeSecond(exec);
|
||||
var codeRegistration = plusSearch.FindCodeRegistration64Bit();
|
||||
plusSearch.SetPointerRangeSecond(data);
|
||||
var metadataRegistration = plusSearch.FindMetadataRegistration64Bit();
|
||||
if (codeRegistration != 0 && metadataRegistration != 0)
|
||||
{
|
||||
Console.WriteLine("CodeRegistration : {0:x}", codeRegistration);
|
||||
Console.WriteLine("MetadataRegistration : {0:x}", metadataRegistration);
|
||||
Init(codeRegistration, metadataRegistration);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
var data = dataList.ToArray();
|
||||
var exec = execList.ToArray();
|
||||
plusSearch.SetSearch(data);
|
||||
plusSearch.SetPointerRangeFirst(data);
|
||||
plusSearch.SetPointerRangeSecond(exec);
|
||||
var codeRegistration = plusSearch.FindCodeRegistration64Bit();
|
||||
plusSearch.SetPointerRangeSecond(data);
|
||||
var metadataRegistration = plusSearch.FindMetadataRegistration64Bit();
|
||||
if (codeRegistration != 0 && metadataRegistration != 0)
|
||||
{
|
||||
Console.WriteLine("CodeRegistration : {0:x}", codeRegistration);
|
||||
Console.WriteLine("MetadataRegistration : {0:x}", metadataRegistration);
|
||||
Init(codeRegistration, metadataRegistration);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool SymbolSearch()
|
||||
{
|
||||
ulong codeRegistration = 0ul;
|
||||
ulong metadataRegistration = 0ul;
|
||||
ulong dynstrOffset = MapVATR(dynamic_table.First(x => x.d_tag == DT_STRTAB).d_un);
|
||||
foreach (var dynamic_symbol in dynamic_symbol_table)
|
||||
{
|
||||
var name = ReadStringToNull(dynstrOffset + dynamic_symbol.st_name);
|
||||
switch (name)
|
||||
{
|
||||
case "g_CodeRegistration":
|
||||
codeRegistration = dynamic_symbol.st_value;
|
||||
break;
|
||||
case "g_MetadataRegistration":
|
||||
metadataRegistration = dynamic_symbol.st_value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (codeRegistration > 0 && metadataRegistration > 0)
|
||||
{
|
||||
Console.WriteLine("Detected Symbol !");
|
||||
Console.WriteLine("CodeRegistration : {0:x}", codeRegistration);
|
||||
Console.WriteLine("MetadataRegistration : {0:x}", metadataRegistration);
|
||||
Init(codeRegistration, metadataRegistration);
|
||||
return true;
|
||||
}
|
||||
Console.WriteLine("ERROR: No symbol is detected");
|
||||
return false;
|
||||
}
|
||||
|
||||
private void RelocationProcessing()
|
||||
{
|
||||
//TODO
|
||||
/*if (sectionWithName.ContainsKey(".dynsym") && sectionWithName.ContainsKey(".dynstr") && sectionWithName.ContainsKey(".rela.dyn"))
|
||||
Console.WriteLine("Applying relocations...");
|
||||
|
||||
try
|
||||
{
|
||||
Console.WriteLine("Applying relocations...");
|
||||
var dynsym = sectionWithName[".dynsym"];
|
||||
var symbol_name_block_off = sectionWithName[".dynstr"].sh_offset;
|
||||
var rela_dyn = sectionWithName[".rela.dyn"];
|
||||
var dynamic_symbol_table = ReadClassArray<Elf64_Sym>(dynsym.sh_offset, (long)dynsym.sh_size / 24);
|
||||
var rel_dynend = rela_dyn.sh_offset + rela_dyn.sh_size;
|
||||
Position = rela_dyn.sh_offset;
|
||||
ulong dynsymOffset = MapVATR(dynamic_table.First(x => x.d_tag == DT_SYMTAB).d_un);
|
||||
ulong dynstrOffset = MapVATR(dynamic_table.First(x => x.d_tag == DT_STRTAB).d_un);
|
||||
var dynsymSize = dynstrOffset - dynsymOffset;
|
||||
ulong relaOffset = MapVATR(dynamic_table.First(x => x.d_tag == DT_RELA).d_un);
|
||||
var relaSize = dynamic_table.First(x => x.d_tag == DT_RELASZ).d_un;
|
||||
dynamic_symbol_table = ReadClassArray<Elf64_Sym>(dynsymOffset, (long)dynsymSize / 24L);
|
||||
var rela_table = ReadClassArray<Elf64_Rela>(relaOffset, (long)relaSize / 24L);
|
||||
var writer = new BinaryWriter(BaseStream);
|
||||
while ((ulong)Position < rel_dynend)
|
||||
foreach (var rel in rela_table)
|
||||
{
|
||||
//Elf64_Rela
|
||||
var r_offset = ReadUInt64();
|
||||
//r_info
|
||||
var type = ReadUInt32();
|
||||
var index = ReadUInt32();
|
||||
var r_addend = ReadUInt64();
|
||||
var type = rel.r_info & 0xffffffff;
|
||||
var sym = rel.r_info >> 32;
|
||||
switch (type)
|
||||
{
|
||||
case 257: //R_AARCH64_ABS64
|
||||
//case 1027: //R_AARCH64_RELATIVE
|
||||
case R_AARCH64_ABS64:
|
||||
{
|
||||
var position = Position;
|
||||
var dynamic_symbol = dynamic_symbol_table[index];
|
||||
writer.BaseStream.Position = (long)r_offset;
|
||||
var dynamic_symbol = dynamic_symbol_table[sym];
|
||||
Position = MapVATR(rel.r_offset);
|
||||
writer.Write(dynamic_symbol.st_value);
|
||||
Position = position;
|
||||
break;
|
||||
}
|
||||
case 1025: //R_AARCH64_GLOB_DAT
|
||||
{
|
||||
var position = Position;
|
||||
var dynamic_symbol = dynamic_symbol_table[index];
|
||||
var name = ReadStringToNull(symbol_name_block_off + dynamic_symbol.st_name);
|
||||
switch (name)
|
||||
{
|
||||
case "g_CodeRegistration":
|
||||
codeRegistration = dynamic_symbol.st_value;
|
||||
break;
|
||||
case "g_MetadataRegistration":
|
||||
metadataRegistration = dynamic_symbol.st_value;
|
||||
break;
|
||||
}
|
||||
Position = position;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
writer.Flush();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,4 +64,17 @@ namespace Il2CppDumper
|
|||
public ulong st_value;
|
||||
public ulong st_size;
|
||||
}
|
||||
|
||||
public class Elf64_Dyn
|
||||
{
|
||||
public long d_tag;
|
||||
public ulong d_un;
|
||||
}
|
||||
|
||||
public class Elf64_Rela
|
||||
{
|
||||
public ulong r_offset;
|
||||
public ulong r_info;
|
||||
public long r_addend;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,22 +77,4 @@ namespace Il2CppDumper
|
|||
public uint r_offset;
|
||||
public uint r_info;
|
||||
}
|
||||
|
||||
static class ElfConstants
|
||||
{
|
||||
public const int DT_PLTGOT = 3;
|
||||
public const int DT_STRTAB = 5;
|
||||
public const int DT_SYMTAB = 6;
|
||||
public const int DT_STRSZ = 10;
|
||||
public const int DT_REL = 17;
|
||||
public const int DT_RELSZ = 18;
|
||||
public const int DT_INIT_ARRAY = 25;
|
||||
public const int DT_INIT_ARRAYSZ = 27;
|
||||
|
||||
public const int R_ARM_ABS32 = 2;
|
||||
public const int R_ARM_RELATIVE = 23;
|
||||
|
||||
public const int R_386_32 = 1;
|
||||
public const int R_386_RELATIVE = 8;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -405,13 +405,11 @@ namespace Il2CppDumper
|
|||
uint pointer = il2Cpp.MapVATR(il2Cpp.ReadUInt32());
|
||||
if (CheckPointerRangeFirst(pointer))
|
||||
{
|
||||
var sign = il2Cpp.Position;
|
||||
var pointers = il2Cpp.ReadClassArray<uint>(pointer, methodCount);
|
||||
if (CheckPointerRangeSecond(pointers))
|
||||
{
|
||||
return (ulong)addr - section.start + section.address; //VirtualAddress
|
||||
}
|
||||
il2Cpp.Position = sign;
|
||||
}
|
||||
}
|
||||
catch
|
||||
|
@ -419,6 +417,7 @@ namespace Il2CppDumper
|
|||
// ignored
|
||||
}
|
||||
}
|
||||
il2Cpp.Position = addr + 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -440,13 +439,11 @@ namespace Il2CppDumper
|
|||
ulong pointer = il2Cpp.MapVATR(il2Cpp.ReadUInt64());
|
||||
if (CheckPointerRangeFirst(pointer))
|
||||
{
|
||||
var sign = il2Cpp.Position;
|
||||
var pointers = il2Cpp.ReadClassArray<ulong>(pointer, methodCount);
|
||||
if (CheckPointerRangeSecond(pointers))
|
||||
{
|
||||
return (ulong)addr - section.start + section.address; //VirtualAddress
|
||||
}
|
||||
il2Cpp.Position = sign;
|
||||
}
|
||||
}
|
||||
catch
|
||||
|
@ -454,6 +451,7 @@ namespace Il2CppDumper
|
|||
// ignored
|
||||
}
|
||||
}
|
||||
il2Cpp.Position = addr + 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -472,7 +470,6 @@ namespace Il2CppDumper
|
|||
{
|
||||
try
|
||||
{
|
||||
var sign = il2Cpp.Position;
|
||||
il2Cpp.Position += 8;
|
||||
uint pointer = il2Cpp.MapVATR(il2Cpp.ReadUInt32());
|
||||
if (CheckPointerRangeFirst(pointer))
|
||||
|
@ -483,13 +480,13 @@ namespace Il2CppDumper
|
|||
return (ulong)addr - 48ul - section.start + section.address; //VirtualAddress
|
||||
}
|
||||
}
|
||||
il2Cpp.Position = sign;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
il2Cpp.Position = addr + 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -508,7 +505,6 @@ namespace Il2CppDumper
|
|||
{
|
||||
try
|
||||
{
|
||||
var sign = il2Cpp.Position;
|
||||
il2Cpp.Position += 16;
|
||||
ulong pointer = il2Cpp.MapVATR(il2Cpp.ReadUInt64());
|
||||
if (CheckPointerRangeFirst(pointer))
|
||||
|
@ -519,13 +515,13 @@ namespace Il2CppDumper
|
|||
return (ulong)addr - 96ul - section.start + section.address; //VirtualAddress
|
||||
}
|
||||
}
|
||||
il2Cpp.Position = sign;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
il2Cpp.Position = addr + 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -92,7 +92,6 @@ namespace Il2CppDumper
|
|||
}
|
||||
Console.WriteLine("Initializing metadata...");
|
||||
metadata = new Metadata(new MemoryStream(metadataBytes), metadataVersion);
|
||||
Console.Clear();
|
||||
//判断il2cpp的magic
|
||||
var il2cppMagic = BitConverter.ToUInt32(il2cppBytes, 0);
|
||||
var isElf = false;
|
||||
|
|
Loading…
Add table
Reference in a new issue