-
-
Notifications
You must be signed in to change notification settings - Fork 204
/
LibCpp2IlBinaryRegistry.cs
92 lines (70 loc) · 3.22 KB
/
LibCpp2IlBinaryRegistry.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using LibCpp2IL.Elf;
using LibCpp2IL.Logging;
using LibCpp2IL.MachO;
using LibCpp2IL.Metadata;
using LibCpp2IL.NintendoSwitch;
using LibCpp2IL.Wasm;
namespace LibCpp2IL;
public static class LibCpp2IlBinaryRegistry
{
private static List<RegisteredBinary> _binaries = [];
public static void RegisterBuiltInBinarySupport()
{
Register("Portable Executable", "LibCpp2IL",
bytes => BitConverter.ToInt16(bytes, 0) == 0x5A4D, //MZ
(memStream) => new PE.PE(memStream));
Register("ELF", "LibCpp2IL",
bytes => BitConverter.ToInt32(bytes, 0) == 0x464c457f, //0x7F ELF
(memStream) => new ElfFile(memStream));
Register("Nintendo Switch Object", "LibCpp2IL",
bytes => BitConverter.ToInt32(bytes, 0) == 0x304F534E, //NSO0
(memStream) => new NsoFile(memStream).Decompress());
Register("WebAssembly File", "LibCpp2IL",
bytes => BitConverter.ToInt32(bytes, 0) == 0x6D736100, //\0WASM
(memStream) => new WasmFile(memStream));
Register("Mach-O File", "LibCppIL",
bytes => BitConverter.ToUInt32(bytes, 0) is 0xFEEDFACE or 0xFEEDFACF,
(memStream) => new MachOFile(memStream)
);
}
public static void Register<T>(string name, string source, Func<byte[], bool> isValid, Func<MemoryStream, T> factory) where T : Il2CppBinary
{
_binaries.Add(new(name, source, isValid, factory));
}
internal static Il2CppBinary CreateAndInit(byte[] buffer, Il2CppMetadata metadata)
{
if (_binaries.Count == 0)
RegisterBuiltInBinarySupport();
var match = _binaries.Find(b => b.IsValid(buffer));
if (match == null)
throw new($"Unknown binary type, no binary handling header bytes {string.Join(" ", buffer.SubArray(0, 4).Select(b => $"{b:X2}"))} has been registered");
LibLogger.InfoNewline($"Using binary type {match.Name} (from {match.Source})");
var memStream = new MemoryStream(buffer, 0, buffer.Length, true, true);
LibLogger.InfoNewline("Searching Binary for Required Data...");
var start = DateTime.Now;
var binary = match.FactoryFunc(memStream);
LibCpp2IlMain.Binary = binary;
var (codereg, metareg) = binary.FindCodeAndMetadataReg(metadata.methodDefs.Count(x => x.methodIndex >= 0), metadata.typeDefs.Length);
LibLogger.InfoNewline($"Got Binary codereg: 0x{codereg:X}, metareg: 0x{metareg:X} in {(DateTime.Now - start).TotalMilliseconds:F0}ms.");
LibLogger.InfoNewline("Initializing Binary...");
start = DateTime.Now;
binary.Init(codereg, metareg);
LibLogger.InfoNewline($"Initialized Binary in {(DateTime.Now - start).TotalMilliseconds:F0}ms");
return binary;
}
private class RegisteredBinary(
string name,
string source,
Func<byte[], bool> verificationFunc,
Func<MemoryStream, Il2CppBinary> factoryFunc)
{
public string Name = name;
public string Source = source;
public Func<byte[], bool> IsValid = verificationFunc;
public Func<MemoryStream, Il2CppBinary> FactoryFunc = factoryFunc;
}
}