重命名

This commit is contained in:
Perfare 2020-02-07 18:16:04 +08:00
parent 2df9418cce
commit b8d03b7f68
5 changed files with 129 additions and 121 deletions

View file

@ -8,10 +8,10 @@ namespace Il2CppDumper
{
public sealed class Elf : Il2Cpp
{
private Elf32_Ehdr elf_header;
private Elf32_Phdr[] program_table;
private Elf32_Dyn[] dynamic_table;
private Elf32_Sym[] dynamic_symbol_table;
private Elf32_Ehdr elfHeader;
private Elf32_Phdr[] programSegment;
private Elf32_Dyn[] dynamicSection;
private Elf32_Sym[] symbolTable;
private Dictionary<string, Elf32_Shdr> sectionWithName = new Dictionary<string, Elf32_Shdr>();
private bool isDumped;
private uint dumpAddr;
@ -27,45 +27,45 @@ namespace Il2CppDumper
public Elf(Stream stream, float version, long maxMetadataUsages) : base(stream, version, maxMetadataUsages)
{
is32Bit = true;
elf_header = new Elf32_Ehdr();
elf_header.ei_mag = ReadUInt32();
elf_header.ei_class = ReadByte();
elf_header.ei_data = ReadByte();
elf_header.ei_version = ReadByte();
elf_header.ei_osabi = ReadByte();
elf_header.ei_abiversion = ReadByte();
elf_header.ei_pad = ReadBytes(7);
elf_header.e_type = ReadUInt16();
elf_header.e_machine = ReadUInt16();
if (elf_header.e_machine != 0x28 && elf_header.e_machine != 0x3)
elfHeader = new Elf32_Ehdr();
elfHeader.ei_mag = ReadUInt32();
elfHeader.ei_class = ReadByte();
elfHeader.ei_data = ReadByte();
elfHeader.ei_version = ReadByte();
elfHeader.ei_osabi = ReadByte();
elfHeader.ei_abiversion = ReadByte();
elfHeader.ei_pad = ReadBytes(7);
elfHeader.e_type = ReadUInt16();
elfHeader.e_machine = ReadUInt16();
if (elfHeader.e_machine != EM_ARM && elfHeader.e_machine != EM_386)
throw new Exception("ERROR: Unsupported machines.");
elf_header.e_version = ReadUInt32();
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 = ReadClassArray<Elf32_Phdr>(elf_header.e_phoff, elf_header.e_phnum);
elfHeader.e_version = ReadUInt32();
elfHeader.e_entry = ReadUInt32();
elfHeader.e_phoff = ReadUInt32();
elfHeader.e_shoff = ReadUInt32();
elfHeader.e_flags = ReadUInt32();
elfHeader.e_ehsize = ReadUInt16();
elfHeader.e_phentsize = ReadUInt16();
elfHeader.e_phnum = ReadUInt16();
elfHeader.e_shentsize = ReadUInt16();
elfHeader.e_shnum = ReadUInt16();
elfHeader.e_shtrndx = ReadUInt16();
programSegment = ReadClassArray<Elf32_Phdr>(elfHeader.e_phoff, elfHeader.e_phnum);
if (!GetSectionWithName())
{
Console.WriteLine("Detected this may be a dump file. If not, it must be protected.");
isDumped = true;
Console.WriteLine("Input dump address:");
dumpAddr = Convert.ToUInt32(Console.ReadLine(), 16);
foreach (var phdr in program_table)
foreach (var phdr in programSegment)
{
phdr.p_offset = phdr.p_vaddr;
phdr.p_filesz = phdr.p_memsz;
phdr.p_vaddr += dumpAddr;
}
}
var pt_dynamic = program_table.First(x => x.p_type == 2u);
dynamic_table = ReadClassArray<Elf32_Dyn>(pt_dynamic.p_offset, pt_dynamic.p_filesz / 8u);
var pt_dynamic = programSegment.First(x => x.p_type == PT_DYNAMIC);
dynamicSection = ReadClassArray<Elf32_Dyn>(pt_dynamic.p_offset, pt_dynamic.p_filesz / 8u);
if (!isDumped)
{
RelocationProcessing();
@ -80,12 +80,12 @@ namespace Il2CppDumper
{
try
{
var section_name_off = elf_header.e_shoff + elf_header.e_shentsize * elf_header.e_shtrndx;
var section_name_off = elfHeader.e_shoff + elfHeader.e_shentsize * elfHeader.e_shtrndx;
Position = (uint)section_name_off + 2 * 4 + 4 + 4;//2 * sizeof(Elf32_Word) + sizeof(Elf32_Xword) + sizeof(Elf32_Addr)
var section_name_block_off = ReadUInt32();
for (uint i = 0; i < elf_header.e_shnum; i++)
for (uint i = 0; i < elfHeader.e_shnum; i++)
{
var section = ReadClass<Elf32_Shdr>(elf_header.e_shoff + elf_header.e_shentsize * i);
var section = ReadClass<Elf32_Shdr>(elfHeader.e_shoff + elfHeader.e_shentsize * i);
var key = ReadStringToNull(section_name_block_off + section.sh_name);
if (!sectionWithName.ContainsKey(key))
{
@ -100,18 +100,18 @@ namespace Il2CppDumper
return true;
}
public override ulong MapVATR(ulong uiAddr)
public override ulong MapVATR(ulong addr)
{
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);
var phdr = programSegment.First(x => addr >= x.p_vaddr && addr <= x.p_vaddr + x.p_memsz);
return addr - (phdr.p_vaddr - phdr.p_offset);
}
public override bool Search()
{
var _GLOBAL_OFFSET_TABLE_ = dynamic_table.First(x => x.d_tag == DT_PLTGOT).d_un;
var execs = program_table.Where(x => x.p_type == 1u && (x.p_flags & 1) == 1).ToArray();
var _GLOBAL_OFFSET_TABLE_ = dynamicSection.First(x => x.d_tag == DT_PLTGOT).d_un;
var execs = programSegment.Where(x => x.p_type == PT_LOAD && (x.p_flags & PF_X) == 1).ToArray();
var resultList = new List<int>();
var featureBytes = elf_header.e_machine == 40 ? ARMFeatureBytes : X86FeatureBytes;
var featureBytes = elfHeader.e_machine == EM_ARM ? ARMFeatureBytes : X86FeatureBytes;
foreach (var exec in execs)
{
Position = exec.p_offset;
@ -132,7 +132,7 @@ namespace Il2CppDumper
var result = (uint)resultList[0];
if (version < 24f)
{
if (elf_header.e_machine == 40)
if (elfHeader.e_machine == EM_ARM)
{
Position = result + 0x14;
codeRegistration = ReadUInt32() + _GLOBAL_OFFSET_TABLE_;
@ -144,7 +144,7 @@ namespace Il2CppDumper
}
else if (version >= 24f)
{
if (elf_header.e_machine == 40)
if (elfHeader.e_machine == EM_ARM)
{
Position = result + 0x14;
codeRegistration = ReadUInt32() + result + 0xcu + dumpAddr;
@ -163,7 +163,7 @@ namespace Il2CppDumper
{
var dataList = new List<Elf32_Phdr>();
var execList = new List<Elf32_Phdr>();
foreach (var phdr in program_table)
foreach (var phdr in programSegment)
{
if (phdr.p_memsz != 0ul)
{
@ -198,17 +198,17 @@ namespace Il2CppDumper
{
uint codeRegistration = 0;
uint metadataRegistration = 0;
var dynstrOffset = MapVATR(dynamic_table.First(x => x.d_tag == DT_STRTAB).d_un);
foreach (var dynamic_symbol in dynamic_symbol_table)
var dynstrOffset = MapVATR(dynamicSection.First(x => x.d_tag == DT_STRTAB).d_un);
foreach (var symbol in symbolTable)
{
var name = ReadStringToNull(dynstrOffset + dynamic_symbol.st_name);
var name = ReadStringToNull(dynstrOffset + symbol.st_name);
switch (name)
{
case "g_CodeRegistration":
codeRegistration = dynamic_symbol.st_value;
codeRegistration = symbol.st_value;
break;
case "g_MetadataRegistration":
metadataRegistration = dynamic_symbol.st_value;
metadataRegistration = symbol.st_value;
break;
}
}
@ -230,15 +230,15 @@ namespace Il2CppDumper
Console.WriteLine("Applying relocations...");
try
{
var dynsymOffset = MapVATR(dynamic_table.First(x => x.d_tag == DT_SYMTAB).d_un);
var dynstrOffset = MapVATR(dynamic_table.First(x => x.d_tag == DT_STRTAB).d_un);
var dynsymOffset = MapVATR(dynamicSection.First(x => x.d_tag == DT_SYMTAB).d_un);
var dynstrOffset = MapVATR(dynamicSection.First(x => x.d_tag == DT_STRTAB).d_un);
var dynsymSize = dynstrOffset - dynsymOffset;
var 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, (long)dynsymSize / 16);
var rel_table = ReadClassArray<Elf32_Rel>(reldynOffset, reldynSize / 8);
var isx86 = elf_header.e_machine == 0x3;
foreach (var rel in rel_table)
var reldynOffset = MapVATR(dynamicSection.First(x => x.d_tag == DT_REL).d_un);
var reldynSize = dynamicSection.First(x => x.d_tag == DT_RELSZ).d_un;
symbolTable = ReadClassArray<Elf32_Sym>(dynsymOffset, (long)dynsymSize / 16);
var relTable = ReadClassArray<Elf32_Rel>(reldynOffset, reldynSize / 8);
var isx86 = elfHeader.e_machine == 0x3;
foreach (var rel in relTable)
{
var type = rel.r_info & 0xff;
var sym = rel.r_info >> 8;
@ -247,9 +247,9 @@ namespace Il2CppDumper
case R_386_32 when isx86:
case R_ARM_ABS32 when !isx86:
{
var dynamic_symbol = dynamic_symbol_table[sym];
var symbol = symbolTable[sym];
Position = MapVATR(rel.r_offset);
Write(dynamic_symbol.st_value);
Write(symbol.st_value);
break;
}
}
@ -265,16 +265,16 @@ namespace Il2CppDumper
{
//简单的加壳检测检测是否含有init function或者JNI_OnLoad
//.init_proc
if (dynamic_table.FirstOrDefault(x => x.d_tag == DT_INIT) != null)
if (dynamicSection.FirstOrDefault(x => x.d_tag == DT_INIT) != null)
{
Console.WriteLine("WARNING: find .init_proc");
return true;
}
//JNI_OnLoad
var dynstrOffset = MapVATR(dynamic_table.First(x => x.d_tag == DT_STRTAB).d_un);
foreach (var dynamic_symbol in dynamic_symbol_table)
var dynstrOffset = MapVATR(dynamicSection.First(x => x.d_tag == DT_STRTAB).d_un);
foreach (var symbol in symbolTable)
{
var name = ReadStringToNull(dynstrOffset + dynamic_symbol.st_name);
var name = ReadStringToNull(dynstrOffset + symbol.st_name);
switch (name)
{
case "JNI_OnLoad":

View file

@ -8,53 +8,53 @@ namespace Il2CppDumper
{
public sealed class Elf64 : Il2Cpp
{
private Elf64_Ehdr elf_header;
private Elf64_Phdr[] program_table;
private Elf64_Dyn[] dynamic_table;
private Elf64_Sym[] dynamic_symbol_table;
private Elf64_Ehdr elfHeader;
private Elf64_Phdr[] programSegment;
private Elf64_Dyn[] dynamicSection;
private Elf64_Sym[] symbolTable;
private Dictionary<string, Elf64_Shdr> sectionWithName = new Dictionary<string, Elf64_Shdr>();
private bool isDumped;
private ulong dumpAddr;
public Elf64(Stream stream, float version, long maxMetadataUsages) : base(stream, version, maxMetadataUsages)
{
elf_header = new Elf64_Ehdr();
elf_header.ei_mag = ReadUInt32();
elf_header.ei_class = ReadByte();
elf_header.ei_data = ReadByte();
elf_header.ei_version = ReadByte();
elf_header.ei_osabi = ReadByte();
elf_header.ei_abiversion = ReadByte();
elf_header.ei_pad = ReadBytes(7);
elf_header.e_type = ReadUInt16();
elf_header.e_machine = ReadUInt16();
elf_header.e_version = ReadUInt32();
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();
program_table = ReadClassArray<Elf64_Phdr>(elf_header.e_phoff, elf_header.e_phnum);
elfHeader = new Elf64_Ehdr();
elfHeader.ei_mag = ReadUInt32();
elfHeader.ei_class = ReadByte();
elfHeader.ei_data = ReadByte();
elfHeader.ei_version = ReadByte();
elfHeader.ei_osabi = ReadByte();
elfHeader.ei_abiversion = ReadByte();
elfHeader.ei_pad = ReadBytes(7);
elfHeader.e_type = ReadUInt16();
elfHeader.e_machine = ReadUInt16();
elfHeader.e_version = ReadUInt32();
elfHeader.e_entry = ReadUInt64();
elfHeader.e_phoff = ReadUInt64();
elfHeader.e_shoff = ReadUInt64();
elfHeader.e_flags = ReadUInt32();
elfHeader.e_ehsize = ReadUInt16();
elfHeader.e_phentsize = ReadUInt16();
elfHeader.e_phnum = ReadUInt16();
elfHeader.e_shentsize = ReadUInt16();
elfHeader.e_shnum = ReadUInt16();
elfHeader.e_shtrndx = ReadUInt16();
programSegment = ReadClassArray<Elf64_Phdr>(elfHeader.e_phoff, elfHeader.e_phnum);
if (!GetSectionWithName())
{
Console.WriteLine("Detected this may be a dump file. If not, it must be protected.");
isDumped = true;
Console.WriteLine("Input dump address:");
dumpAddr = Convert.ToUInt64(Console.ReadLine(), 16);
foreach (var phdr in program_table)
foreach (var phdr in programSegment)
{
phdr.p_offset = phdr.p_vaddr;
phdr.p_filesz = phdr.p_memsz;
phdr.p_vaddr += dumpAddr;
}
}
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);
var pt_dynamic = programSegment.First(x => x.p_type == PT_DYNAMIC);
dynamicSection = ReadClassArray<Elf64_Dyn>(pt_dynamic.p_offset, (long)pt_dynamic.p_filesz / 16L);
if (!isDumped)
{
RelocationProcessing();
@ -69,12 +69,12 @@ namespace Il2CppDumper
{
try
{
var section_name_off = elf_header.e_shoff + (ulong)elf_header.e_shentsize * elf_header.e_shtrndx;
var section_name_off = elfHeader.e_shoff + (ulong)elfHeader.e_shentsize * elfHeader.e_shtrndx;
Position = section_name_off + 2 * 4 + 8 + 8;//2 * sizeof(Elf64_Word) + sizeof(Elf64_Xword) + sizeof(Elf64_Addr)
var section_name_block_off = ReadUInt32();
for (int i = 0; i < elf_header.e_shnum; i++)
for (int i = 0; i < elfHeader.e_shnum; i++)
{
var section = ReadClass<Elf64_Shdr>(elf_header.e_shoff + elf_header.e_shentsize * (ulong)i);
var section = ReadClass<Elf64_Shdr>(elfHeader.e_shoff + elfHeader.e_shentsize * (ulong)i);
var key = ReadStringToNull(section_name_block_off + section.sh_name);
if (!sectionWithName.ContainsKey(key))
{
@ -89,10 +89,10 @@ namespace Il2CppDumper
return true;
}
public override ulong MapVATR(ulong uiAddr)
public override ulong MapVATR(ulong addr)
{
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);
var phdr = programSegment.First(x => addr >= x.p_vaddr && addr <= x.p_vaddr + x.p_memsz);
return addr - (phdr.p_vaddr - phdr.p_offset);
}
public override bool Search()
@ -104,7 +104,7 @@ namespace Il2CppDumper
{
var dataList = new List<Elf64_Phdr>();
var execList = new List<Elf64_Phdr>();
foreach (var phdr in program_table)
foreach (var phdr in programSegment)
{
if (phdr.p_memsz != 0ul)
{
@ -139,17 +139,17 @@ namespace Il2CppDumper
{
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)
ulong dynstrOffset = MapVATR(dynamicSection.First(x => x.d_tag == DT_STRTAB).d_un);
foreach (var symbol in symbolTable)
{
var name = ReadStringToNull(dynstrOffset + dynamic_symbol.st_name);
var name = ReadStringToNull(dynstrOffset + symbol.st_name);
switch (name)
{
case "g_CodeRegistration":
codeRegistration = dynamic_symbol.st_value;
codeRegistration = symbol.st_value;
break;
case "g_MetadataRegistration":
metadataRegistration = dynamic_symbol.st_value;
metadataRegistration = symbol.st_value;
break;
}
}
@ -171,30 +171,30 @@ namespace Il2CppDumper
try
{
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);
ulong dynsymOffset = MapVATR(dynamicSection.First(x => x.d_tag == DT_SYMTAB).d_un);
ulong dynstrOffset = MapVATR(dynamicSection.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);
foreach (var rel in rela_table)
ulong relaOffset = MapVATR(dynamicSection.First(x => x.d_tag == DT_RELA).d_un);
var relaSize = dynamicSection.First(x => x.d_tag == DT_RELASZ).d_un;
symbolTable = ReadClassArray<Elf64_Sym>(dynsymOffset, (long)dynsymSize / 24L);
var relaTable = ReadClassArray<Elf64_Rela>(relaOffset, (long)relaSize / 24L);
foreach (var rela in relaTable)
{
var type = rel.r_info & 0xffffffff;
var sym = rel.r_info >> 32;
var type = rela.r_info & 0xffffffff;
var sym = rela.r_info >> 32;
switch (type)
{
case R_AARCH64_ABS64:
{
var dynamic_symbol = dynamic_symbol_table[sym];
Position = MapVATR(rel.r_offset);
Write(dynamic_symbol.st_value + (ulong)rel.r_addend);
var symbol = symbolTable[sym];
Position = MapVATR(rela.r_offset);
Write(symbol.st_value + (ulong)rela.r_addend);
break;
}
case R_AARCH64_RELATIVE:
{
Position = MapVATR(rel.r_offset);
Write(rel.r_addend);
Position = MapVATR(rela.r_offset);
Write(rela.r_addend);
break;
}
}
@ -210,16 +210,16 @@ namespace Il2CppDumper
{
//简单的加壳检测检测是否含有init function或者JNI_OnLoad
//.init_proc
if (dynamic_table.FirstOrDefault(x => x.d_tag == DT_INIT) != null)
if (dynamicSection.FirstOrDefault(x => x.d_tag == DT_INIT) != null)
{
Console.WriteLine("WARNING: find .init_proc");
return true;
}
//JNI_OnLoad
ulong dynstrOffset = MapVATR(dynamic_table.First(x => x.d_tag == DT_STRTAB).d_un);
foreach (var dynamic_symbol in dynamic_symbol_table)
ulong dynstrOffset = MapVATR(dynamicSection.First(x => x.d_tag == DT_STRTAB).d_un);
foreach (var symbol in symbolTable)
{
var name = ReadStringToNull(dynstrOffset + dynamic_symbol.st_name);
var name = ReadStringToNull(dynstrOffset + symbol.st_name);
switch (name)
{
case "JNI_OnLoad":

View file

@ -2,6 +2,14 @@
{
static class ElfConstants
{
public const int EM_386 = 3;
public const int EM_ARM = 40;
public const int PT_LOAD = 1;
public const int PT_DYNAMIC = 2;
public const int PF_X = 1;
public const int DT_PLTGOT = 3;
public const int DT_HASH = 4;
public const int DT_STRTAB = 5;

View file

@ -81,7 +81,7 @@
<Compile Include="ElfClass.cs" />
<Compile Include="MachoClass.cs" />
<Compile Include="MachoFat.cs" />
<Compile Include="MyBinaryReader.cs" />
<Compile Include="BinaryStream.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Macho64.cs" />