mirror of
https://github.com/Perfare/Il2CppDumper.git
synced 2025-01-27 03:03:00 -03:00
处理nso的重定向
This commit is contained in:
parent
f25ad7a612
commit
8018e82b88
1 changed files with 110 additions and 2 deletions
|
@ -2,7 +2,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using static Il2CppDumper.ElfConstants;
|
||||||
|
|
||||||
namespace Il2CppDumper
|
namespace Il2CppDumper
|
||||||
{
|
{
|
||||||
|
@ -13,6 +13,8 @@ namespace Il2CppDumper
|
||||||
private bool isRoDataCompressed;
|
private bool isRoDataCompressed;
|
||||||
private bool isDataCompressed;
|
private bool isDataCompressed;
|
||||||
private List<NSOSegmentHeader> segments = new List<NSOSegmentHeader>();
|
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;
|
private bool isCompressed => isTextCompressed || isRoDataCompressed || isDataCompressed;
|
||||||
|
|
||||||
|
|
||||||
|
@ -78,7 +80,8 @@ namespace Il2CppDumper
|
||||||
{
|
{
|
||||||
Position = header.TextSegment.FileOffset + 4;
|
Position = header.TextSegment.FileOffset + 4;
|
||||||
var modOffset = ReadUInt32();
|
var modOffset = ReadUInt32();
|
||||||
Position = header.TextSegment.FileOffset + modOffset + 8;
|
Position = header.TextSegment.FileOffset + modOffset + 4;
|
||||||
|
var dynamicOffset = ReadUInt32() + modOffset;
|
||||||
var bssStart = ReadUInt32();
|
var bssStart = ReadUInt32();
|
||||||
var bssEnd = ReadUInt32();
|
var bssEnd = ReadUInt32();
|
||||||
header.BssSegment = new NSOSegmentHeader
|
header.BssSegment = new NSOSegmentHeader
|
||||||
|
@ -87,6 +90,111 @@ namespace Il2CppDumper
|
||||||
MemoryOffset = bssStart,
|
MemoryOffset = bssStart,
|
||||||
DecompressedSize = bssEnd - 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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue