Add progress callbacks to Il2CppBinary and Il2CppInspector
This commit is contained in:
@@ -13,9 +13,10 @@ namespace Il2CppInspector
|
|||||||
{
|
{
|
||||||
internal class Il2CppBinaryARM : Il2CppBinary
|
internal class Il2CppBinaryARM : Il2CppBinary
|
||||||
{
|
{
|
||||||
public Il2CppBinaryARM(IFileFormatReader stream) : base(stream) { }
|
public Il2CppBinaryARM(IFileFormatReader stream, EventHandler<string> statusCallback = null) : base(stream, statusCallback) { }
|
||||||
|
|
||||||
public Il2CppBinaryARM(IFileFormatReader stream, uint codeRegistration, uint metadataRegistration) : base(stream, codeRegistration, metadataRegistration) { }
|
public Il2CppBinaryARM(IFileFormatReader stream, uint codeRegistration, uint metadataRegistration, EventHandler<string> statusCallback = null)
|
||||||
|
: base(stream, codeRegistration, metadataRegistration, statusCallback) { }
|
||||||
|
|
||||||
// ARMv7-A Architecture Reference Manual: https://static.docs.arm.com/ddi0406/c/DDI0406C_C_arm_architecture_reference_manual.pdf
|
// ARMv7-A Architecture Reference Manual: https://static.docs.arm.com/ddi0406/c/DDI0406C_C_arm_architecture_reference_manual.pdf
|
||||||
|
|
||||||
|
|||||||
@@ -12,9 +12,10 @@ namespace Il2CppInspector
|
|||||||
// A64 ISA reference: https://static.docs.arm.com/ddi0596/a/DDI_0596_ARM_a64_instruction_set_architecture.pdf
|
// A64 ISA reference: https://static.docs.arm.com/ddi0596/a/DDI_0596_ARM_a64_instruction_set_architecture.pdf
|
||||||
internal class Il2CppBinaryARM64 : Il2CppBinary
|
internal class Il2CppBinaryARM64 : Il2CppBinary
|
||||||
{
|
{
|
||||||
public Il2CppBinaryARM64(IFileFormatReader stream) : base(stream) { }
|
public Il2CppBinaryARM64(IFileFormatReader stream, EventHandler<string> statusCallback = null) : base(stream, statusCallback) { }
|
||||||
|
|
||||||
public Il2CppBinaryARM64(IFileFormatReader stream, uint codeRegistration, uint metadataRegistration) : base(stream, codeRegistration, metadataRegistration) { }
|
public Il2CppBinaryARM64(IFileFormatReader stream, uint codeRegistration, uint metadataRegistration, EventHandler<string> statusCallback = null)
|
||||||
|
: base(stream, codeRegistration, metadataRegistration, statusCallback) { }
|
||||||
|
|
||||||
private (uint reg, ulong page)? getAdrp(uint inst, ulong pc) {
|
private (uint reg, ulong page)? getAdrp(uint inst, ulong pc) {
|
||||||
if ((inst.Bits(24, 8) & 0b_1000_1111) != 1 << 7)
|
if ((inst.Bits(24, 8) & 0b_1000_1111) != 1 << 7)
|
||||||
|
|||||||
@@ -13,8 +13,10 @@ namespace Il2CppInspector
|
|||||||
{
|
{
|
||||||
internal class Il2CppBinaryX64 : Il2CppBinary
|
internal class Il2CppBinaryX64 : Il2CppBinary
|
||||||
{
|
{
|
||||||
public Il2CppBinaryX64(IFileFormatReader stream) : base(stream) { }
|
public Il2CppBinaryX64(IFileFormatReader stream, EventHandler<string> statusCallback = null) : base(stream, statusCallback) { }
|
||||||
public Il2CppBinaryX64(IFileFormatReader stream, uint codeRegistration, uint metadataRegistration) : base(stream, codeRegistration, metadataRegistration) { }
|
|
||||||
|
public Il2CppBinaryX64(IFileFormatReader stream, uint codeRegistration, uint metadataRegistration, EventHandler<string> statusCallback = null)
|
||||||
|
: base(stream, codeRegistration, metadataRegistration, statusCallback) { }
|
||||||
|
|
||||||
// Format of 64-bit LEA:
|
// Format of 64-bit LEA:
|
||||||
// 0x48/0x4C - REX prefix signifying 64-bit mode with 64-bit operand size (REX prefix bits: Volume 2A, page 2-9) (bit 2 is register bit 3)
|
// 0x48/0x4C - REX prefix signifying 64-bit mode with 64-bit operand size (REX prefix bits: Volume 2A, page 2-9) (bit 2 is register bit 3)
|
||||||
|
|||||||
@@ -11,8 +11,10 @@ namespace Il2CppInspector
|
|||||||
{
|
{
|
||||||
internal class Il2CppBinaryX86 : Il2CppBinary
|
internal class Il2CppBinaryX86 : Il2CppBinary
|
||||||
{
|
{
|
||||||
public Il2CppBinaryX86(IFileFormatReader stream) : base(stream) { }
|
public Il2CppBinaryX86(IFileFormatReader stream, EventHandler<string> statusCallback = null) : base(stream, statusCallback) { }
|
||||||
public Il2CppBinaryX86(IFileFormatReader stream, uint codeRegistration, uint metadataRegistration) : base(stream, codeRegistration, metadataRegistration) { }
|
|
||||||
|
public Il2CppBinaryX86(IFileFormatReader stream, uint codeRegistration, uint metadataRegistration, EventHandler<string> statusCallback = null)
|
||||||
|
: base(stream, codeRegistration, metadataRegistration, statusCallback) { }
|
||||||
|
|
||||||
protected override (ulong, ulong) ConsiderCode(IFileFormatReader image, uint loc) {
|
protected override (ulong, ulong) ConsiderCode(IFileFormatReader image, uint loc) {
|
||||||
ulong metadata, code;
|
ulong metadata, code;
|
||||||
|
|||||||
@@ -80,17 +80,22 @@ namespace Il2CppInspector
|
|||||||
// One assembly may contain multiple modules
|
// One assembly may contain multiple modules
|
||||||
public Dictionary<string, Il2CppCodeGenModule> Modules { get; private set; }
|
public Dictionary<string, Il2CppCodeGenModule> Modules { get; private set; }
|
||||||
|
|
||||||
protected Il2CppBinary(IFileFormatReader stream) {
|
private EventHandler<string> OnStatusUpdate { get; set; }
|
||||||
|
private void StatusUpdate(string status) => OnStatusUpdate?.Invoke(this, status);
|
||||||
|
|
||||||
|
protected Il2CppBinary(IFileFormatReader stream, EventHandler<string> statusCallback = null) {
|
||||||
Image = stream;
|
Image = stream;
|
||||||
|
OnStatusUpdate = statusCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Il2CppBinary(IFileFormatReader stream, uint codeRegistration, uint metadataRegistration) {
|
protected Il2CppBinary(IFileFormatReader stream, uint codeRegistration, uint metadataRegistration, EventHandler<string> statusCallback = null) {
|
||||||
Image = stream;
|
Image = stream;
|
||||||
|
OnStatusUpdate = statusCallback;
|
||||||
Configure(codeRegistration, metadataRegistration);
|
Configure(codeRegistration, metadataRegistration);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load and initialize a binary of any supported architecture
|
// Load and initialize a binary of any supported architecture
|
||||||
private static Il2CppBinary LoadImpl(IFileFormatReader stream) {
|
private static Il2CppBinary LoadImpl(IFileFormatReader stream, EventHandler<string> statusCallback) {
|
||||||
// Get type from image architecture
|
// Get type from image architecture
|
||||||
var type = Assembly.GetExecutingAssembly().GetType("Il2CppInspector.Il2CppBinary" + stream.Arch.ToUpper());
|
var type = Assembly.GetExecutingAssembly().GetType("Il2CppInspector.Il2CppBinary" + stream.Arch.ToUpper());
|
||||||
if (type == null)
|
if (type == null)
|
||||||
@@ -102,12 +107,12 @@ namespace Il2CppInspector
|
|||||||
stream[0].Stream.PrimitiveMappings.Add(typeof(ulong), typeof(uint));
|
stream[0].Stream.PrimitiveMappings.Add(typeof(ulong), typeof(uint));
|
||||||
}
|
}
|
||||||
|
|
||||||
return (Il2CppBinary) Activator.CreateInstance(type, stream[0]);
|
return (Il2CppBinary) Activator.CreateInstance(type, stream[0], statusCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load binary without a global-metadata.dat available
|
// Load binary without a global-metadata.dat available
|
||||||
public static Il2CppBinary Load(IFileFormatReader stream, double metadataVersion) {
|
public static Il2CppBinary Load(IFileFormatReader stream, double metadataVersion, EventHandler<string> statusCallback = null) {
|
||||||
var inst = LoadImpl(stream);
|
var inst = LoadImpl(stream, statusCallback);
|
||||||
return inst.Initialize(metadataVersion) ? inst : null;
|
return inst.Initialize(metadataVersion) ? inst : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,13 +121,13 @@ namespace Il2CppInspector
|
|||||||
// If it is specified and both symbol table and function scanning fail,
|
// If it is specified and both symbol table and function scanning fail,
|
||||||
// Metadata will be used to try to find the required structures with data analysis
|
// Metadata will be used to try to find the required structures with data analysis
|
||||||
// If it is not specified, data analysis will not be performed
|
// If it is not specified, data analysis will not be performed
|
||||||
public static Il2CppBinary Load(IFileFormatReader stream, Metadata metadata) {
|
public static Il2CppBinary Load(IFileFormatReader stream, Metadata metadata, EventHandler<string> statusCallback = null) {
|
||||||
var inst = LoadImpl(stream);
|
var inst = LoadImpl(stream, statusCallback);
|
||||||
return inst.Initialize(metadata) ? inst : null;
|
return inst.Initialize(metadata) ? inst : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize binary without a global-metadata.dat available
|
// Initialize binary without a global-metadata.dat available
|
||||||
public bool Initialize(double metadataVersion) {
|
public bool Initialize(double metadataVersion, EventHandler<string> statusCallback = null) {
|
||||||
Image.Version = metadataVersion;
|
Image.Version = metadataVersion;
|
||||||
|
|
||||||
if (!((FindMetadataFromSymbols() ?? FindMetadataFromCode()) is var ptrs))
|
if (!((FindMetadataFromSymbols() ?? FindMetadataFromCode()) is var ptrs))
|
||||||
@@ -133,7 +138,7 @@ namespace Il2CppInspector
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize binary with a global-metadata.dat available
|
// Initialize binary with a global-metadata.dat available
|
||||||
public bool Initialize(Metadata metadata) {
|
public bool Initialize(Metadata metadata, EventHandler<string> statusCallback = null) {
|
||||||
Image.Version = metadata.Version;
|
Image.Version = metadata.Version;
|
||||||
|
|
||||||
if (!((FindMetadataFromSymbols() ?? FindMetadataFromCode() ?? FindMetadataFromData(metadata)) is var ptrs))
|
if (!((FindMetadataFromSymbols() ?? FindMetadataFromCode() ?? FindMetadataFromData(metadata)) is var ptrs))
|
||||||
|
|||||||
@@ -497,18 +497,18 @@ namespace Il2CppInspector
|
|||||||
var streams = GetStreamsFromPackage(packageFiles, silent);
|
var streams = GetStreamsFromPackage(packageFiles, silent);
|
||||||
if (!streams.HasValue)
|
if (!streams.HasValue)
|
||||||
return null;
|
return null;
|
||||||
return LoadFromStream(streams.Value.Binary, streams.Value.Metadata, silent);
|
return LoadFromStream(streams.Value.Binary, streams.Value.Metadata, silent: silent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load from a binary file and metadata file
|
// Load from a binary file and metadata file
|
||||||
public static List<Il2CppInspector> LoadFromFile(string binaryFile, string metadataFile, bool silent = false)
|
public static List<Il2CppInspector> LoadFromFile(string binaryFile, string metadataFile, bool silent = false)
|
||||||
=> LoadFromStream(new FileStream(binaryFile, FileMode.Open, FileAccess.Read, FileShare.Read),
|
=> LoadFromStream(new FileStream(binaryFile, FileMode.Open, FileAccess.Read, FileShare.Read),
|
||||||
new MemoryStream(File.ReadAllBytes(metadataFile)),
|
new MemoryStream(File.ReadAllBytes(metadataFile)),
|
||||||
silent);
|
silent: silent);
|
||||||
|
|
||||||
// Load from a binary stream and metadata stream
|
// Load from a binary stream and metadata stream
|
||||||
// Must be a seekable stream otherwise we catch a System.IO.NotSupportedException
|
// Must be a seekable stream otherwise we catch a System.IO.NotSupportedException
|
||||||
public static List<Il2CppInspector> LoadFromStream(Stream binaryStream, Stream metadataStream, bool silent = false) {
|
public static List<Il2CppInspector> LoadFromStream(Stream binaryStream, Stream metadataStream, EventHandler<string> statusCallback = null, bool silent = false) {
|
||||||
|
|
||||||
// Silent operation if requested
|
// Silent operation if requested
|
||||||
var stdout = Console.Out;
|
var stdout = Console.Out;
|
||||||
@@ -518,7 +518,7 @@ namespace Il2CppInspector
|
|||||||
// Load the metadata file
|
// Load the metadata file
|
||||||
Metadata metadata;
|
Metadata metadata;
|
||||||
try {
|
try {
|
||||||
metadata = new Metadata(metadataStream);
|
metadata = new Metadata(metadataStream, statusCallback);
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
Console.Error.WriteLine(ex.Message);
|
Console.Error.WriteLine(ex.Message);
|
||||||
@@ -531,7 +531,7 @@ namespace Il2CppInspector
|
|||||||
// Load the il2cpp code file (try all available file formats)
|
// Load the il2cpp code file (try all available file formats)
|
||||||
IFileFormatReader stream;
|
IFileFormatReader stream;
|
||||||
try {
|
try {
|
||||||
stream = FileFormatReader.Load(binaryStream);
|
stream = FileFormatReader.Load(binaryStream, statusCallback);
|
||||||
|
|
||||||
if (stream == null)
|
if (stream == null)
|
||||||
throw new InvalidOperationException("Unsupported executable file format");
|
throw new InvalidOperationException("Unsupported executable file format");
|
||||||
@@ -553,7 +553,7 @@ namespace Il2CppInspector
|
|||||||
|
|
||||||
// Architecture-agnostic load attempt
|
// Architecture-agnostic load attempt
|
||||||
try {
|
try {
|
||||||
if (Il2CppBinary.Load(image, metadata) is Il2CppBinary binary) {
|
if (Il2CppBinary.Load(image, metadata, statusCallback) is Il2CppBinary binary) {
|
||||||
Console.WriteLine("IL2CPP binary version " + image.Version);
|
Console.WriteLine("IL2CPP binary version " + image.Version);
|
||||||
|
|
||||||
processors.Add(new Il2CppInspector(binary, metadata));
|
processors.Add(new Il2CppInspector(binary, metadata));
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ namespace Il2CppInspector
|
|||||||
|
|
||||||
public Dictionary<int, string> Strings { get; } = new Dictionary<int, string>();
|
public Dictionary<int, string> Strings { get; } = new Dictionary<int, string>();
|
||||||
|
|
||||||
public Metadata(Stream stream) : base(stream)
|
public Metadata(Stream stream, EventHandler<string> statusCallback = null) : base(stream)
|
||||||
{
|
{
|
||||||
// Read magic bytes
|
// Read magic bytes
|
||||||
if (ReadUInt32() != 0xFAB11BAF) {
|
if (ReadUInt32() != 0xFAB11BAF) {
|
||||||
@@ -170,6 +170,9 @@ namespace Il2CppInspector
|
|||||||
// Only do this if we need to because it's very slow
|
// Only do this if we need to because it's very slow
|
||||||
if (stringOffsets.Except(Strings.Keys).Any()) {
|
if (stringOffsets.Except(Strings.Keys).Any()) {
|
||||||
|
|
||||||
|
Console.WriteLine("Decrypting strings...");
|
||||||
|
statusCallback?.Invoke(this, "Decrypting strings");
|
||||||
|
|
||||||
// Start again
|
// Start again
|
||||||
Strings.Clear();
|
Strings.Clear();
|
||||||
Position = Header.stringOffset;
|
Position = Header.stringOffset;
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ namespace Il2CppInspectorGUI
|
|||||||
try {
|
try {
|
||||||
OnStatusUpdate?.Invoke(this, "Processing metadata");
|
OnStatusUpdate?.Invoke(this, "Processing metadata");
|
||||||
|
|
||||||
metadata = new Metadata(metadataStream);
|
metadata = new Metadata(metadataStream, StatusUpdate);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
@@ -95,7 +95,7 @@ namespace Il2CppInspectorGUI
|
|||||||
// Architecture-agnostic load attempt
|
// Architecture-agnostic load attempt
|
||||||
try {
|
try {
|
||||||
// If we can't load the IL2CPP data here, it's probably packed or obfuscated; ignore it
|
// If we can't load the IL2CPP data here, it's probably packed or obfuscated; ignore it
|
||||||
if (Il2CppBinary.Load(image, metadata) is Il2CppBinary binary) {
|
if (Il2CppBinary.Load(image, metadata, StatusUpdate) is Il2CppBinary binary) {
|
||||||
var inspector = new Inspector(binary, metadata);
|
var inspector = new Inspector(binary, metadata);
|
||||||
|
|
||||||
// Build type model
|
// Build type model
|
||||||
|
|||||||
Reference in New Issue
Block a user