From c45284f343c9db224f2b44c9efdac1b8080f85ff Mon Sep 17 00:00:00 2001 From: Perfare Date: Wed, 6 Feb 2019 20:41:24 +0800 Subject: [PATCH] =?UTF-8?q?Elf64=E5=AE=8C=E5=96=84=20Auto(Plus)=E5=AE=8C?= =?UTF-8?q?=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Il2CppDumper/DefineConstants.cs | 20 ++++ Il2CppDumper/Elf.cs | 59 +++++------ Il2CppDumper/Elf64.cs | 171 +++++++++++++++++--------------- Il2CppDumper/Elf64Class.cs | 13 +++ Il2CppDumper/ElfClass.cs | 18 ---- Il2CppDumper/PlusSearch.cs | 12 +-- Il2CppDumper/Program.cs | 1 - 7 files changed, 153 insertions(+), 141 deletions(-) diff --git a/Il2CppDumper/DefineConstants.cs b/Il2CppDumper/DefineConstants.cs index 263dfc9..5a07027 100644 --- a/Il2CppDumper/DefineConstants.cs +++ b/Il2CppDumper/DefineConstants.cs @@ -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; + } } \ No newline at end of file diff --git a/Il2CppDumper/Elf.cs b/Il2CppDumper/Elf.cs index 768094e..23acd50 100644 --- a/Il2CppDumper/Elf.cs +++ b/Il2CppDumper/Elf.cs @@ -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(dynsymOffset, dynsymSize / 16); - var rel_table = ReadClassArray(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(dynsymOffset, dynsymSize / 16); + var rel_table = ReadClassArray(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) diff --git a/Il2CppDumper/Elf64.cs b/Il2CppDumper/Elf64.cs index fb41f63..40935fe 100644 --- a/Il2CppDumper/Elf64.cs +++ b/Il2CppDumper/Elf64.cs @@ -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 sectionWithName = new Dictionary(); 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(elf_header.e_phoff, elf_header.e_phnum); + program_table = ReadClassArray(elf_header.e_phoff, elf_header.e_phnum); GetSectionWithName(); + var pt_dynamic = program_table.First(x => x.p_type == 2u); + dynamic_table = ReadClassArray(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(); + var execList = new List(); + foreach (var phdr in program_table) { - var plusSearch = new PlusSearch(this, methodCount, typeDefinitionsCount, maxMetadataUsages); - var dataList = new List(); - var execList = new List(); - 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(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(dynsymOffset, (long)dynsymSize / 24L); + var rela_table = ReadClassArray(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 + } } } } diff --git a/Il2CppDumper/Elf64Class.cs b/Il2CppDumper/Elf64Class.cs index b644a98..5c8db82 100644 --- a/Il2CppDumper/Elf64Class.cs +++ b/Il2CppDumper/Elf64Class.cs @@ -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; + } } diff --git a/Il2CppDumper/ElfClass.cs b/Il2CppDumper/ElfClass.cs index 211e1bf..5ed845a 100644 --- a/Il2CppDumper/ElfClass.cs +++ b/Il2CppDumper/ElfClass.cs @@ -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; - } } diff --git a/Il2CppDumper/PlusSearch.cs b/Il2CppDumper/PlusSearch.cs index e45dddd..bb17025 100644 --- a/Il2CppDumper/PlusSearch.cs +++ b/Il2CppDumper/PlusSearch.cs @@ -405,13 +405,11 @@ namespace Il2CppDumper uint pointer = il2Cpp.MapVATR(il2Cpp.ReadUInt32()); if (CheckPointerRangeFirst(pointer)) { - var sign = il2Cpp.Position; var pointers = il2Cpp.ReadClassArray(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(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; } } diff --git a/Il2CppDumper/Program.cs b/Il2CppDumper/Program.cs index 8c04c6f..f9802c6 100644 --- a/Il2CppDumper/Program.cs +++ b/Il2CppDumper/Program.cs @@ -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;