RemoteNET icon indicating copy to clipboard operation
RemoteNET copied to clipboard

Add instance-specific method hooking support

Open Copilot opened this issue 1 month ago • 0 comments

Hooking was limited to capturing ALL method invocations across ALL instances. This adds support for hooking methods on specific instances only.

Architecture

Backend (ScubaDiver)

  • HookingCenter: Centralized registry mapping method+position → instance-specific callbacks using ConcurrentDictionary<int, HookRegistration> for O(1) operations
  • DiverBase: Per-method locks prevent race conditions during Harmony hook installation; unified callback dispatches to registered instances
  • ResolveInstanceAddress: DotNetDiver uses pinned addresses or RuntimeHelpers.GetHashCode; MsvcDiver uses NativeObject addresses
  • FunctionHookRequest: Added optional InstanceAddress field (0 = all instances, backward compatible)

Frontend (RemoteNET)

  • DiverCommunicator.HookMethod: Added optional instanceAddress parameter
  • RemoteHookingManager: Accepts RemoteObject or dynamic instances, prevents duplicate hooks per instance+position
  • RemoteObject: Added Hook() and Patch() convenience methods on both ManagedRemoteObject and UnmanagedRemoteObject

Usage

// Hook specific instance
var instance = app.GetRemoteObject(candidate);
instance.Hook(method, HarmonyPatchPosition.Prefix, 
    (ctx, inst, args, ref ret) => Console.WriteLine("Specific instance called"));

// Hook all instances (existing behavior unchanged)
app.HookingManager.HookMethod(method, HarmonyPatchPosition.Prefix, callback);

Notes

  • Thread-safe: Per-method locks + concurrent collections
  • Performance: O(1) hook registration/unregistration
  • Limitation: Unpinned .NET objects use identity hashcode (collision possible)
  • All ScubaDiver project files updated to include HookingCenter.cs
Original prompt

Hooking in the Scuba Diver ("back" end) and RemoteNET ("front" end) is currently limited to capturing ALL hits on the method. Some methods are STATIC/instance-less and it's FINE like this. But it's becoming common to want to hook a CLASS METHOD on a SPECIFIC INSTANCE.

Please modify the ScubaDivers (both .NET/MSVC) to allow another parameter called "instance" then implement hooking JUST for this instance.

We'd need a new centralized "Hooking Center" class that'll take care of registering for the hooks and then, using a callback of their own, re-route JUST the hits for any instances that were "registered".

In the RemoteNET side, change the API so such that we cann call Hook Method with this new optional argument - it should be a a RemoteObject or a DynamicRemoteObject Also add a "Hook" function to the RemoteObject class for easier access (it should mimic the API for hooking currently found on the RemoteApp class, but the INSTANCE is implied in this case, obviously)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot avatar Dec 06 '25 11:12 Copilot