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"},
};
}
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...");
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)

View file

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

View file

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

View file

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

View file

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

View file

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