Tidy up FileFormatReader stream access methods
This commit is contained in:
@@ -7,7 +7,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.IO.IsolatedStorage;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using NoisyCowStudios.Bin2Object;
|
using NoisyCowStudios.Bin2Object;
|
||||||
@@ -17,6 +16,8 @@ namespace Il2CppInspector
|
|||||||
public interface IFileFormatReader
|
public interface IFileFormatReader
|
||||||
{
|
{
|
||||||
BinaryObjectReader Stream { get; }
|
BinaryObjectReader Stream { get; }
|
||||||
|
double Version { get; set; }
|
||||||
|
long Length { get; }
|
||||||
uint NumImages { get; }
|
uint NumImages { get; }
|
||||||
IEnumerable<IFileFormatReader> Images { get; }
|
IEnumerable<IFileFormatReader> Images { get; }
|
||||||
IFileFormatReader this[uint index] { get; }
|
IFileFormatReader this[uint index] { get; }
|
||||||
@@ -29,13 +30,21 @@ namespace Il2CppInspector
|
|||||||
uint[] GetFunctionTable();
|
uint[] GetFunctionTable();
|
||||||
U ReadMappedObject<U>(ulong uiAddr) where U : new();
|
U ReadMappedObject<U>(ulong uiAddr) where U : new();
|
||||||
U[] ReadMappedArray<U>(ulong uiAddr, int count) where U : new();
|
U[] ReadMappedArray<U>(ulong uiAddr, int count) where U : new();
|
||||||
|
long[] ReadMappedWordArray(ulong uiAddr, int count);
|
||||||
uint MapVATR(ulong uiAddr);
|
uint MapVATR(ulong uiAddr);
|
||||||
|
|
||||||
byte[] ReadBytes(int count);
|
byte[] ReadBytes(int count);
|
||||||
ulong ReadUInt64();
|
ulong ReadUInt64();
|
||||||
|
ulong ReadUInt64(long uiAddr);
|
||||||
uint ReadUInt32();
|
uint ReadUInt32();
|
||||||
|
uint ReadUInt32(long uiAddr);
|
||||||
ushort ReadUInt16();
|
ushort ReadUInt16();
|
||||||
|
ushort ReadUInt16(long uiAddr);
|
||||||
byte ReadByte();
|
byte ReadByte();
|
||||||
|
byte ReadByte(long uiAddr);
|
||||||
|
long ReadWord();
|
||||||
|
long ReadWord(long uiAddr);
|
||||||
|
U ReadObject<U>() where U : new();
|
||||||
string ReadMappedNullTerminatedString(ulong uiAddr);
|
string ReadMappedNullTerminatedString(ulong uiAddr);
|
||||||
List<U> ReadMappedObjectPointerArray<U>(ulong uiAddr, int count) where U : new();
|
List<U> ReadMappedObjectPointerArray<U>(ulong uiAddr, int count) where U : new();
|
||||||
}
|
}
|
||||||
@@ -65,6 +74,8 @@ namespace Il2CppInspector
|
|||||||
|
|
||||||
public BinaryObjectReader Stream => this;
|
public BinaryObjectReader Stream => this;
|
||||||
|
|
||||||
|
public long Length => BaseStream.Length;
|
||||||
|
|
||||||
public uint NumImages { get; protected set; } = 1;
|
public uint NumImages { get; protected set; } = 1;
|
||||||
|
|
||||||
public ulong GlobalOffset { get; protected set; }
|
public ulong GlobalOffset { get; protected set; }
|
||||||
@@ -83,8 +94,8 @@ namespace Il2CppInspector
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static T Load(string filename) {
|
public static T Load(string filename) {
|
||||||
using (var stream = new FileStream(filename, FileMode.Open, FileAccess.Read))
|
using var stream = new FileStream(filename, FileMode.Open, FileAccess.Read);
|
||||||
return Load(stream);
|
return Load(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static T Load(Stream stream) {
|
public static T Load(Stream stream) {
|
||||||
@@ -102,13 +113,7 @@ namespace Il2CppInspector
|
|||||||
protected virtual bool Init() => throw new NotImplementedException();
|
protected virtual bool Init() => throw new NotImplementedException();
|
||||||
|
|
||||||
// Choose a sub-binary within the image for multi-architecture binaries
|
// Choose a sub-binary within the image for multi-architecture binaries
|
||||||
public virtual IFileFormatReader this[uint index] {
|
public virtual IFileFormatReader this[uint index] => (index == 0)? this : throw new IndexOutOfRangeException("Binary image index out of bounds");
|
||||||
get {
|
|
||||||
if (index == 0)
|
|
||||||
return this;
|
|
||||||
throw new IndexOutOfRangeException("Binary image index out of bounds");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find search locations in the symbol table for Il2Cpp data
|
// Find search locations in the symbol table for Il2Cpp data
|
||||||
public virtual Dictionary<string, ulong> GetSymbolTable() => null;
|
public virtual Dictionary<string, ulong> GetSymbolTable() => null;
|
||||||
@@ -120,18 +125,21 @@ namespace Il2CppInspector
|
|||||||
// No mapping by default
|
// No mapping by default
|
||||||
public virtual uint MapVATR(ulong uiAddr) => (uint) uiAddr;
|
public virtual uint MapVATR(ulong uiAddr) => (uint) uiAddr;
|
||||||
|
|
||||||
|
// Read a file format dependent word (32 or 64 bits)
|
||||||
|
// The primitive mappings in Bin2Object will automatically read a uint if the file is 32-bit
|
||||||
|
public long ReadWord() => ReadObject<long>();
|
||||||
|
public long ReadWord(long uiAddr) => ReadObject<long>(uiAddr);
|
||||||
|
|
||||||
// Retrieve object(s) from specified RVA(s)
|
// Retrieve object(s) from specified RVA(s)
|
||||||
public U ReadMappedObject<U>(ulong uiAddr) where U : new() {
|
public U ReadMappedObject<U>(ulong uiAddr) where U : new() => ReadObject<U>(MapVATR(uiAddr));
|
||||||
return ReadObject<U>(MapVATR(uiAddr));
|
|
||||||
}
|
|
||||||
|
|
||||||
public U[] ReadMappedArray<U>(ulong uiAddr, int count) where U : new() {
|
public U[] ReadMappedArray<U>(ulong uiAddr, int count) where U : new() => ReadArray<U>(MapVATR(uiAddr), count);
|
||||||
return ReadArray<U>(MapVATR(uiAddr), count);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string ReadMappedNullTerminatedString(ulong uiAddr) {
|
// Read a file format dependent array of words (32 or 64 bits)
|
||||||
return ReadNullTerminatedString(MapVATR(uiAddr));
|
// The primitive mappings in Bin2Object will automatically read a uint if the file is 32-bit
|
||||||
}
|
public long[] ReadMappedWordArray(ulong uiAddr, int count) => ReadArray<long>(MapVATR(uiAddr), count);
|
||||||
|
|
||||||
|
public string ReadMappedNullTerminatedString(ulong uiAddr) => 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>(ulong uiAddr, int count) where U : new() {
|
public List<U> ReadMappedObjectPointerArray<U>(ulong uiAddr, int count) where U : new() {
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ namespace Il2CppInspector
|
|||||||
// Check all search locations
|
// Check all search locations
|
||||||
public bool Initialize(double version, uint imageIndex = 0) {
|
public bool Initialize(double version, uint imageIndex = 0) {
|
||||||
var subImage = Image[imageIndex];
|
var subImage = Image[imageIndex];
|
||||||
subImage.Stream.Version = version;
|
subImage.Version = version;
|
||||||
|
|
||||||
// Try searching the symbol table
|
// Try searching the symbol table
|
||||||
var symbols = subImage.GetSymbolTable();
|
var symbols = subImage.GetSymbolTable();
|
||||||
@@ -128,11 +128,11 @@ namespace Il2CppInspector
|
|||||||
MetadataRegistration = image.ReadMappedObject<Il2CppMetadataRegistration>(metadataRegistration);
|
MetadataRegistration = image.ReadMappedObject<Il2CppMetadataRegistration>(metadataRegistration);
|
||||||
|
|
||||||
// The global method pointer list was deprecated in v24.2 in favour of Il2CppCodeGenModule
|
// The global method pointer list was deprecated in v24.2 in favour of Il2CppCodeGenModule
|
||||||
if (Image.Stream.Version <= 24.1)
|
if (Image.Version <= 24.1)
|
||||||
GlobalMethodPointers = image.ReadMappedArray<ulong>(CodeRegistration.pmethodPointers, (int) CodeRegistration.methodPointersCount);
|
GlobalMethodPointers = image.ReadMappedArray<ulong>(CodeRegistration.pmethodPointers, (int) CodeRegistration.methodPointersCount);
|
||||||
|
|
||||||
// After v24 method pointers and RGCTX data were stored in Il2CppCodeGenModules
|
// After v24 method pointers and RGCTX data were stored in Il2CppCodeGenModules
|
||||||
if (Image.Stream.Version >= 24.2) {
|
if (Image.Version >= 24.2) {
|
||||||
Modules = new Dictionary<string, Il2CppCodeGenModule>();
|
Modules = new Dictionary<string, Il2CppCodeGenModule>();
|
||||||
|
|
||||||
// Array of pointers to Il2CppCodeGenModule
|
// Array of pointers to Il2CppCodeGenModule
|
||||||
@@ -145,7 +145,7 @@ namespace Il2CppInspector
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Field offset data. Metadata <=21.x uses a value-type array; >=21.x uses a pointer array
|
// Field offset data. Metadata <=21.x uses a value-type array; >=21.x uses a pointer array
|
||||||
FieldOffsetData = image.ReadMappedArray<long>(MetadataRegistration.pfieldOffsets, (int) MetadataRegistration.fieldOffsetsCount);
|
FieldOffsetData = image.ReadMappedWordArray(MetadataRegistration.pfieldOffsets, (int) MetadataRegistration.fieldOffsetsCount);
|
||||||
|
|
||||||
// Type definitions (pointer array)
|
// Type definitions (pointer array)
|
||||||
Types = image.ReadMappedObjectPointerArray<Il2CppType>(MetadataRegistration.ptypes, (int) MetadataRegistration.typesCount);
|
Types = image.ReadMappedObjectPointerArray<Il2CppType>(MetadataRegistration.ptypes, (int) MetadataRegistration.typesCount);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2017 Katy Coe - http://www.hearthcode.org - http://www.djkaty.com
|
Copyright 2017-2019 Katy Coe - http://www.hearthcode.org - http://www.djkaty.com
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
*/
|
*/
|
||||||
@@ -50,7 +50,7 @@ namespace Il2CppInspector
|
|||||||
|
|
||||||
image.Position += 8;
|
image.Position += 8;
|
||||||
funcPtr = image.MapVATR(image.ReadUInt32() + image.GlobalOffset);
|
funcPtr = image.MapVATR(image.ReadUInt32() + image.GlobalOffset);
|
||||||
if (funcPtr > image.Stream.BaseStream.Length)
|
if (funcPtr > image.Length)
|
||||||
return (0, 0);
|
return (0, 0);
|
||||||
|
|
||||||
// Extract Metadata pointer
|
// Extract Metadata pointer
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ namespace Il2CppInspector
|
|||||||
BinaryImage.Position = BinaryImage.MapVATR((ulong) pFieldOffsets);
|
BinaryImage.Position = BinaryImage.MapVATR((ulong) pFieldOffsets);
|
||||||
|
|
||||||
for (var f = 0; f < def.field_count; f++)
|
for (var f = 0; f < def.field_count; f++)
|
||||||
offsets.Add(def.fieldStart + f, BinaryImage.Stream.ReadObject<long>());
|
offsets.Add(def.fieldStart + f, BinaryImage.ReadWord());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ namespace Il2CppInspector.Reflection
|
|||||||
// This probably means it has been optimized away by the compiler, or is an unused generic method
|
// This probably means it has been optimized away by the compiler, or is an unused generic method
|
||||||
try {
|
try {
|
||||||
pkg.BinaryImage.Position = pkg.BinaryImage.MapVATR(Assembly.Module.methodPointers + (ulong) ((method - 1) * (pkg.BinaryImage.Bits / 8)));
|
pkg.BinaryImage.Position = pkg.BinaryImage.MapVATR(Assembly.Module.methodPointers + (ulong) ((method - 1) * (pkg.BinaryImage.Bits / 8)));
|
||||||
VirtualAddress = pkg.BinaryImage.Stream.ReadObject<ulong>();
|
VirtualAddress = (ulong) pkg.BinaryImage.ReadWord();
|
||||||
} catch (Exception) { }
|
} catch (Exception) { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Il2CppInspector.Reflection {
|
namespace Il2CppInspector.Reflection {
|
||||||
public class TypeInfo : MemberInfo
|
public class TypeInfo : MemberInfo
|
||||||
@@ -224,11 +223,11 @@ namespace Il2CppInspector.Reflection {
|
|||||||
var genericInstance = image.ReadMappedObject<Il2CppGenericInst>(generic.context.class_inst);
|
var genericInstance = image.ReadMappedObject<Il2CppGenericInst>(generic.context.class_inst);
|
||||||
|
|
||||||
// Get list of pointers to type parameters (both unresolved and concrete)
|
// Get list of pointers to type parameters (both unresolved and concrete)
|
||||||
var genericTypeParameters = image.ReadMappedArray<ulong>(genericInstance.type_argv, (int)genericInstance.type_argc);
|
var genericTypeParameters = image.ReadMappedWordArray(genericInstance.type_argv, (int)genericInstance.type_argc);
|
||||||
|
|
||||||
GenericTypeParameters = new List<TypeInfo>();
|
GenericTypeParameters = new List<TypeInfo>();
|
||||||
foreach (var pArg in genericTypeParameters) {
|
foreach (var pArg in genericTypeParameters) {
|
||||||
var argType = image.ReadMappedObject<Il2CppType>(pArg);
|
var argType = image.ReadMappedObject<Il2CppType>((ulong) pArg);
|
||||||
// TODO: Detect whether unresolved or concrete (add concrete to GenericTypeArguments instead)
|
// TODO: Detect whether unresolved or concrete (add concrete to GenericTypeArguments instead)
|
||||||
// TODO: GenericParameterPosition etc. in types we generate here
|
// TODO: GenericParameterPosition etc. in types we generate here
|
||||||
GenericTypeParameters.Add(model.GetType(argType)); // TODO: Fix MemberType here
|
GenericTypeParameters.Add(model.GetType(argType)); // TODO: Fix MemberType here
|
||||||
|
|||||||
Reference in New Issue
Block a user