Prepare for 64-bit support
This commit is contained in:
@@ -24,20 +24,20 @@ namespace Il2CppInspector
|
||||
string Format { get; }
|
||||
string Arch { get; }
|
||||
int Bits { get; }
|
||||
uint GlobalOffset { get; }
|
||||
Dictionary<string, uint> GetSymbolTable();
|
||||
ulong GlobalOffset { get; }
|
||||
Dictionary<string, ulong> GetSymbolTable();
|
||||
uint[] GetFunctionTable();
|
||||
U ReadMappedObject<U>(uint uiAddr) where U : new();
|
||||
U[] ReadMappedArray<U>(uint uiAddr, int count) where U : new();
|
||||
uint MapVATR(uint uiAddr);
|
||||
U ReadMappedObject<U>(ulong uiAddr) where U : new();
|
||||
U[] ReadMappedArray<U>(ulong uiAddr, int count) where U : new();
|
||||
uint MapVATR(ulong uiAddr);
|
||||
|
||||
byte[] ReadBytes(int count);
|
||||
ulong ReadUInt64();
|
||||
uint ReadUInt32();
|
||||
ushort ReadUInt16();
|
||||
byte ReadByte();
|
||||
string ReadMappedNullTerminatedString(uint uiAddr);
|
||||
List<U> ReadMappedObjectPointerArray<U>(uint uiAddr, int count) where U : new();
|
||||
string ReadMappedNullTerminatedString(ulong uiAddr);
|
||||
List<U> ReadMappedObjectPointerArray<U>(ulong uiAddr, int count) where U : new();
|
||||
}
|
||||
|
||||
internal class FileFormatReader
|
||||
@@ -50,7 +50,8 @@ namespace Il2CppInspector
|
||||
.Where(x => x.ImplementedInterfaces.Contains(typeof(IFileFormatReader)) && !x.IsGenericTypeDefinition);
|
||||
|
||||
foreach (var type in types) {
|
||||
if (type.BaseType.GetMethod("Load", new [] {typeof(Stream)})
|
||||
if (type.GetMethod("Load", BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.Public,
|
||||
null, new [] {typeof(Stream)}, null)
|
||||
.Invoke(null, new object[] { stream }) is IFileFormatReader loaded)
|
||||
return loaded;
|
||||
}
|
||||
@@ -66,7 +67,7 @@ namespace Il2CppInspector
|
||||
|
||||
public uint NumImages { get; protected set; } = 1;
|
||||
|
||||
public uint GlobalOffset { get; protected set; }
|
||||
public ulong GlobalOffset { get; protected set; }
|
||||
|
||||
public virtual string Format => throw new NotImplementedException();
|
||||
|
||||
@@ -110,30 +111,30 @@ namespace Il2CppInspector
|
||||
}
|
||||
|
||||
// Find search locations in the symbol table for Il2Cpp data
|
||||
public virtual Dictionary<string, uint> GetSymbolTable() => null;
|
||||
public virtual Dictionary<string, ulong> GetSymbolTable() => null;
|
||||
|
||||
// Find search locations in the machine code for Il2Cpp data
|
||||
public virtual uint[] GetFunctionTable() => throw new NotImplementedException();
|
||||
|
||||
// Map an RVA to an offset into the file image
|
||||
// No mapping by default
|
||||
public virtual uint MapVATR(uint uiAddr) => uiAddr;
|
||||
public virtual uint MapVATR(ulong uiAddr) => (uint) uiAddr;
|
||||
|
||||
// Retrieve object(s) from specified RVA(s)
|
||||
public U ReadMappedObject<U>(uint uiAddr) where U : new() {
|
||||
public U ReadMappedObject<U>(ulong uiAddr) where U : new() {
|
||||
return ReadObject<U>(MapVATR(uiAddr));
|
||||
}
|
||||
|
||||
public U[] ReadMappedArray<U>(uint uiAddr, int count) where U : new() {
|
||||
public U[] ReadMappedArray<U>(ulong uiAddr, int count) where U : new() {
|
||||
return ReadArray<U>(MapVATR(uiAddr), count);
|
||||
}
|
||||
|
||||
public string ReadMappedNullTerminatedString(uint uiAddr) {
|
||||
public string ReadMappedNullTerminatedString(ulong uiAddr) {
|
||||
return ReadNullTerminatedString(MapVATR(uiAddr));
|
||||
}
|
||||
|
||||
// Reads a list of pointers, then reads each object pointed to
|
||||
public List<U> ReadMappedObjectPointerArray<U>(uint uiAddr, int count) where U : new() {
|
||||
public List<U> ReadMappedObjectPointerArray<U>(ulong uiAddr, int count) where U : new() {
|
||||
var pointers = ReadMappedArray<uint>(uiAddr, count);
|
||||
var array = new List<U>();
|
||||
for (int i = 0; i < count; i++)
|
||||
|
||||
@@ -177,7 +177,7 @@ namespace Il2CppInspector
|
||||
return true;
|
||||
}
|
||||
|
||||
public override Dictionary<string, uint> GetSymbolTable() {
|
||||
public override Dictionary<string, ulong> GetSymbolTable() {
|
||||
// Three possible symbol tables in ELF files
|
||||
var pTables = new List<(uint offset, uint count, uint strings)>();
|
||||
|
||||
@@ -209,7 +209,7 @@ namespace Il2CppInspector
|
||||
}
|
||||
|
||||
// Now iterate through all of the symbol and string tables we found to build a full list
|
||||
var symbolTable = new Dictionary<string, uint>();
|
||||
var symbolTable = new Dictionary<string, ulong>();
|
||||
|
||||
foreach (var pTab in pTables) {
|
||||
var symbol_table = ReadArray<elf_32_sym>(pTab.offset, (int) pTab.count);
|
||||
@@ -238,10 +238,10 @@ namespace Il2CppInspector
|
||||
// Map a virtual address to an offset into the image file. Throws an exception if the virtual address is not mapped into the file.
|
||||
// Note if uiAddr is a valid segment but filesz < memsz and the adjusted uiAddr falls between the range of filesz and memsz,
|
||||
// an exception will be thrown. This area of memory is assumed to contain all zeroes.
|
||||
public override uint MapVATR(uint uiAddr)
|
||||
{
|
||||
var program_header_table = this.program_header_table.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 override uint MapVATR(ulong uiAddr) {
|
||||
var addr32 = (uint) uiAddr; // 32-bit implementation
|
||||
var program_header_table = this.program_header_table.First(x => addr32 >= x.p_vaddr && addr32 <= (x.p_vaddr + x.p_filesz));
|
||||
return addr32 - (program_header_table.p_vaddr - program_header_table.p_offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -132,13 +132,13 @@ namespace Il2CppInspector
|
||||
return functionPointers.ToArray();
|
||||
}
|
||||
|
||||
public override uint MapVATR(uint uiAddr) {
|
||||
public override uint MapVATR(ulong uiAddr) {
|
||||
if (!is64) {
|
||||
var section = sections.First(x => uiAddr >= x.Address && uiAddr <= (x.Address + x.Size));
|
||||
return uiAddr - (section.Address - section.ImageOffset);
|
||||
return (uint) (uiAddr - (section.Address - section.ImageOffset));
|
||||
}
|
||||
var section64 = sections64.First(x => uiAddr >= x.Address && uiAddr <= (x.Address + x.Size));
|
||||
return uiAddr - ((uint)section64.Address - section64.ImageOffset);
|
||||
return (uint) (uiAddr - ((uint)section64.Address - section64.ImageOffset));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,13 +91,13 @@ namespace Il2CppInspector
|
||||
return addrs.ToArray();
|
||||
}
|
||||
|
||||
public override uint MapVATR(uint uiAddr) {
|
||||
public override uint MapVATR(ulong uiAddr) {
|
||||
if (uiAddr == 0)
|
||||
return 0;
|
||||
|
||||
var section = sections.First(x => uiAddr - GlobalOffset >= x.BaseMemory &&
|
||||
uiAddr - GlobalOffset < x.BaseMemory + x.SizeImage);
|
||||
return uiAddr - section.BaseMemory - GlobalOffset + section.BaseImage;
|
||||
return (uint) (uiAddr - section.BaseMemory - GlobalOffset + section.BaseImage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace Il2CppInspector
|
||||
}
|
||||
|
||||
// Architecture-specific search function
|
||||
protected abstract (uint, uint) ConsiderCode(uint loc, uint globalOffset);
|
||||
protected abstract (ulong, ulong) ConsiderCode(uint loc, ulong globalOffset);
|
||||
|
||||
// Check all search locations
|
||||
public bool Initialize(double version, uint imageIndex = 0) {
|
||||
@@ -111,7 +111,7 @@ namespace Il2CppInspector
|
||||
return false;
|
||||
}
|
||||
|
||||
private void Configure(IFileFormatReader image, uint codeRegistration, uint metadataRegistration) {
|
||||
private void Configure(IFileFormatReader image, ulong codeRegistration, ulong metadataRegistration) {
|
||||
// Root structures from which we find everything else
|
||||
CodeRegistration = image.ReadMappedObject<Il2CppCodeRegistration>(codeRegistration);
|
||||
MetadataRegistration = image.ReadMappedObject<Il2CppMetadataRegistration>(metadataRegistration);
|
||||
|
||||
@@ -16,9 +16,9 @@ namespace Il2CppInspector
|
||||
|
||||
public Il2CppBinaryARM(IFileFormatReader stream, uint codeRegistration, uint metadataRegistration) : base(stream, codeRegistration, metadataRegistration) { }
|
||||
|
||||
protected override (uint, uint) ConsiderCode(uint loc, uint globalOffset) {
|
||||
protected override (ulong, ulong) ConsiderCode(uint loc, ulong globalOffset) {
|
||||
// Assembly bytes to search for at start of each function
|
||||
uint metadataRegistration, codeRegistration;
|
||||
ulong metadataRegistration, codeRegistration;
|
||||
byte[] buff;
|
||||
|
||||
// ARMv7
|
||||
@@ -29,9 +29,9 @@ namespace Il2CppInspector
|
||||
if (bytes.SequenceEqual(buff)) {
|
||||
Image.Position = loc + 0x2c;
|
||||
var subaddr = Image.ReadUInt32() + globalOffset;
|
||||
Image.Position = subaddr + 0x28;
|
||||
Image.Position = (uint) (subaddr + 0x28);
|
||||
codeRegistration = Image.ReadUInt32() + globalOffset;
|
||||
Image.Position = subaddr + 0x2C;
|
||||
Image.Position = (uint) (subaddr + 0x2C);
|
||||
var ptr = Image.ReadUInt32() + globalOffset;
|
||||
Image.Position = Image.MapVATR(ptr);
|
||||
metadataRegistration = Image.ReadUInt32();
|
||||
|
||||
@@ -12,8 +12,9 @@ namespace Il2CppInspector
|
||||
{
|
||||
public Il2CppBinaryX86(IFileFormatReader stream) : base(stream) { }
|
||||
public Il2CppBinaryX86(IFileFormatReader stream, uint codeRegistration, uint metadataRegistration) : base(stream, codeRegistration, metadataRegistration) { }
|
||||
protected override (uint, uint) ConsiderCode(uint loc, uint globalOffset) {
|
||||
uint funcPtr, metadata, code;
|
||||
protected override (ulong, ulong) ConsiderCode(uint loc, ulong globalOffset) {
|
||||
ulong metadata, code;
|
||||
long funcPtr;
|
||||
ushort opcode;
|
||||
|
||||
// Variant 1
|
||||
@@ -31,9 +32,9 @@ namespace Il2CppInspector
|
||||
return (0, 0);
|
||||
|
||||
// Jump to Il2CppCodegenRegistration
|
||||
Image.Position = Image.MapVATR(funcPtr) + 6;
|
||||
Image.Position = Image.MapVATR((ulong) funcPtr) + 6;
|
||||
metadata = Image.ReadUInt32();
|
||||
Image.Position = Image.MapVATR(funcPtr) + 11;
|
||||
Image.Position = Image.MapVATR((ulong) funcPtr) + 11;
|
||||
code = Image.ReadUInt32();
|
||||
return (code, metadata);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user