Add progress callbacks to Il2CppBinary and Il2CppInspector
This commit is contained in:
@@ -13,9 +13,10 @@ namespace Il2CppInspector
|
||||
{
|
||||
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
|
||||
|
||||
|
||||
@@ -12,9 +12,10 @@ namespace Il2CppInspector
|
||||
// A64 ISA reference: https://static.docs.arm.com/ddi0596/a/DDI_0596_ARM_a64_instruction_set_architecture.pdf
|
||||
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) {
|
||||
if ((inst.Bits(24, 8) & 0b_1000_1111) != 1 << 7)
|
||||
|
||||
@@ -13,8 +13,10 @@ namespace Il2CppInspector
|
||||
{
|
||||
internal class Il2CppBinaryX64 : Il2CppBinary
|
||||
{
|
||||
public Il2CppBinaryX64(IFileFormatReader stream) : base(stream) { }
|
||||
public Il2CppBinaryX64(IFileFormatReader stream, uint codeRegistration, uint metadataRegistration) : base(stream, codeRegistration, metadataRegistration) { }
|
||||
public Il2CppBinaryX64(IFileFormatReader stream, EventHandler<string> statusCallback = null) : base(stream, statusCallback) { }
|
||||
|
||||
public Il2CppBinaryX64(IFileFormatReader stream, uint codeRegistration, uint metadataRegistration, EventHandler<string> statusCallback = null)
|
||||
: base(stream, codeRegistration, metadataRegistration, statusCallback) { }
|
||||
|
||||
// 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)
|
||||
|
||||
@@ -11,8 +11,10 @@ namespace Il2CppInspector
|
||||
{
|
||||
internal class Il2CppBinaryX86 : Il2CppBinary
|
||||
{
|
||||
public Il2CppBinaryX86(IFileFormatReader stream) : base(stream) { }
|
||||
public Il2CppBinaryX86(IFileFormatReader stream, uint codeRegistration, uint metadataRegistration) : base(stream, codeRegistration, metadataRegistration) { }
|
||||
public Il2CppBinaryX86(IFileFormatReader stream, EventHandler<string> statusCallback = null) : base(stream, statusCallback) { }
|
||||
|
||||
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) {
|
||||
ulong metadata, code;
|
||||
|
||||
@@ -80,17 +80,22 @@ namespace Il2CppInspector
|
||||
// One assembly may contain multiple modules
|
||||
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;
|
||||
OnStatusUpdate = statusCallback;
|
||||
}
|
||||
|
||||
protected Il2CppBinary(IFileFormatReader stream, uint codeRegistration, uint metadataRegistration) {
|
||||
protected Il2CppBinary(IFileFormatReader stream, uint codeRegistration, uint metadataRegistration, EventHandler<string> statusCallback = null) {
|
||||
Image = stream;
|
||||
OnStatusUpdate = statusCallback;
|
||||
Configure(codeRegistration, metadataRegistration);
|
||||
}
|
||||
|
||||
// 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
|
||||
var type = Assembly.GetExecutingAssembly().GetType("Il2CppInspector.Il2CppBinary" + stream.Arch.ToUpper());
|
||||
if (type == null)
|
||||
@@ -102,12 +107,12 @@ namespace Il2CppInspector
|
||||
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
|
||||
public static Il2CppBinary Load(IFileFormatReader stream, double metadataVersion) {
|
||||
var inst = LoadImpl(stream);
|
||||
public static Il2CppBinary Load(IFileFormatReader stream, double metadataVersion, EventHandler<string> statusCallback = null) {
|
||||
var inst = LoadImpl(stream, statusCallback);
|
||||
return inst.Initialize(metadataVersion) ? inst : null;
|
||||
}
|
||||
|
||||
@@ -116,13 +121,13 @@ namespace Il2CppInspector
|
||||
// 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
|
||||
// If it is not specified, data analysis will not be performed
|
||||
public static Il2CppBinary Load(IFileFormatReader stream, Metadata metadata) {
|
||||
var inst = LoadImpl(stream);
|
||||
public static Il2CppBinary Load(IFileFormatReader stream, Metadata metadata, EventHandler<string> statusCallback = null) {
|
||||
var inst = LoadImpl(stream, statusCallback);
|
||||
return inst.Initialize(metadata) ? inst : null;
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
if (!((FindMetadataFromSymbols() ?? FindMetadataFromCode()) is var ptrs))
|
||||
@@ -133,7 +138,7 @@ namespace Il2CppInspector
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
if (!((FindMetadataFromSymbols() ?? FindMetadataFromCode() ?? FindMetadataFromData(metadata)) is var ptrs))
|
||||
|
||||
@@ -497,18 +497,18 @@ namespace Il2CppInspector
|
||||
var streams = GetStreamsFromPackage(packageFiles, silent);
|
||||
if (!streams.HasValue)
|
||||
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
|
||||
public static List<Il2CppInspector> LoadFromFile(string binaryFile, string metadataFile, bool silent = false)
|
||||
=> LoadFromStream(new FileStream(binaryFile, FileMode.Open, FileAccess.Read, FileShare.Read),
|
||||
new MemoryStream(File.ReadAllBytes(metadataFile)),
|
||||
silent);
|
||||
silent: silent);
|
||||
|
||||
// Load from a binary stream and metadata stream
|
||||
// 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
|
||||
var stdout = Console.Out;
|
||||
@@ -518,7 +518,7 @@ namespace Il2CppInspector
|
||||
// Load the metadata file
|
||||
Metadata metadata;
|
||||
try {
|
||||
metadata = new Metadata(metadataStream);
|
||||
metadata = new Metadata(metadataStream, statusCallback);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
Console.Error.WriteLine(ex.Message);
|
||||
@@ -531,7 +531,7 @@ namespace Il2CppInspector
|
||||
// Load the il2cpp code file (try all available file formats)
|
||||
IFileFormatReader stream;
|
||||
try {
|
||||
stream = FileFormatReader.Load(binaryStream);
|
||||
stream = FileFormatReader.Load(binaryStream, statusCallback);
|
||||
|
||||
if (stream == null)
|
||||
throw new InvalidOperationException("Unsupported executable file format");
|
||||
@@ -553,7 +553,7 @@ namespace Il2CppInspector
|
||||
|
||||
// Architecture-agnostic load attempt
|
||||
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);
|
||||
|
||||
processors.Add(new Il2CppInspector(binary, metadata));
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace Il2CppInspector
|
||||
|
||||
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
|
||||
if (ReadUInt32() != 0xFAB11BAF) {
|
||||
@@ -170,6 +170,9 @@ namespace Il2CppInspector
|
||||
// Only do this if we need to because it's very slow
|
||||
if (stringOffsets.Except(Strings.Keys).Any()) {
|
||||
|
||||
Console.WriteLine("Decrypting strings...");
|
||||
statusCallback?.Invoke(this, "Decrypting strings");
|
||||
|
||||
// Start again
|
||||
Strings.Clear();
|
||||
Position = Header.stringOffset;
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace Il2CppInspectorGUI
|
||||
try {
|
||||
OnStatusUpdate?.Invoke(this, "Processing metadata");
|
||||
|
||||
metadata = new Metadata(metadataStream);
|
||||
metadata = new Metadata(metadataStream, StatusUpdate);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
@@ -95,7 +95,7 @@ namespace Il2CppInspectorGUI
|
||||
// Architecture-agnostic load attempt
|
||||
try {
|
||||
// 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);
|
||||
|
||||
// Build type model
|
||||
|
||||
Reference in New Issue
Block a user