mirror of
https://github.com/JogmansonReal/Radicade.git
synced 2026-10-25 23:18:56 -07:00
65 lines
3.3 KiB
C#
65 lines
3.3 KiB
C#
using System.Reflection;
|
|
using System.Runtime.Loader;
|
|
using Mono.Cecil;
|
|
using Mono.Cecil.Cil;
|
|
|
|
if (args.Length == 3 && args[0] == "--patch-loader")
|
|
{
|
|
if (Path.GetFullPath(args[1]).Equals(Path.GetFullPath(args[2]), StringComparison.OrdinalIgnoreCase))
|
|
throw new ArgumentException("Write a separate loader copy; do not overwrite the source.");
|
|
using var assembly = AssemblyDefinition.ReadAssembly(args[1]);
|
|
int changes = 0;
|
|
foreach (var type in assembly.MainModule.Types)
|
|
foreach (var method in type.Methods.Where(m => m.HasBody))
|
|
foreach (var instruction in method.Body.Instructions)
|
|
if (type.FullName == "BepInEx.Unity.IL2CPP.Il2CppInteropManager" &&
|
|
instruction.OpCode == OpCodes.Ldstr && (string)instruction.Operand == "global-metadata.dat")
|
|
{
|
|
instruction.Operand = "global-metadata.interop.dat";
|
|
Console.WriteLine($"Redirected metadata input in {method.Name}");
|
|
changes++;
|
|
}
|
|
if (changes != 1) throw new InvalidOperationException($"Expected one loader metadata reference, found {changes}.");
|
|
assembly.Write(args[2]);
|
|
Console.WriteLine($"Created loader copy with {changes} metadata path reference(s) changed.");
|
|
return;
|
|
}
|
|
|
|
if (args.Length is < 2 or > 5)
|
|
{
|
|
Console.Error.WriteLine("Usage: AugustInterop <BepInEx-core> <normalized-metadata> [GameAssembly.dll]");
|
|
Console.Error.WriteLine(" or: AugustInterop --patch-loader <original-loader.dll> <output-loader.dll>");
|
|
Environment.ExitCode = 1;
|
|
return;
|
|
}
|
|
|
|
var core = args[0];
|
|
AssemblyLoadContext.Default.Resolving += (_, name) =>
|
|
{
|
|
var path = Path.Combine(core, name.Name + ".dll");
|
|
return File.Exists(path) ? AssemblyLoadContext.Default.LoadFromAssemblyPath(path) : null;
|
|
};
|
|
var library = AssemblyLoadContext.Default.LoadFromAssemblyPath(Path.Combine(core, "LibCpp2IL.dll"));
|
|
if (args.Length > 1)
|
|
{
|
|
var primitives = AssemblyLoadContext.Default.LoadFromAssemblyPath(Path.Combine(core, "AssetRipper.Primitives.dll"));
|
|
var versionType = primitives.GetType("AssetRipper.Primitives.UnityVersion")!;
|
|
var version = versionType.GetMethod("Parse", new[] { typeof(string) })!.Invoke(null, new object[] { "2020.3.33f1" });
|
|
var type = library.GetType("LibCpp2IL.Metadata.Il2CppMetadata")!;
|
|
var metadata = type.GetMethod("ReadFrom")!.Invoke(null, new object[] { File.ReadAllBytes(args[1]), version });
|
|
Console.WriteLine("Metadata parsed successfully.");
|
|
foreach (var field in type.GetFields(BindingFlags.Instance | BindingFlags.Public))
|
|
if (field.GetValue(metadata) is Array array) Console.WriteLine($"{field.Name}: {array.Length}");
|
|
if (args.Length > 2)
|
|
{
|
|
var registry = library.GetTypes().Single(t => t.Name == "LibCpp2IlBinaryRegistry");
|
|
registry.GetMethod("RegisterBuiltInBinarySupport")!.Invoke(null, null);
|
|
var main = library.GetType("LibCpp2IL.LibCpp2IlMain")!;
|
|
var result = main.GetMethod("LoadFromFile")!.Invoke(null, new[] { (object)args[2], Path.GetFullPath(args[1]), version });
|
|
Console.WriteLine($"Binary + metadata initialization: {result}");
|
|
if (args.Length > 3 && args[3] == "--literal-find" && args.Length > 4)
|
|
LiteralFinder.Run(main, metadata, args[2], args[4]);
|
|
else if (args.Length > 3) NativeInspect.Run(main, metadata, args[2], args[3], args.Length > 4 ? args[4] : "");
|
|
}
|
|
}
|