Prepare for 64-bit support

This commit is contained in:
Katy Coe
2019-10-22 15:27:18 +02:00
parent f78d7f8250
commit e036151f4d
7 changed files with 38 additions and 36 deletions

View File

@@ -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++)

View File

@@ -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);
}
}
}

View File

@@ -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));
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);

View File

@@ -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();

View File

@@ -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);
}