处理nso的重定向

This commit is contained in:
Perfare 2021-11-25 10:20:24 +08:00
parent f25ad7a612
commit 8018e82b88

View file

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using static Il2CppDumper.ElfConstants;
namespace Il2CppDumper
{
@ -13,6 +13,8 @@ namespace Il2CppDumper
private bool isRoDataCompressed;
private bool isDataCompressed;
private List<NSOSegmentHeader> segments = new List<NSOSegmentHeader>();
private Elf64_Sym[] symbolTable;
private List<Elf64_Dyn> dynamicSection = new List<Elf64_Dyn>();
private bool isCompressed => isTextCompressed || isRoDataCompressed || isDataCompressed;
@ -78,7 +80,8 @@ namespace Il2CppDumper
{
Position = header.TextSegment.FileOffset + 4;
var modOffset = ReadUInt32();
Position = header.TextSegment.FileOffset + modOffset + 8;
Position = header.TextSegment.FileOffset + modOffset + 4;
var dynamicOffset = ReadUInt32() + modOffset;
var bssStart = ReadUInt32();
var bssEnd = ReadUInt32();
header.BssSegment = new NSOSegmentHeader
@ -87,6 +90,111 @@ namespace Il2CppDumper
MemoryOffset = bssStart,
DecompressedSize = bssEnd - bssStart
};
var maxSize = (header.DataSegment.MemoryOffset + header.DataSegment.DecompressedSize - dynamicOffset) / 16;
Position = MapVATR(dynamicOffset);
for (int i = 0; i < maxSize; i++)
{
var dynamic = ReadClass<Elf64_Dyn>();
if (dynamic.d_tag == 0)
{
break;
}
else
{
dynamicSection.Add(dynamic);
}
}
ReadSymbol();
RelocationProcessing();
}
}
private void ReadSymbol()
{
try
{
var symbolCount = 0u;
var hash = dynamicSection.FirstOrDefault(x => x.d_tag == DT_HASH);
if (hash != null)
{
var addr = MapVATR(hash.d_un);
Position = addr;
var nbucket = ReadUInt32();
var nchain = ReadUInt32();
symbolCount = nchain;
}
else
{
hash = dynamicSection.First(x => x.d_tag == DT_GNU_HASH);
var addr = MapVATR(hash.d_un);
Position = addr;
var nbuckets = ReadUInt32();
var symoffset = ReadUInt32();
var bloom_size = ReadUInt32();
var bloom_shift = ReadUInt32();
var buckets_address = addr + 16 + (8 * bloom_size);
var buckets = ReadClassArray<uint>(buckets_address, nbuckets);
var last_symbol = buckets.Max();
if (last_symbol < symoffset)
{
symbolCount = symoffset;
}
else
{
var chains_base_address = buckets_address + 4 * nbuckets;
Position = chains_base_address + (last_symbol - symoffset) * 4;
while (true)
{
var chain_entry = ReadUInt32();
++last_symbol;
if ((chain_entry & 1) != 0)
break;
}
symbolCount = last_symbol;
}
}
var dynsymOffset = MapVATR(dynamicSection.First(x => x.d_tag == DT_SYMTAB).d_un);
symbolTable = ReadClassArray<Elf64_Sym>(dynsymOffset, symbolCount);
}
catch
{
// ignored
}
}
private void RelocationProcessing()
{
Console.WriteLine("Applying relocations...");
try
{
var relaOffset = MapVATR(dynamicSection.First(x => x.d_tag == DT_RELA).d_un);
var relaSize = dynamicSection.First(x => x.d_tag == DT_RELASZ).d_un;
var relaTable = ReadClassArray<Elf64_Rela>(relaOffset, (long)relaSize / 24L);
foreach (var rela in relaTable)
{
var type = rela.r_info & 0xffffffff;
var sym = rela.r_info >> 32;
switch (type)
{
case R_AARCH64_ABS64:
{
var symbol = symbolTable[sym];
Position = MapVATR(rela.r_offset);
Write(symbol.st_value + (ulong)rela.r_addend);
break;
}
case R_AARCH64_RELATIVE:
{
Position = MapVATR(rela.r_offset);
Write(rela.r_addend);
break;
}
}
}
}
catch
{
// ignored
}
}