Plugins: Add PreProcessImage

This commit is contained in:
Katy Coe
2020-12-29 01:31:26 +01:00
parent 964d845fd4
commit b5f6bcba72
3 changed files with 22 additions and 13 deletions

View File

@@ -20,7 +20,7 @@ namespace Il2CppInspector
long Length { get; } long Length { get; }
uint NumImages { get; } uint NumImages { get; }
string DefaultFilename { get; } string DefaultFilename { get; }
bool IsModified { get; } bool IsModified { get; internal set; }
IEnumerable<IFileFormatStream> Images { get; } // Each child image of this object (eg. 32/64-bit versions in Fat MachO file) IEnumerable<IFileFormatStream> Images { get; } // Each child image of this object (eg. 32/64-bit versions in Fat MachO file)
IFileFormatStream this[uint index] { get; } // With no additional override, one object = one file, this[0] == this IFileFormatStream this[uint index] { get; } // With no additional override, one object = one file, this[0] == this
long Position { get; set; } long Position { get; set; }
@@ -132,13 +132,25 @@ namespace Il2CppInspector
var types = Assembly.GetExecutingAssembly().DefinedTypes var types = Assembly.GetExecutingAssembly().DefinedTypes
.Where(x => x.ImplementedInterfaces.Contains(typeof(IFileFormatStream)) && !x.IsGenericTypeDefinition); .Where(x => x.ImplementedInterfaces.Contains(typeof(IFileFormatStream)) && !x.IsGenericTypeDefinition);
// Copy to memory-based stream
var binaryObjectStream = new BinaryObjectStream();
stream.Position = 0;
stream.CopyTo(binaryObjectStream);
binaryObjectStream.Position = 0;
// Plugin hook to pre-process image before we determine its format
var preProcessResult = PluginHooks.PreProcessImage(binaryObjectStream);
foreach (var type in types) { foreach (var type in types) {
try { try {
if (type.GetMethod("Load", BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.Public, if (type.GetMethod("Load", BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.Public,
null, new[] {typeof(Stream), typeof(LoadOptions), typeof(EventHandler<string>)}, null) null, new[] { typeof(BinaryObjectStream), typeof(LoadOptions), typeof(EventHandler<string>) }, null)
.Invoke(null, new object[] {stream, loadOptions, statusCallback}) is IFileFormatStream loaded) .Invoke(null, new object[] { binaryObjectStream, loadOptions, statusCallback }) is IFileFormatStream loaded) {
loaded.IsModified |= preProcessResult.IsStreamModified;
return loaded; return loaded;
} }
}
catch (TargetInvocationException ex) { catch (TargetInvocationException ex) {
throw ex.InnerException; throw ex.InnerException;
} }
@@ -151,6 +163,7 @@ namespace Il2CppInspector
{ {
public abstract string DefaultFilename { get; } public abstract string DefaultFilename { get; }
bool IFileFormatStream.IsModified { get => IsModified; set => IsModified = value; }
public bool IsModified { get; protected set; } = false; public bool IsModified { get; protected set; } = false;
public uint NumImages { get; protected set; } = 1; public uint NumImages { get; protected set; } = 1;
@@ -180,25 +193,21 @@ namespace Il2CppInspector
} }
public static T Load(string filename, LoadOptions loadOptions = null, EventHandler<string> statusCallback = null) { public static T Load(string filename, LoadOptions loadOptions = null, EventHandler<string> statusCallback = null) {
using var stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read); return Load(new BinaryObjectStream(File.ReadAllBytes(filename)), loadOptions, statusCallback);
return Load(stream, loadOptions, statusCallback);
} }
public static T Load(Stream stream, LoadOptions loadOptions = null, EventHandler<string> statusCallback = null) { public static T Load(Stream stream, LoadOptions loadOptions = null, EventHandler<string> statusCallback = null) {
// Copy the original stream in case we modify it var binary = (T) Activator.CreateInstance(typeof(T));
if (stream.CanSeek) if (stream.CanSeek)
stream.Position = 0; stream.Position = 0;
var binary = (T) Activator.CreateInstance(typeof(T));
stream.CopyTo(binary); stream.CopyTo(binary);
binary.Position = 0;
return binary.InitImpl(loadOptions, statusCallback) ? binary : null; return binary.InitImpl(loadOptions, statusCallback) ? binary : null;
} }
private bool InitImpl(LoadOptions loadOptions, EventHandler<string> statusCallback) { private bool InitImpl(LoadOptions loadOptions, EventHandler<string> statusCallback) {
LoadOptions = loadOptions; LoadOptions = loadOptions;
OnStatusUpdate = statusCallback; OnStatusUpdate = statusCallback;
Position = 0;
// TODO: Plugin hook PreProcessFile
return Init(); return Init();

View File

@@ -17,7 +17,7 @@ namespace Il2CppInspector
// We re-construct libil2cpp.so from the *.bin files and return it as the first image // We re-construct libil2cpp.so from the *.bin files and return it as the first image
internal class ProcessMapReader : FileFormatStream<ProcessMapReader> internal class ProcessMapReader : FileFormatStream<ProcessMapReader>
{ {
private MemoryStream il2cpp; private BinaryObjectStream il2cpp;
public override string DefaultFilename => "maps.txt"; public override string DefaultFilename => "maps.txt";
@@ -81,7 +81,7 @@ namespace Il2CppInspector
var lengthLast = il2cppMemory.Last().End - neededFiles.Last().Start; var lengthLast = il2cppMemory.Last().End - neededFiles.Last().Start;
// Merge the files // Merge the files
il2cpp = new MemoryStream(); il2cpp = new BinaryObjectStream();
for (var i = 0; i < neededFiles.Count; i++) { for (var i = 0; i < neededFiles.Count; i++) {
var offset = (i == 0)? offsetFirst : 0; var offset = (i == 0)? offsetFirst : 0;

View File

@@ -38,7 +38,7 @@ namespace Il2CppInspector
Position = arch.Offset; Position = arch.Offset;
Endianness = Endianness.Little; Endianness = Endianness.Little;
using var s = new MemoryStream(ReadBytes((int) arch.Size)); using var s = new BinaryObjectStream(ReadBytes((int) arch.Size));
return (IFileFormatStream) MachOReader32.Load(s, LoadOptions, OnStatusUpdate) ?? MachOReader64.Load(s, LoadOptions, OnStatusUpdate); return (IFileFormatStream) MachOReader32.Load(s, LoadOptions, OnStatusUpdate) ?? MachOReader64.Load(s, LoadOptions, OnStatusUpdate);
} }
} }