mirror of
https://github.com/Perfare/Il2CppDumper.git
synced 2025-01-25 02:03:02 -03:00
- 不依赖section进行工作
- 删除无用代码
This commit is contained in:
parent
ef9e9de713
commit
674e2bc02c
5 changed files with 93 additions and 153 deletions
|
@ -9,8 +9,7 @@ namespace Il2CppDumper
|
|||
class Elf : MyBinaryReader
|
||||
{
|
||||
public elf_header elf_header;
|
||||
public Dictionary<string, elf_32_shdr> sectionWithName;
|
||||
List<elf_32_shdr> sections;
|
||||
public program_header_table[] program_table_element;
|
||||
|
||||
public Elf(Stream stream) : base(stream)
|
||||
{
|
||||
|
@ -21,6 +20,10 @@ namespace Il2CppDumper
|
|||
throw new Exception("ERROR: il2cpp lib provided is not a valid ELF file.");
|
||||
}
|
||||
elf_header.m_arch = ReadByte();
|
||||
if (elf_header.m_arch == 2)//64
|
||||
{
|
||||
throw new Exception("ERROR: 64 bit so files are not supported.");
|
||||
}
|
||||
elf_header.m_endian = ReadByte();
|
||||
elf_header.m_version = ReadByte();
|
||||
elf_header.m_osabi = ReadByte();
|
||||
|
@ -29,92 +32,23 @@ namespace Il2CppDumper
|
|||
elf_header.e_type = ReadUInt16();
|
||||
elf_header.e_machine = ReadUInt16();
|
||||
elf_header.e_version = ReadUInt32();
|
||||
if (elf_header.m_arch == 1)//32
|
||||
{
|
||||
elf_header.e_entry = ReadUInt32();
|
||||
elf_header.e_phoff = ReadUInt32();
|
||||
elf_header.e_shoff = ReadUInt32();
|
||||
elf_header.e_flags = ReadUInt32();
|
||||
elf_header.e_ehsize = ReadUInt16();
|
||||
elf_header.e_phentsize = ReadUInt16();
|
||||
elf_header.e_phnum = ReadUInt16();
|
||||
elf_header.e_shentsize = ReadUInt16();
|
||||
elf_header.e_shnum = ReadUInt16();
|
||||
elf_header.e_shtrndx = ReadUInt16();
|
||||
}
|
||||
else//64
|
||||
{
|
||||
elf_header.e_entry = ReadUInt64();
|
||||
elf_header.e_phoff = ReadUInt64();
|
||||
elf_header.e_shoff = ReadUInt64();
|
||||
elf_header.e_flags = ReadUInt32();
|
||||
elf_header.e_ehsize = ReadUInt16();
|
||||
elf_header.e_phentsize = ReadUInt16();
|
||||
elf_header.e_phnum = ReadUInt16();
|
||||
elf_header.e_shentsize = ReadUInt16();
|
||||
elf_header.e_shnum = ReadUInt16();
|
||||
elf_header.e_shtrndx = ReadUInt16();
|
||||
}
|
||||
GetSectionWithName();
|
||||
}
|
||||
|
||||
private void GetSectionWithName()
|
||||
{
|
||||
try
|
||||
{
|
||||
var section_name_block_off = (int)elf_header.e_shoff + (elf_header.e_shentsize * elf_header.e_shtrndx);
|
||||
if (elf_header.m_arch == 1)//32
|
||||
{
|
||||
Position = section_name_block_off + 2 * 4 + 4 + 4;
|
||||
section_name_block_off = ReadInt32();
|
||||
}
|
||||
else//Hmm...
|
||||
{
|
||||
Position = section_name_block_off + 2 * 4 + 8 + 8;
|
||||
section_name_block_off = ReadInt32();
|
||||
}
|
||||
var sectionWithNametmp = new Dictionary<string, elf_32_shdr>();
|
||||
var sectionstmp = new List<elf_32_shdr>();
|
||||
for (int i = 0; i < elf_header.e_shnum; i++)
|
||||
{
|
||||
var section = GetSection(i);
|
||||
sectionWithNametmp.Add(ReadStringToNull(section_name_block_off + section.sh_name), section);
|
||||
sectionstmp.Add(section);
|
||||
}
|
||||
sectionWithName = sectionWithNametmp;
|
||||
sections = sectionstmp;
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine("ERROR: Unable to get section.");
|
||||
}
|
||||
}
|
||||
|
||||
private elf_32_shdr GetSection(int iSection)
|
||||
{
|
||||
return ReadClass<elf_32_shdr>((int)elf_header.e_shoff + (elf_header.e_shentsize * iSection));
|
||||
elf_header.e_entry = ReadUInt32();
|
||||
elf_header.e_phoff = ReadUInt32();
|
||||
elf_header.e_shoff = ReadUInt32();
|
||||
elf_header.e_flags = ReadUInt32();
|
||||
elf_header.e_ehsize = ReadUInt16();
|
||||
elf_header.e_phentsize = ReadUInt16();
|
||||
elf_header.e_phnum = ReadUInt16();
|
||||
elf_header.e_shentsize = ReadUInt16();
|
||||
elf_header.e_shnum = ReadUInt16();
|
||||
elf_header.e_shtrndx = ReadUInt16();
|
||||
program_table_element = ReadClassArray<program_header_table>(elf_header.e_phoff, elf_header.e_phnum);
|
||||
}
|
||||
|
||||
public uint MapVATR(uint uiAddr)
|
||||
{
|
||||
if (sections == null)
|
||||
return uiAddr;
|
||||
elf_32_shdr pFirstSec = sections[0];
|
||||
if (uiAddr < pFirstSec.sh_addr)
|
||||
return 0;
|
||||
for (int i = 1; i < elf_header.e_shnum; ++i)
|
||||
{
|
||||
elf_32_shdr pSection = sections[i];
|
||||
if (pSection.sh_addr > uiAddr)
|
||||
{
|
||||
elf_32_shdr pRetSec = sections[i - 1];
|
||||
uint uiResOffset = uiAddr - pRetSec.sh_addr;
|
||||
return pRetSec.sh_offset + uiResOffset;
|
||||
}
|
||||
}
|
||||
elf_32_shdr pRetSec2 = sections[elf_header.e_shnum - 1];
|
||||
uint uiResOffset2 = uiAddr - pRetSec2.sh_addr;
|
||||
return pRetSec2.sh_offset + uiResOffset2;
|
||||
var program_header_table = program_table_element.First(x => uiAddr >= x.p_vaddr && uiAddr <= (x.p_vaddr + x.p_filesz));
|
||||
return uiAddr - (program_header_table.p_vaddr - program_header_table.p_offset);
|
||||
}
|
||||
|
||||
public T MapVATR<T>(uint uiAddr) where T : new()
|
||||
|
|
|
@ -42,10 +42,9 @@ namespace Il2CppDumper
|
|||
|
||||
public uint e_version;
|
||||
|
||||
//全部定义为64位
|
||||
public ulong e_entry;
|
||||
public ulong e_phoff;
|
||||
public ulong e_shoff;
|
||||
public uint e_entry;
|
||||
public uint e_phoff;
|
||||
public uint e_shoff;
|
||||
public uint e_flags;
|
||||
public ushort e_ehsize;
|
||||
public ushort e_phentsize;
|
||||
|
@ -55,6 +54,19 @@ namespace Il2CppDumper
|
|||
public ushort e_shtrndx;
|
||||
}
|
||||
|
||||
class program_header_table
|
||||
{
|
||||
public uint p_type;
|
||||
public uint p_offset;
|
||||
public uint p_vaddr;
|
||||
public uint p_paddr;
|
||||
public uint p_filesz;
|
||||
public uint p_memsz;
|
||||
public uint p_flags;
|
||||
public uint p_align;
|
||||
//public byte[] p_data;忽略
|
||||
}
|
||||
|
||||
class elf_32_shdr
|
||||
{
|
||||
public uint sh_name;
|
||||
|
|
|
@ -53,63 +53,61 @@ namespace Il2CppDumper
|
|||
|
||||
public bool Auto()
|
||||
{
|
||||
if (sectionWithName != null)
|
||||
//函数特征码
|
||||
var bytes = new byte[] { 0x1c, 0x0, 0x9f, 0xe5, 0x1c, 0x10, 0x9f, 0xe5, 0x1c, 0x20, 0x9f, 0xe5 };
|
||||
//取.dynamic
|
||||
var dynamic = new elf_32_shdr();
|
||||
var PT_DYNAMIC = program_table_element.First(x => x.p_type == 2u);
|
||||
dynamic.sh_offset = PT_DYNAMIC.p_offset;
|
||||
dynamic.sh_size = PT_DYNAMIC.p_filesz;
|
||||
//从.dynamic获取_GLOBAL_OFFSET_TABLE_和.init_array
|
||||
uint _GLOBAL_OFFSET_TABLE_ = 0;
|
||||
var init_array = new elf_32_shdr();
|
||||
Position = dynamic.sh_offset;
|
||||
var dynamicend = dynamic.sh_offset + dynamic.sh_size;
|
||||
while (Position < dynamicend)
|
||||
{
|
||||
var bytes = new byte[] { 0x1c, 0x0, 0x9f, 0xe5, 0x1c, 0x10, 0x9f, 0xe5, 0x1c, 0x20, 0x9f, 0xe5 };
|
||||
//判断必要的section是否都在
|
||||
if (sectionWithName.ContainsKey(".got") && sectionWithName.ContainsKey(".init_array") && sectionWithName.ContainsKey(".dynamic"))
|
||||
var tag = ReadInt32();
|
||||
if (tag == 3)//DT_PLTGOT
|
||||
{
|
||||
var dynamic = sectionWithName[".dynamic"];
|
||||
var got = sectionWithName[".got"];
|
||||
//从.dynamic获取_GLOBAL_OFFSET_TABLE_
|
||||
uint _GLOBAL_OFFSET_TABLE_ = 0;
|
||||
Position = dynamic.sh_offset;
|
||||
var dynamicend = dynamic.sh_offset + dynamic.sh_size;
|
||||
var gotend = got.sh_offset + got.sh_size;
|
||||
while (Position < dynamicend)
|
||||
{
|
||||
var tag = ReadInt32();
|
||||
if (tag == 3)
|
||||
{
|
||||
var tmp = ReadUInt32();
|
||||
if (tmp >= got.sh_offset && tmp <= gotend)
|
||||
{
|
||||
_GLOBAL_OFFSET_TABLE_ = tmp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Position += 4;
|
||||
}
|
||||
//从.init_array获取函数
|
||||
var init_array = sectionWithName[".init_array"];
|
||||
var addrs = ReadClassArray<uint>(init_array.sh_offset, (int)init_array.sh_size / 4);
|
||||
foreach (var i in addrs)
|
||||
{
|
||||
if (i != 0)
|
||||
{
|
||||
Position = i;
|
||||
var buff = ReadBytes(12);
|
||||
if (bytes.SequenceEqual(buff))
|
||||
{
|
||||
Position = i + 0x2c;
|
||||
var subaddr = ReadUInt32() + _GLOBAL_OFFSET_TABLE_;
|
||||
Position = subaddr + 0x28;
|
||||
var codeRegistration = ReadUInt32() + _GLOBAL_OFFSET_TABLE_;
|
||||
Console.WriteLine("CodeRegistration : {0:x}", codeRegistration);
|
||||
Position = subaddr + 0x2C;
|
||||
var ptr = ReadUInt32() + _GLOBAL_OFFSET_TABLE_;
|
||||
Position = MapVATR(ptr);
|
||||
var metadataRegistration = ReadUInt32();
|
||||
Console.WriteLine("MetadataRegistration : {0:x}", metadataRegistration);
|
||||
Init(codeRegistration, metadataRegistration);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
_GLOBAL_OFFSET_TABLE_ = ReadUInt32();
|
||||
continue;
|
||||
}
|
||||
else
|
||||
else if (tag == 25)//DT_INIT_ARRAY
|
||||
{
|
||||
Console.WriteLine("ERROR: The necessary section is missing.");
|
||||
init_array.sh_offset = MapVATR(ReadUInt32());
|
||||
continue;
|
||||
}
|
||||
else if (tag == 27)//DT_INIT_ARRAYSZ
|
||||
{
|
||||
init_array.sh_size = ReadUInt32();
|
||||
continue;
|
||||
}
|
||||
Position += 4;
|
||||
}
|
||||
//从.init_array获取函数
|
||||
var addrs = ReadClassArray<uint>(init_array.sh_offset, (int)init_array.sh_size / 4);
|
||||
foreach (var i in addrs)
|
||||
{
|
||||
if (i != 0)
|
||||
{
|
||||
Position = i;
|
||||
var buff = ReadBytes(12);
|
||||
if (bytes.SequenceEqual(buff))
|
||||
{
|
||||
Position = i + 0x2c;
|
||||
var subaddr = ReadUInt32() + _GLOBAL_OFFSET_TABLE_;
|
||||
Position = subaddr + 0x28;
|
||||
var codeRegistration = ReadUInt32() + _GLOBAL_OFFSET_TABLE_;
|
||||
Console.WriteLine("CodeRegistration : {0:x}", codeRegistration);
|
||||
Position = subaddr + 0x2C;
|
||||
var ptr = ReadUInt32() + _GLOBAL_OFFSET_TABLE_;
|
||||
Position = MapVATR(ptr);
|
||||
var metadataRegistration = ReadUInt32();
|
||||
Console.WriteLine("MetadataRegistration : {0:x}", metadataRegistration);
|
||||
Init(codeRegistration, metadataRegistration);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -120,7 +120,7 @@ namespace Il2CppDumper
|
|||
|
||||
public void Init()
|
||||
{
|
||||
var str = System.Convert.ToString(bits, 2);
|
||||
var str = Convert.ToString(bits, 2);
|
||||
if (str.Length != 32)
|
||||
{
|
||||
str = new string(Enumerable.Repeat('0', 32 - str.Length).Concat(str.ToCharArray()).ToArray());
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Il2CppDumper
|
||||
{
|
||||
|
@ -123,17 +125,11 @@ namespace Il2CppDumper
|
|||
public string ReadStringToNull(long addr)
|
||||
{
|
||||
BaseStream.Position = addr;
|
||||
string result = "";
|
||||
char c;
|
||||
for (int i = 0; i < base.BaseStream.Length; i++)
|
||||
{
|
||||
if ((c = (char)base.ReadByte()) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
result += c.ToString();
|
||||
}
|
||||
return result;
|
||||
List<byte> bytes = new List<byte>();
|
||||
byte b;
|
||||
while ((b = ReadByte()) != 0)
|
||||
bytes.Add(b);
|
||||
return Encoding.UTF8.GetString(bytes.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue