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 Format { get; }
string Arch { get; } string Arch { get; }
int Bits { get; } int Bits { get; }
uint GlobalOffset { get; } ulong GlobalOffset { get; }
Dictionary<string, uint> GetSymbolTable(); Dictionary<string, ulong> GetSymbolTable();
uint[] GetFunctionTable(); uint[] GetFunctionTable();
U ReadMappedObject<U>(uint uiAddr) where U : new(); U ReadMappedObject<U>(ulong uiAddr) where U : new();
U[] ReadMappedArray<U>(uint uiAddr, int count) where U : new(); U[] ReadMappedArray<U>(ulong uiAddr, int count) where U : new();
uint MapVATR(uint uiAddr); uint MapVATR(ulong uiAddr);
byte[] ReadBytes(int count); byte[] ReadBytes(int count);
ulong ReadUInt64(); ulong ReadUInt64();
uint ReadUInt32(); uint ReadUInt32();
ushort ReadUInt16(); ushort ReadUInt16();
byte ReadByte(); byte ReadByte();
string ReadMappedNullTerminatedString(uint uiAddr); string ReadMappedNullTerminatedString(ulong uiAddr);
List<U> ReadMappedObjectPointerArray<U>(uint uiAddr, int count) where U : new(); List<U> ReadMappedObjectPointerArray<U>(ulong uiAddr, int count) where U : new();
} }
internal class FileFormatReader internal class FileFormatReader
@@ -50,7 +50,8 @@ namespace Il2CppInspector
.Where(x => x.ImplementedInterfaces.Contains(typeof(IFileFormatReader)) && !x.IsGenericTypeDefinition); .Where(x => x.ImplementedInterfaces.Contains(typeof(IFileFormatReader)) && !x.IsGenericTypeDefinition);
foreach (var type in types) { 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) .Invoke(null, new object[] { stream }) is IFileFormatReader loaded)
return loaded; return loaded;
} }
@@ -66,7 +67,7 @@ namespace Il2CppInspector
public uint NumImages { get; protected set; } = 1; 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(); public virtual string Format => throw new NotImplementedException();
@@ -110,30 +111,30 @@ namespace Il2CppInspector
} }
// Find search locations in the symbol table for Il2Cpp data // 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 // Find search locations in the machine code for Il2Cpp data
public virtual uint[] GetFunctionTable() => throw new NotImplementedException(); public virtual uint[] GetFunctionTable() => throw new NotImplementedException();
// Map an RVA to an offset into the file image // Map an RVA to an offset into the file image
// No mapping by default // 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) // 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)); 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); return ReadArray<U>(MapVATR(uiAddr), count);
} }
public string ReadMappedNullTerminatedString(uint uiAddr) { public string ReadMappedNullTerminatedString(ulong uiAddr) {
return ReadNullTerminatedString(MapVATR(uiAddr)); return ReadNullTerminatedString(MapVATR(uiAddr));
} }
// Reads a list of pointers, then reads each object pointed to // 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 pointers = ReadMappedArray<uint>(uiAddr, count);
var array = new List<U>(); var array = new List<U>();
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)

View File

@@ -177,7 +177,7 @@ namespace Il2CppInspector
return true; return true;
} }
public override Dictionary<string, uint> GetSymbolTable() { public override Dictionary<string, ulong> GetSymbolTable() {
// Three possible symbol tables in ELF files // Three possible symbol tables in ELF files
var pTables = new List<(uint offset, uint count, uint strings)>(); 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 // 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) { foreach (var pTab in pTables) {
var symbol_table = ReadArray<elf_32_sym>(pTab.offset, (int) pTab.count); 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. // 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, // 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. // an exception will be thrown. This area of memory is assumed to contain all zeroes.
public override uint MapVATR(uint uiAddr) public override uint MapVATR(ulong uiAddr) {
{ var addr32 = (uint) uiAddr; // 32-bit implementation
var program_header_table = this.program_header_table.First(x => uiAddr >= x.p_vaddr && uiAddr <= (x.p_vaddr + x.p_filesz)); var program_header_table = this.program_header_table.First(x => addr32 >= x.p_vaddr && addr32 <= (x.p_vaddr + x.p_filesz));
return uiAddr - (program_header_table.p_vaddr - program_header_table.p_offset); return addr32 - (program_header_table.p_vaddr - program_header_table.p_offset);
} }
} }
} }

View File

@@ -132,13 +132,13 @@ namespace Il2CppInspector
return functionPointers.ToArray(); return functionPointers.ToArray();
} }
public override uint MapVATR(uint uiAddr) { public override uint MapVATR(ulong uiAddr) {
if (!is64) { if (!is64) {
var section = sections.First(x => uiAddr >= x.Address && uiAddr <= (x.Address + x.Size)); 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)); 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(); return addrs.ToArray();
} }
public override uint MapVATR(uint uiAddr) { public override uint MapVATR(ulong uiAddr) {
if (uiAddr == 0) if (uiAddr == 0)
return 0; return 0;
var section = sections.First(x => uiAddr - GlobalOffset >= x.BaseMemory && var section = sections.First(x => uiAddr - GlobalOffset >= x.BaseMemory &&
uiAddr - GlobalOffset < x.BaseMemory + x.SizeImage); 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 // 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 // Check all search locations
public bool Initialize(double version, uint imageIndex = 0) { public bool Initialize(double version, uint imageIndex = 0) {
@@ -111,7 +111,7 @@ namespace Il2CppInspector
return false; 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 // Root structures from which we find everything else
CodeRegistration = image.ReadMappedObject<Il2CppCodeRegistration>(codeRegistration); CodeRegistration = image.ReadMappedObject<Il2CppCodeRegistration>(codeRegistration);
MetadataRegistration = image.ReadMappedObject<Il2CppMetadataRegistration>(metadataRegistration); 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) { } 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 // Assembly bytes to search for at start of each function
uint metadataRegistration, codeRegistration; ulong metadataRegistration, codeRegistration;
byte[] buff; byte[] buff;
// ARMv7 // ARMv7
@@ -29,9 +29,9 @@ namespace Il2CppInspector
if (bytes.SequenceEqual(buff)) { if (bytes.SequenceEqual(buff)) {
Image.Position = loc + 0x2c; Image.Position = loc + 0x2c;
var subaddr = Image.ReadUInt32() + globalOffset; var subaddr = Image.ReadUInt32() + globalOffset;
Image.Position = subaddr + 0x28; Image.Position = (uint) (subaddr + 0x28);
codeRegistration = Image.ReadUInt32() + globalOffset; codeRegistration = Image.ReadUInt32() + globalOffset;
Image.Position = subaddr + 0x2C; Image.Position = (uint) (subaddr + 0x2C);
var ptr = Image.ReadUInt32() + globalOffset; var ptr = Image.ReadUInt32() + globalOffset;
Image.Position = Image.MapVATR(ptr); Image.Position = Image.MapVATR(ptr);
metadataRegistration = Image.ReadUInt32(); metadataRegistration = Image.ReadUInt32();

View File

@@ -12,8 +12,9 @@ namespace Il2CppInspector
{ {
public Il2CppBinaryX86(IFileFormatReader stream) : base(stream) { } public Il2CppBinaryX86(IFileFormatReader stream) : base(stream) { }
public Il2CppBinaryX86(IFileFormatReader stream, uint codeRegistration, uint metadataRegistration) : base(stream, codeRegistration, metadataRegistration) { } public Il2CppBinaryX86(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) {
uint funcPtr, metadata, code; ulong metadata, code;
long funcPtr;
ushort opcode; ushort opcode;
// Variant 1 // Variant 1
@@ -31,9 +32,9 @@ namespace Il2CppInspector
return (0, 0); return (0, 0);
// Jump to Il2CppCodegenRegistration // Jump to Il2CppCodegenRegistration
Image.Position = Image.MapVATR(funcPtr) + 6; Image.Position = Image.MapVATR((ulong) funcPtr) + 6;
metadata = Image.ReadUInt32(); metadata = Image.ReadUInt32();
Image.Position = Image.MapVATR(funcPtr) + 11; Image.Position = Image.MapVATR((ulong) funcPtr) + 11;
code = Image.ReadUInt32(); code = Image.ReadUInt32();
return (code, metadata); return (code, metadata);
} }