Prepare for 64-bit support
This commit is contained in:
@@ -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++)
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user