Additional refactoring
This commit is contained in:
@@ -8,9 +8,9 @@ namespace Il2CppInspector
|
|||||||
{
|
{
|
||||||
public class Il2CppDumper
|
public class Il2CppDumper
|
||||||
{
|
{
|
||||||
private readonly Il2CppProcessor il2cpp;
|
private readonly Il2CppInspector il2cpp;
|
||||||
|
|
||||||
public Il2CppDumper(Il2CppProcessor proc) {
|
public Il2CppDumper(Il2CppInspector proc) {
|
||||||
il2cpp = proc;
|
il2cpp = proc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,7 +100,7 @@ namespace Il2CppInspector
|
|||||||
}
|
}
|
||||||
if (methodDef.methodIndex >= 0)
|
if (methodDef.methodIndex >= 0)
|
||||||
writer.Write("); // {0:x} - {1}\n",
|
writer.Write("); // {0:x} - {1}\n",
|
||||||
il2cpp.Code.PtrCodeRegistration.methodPointers[methodDef.methodIndex],
|
il2cpp.Binary.MethodPointers[methodDef.methodIndex],
|
||||||
methodDef.methodIndex);
|
methodDef.methodIndex);
|
||||||
else
|
else
|
||||||
writer.Write("); // 0 - -1\n");
|
writer.Write("); // 0 - -1\n");
|
||||||
|
|||||||
@@ -40,13 +40,13 @@ namespace Il2CppInspector
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Analyze data
|
// Analyze data
|
||||||
var il2cppProcessors = Il2CppProcessor.LoadFromFile(imageFile, metaFile);
|
var il2cppInspectors = Il2CppInspector.LoadFromFile(imageFile, metaFile);
|
||||||
if (il2cppProcessors == null)
|
if (il2cppInspectors == null)
|
||||||
Environment.Exit(1);
|
Environment.Exit(1);
|
||||||
|
|
||||||
// Write output file
|
// Write output file
|
||||||
int i = 0;
|
int i = 0;
|
||||||
foreach (var il2cpp in il2cppProcessors)
|
foreach (var il2cpp in il2cppInspectors)
|
||||||
new Il2CppDumper(il2cpp).WriteFile(outFile + (i++ > 0 ? "-" + (i-1) : ""));
|
new Il2CppDumper(il2cpp).WriteFile(outFile + (i++ > 0 ? "-" + (i-1) : ""));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,11 +21,11 @@ namespace Il2CppInspector
|
|||||||
long Position { get; set; }
|
long Position { get; set; }
|
||||||
string Arch { get; }
|
string Arch { get; }
|
||||||
uint GlobalOffset { get; }
|
uint GlobalOffset { get; }
|
||||||
uint[] GetSearchLocations();
|
uint[] GetFunctionTable();
|
||||||
U ReadMappedObject<U>(uint uiAddr) where U : new();
|
U ReadMappedObject<U>(uint uiAddr) where U : new();
|
||||||
U[] ReadMappedArray<U>(uint uiAddr, int count) where U : new();
|
U[] ReadMappedArray<U>(uint uiAddr, int count) where U : new();
|
||||||
uint MapVATR(uint uiAddr);
|
uint MapVATR(uint uiAddr);
|
||||||
void FinalizeInit(Il2CppReader il2cpp);
|
void FinalizeInit(Il2CppBinary il2cpp);
|
||||||
|
|
||||||
byte[] ReadBytes(int count);
|
byte[] ReadBytes(int count);
|
||||||
ulong ReadUInt64();
|
ulong ReadUInt64();
|
||||||
@@ -77,7 +77,7 @@ namespace Il2CppInspector
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Find search locations in the machine code for Il2Cpp data
|
// Find search locations in the machine code for Il2Cpp data
|
||||||
public virtual uint[] GetSearchLocations() => 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
|
||||||
@@ -93,6 +93,6 @@ namespace Il2CppInspector
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Perform file format-based post-load manipulations to the IL2Cpp data
|
// Perform file format-based post-load manipulations to the IL2Cpp data
|
||||||
public virtual void FinalizeInit(Il2CppReader il2cpp) { }
|
public virtual void FinalizeInit(Il2CppBinary il2cpp) { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -47,7 +47,7 @@ namespace Il2CppInspector
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override uint[] GetSearchLocations() {
|
public override uint[] GetFunctionTable() {
|
||||||
// Find dynamic section
|
// Find dynamic section
|
||||||
var dynamic = new elf_32_shdr();
|
var dynamic = new elf_32_shdr();
|
||||||
var PT_DYNAMIC = program_table_element.First(x => x.p_type == 2u);
|
var PT_DYNAMIC = program_table_element.First(x => x.p_type == 2u);
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ namespace Il2CppInspector
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override uint[] GetSearchLocations() {
|
public override uint[] GetFunctionTable() {
|
||||||
Position = pFuncTable;
|
Position = pFuncTable;
|
||||||
var functionPointers = new List<uint>();
|
var functionPointers = new List<uint>();
|
||||||
|
|
||||||
@@ -139,10 +139,9 @@ namespace Il2CppInspector
|
|||||||
return functionPointers.ToArray();
|
return functionPointers.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void FinalizeInit(Il2CppReader il2cpp) {
|
public override void FinalizeInit(Il2CppBinary il2cpp) {
|
||||||
// Mach-O function pointers have an annoying habit of being 1-off
|
// Mach-O function pointers have an annoying habit of being 1-off
|
||||||
il2cpp.PtrCodeRegistration.methodPointers =
|
il2cpp.MethodPointers = il2cpp.MethodPointers.Select(x => x - 1).ToArray();
|
||||||
il2cpp.PtrCodeRegistration.methodPointers.Select(x => x - 1).ToArray();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override uint MapVATR(uint uiAddr) {
|
public override uint MapVATR(uint uiAddr) {
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ namespace Il2CppInspector
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override uint[] GetSearchLocations() {
|
public override uint[] GetFunctionTable() {
|
||||||
Position = pFuncTable;
|
Position = pFuncTable;
|
||||||
var addrs = new List<uint>();
|
var addrs = new List<uint>();
|
||||||
uint addr;
|
uint addr;
|
||||||
|
|||||||
62
Il2CppInspector/Il2CppBinary.cs
Normal file
62
Il2CppInspector/Il2CppBinary.cs
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2017 Perfare - https://github.com/Perfare/Il2CppDumper
|
||||||
|
Copyright 2017 Katy Coe - http://www.hearthcode.org - http://www.djkaty.com
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Il2CppInspector
|
||||||
|
{
|
||||||
|
public abstract class Il2CppBinary
|
||||||
|
{
|
||||||
|
public IFileFormatReader Image { get; }
|
||||||
|
|
||||||
|
public Il2CppCodeRegistration CodeRegistration { get; protected set; }
|
||||||
|
public Il2CppMetadataRegistration MetadataRegistration { get; protected set; }
|
||||||
|
|
||||||
|
public uint[] MethodPointers { get; set; }
|
||||||
|
public int[] FieldOffsets { get; private set; }
|
||||||
|
public List<Il2CppType> Types { get; } = new List<Il2CppType>();
|
||||||
|
|
||||||
|
protected Il2CppBinary(IFileFormatReader stream) {
|
||||||
|
Image = stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Il2CppBinary(IFileFormatReader stream, uint codeRegistration, uint metadataRegistration) {
|
||||||
|
Image = stream;
|
||||||
|
Configure(Image, codeRegistration, metadataRegistration);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Architecture-specific search function
|
||||||
|
protected abstract (uint, uint) ConsiderCode(uint loc, uint globalOffset);
|
||||||
|
|
||||||
|
// Check all search locations
|
||||||
|
public bool Initialize(int version, uint imageIndex = 0) {
|
||||||
|
var subImage = Image[imageIndex];
|
||||||
|
Image.Stream.Version = version;
|
||||||
|
var addrs = subImage.GetFunctionTable();
|
||||||
|
foreach (var loc in addrs)
|
||||||
|
if (loc != 0) {
|
||||||
|
var (code, metadata) = ConsiderCode(loc, Image.GlobalOffset);
|
||||||
|
if (code != 0) {
|
||||||
|
Configure(subImage, code, metadata);
|
||||||
|
subImage.FinalizeInit(this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Configure(IFileFormatReader image, uint codeRegistration, uint metadataRegistration) {
|
||||||
|
CodeRegistration = image.ReadMappedObject<Il2CppCodeRegistration>(codeRegistration);
|
||||||
|
MetadataRegistration = image.ReadMappedObject<Il2CppMetadataRegistration>(metadataRegistration);
|
||||||
|
MethodPointers = image.ReadMappedArray<uint>(CodeRegistration.pmethodPointers, (int) CodeRegistration.methodPointersCount);
|
||||||
|
FieldOffsets = image.ReadMappedArray<int>(MetadataRegistration.pfieldOffsets, MetadataRegistration.fieldOffsetsCount);
|
||||||
|
var types = image.ReadMappedArray<uint>(MetadataRegistration.ptypes, MetadataRegistration.typesCount);
|
||||||
|
for (int i = 0; i < MetadataRegistration.typesCount; i++)
|
||||||
|
Types.Add(image.ReadMappedObject<Il2CppType>(types[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,13 +9,13 @@ using System.Linq;
|
|||||||
|
|
||||||
namespace Il2CppInspector
|
namespace Il2CppInspector
|
||||||
{
|
{
|
||||||
internal class Il2CppReaderARM : Il2CppReader
|
internal class Il2CppBinaryARM : Il2CppBinary
|
||||||
{
|
{
|
||||||
public Il2CppReaderARM(IFileFormatReader stream) : base(stream) { }
|
public Il2CppBinaryARM(IFileFormatReader stream) : base(stream) { }
|
||||||
|
|
||||||
public Il2CppReaderARM(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) Search(uint loc, uint globalOffset) {
|
protected override (uint, uint) ConsiderCode(uint loc, uint globalOffset) {
|
||||||
// Assembly bytes to search for at start of each function
|
// Assembly bytes to search for at start of each function
|
||||||
uint metadataRegistration, codeRegistration;
|
uint metadataRegistration, codeRegistration;
|
||||||
|
|
||||||
@@ -49,12 +49,6 @@ namespace Il2CppInspector
|
|||||||
public uint interopDataCount;
|
public uint interopDataCount;
|
||||||
[Version(Min = 23)]
|
[Version(Min = 23)]
|
||||||
public uint interopData;
|
public uint interopData;
|
||||||
|
|
||||||
// Properties
|
|
||||||
public uint[] methodPointers
|
|
||||||
{
|
|
||||||
get; set;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma warning disable CS0649
|
#pragma warning disable CS0649
|
||||||
@@ -78,16 +72,6 @@ namespace Il2CppInspector
|
|||||||
public uint typeDefinitionsSizes;
|
public uint typeDefinitionsSizes;
|
||||||
public uint metadataUsagesCount;
|
public uint metadataUsagesCount;
|
||||||
public uint metadataUsages;
|
public uint metadataUsages;
|
||||||
|
|
||||||
public int[] fieldOffsets
|
|
||||||
{
|
|
||||||
get; set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Il2CppType[] types
|
|
||||||
{
|
|
||||||
get; set;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#pragma warning restore CS0649
|
#pragma warning restore CS0649
|
||||||
|
|
||||||
@@ -136,68 +120,13 @@ namespace Il2CppInspector
|
|||||||
public class Il2CppType
|
public class Il2CppType
|
||||||
{
|
{
|
||||||
public uint datapoint;
|
public uint datapoint;
|
||||||
public Anonymous data { get; set; }
|
|
||||||
public uint bits;
|
public uint bits;
|
||||||
public uint attrs { get; set; }
|
|
||||||
public Il2CppTypeEnum type { get; set; }
|
|
||||||
public uint num_mods { get; set; }
|
|
||||||
public uint byref { get; set; }
|
|
||||||
public uint pinned { get; set; }
|
|
||||||
|
|
||||||
public void Init()
|
public uint attrs => bits & 0xffff;
|
||||||
{
|
public Il2CppTypeEnum type => (Il2CppTypeEnum)((bits >> 16) & 0xff);
|
||||||
var str = Convert.ToString(bits, 2);
|
public uint num_mods => (bits >> 24) & 0x3f;
|
||||||
if (str.Length != 32)
|
public bool byref => ((bits >> 30) & 1) == 1;
|
||||||
{
|
public bool pinned => (bits >> 31) == 1;
|
||||||
str = new string(Enumerable.Repeat('0', 32 - str.Length).Concat(str.ToCharArray()).ToArray());
|
|
||||||
}
|
|
||||||
attrs = Convert.ToUInt32(str.Substring(16, 16), 2);
|
|
||||||
type = (Il2CppTypeEnum)Convert.ToInt32(str.Substring(8, 8), 2);
|
|
||||||
num_mods = Convert.ToUInt32(str.Substring(2, 6), 2);
|
|
||||||
byref = Convert.ToUInt32(str.Substring(1, 1), 2);
|
|
||||||
pinned = Convert.ToUInt32(str.Substring(0, 1), 2);
|
|
||||||
data = new Anonymous() { dummy = datapoint };
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Anonymous
|
|
||||||
{
|
|
||||||
public uint dummy;
|
|
||||||
public int klassIndex
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return (int)dummy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public uint type
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return dummy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public uint array
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return dummy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public int genericParameterIndex
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return (int)dummy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public uint generic_class
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return dummy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Il2CppGenericClass
|
public class Il2CppGenericClass
|
||||||
@@ -8,11 +8,11 @@ using System.Linq;
|
|||||||
|
|
||||||
namespace Il2CppInspector
|
namespace Il2CppInspector
|
||||||
{
|
{
|
||||||
internal class Il2CppReaderX86 : Il2CppReader
|
internal class Il2CppBinaryX86 : Il2CppBinary
|
||||||
{
|
{
|
||||||
public Il2CppReaderX86(IFileFormatReader stream) : base(stream) { }
|
public Il2CppBinaryX86(IFileFormatReader stream) : base(stream) { }
|
||||||
public Il2CppReaderX86(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) Search(uint loc, uint globalOffset) {
|
protected override (uint, uint) ConsiderCode(uint loc, uint globalOffset) {
|
||||||
uint funcPtr, metadata, code;
|
uint funcPtr, metadata, code;
|
||||||
ushort opcode;
|
ushort opcode;
|
||||||
|
|
||||||
@@ -12,17 +12,17 @@ using System.Text;
|
|||||||
|
|
||||||
namespace Il2CppInspector
|
namespace Il2CppInspector
|
||||||
{
|
{
|
||||||
public class Il2CppProcessor
|
public class Il2CppInspector
|
||||||
{
|
{
|
||||||
public Il2CppReader Code { get; }
|
public Il2CppBinary Binary { get; }
|
||||||
public Metadata Metadata { get; }
|
public Metadata Metadata { get; }
|
||||||
|
|
||||||
public Il2CppProcessor(Il2CppReader code, Metadata metadata) {
|
public Il2CppInspector(Il2CppBinary binary, Metadata metadata) {
|
||||||
Code = code;
|
Binary = binary;
|
||||||
Metadata = metadata;
|
Metadata = metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Il2CppProcessor> LoadFromFile(string codeFile, string metadataFile) {
|
public static List<Il2CppInspector> LoadFromFile(string codeFile, string metadataFile) {
|
||||||
// Load the metadata file
|
// Load the metadata file
|
||||||
Metadata metadata;
|
Metadata metadata;
|
||||||
try {
|
try {
|
||||||
@@ -33,7 +33,7 @@ namespace Il2CppInspector
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the il2cpp code file (try ELF and PE)
|
// Load the il2cpp code file (try ELF, PE, Mach-O and Universal Binary)
|
||||||
var memoryStream = new MemoryStream(File.ReadAllBytes(codeFile));
|
var memoryStream = new MemoryStream(File.ReadAllBytes(codeFile));
|
||||||
IFileFormatReader stream =
|
IFileFormatReader stream =
|
||||||
(((IFileFormatReader) ElfReader.Load(memoryStream) ??
|
(((IFileFormatReader) ElfReader.Load(memoryStream) ??
|
||||||
@@ -45,17 +45,18 @@ namespace Il2CppInspector
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var processors = new List<Il2CppProcessor>();
|
// Multi-image binaries may contain more than one Il2Cpp image
|
||||||
|
var processors = new List<Il2CppInspector>();
|
||||||
foreach (var image in stream.Images) {
|
foreach (var image in stream.Images) {
|
||||||
Il2CppReader il2cpp;
|
Il2CppBinary binary;
|
||||||
|
|
||||||
// We are currently supporting x86 and ARM architectures
|
// We are currently supporting x86 and ARM architectures
|
||||||
switch (image.Arch) {
|
switch (image.Arch) {
|
||||||
case "x86":
|
case "x86":
|
||||||
il2cpp = new Il2CppReaderX86(image);
|
binary = new Il2CppBinaryX86(image);
|
||||||
break;
|
break;
|
||||||
case "ARM":
|
case "ARM":
|
||||||
il2cpp = new Il2CppReaderARM(image);
|
binary = new Il2CppBinaryARM(image);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Console.Error.WriteLine("Unsupported architecture");
|
Console.Error.WriteLine("Unsupported architecture");
|
||||||
@@ -63,11 +64,11 @@ namespace Il2CppInspector
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Find code and metadata regions
|
// Find code and metadata regions
|
||||||
if (!il2cpp.Load(metadata.Version)) {
|
if (!binary.Initialize(metadata.Version)) {
|
||||||
Console.Error.WriteLine("Could not process IL2CPP image");
|
Console.Error.WriteLine("Could not process IL2CPP image");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
processors.Add(new Il2CppProcessor(il2cpp, metadata));
|
processors.Add(new Il2CppInspector(binary, metadata));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return processors;
|
return processors;
|
||||||
@@ -76,32 +77,29 @@ namespace Il2CppInspector
|
|||||||
public string GetTypeName(Il2CppType pType) {
|
public string GetTypeName(Il2CppType pType) {
|
||||||
string ret;
|
string ret;
|
||||||
if (pType.type == Il2CppTypeEnum.IL2CPP_TYPE_CLASS || pType.type == Il2CppTypeEnum.IL2CPP_TYPE_VALUETYPE) {
|
if (pType.type == Il2CppTypeEnum.IL2CPP_TYPE_CLASS || pType.type == Il2CppTypeEnum.IL2CPP_TYPE_VALUETYPE) {
|
||||||
Il2CppTypeDefinition klass = Metadata.Types[pType.data.klassIndex];
|
Il2CppTypeDefinition klass = Metadata.Types[pType.datapoint];
|
||||||
ret = Metadata.Strings[klass.nameIndex];
|
ret = Metadata.Strings[klass.nameIndex];
|
||||||
}
|
}
|
||||||
else if (pType.type == Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST) {
|
else if (pType.type == Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST) {
|
||||||
Il2CppGenericClass generic_class = Code.Image.ReadMappedObject<Il2CppGenericClass>(pType.data.generic_class);
|
Il2CppGenericClass generic_class = Binary.Image.ReadMappedObject<Il2CppGenericClass>(pType.datapoint);
|
||||||
Il2CppTypeDefinition pMainDef = Metadata.Types[generic_class.typeDefinitionIndex];
|
Il2CppTypeDefinition pMainDef = Metadata.Types[generic_class.typeDefinitionIndex];
|
||||||
ret = Metadata.Strings[pMainDef.nameIndex];
|
ret = Metadata.Strings[pMainDef.nameIndex];
|
||||||
var typeNames = new List<string>();
|
var typeNames = new List<string>();
|
||||||
Il2CppGenericInst pInst = Code.Image.ReadMappedObject<Il2CppGenericInst>(generic_class.context.class_inst);
|
Il2CppGenericInst pInst = Binary.Image.ReadMappedObject<Il2CppGenericInst>(generic_class.context.class_inst);
|
||||||
var pointers = Code.Image.ReadMappedArray<uint>(pInst.type_argv, (int)pInst.type_argc);
|
var pointers = Binary.Image.ReadMappedArray<uint>(pInst.type_argv, (int)pInst.type_argc);
|
||||||
for (int i = 0; i < pInst.type_argc; ++i) {
|
for (int i = 0; i < pInst.type_argc; ++i) {
|
||||||
var pOriType = Code.Image.ReadMappedObject<Il2CppType>(pointers[i]);
|
var pOriType = Binary.Image.ReadMappedObject<Il2CppType>(pointers[i]);
|
||||||
pOriType.Init();
|
|
||||||
typeNames.Add(GetTypeName(pOriType));
|
typeNames.Add(GetTypeName(pOriType));
|
||||||
}
|
}
|
||||||
ret += $"<{string.Join(", ", typeNames)}>";
|
ret += $"<{string.Join(", ", typeNames)}>";
|
||||||
}
|
}
|
||||||
else if (pType.type == Il2CppTypeEnum.IL2CPP_TYPE_ARRAY) {
|
else if (pType.type == Il2CppTypeEnum.IL2CPP_TYPE_ARRAY) {
|
||||||
Il2CppArrayType arrayType = Code.Image.ReadMappedObject<Il2CppArrayType>(pType.data.array);
|
Il2CppArrayType arrayType = Binary.Image.ReadMappedObject<Il2CppArrayType>(pType.datapoint);
|
||||||
var type = Code.Image.ReadMappedObject<Il2CppType>(arrayType.etype);
|
var type = Binary.Image.ReadMappedObject<Il2CppType>(arrayType.etype);
|
||||||
type.Init();
|
|
||||||
ret = $"{GetTypeName(type)}[]";
|
ret = $"{GetTypeName(type)}[]";
|
||||||
}
|
}
|
||||||
else if (pType.type == Il2CppTypeEnum.IL2CPP_TYPE_SZARRAY) {
|
else if (pType.type == Il2CppTypeEnum.IL2CPP_TYPE_SZARRAY) {
|
||||||
var type = Code.Image.ReadMappedObject<Il2CppType>(pType.data.type);
|
var type = Binary.Image.ReadMappedObject<Il2CppType>(pType.datapoint);
|
||||||
type.Init();
|
|
||||||
ret = $"{GetTypeName(type)}[]";
|
ret = $"{GetTypeName(type)}[]";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -114,7 +112,7 @@ namespace Il2CppInspector
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Il2CppType GetTypeFromTypeIndex(int idx) {
|
public Il2CppType GetTypeFromTypeIndex(int idx) {
|
||||||
return Code.PtrMetadataRegistration.types[idx];
|
return Binary.Types[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetFieldOffsetFromIndex(int typeIndex, int fieldIndexInType) {
|
public int GetFieldOffsetFromIndex(int typeIndex, int fieldIndexInType) {
|
||||||
@@ -123,19 +121,19 @@ namespace Il2CppInspector
|
|||||||
|
|
||||||
// Some variants of 21 also use an array of pointers
|
// Some variants of 21 also use an array of pointers
|
||||||
if (Metadata.Version == 21) {
|
if (Metadata.Version == 21) {
|
||||||
var f = Code.PtrMetadataRegistration.fieldOffsets;
|
var f = Binary.FieldOffsets;
|
||||||
fieldOffsetsArePointers = (f[0] == 0 && f[1] == 0 && f[2] == 0 && f[3] == 0 && f[4] == 0 && f[5] > 0);
|
fieldOffsetsArePointers = (f[0] == 0 && f[1] == 0 && f[2] == 0 && f[3] == 0 && f[4] == 0 && f[5] > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// All older versions use values directly in the array
|
// All older versions use values directly in the array
|
||||||
if (!fieldOffsetsArePointers) {
|
if (!fieldOffsetsArePointers) {
|
||||||
var typeDef = Metadata.Types[typeIndex];
|
var typeDef = Metadata.Types[typeIndex];
|
||||||
return Code.PtrMetadataRegistration.fieldOffsets[typeDef.fieldStart + fieldIndexInType];
|
return Binary.FieldOffsets[typeDef.fieldStart + fieldIndexInType];
|
||||||
}
|
}
|
||||||
|
|
||||||
var ptr = Code.PtrMetadataRegistration.fieldOffsets[typeIndex];
|
var ptr = Binary.FieldOffsets[typeIndex];
|
||||||
Code.Image.Stream.Position = Code.Image.MapVATR((uint)ptr) + 4 * fieldIndexInType;
|
Binary.Image.Stream.Position = Binary.Image.MapVATR((uint)ptr) + 4 * fieldIndexInType;
|
||||||
return Code.Image.Stream.ReadInt32();
|
return Binary.Image.Stream.ReadInt32();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2017 Perfare - https://github.com/Perfare/Il2CppDumper
|
|
||||||
Copyright 2017 Katy Coe - http://www.hearthcode.org - http://www.djkaty.com
|
|
||||||
|
|
||||||
All rights reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Il2CppInspector
|
|
||||||
{
|
|
||||||
public abstract class Il2CppReader
|
|
||||||
{
|
|
||||||
public IFileFormatReader Image { get; }
|
|
||||||
|
|
||||||
protected Il2CppReader(IFileFormatReader stream) {
|
|
||||||
Image = stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Il2CppReader(IFileFormatReader stream, uint codeRegistration, uint metadataRegistration) {
|
|
||||||
Image = stream;
|
|
||||||
Configure(Image, codeRegistration, metadataRegistration);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Il2CppCodeRegistration PtrCodeRegistration { get; protected set; }
|
|
||||||
public Il2CppMetadataRegistration PtrMetadataRegistration { get; protected set; }
|
|
||||||
|
|
||||||
// Architecture-specific search function
|
|
||||||
protected abstract (uint, uint) Search(uint loc, uint globalOffset);
|
|
||||||
|
|
||||||
// Check all search locations
|
|
||||||
public bool Load(int version, uint imageIndex = 0) {
|
|
||||||
var subImage = Image[imageIndex];
|
|
||||||
Image.Stream.Version = version;
|
|
||||||
var addrs = subImage.GetSearchLocations();
|
|
||||||
foreach (var loc in addrs)
|
|
||||||
if (loc != 0) {
|
|
||||||
var (code, metadata) = Search(loc, Image.GlobalOffset);
|
|
||||||
if (code != 0) {
|
|
||||||
Configure(subImage, code, metadata);
|
|
||||||
subImage.FinalizeInit(this);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Configure(IFileFormatReader image, uint codeRegistration, uint metadataRegistration) {
|
|
||||||
PtrCodeRegistration = image.ReadMappedObject<Il2CppCodeRegistration>(codeRegistration);
|
|
||||||
PtrMetadataRegistration = image.ReadMappedObject<Il2CppMetadataRegistration>(metadataRegistration);
|
|
||||||
PtrCodeRegistration.methodPointers = image.ReadMappedArray<uint>(PtrCodeRegistration.pmethodPointers,
|
|
||||||
(int) PtrCodeRegistration.methodPointersCount);
|
|
||||||
PtrMetadataRegistration.fieldOffsets = image.ReadMappedArray<int>(PtrMetadataRegistration.pfieldOffsets,
|
|
||||||
PtrMetadataRegistration.fieldOffsetsCount);
|
|
||||||
var types = image.ReadMappedArray<uint>(PtrMetadataRegistration.ptypes, PtrMetadataRegistration.typesCount);
|
|
||||||
PtrMetadataRegistration.types = new Il2CppType[PtrMetadataRegistration.typesCount];
|
|
||||||
for (int i = 0; i < PtrMetadataRegistration.typesCount; ++i) {
|
|
||||||
PtrMetadataRegistration.types[i] = image.ReadMappedObject<Il2CppType>(types[i]);
|
|
||||||
PtrMetadataRegistration.types[i].Init();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user