From d348a1a36e66a2189b9f9b532cef131ed2fc3f95 Mon Sep 17 00:00:00 2001 From: Bert Proesmans Date: Tue, 6 Jun 2017 21:37:19 +0200 Subject: [PATCH] Fixed referenced library preload --- HookRegistry/HookRegistry.csproj | 1 + HookRegistry/src/HookRegistry.cs | 5 +++- HookRegistry/src/IncomingPackets.cs | 15 ---------- HookRegistry/src/OutgoingPackets.cs | 15 ---------- HookRegistry/src/ReferenceLoader.cs | 44 +++++++++++++++++++++++++++++ 5 files changed, 49 insertions(+), 31 deletions(-) create mode 100644 HookRegistry/src/ReferenceLoader.cs diff --git a/HookRegistry/HookRegistry.csproj b/HookRegistry/HookRegistry.csproj index 02df425..50ad4ad 100644 --- a/HookRegistry/HookRegistry.csproj +++ b/HookRegistry/HookRegistry.csproj @@ -64,6 +64,7 @@ + \ No newline at end of file diff --git a/HookRegistry/src/HookRegistry.cs b/HookRegistry/src/HookRegistry.cs index ad345fa..1cede16 100644 --- a/HookRegistry/src/HookRegistry.cs +++ b/HookRegistry/src/HookRegistry.cs @@ -52,9 +52,12 @@ public static HookRegistry Get() // Initialise the assembly store. _instance.Init(); - // Setup all hook information + // Setup all hook information. _instance.LoadRuntimeHooks(); + // Pre-load necessary library files. + ReferenceLoader.Load(); + try { // Test if this code is running within the Unity Engine diff --git a/HookRegistry/src/IncomingPackets.cs b/HookRegistry/src/IncomingPackets.cs index 2a8cd4c..3ff13c5 100644 --- a/HookRegistry/src/IncomingPackets.cs +++ b/HookRegistry/src/IncomingPackets.cs @@ -5,8 +5,6 @@ using HackstoneAnalyzer.PayloadFormat; using Hooks.PacketDumper; using System; -using static Google.Protobuf.WireFormat; -using System.Runtime.CompilerServices; namespace Hooks { @@ -27,19 +25,6 @@ public IncomingPackets() // Perform hooking administration. HookRegistry.Register(OnCall); - - ForceLoadReferences(); - } - - // Use types from dependancy, since it's not possible to detect referenced libraries - // without code needing them. - [MethodImpl(MethodImplOptions.NoOptimization)] - private void ForceLoadReferences() - { -#pragma warning disable CS0219 // Variable is assigned but its value is never used - WireType _nil = WireType.Fixed32; - ulong _magic = Util.MAGIC_V; -#pragma warning restore CS0219 // Variable is assigned but its value is never used } // Returns a list of methods (full names) that this hook expects. diff --git a/HookRegistry/src/OutgoingPackets.cs b/HookRegistry/src/OutgoingPackets.cs index 330987e..ee325a6 100644 --- a/HookRegistry/src/OutgoingPackets.cs +++ b/HookRegistry/src/OutgoingPackets.cs @@ -6,8 +6,6 @@ using HackstoneAnalyzer.PayloadFormat; using Hooks.PacketDumper; using System; -using static Google.Protobuf.WireFormat; -using System.Runtime.CompilerServices; namespace Hooks { @@ -29,19 +27,6 @@ public OutgoingPackets() // Perform hooking administration. HookRegistry.Register(OnCall); RegisterGenericDeclaringTypes(); - - ForceLoadReferences(); - } - - // Use types from dependancy, since it's not possible to detect referenced libraries - // without code needing them. - [MethodImpl(MethodImplOptions.NoOptimization)] - private void ForceLoadReferences() - { -#pragma warning disable CS0219 // Variable is assigned but its value is never used - WireType _nil = WireType.Fixed32; - ulong _magic = Util.MAGIC_V; -#pragma warning restore CS0219 // Variable is assigned but its value is never used } private void RegisterGenericDeclaringTypes() diff --git a/HookRegistry/src/ReferenceLoader.cs b/HookRegistry/src/ReferenceLoader.cs new file mode 100644 index 0000000..5810114 --- /dev/null +++ b/HookRegistry/src/ReferenceLoader.cs @@ -0,0 +1,44 @@ +using Google.Protobuf.Reflection; +using HackstoneAnalyzer.PayloadFormat; +using System; +using System.Collections.Generic; + +namespace Hooks +{ + static class ReferenceLoader + { + /* + * Referenced libraries are loaded by the .NET runtime when they are used. + * + * UnityHook loads this library file (HookRegistry.dll) and starts the initialisation procedure + * to validate it's contents. + * While doing that, all loaded libraries that were referenced during initialisation were recorded + * and they will be copied WITH HookRegistry.dll to the game library folder. + * + * The result is that the injected code won't throw an exception because of missing library files, since + * all code will eventually run from the library folder of the game! + * + * The `Load()` method will be called after initialisation of HookRegistry is complete. + */ + + // Holds the types created by Load(). + // These types are explicitly stored in a list to prevent the compiler optimize away our load calls. + static List _references; + + public static void Load() + { + // Put here a type statement for each referenced library, which MUST BE COPIED together + // with HookRegistry.dll to the game's library folder. + // e.g. typeof(String); + + _references = new List() + { + // Reference to PayloadFormat.dll + typeof(Handshake), + + // Reference to Google.Protobuf.dll + typeof(MessageDescriptor), + }; + } + } +}