Elf64完善

Auto(Plus)完善
This commit is contained in:
Perfare 2019-02-06 20:41:24 +08:00
parent f1c1039d1c
commit c45284f343
7 changed files with 153 additions and 141 deletions

View file

@ -96,4 +96,24 @@ namespace Il2CppDumper
{30,"T"}, {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;
}
} }

View file

@ -291,45 +291,40 @@ namespace Il2CppDumper
{ {
Console.WriteLine("Applying relocations..."); Console.WriteLine("Applying relocations...");
uint dynsymOffset = MapVATR(dynamic_table.First(x => x.d_tag == DT_SYMTAB).d_un); try
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)
{ {
var type = rel.r_info & 0xff; uint dynsymOffset = MapVATR(dynamic_table.First(x => x.d_tag == DT_SYMTAB).d_un);
var sym = rel.r_info >> 8; uint dynstrOffset = MapVATR(dynamic_table.First(x => x.d_tag == DT_STRTAB).d_un);
switch (type) 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: var type = rel.r_info & 0xff;
case R_ARM_ABS32 when !isx86: var sym = rel.r_info >> 8;
{ switch (type)
var dynamic_symbol = dynamic_symbol_table[sym]; {
Position = MapVATR(rel.r_offset); case R_386_32 when isx86:
writer.Write(dynamic_symbol.st_value); case R_ARM_ABS32 when !isx86:
break;
}
/*case R_386_RELATIVE when isDump && isx86:
case R_ARM_RELATIVE when isDump && !isx86:
{ {
var dynamic_symbol = dynamic_symbol_table[sym];
Position = MapVATR(rel.r_offset); Position = MapVATR(rel.r_offset);
var val = ReadUInt32(); writer.Write(dynamic_symbol.st_value);
if (val == 0)
break;
val -= dumpAddr;
Position = MapVATR(rel.r_offset);
writer.Write(val);
break; break;
}*/ }
}
} }
writer.Flush();
}
catch
{
// ignored
} }
writer.Flush();
} }
public override bool PlusSearch(int methodCount, int typeDefinitionsCount) public override bool PlusSearch(int methodCount, int typeDefinitionsCount)

View file

@ -2,14 +2,16 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text; using static Il2CppDumper.ElfConstants;
namespace Il2CppDumper namespace Il2CppDumper
{ {
public sealed class Elf64 : Il2Cpp public sealed class Elf64 : Il2Cpp
{ {
private Elf64_Ehdr elf_header; 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>(); private Dictionary<string, Elf64_Shdr> sectionWithName = new Dictionary<string, Elf64_Shdr>();
public Elf64(Stream stream, float version, long maxMetadataUsages) : base(stream, version, maxMetadataUsages) 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_shentsize = ReadUInt16();
elf_header.e_shnum = ReadUInt16(); elf_header.e_shnum = ReadUInt16();
elf_header.e_shtrndx = 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(); 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(); RelocationProcessing();
} }
@ -61,7 +65,7 @@ namespace Il2CppDumper
public override dynamic MapVATR(dynamic uiAddr) 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); 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) 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 data = sectionWithName[".data"];
var text = sectionWithName[".text"]; var text = sectionWithName[".text"];
@ -97,110 +101,113 @@ namespace Il2CppDumper
Init(codeRegistration, metadataRegistration); Init(codeRegistration, metadataRegistration);
return true; 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); if (phdr.p_memsz != 0ul)
var dataList = new List<Elf64_Phdr>();
var execList = new List<Elf64_Phdr>();
foreach (var phdr in program_table_element)
{ {
if (phdr.p_memsz != 0ul) switch (phdr.p_flags)
{ {
switch (phdr.p_flags) case 1u: //PF_X
{ case 3u:
case 1u: //PF_X case 5u:
case 3u: case 7u:
case 5u: execList.Add(phdr);
case 7u: break;
execList.Add(phdr); case 2u: //PF_W && PF_R
break; case 4u:
case 2u: //PF_W && PF_R case 6u:
case 4u: dataList.Add(phdr);
case 6u: break;
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; return false;
} }
public override bool SymbolSearch() 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; return false;
} }
private void RelocationProcessing() private void RelocationProcessing()
{ {
//TODO Console.WriteLine("Applying relocations...");
/*if (sectionWithName.ContainsKey(".dynsym") && sectionWithName.ContainsKey(".dynstr") && sectionWithName.ContainsKey(".rela.dyn"))
try
{ {
Console.WriteLine("Applying relocations..."); ulong dynsymOffset = MapVATR(dynamic_table.First(x => x.d_tag == DT_SYMTAB).d_un);
var dynsym = sectionWithName[".dynsym"]; ulong dynstrOffset = MapVATR(dynamic_table.First(x => x.d_tag == DT_STRTAB).d_un);
var symbol_name_block_off = sectionWithName[".dynstr"].sh_offset; var dynsymSize = dynstrOffset - dynsymOffset;
var rela_dyn = sectionWithName[".rela.dyn"]; ulong relaOffset = MapVATR(dynamic_table.First(x => x.d_tag == DT_RELA).d_un);
var dynamic_symbol_table = ReadClassArray<Elf64_Sym>(dynsym.sh_offset, (long)dynsym.sh_size / 24); var relaSize = dynamic_table.First(x => x.d_tag == DT_RELASZ).d_un;
var rel_dynend = rela_dyn.sh_offset + rela_dyn.sh_size; dynamic_symbol_table = ReadClassArray<Elf64_Sym>(dynsymOffset, (long)dynsymSize / 24L);
Position = rela_dyn.sh_offset; var rela_table = ReadClassArray<Elf64_Rela>(relaOffset, (long)relaSize / 24L);
var writer = new BinaryWriter(BaseStream); var writer = new BinaryWriter(BaseStream);
while ((ulong)Position < rel_dynend) foreach (var rel in rela_table)
{ {
//Elf64_Rela var type = rel.r_info & 0xffffffff;
var r_offset = ReadUInt64(); var sym = rel.r_info >> 32;
//r_info
var type = ReadUInt32();
var index = ReadUInt32();
var r_addend = ReadUInt64();
switch (type) switch (type)
{ {
case 257: //R_AARCH64_ABS64 case R_AARCH64_ABS64:
//case 1027: //R_AARCH64_RELATIVE
{ {
var position = Position; var dynamic_symbol = dynamic_symbol_table[sym];
var dynamic_symbol = dynamic_symbol_table[index]; Position = MapVATR(rel.r_offset);
writer.BaseStream.Position = (long)r_offset;
writer.Write(dynamic_symbol.st_value); 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; break;
} }
} }
} }
}*/ writer.Flush();
}
catch
{
// ignored
}
} }
} }
} }

View file

@ -64,4 +64,17 @@ namespace Il2CppDumper
public ulong st_value; public ulong st_value;
public ulong st_size; 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;
}
} }

View file

@ -77,22 +77,4 @@ namespace Il2CppDumper
public uint r_offset; public uint r_offset;
public uint r_info; 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;
}
} }

View file

@ -405,13 +405,11 @@ namespace Il2CppDumper
uint pointer = il2Cpp.MapVATR(il2Cpp.ReadUInt32()); uint pointer = il2Cpp.MapVATR(il2Cpp.ReadUInt32());
if (CheckPointerRangeFirst(pointer)) if (CheckPointerRangeFirst(pointer))
{ {
var sign = il2Cpp.Position;
var pointers = il2Cpp.ReadClassArray<uint>(pointer, methodCount); var pointers = il2Cpp.ReadClassArray<uint>(pointer, methodCount);
if (CheckPointerRangeSecond(pointers)) if (CheckPointerRangeSecond(pointers))
{ {
return (ulong)addr - section.start + section.address; //VirtualAddress return (ulong)addr - section.start + section.address; //VirtualAddress
} }
il2Cpp.Position = sign;
} }
} }
catch catch
@ -419,6 +417,7 @@ namespace Il2CppDumper
// ignored // ignored
} }
} }
il2Cpp.Position = addr + 4;
} }
} }
@ -440,13 +439,11 @@ namespace Il2CppDumper
ulong pointer = il2Cpp.MapVATR(il2Cpp.ReadUInt64()); ulong pointer = il2Cpp.MapVATR(il2Cpp.ReadUInt64());
if (CheckPointerRangeFirst(pointer)) if (CheckPointerRangeFirst(pointer))
{ {
var sign = il2Cpp.Position;
var pointers = il2Cpp.ReadClassArray<ulong>(pointer, methodCount); var pointers = il2Cpp.ReadClassArray<ulong>(pointer, methodCount);
if (CheckPointerRangeSecond(pointers)) if (CheckPointerRangeSecond(pointers))
{ {
return (ulong)addr - section.start + section.address; //VirtualAddress return (ulong)addr - section.start + section.address; //VirtualAddress
} }
il2Cpp.Position = sign;
} }
} }
catch catch
@ -454,6 +451,7 @@ namespace Il2CppDumper
// ignored // ignored
} }
} }
il2Cpp.Position = addr + 8;
} }
} }
@ -472,7 +470,6 @@ namespace Il2CppDumper
{ {
try try
{ {
var sign = il2Cpp.Position;
il2Cpp.Position += 8; il2Cpp.Position += 8;
uint pointer = il2Cpp.MapVATR(il2Cpp.ReadUInt32()); uint pointer = il2Cpp.MapVATR(il2Cpp.ReadUInt32());
if (CheckPointerRangeFirst(pointer)) if (CheckPointerRangeFirst(pointer))
@ -483,13 +480,13 @@ namespace Il2CppDumper
return (ulong)addr - 48ul - section.start + section.address; //VirtualAddress return (ulong)addr - 48ul - section.start + section.address; //VirtualAddress
} }
} }
il2Cpp.Position = sign;
} }
catch catch
{ {
// ignored // ignored
} }
} }
il2Cpp.Position = addr + 4;
} }
} }
@ -508,7 +505,6 @@ namespace Il2CppDumper
{ {
try try
{ {
var sign = il2Cpp.Position;
il2Cpp.Position += 16; il2Cpp.Position += 16;
ulong pointer = il2Cpp.MapVATR(il2Cpp.ReadUInt64()); ulong pointer = il2Cpp.MapVATR(il2Cpp.ReadUInt64());
if (CheckPointerRangeFirst(pointer)) if (CheckPointerRangeFirst(pointer))
@ -519,13 +515,13 @@ namespace Il2CppDumper
return (ulong)addr - 96ul - section.start + section.address; //VirtualAddress return (ulong)addr - 96ul - section.start + section.address; //VirtualAddress
} }
} }
il2Cpp.Position = sign;
} }
catch catch
{ {
// ignored // ignored
} }
} }
il2Cpp.Position = addr + 8;
} }
} }

View file

@ -92,7 +92,6 @@ namespace Il2CppDumper
} }
Console.WriteLine("Initializing metadata..."); Console.WriteLine("Initializing metadata...");
metadata = new Metadata(new MemoryStream(metadataBytes), metadataVersion); metadata = new Metadata(new MemoryStream(metadataBytes), metadataVersion);
Console.Clear();
//判断il2cpp的magic //判断il2cpp的magic
var il2cppMagic = BitConverter.ToUInt32(il2cppBytes, 0); var il2cppMagic = BitConverter.ToUInt32(il2cppBytes, 0);
var isElf = false; var isElf = false;