From 11da24b7989e1da7541bbdaea702e416c34750a0 Mon Sep 17 00:00:00 2001 From: JohnCorby Date: Fri, 11 Feb 2022 19:55:39 -0800 Subject: [PATCH] proxy injector --- ProxyInjector/Program.cs | 65 ++++++++++++++++++++++++ ProxyInjector/Properties/AssemblyInfo.cs | 35 +++++++++++++ ProxyInjector/ProxyInjector.csproj | 9 ++++ QSB.sln | 6 +++ 4 files changed, 115 insertions(+) create mode 100644 ProxyInjector/Program.cs create mode 100644 ProxyInjector/Properties/AssemblyInfo.cs create mode 100644 ProxyInjector/ProxyInjector.csproj diff --git a/ProxyInjector/Program.cs b/ProxyInjector/Program.cs new file mode 100644 index 00000000..51b8a633 --- /dev/null +++ b/ProxyInjector/Program.cs @@ -0,0 +1,65 @@ +using Mono.Cecil; +using MonoMod.Utils; +using System; +using System.Diagnostics; +using System.IO; +using UnityEngine; + +namespace ProxyInjector +{ + public static class Program + { + public static void Main(string[] args) + { + var sw = Stopwatch.StartNew(); + + var qsbDll = args[0]; + var gameDll = args[1]; + + var resolver = new DefaultAssemblyResolver(); + resolver.AddSearchDirectory(Path.GetDirectoryName(gameDll)); + + using var qsbModule = ModuleDefinition.ReadModule(qsbDll, new ReaderParameters + { + ReadWrite = true, + ReadSymbols = true, + AssemblyResolver = resolver + }); + using var gameModule = ModuleDefinition.ReadModule(gameDll, new ReaderParameters { AssemblyResolver = resolver }); + + var count = 0; + foreach (var td in gameModule.Types) + { + if (!td.IsDerivedFrom() || + td.IsAbstract || + td.HasGenericParameters) + { + continue; + } + + var proxyTd = new TypeDefinition(td.Namespace, td.Name, td.Attributes, qsbModule.ImportReference(td)); + qsbModule.Types.Add(proxyTd); + count++; + } + + qsbModule.Write(new WriterParameters { WriteSymbols = true }); + + Console.WriteLine($"injected {count} proxy scripts in {sw.ElapsedMilliseconds} ms"); + } + + private static bool IsDerivedFrom(this TypeDefinition td) + { + while (td != null) + { + if (td.Is(typeof(T))) + { + return true; + } + + td = td.BaseType?.Resolve(); + } + + return false; + } + } +} diff --git a/ProxyInjector/Properties/AssemblyInfo.cs b/ProxyInjector/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..01fb7e42 --- /dev/null +++ b/ProxyInjector/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("ProxyInjector")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ProxyInjector")] +[assembly: AssemblyCopyright("Copyright © 2022")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("2F24758A-7BD3-405F-8968-07F8D96C6DE4")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/ProxyInjector/ProxyInjector.csproj b/ProxyInjector/ProxyInjector.csproj new file mode 100644 index 00000000..a0a197a0 --- /dev/null +++ b/ProxyInjector/ProxyInjector.csproj @@ -0,0 +1,9 @@ + + + Exe + + + + + + diff --git a/QSB.sln b/QSB.sln index 6f714ce5..e09c90a2 100644 --- a/QSB.sln +++ b/QSB.sln @@ -20,6 +20,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EpicOnlineTransport", "Epic EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EpicRerouter", "EpicRerouter\EpicRerouter.csproj", "{639EFAEE-C4A1-4DA2-8457-D0472A9F6343}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProxyInjector", "ProxyInjector\ProxyInjector.csproj", "{2F24758A-7BD3-405F-8968-07F8D96C6DE4}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -46,6 +48,10 @@ Global {639EFAEE-C4A1-4DA2-8457-D0472A9F6343}.Debug|Any CPU.Build.0 = Debug|Any CPU {639EFAEE-C4A1-4DA2-8457-D0472A9F6343}.Release|Any CPU.ActiveCfg = Release|Any CPU {639EFAEE-C4A1-4DA2-8457-D0472A9F6343}.Release|Any CPU.Build.0 = Release|Any CPU + {2F24758A-7BD3-405F-8968-07F8D96C6DE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2F24758A-7BD3-405F-8968-07F8D96C6DE4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2F24758A-7BD3-405F-8968-07F8D96C6DE4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2F24758A-7BD3-405F-8968-07F8D96C6DE4}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE