Skip to content

Conversation

Copy link

Copilot AI commented Nov 2, 2025

Feature: Custom Function Registration for Unmanaged Targets

This PR implements the feature request to allow users to define custom functions on RemoteTypes for unmanaged (MSVC C++) targets.

Latest Update: Fixed Build Errors in ScubaDiver Projects

CustomUndecoratedFunction now properly referenced in all project files!

Added explicit <Compile Include> references to CustomUndecoratedFunction.cs in:

  • ScubaDiver_Net6_x64.csproj
  • ScubaDiver_Net6_x86.csproj

The ScubaDiver projects use explicit file references instead of wildcards, so new source files must be manually added to the .csproj files.

Implementation Complete ✅

  • API communication layer (request/response classes with TypeMethod dump)
  • Diver server-side handler (MsvcDiver returns method dump)
  • Type system integration (CustomUndecoratedFunction, MsvcType)
  • Client-side type update (RemoteRttiType modification via factory)
  • Public API with type verification (UnmanagedRemoteApp.RegisterCustomFunction)
  • Returns MethodInfo directly from factory (no search needed)
  • Unit tests
  • Documentation (README with usage example)
  • All code review feedback addressed
  • Compilation errors fixed (Filter, CustomUndecoratedFunction)
  • Performance optimization applied
  • Project file references updated

Key Features

  • Register custom functions by module name + offset
  • Functions added to existing RemoteRttiType instances using same factory method
  • Type verification ensures only RemoteRttiType can be modified
  • Returns MethodInfo directly - no O(n) search required
  • Can be invoked like any other remote method
  • Includes overflow checking and proper error handling
  • Only available for unmanaged (C++) targets

Usage Example

var app = (UnmanagedRemoteApp)RemoteAppFactory.Connect("target.exe", RuntimeType.Unmanaged);
var type = app.GetRemoteType("MyNamespace::MyClass", "MyModule.dll"); // Creates RemoteRttiType

MethodInfo customMethod = app.RegisterCustomFunction(
    parentType: type,
    functionName: "HiddenMethod",
    moduleName: "MyModule.dll",
    offset: 0x1234,
    returnType: typeof(int),
    parameterTypes: new[] { typeof(float) }
);

if (customMethod != null)
{
    // Invoke like any other method - works on all instances of this type
    dynamic obj = remoteObject.Dynamify();
    int result = obj.HiddenMethod(3.14f);
}

Includes overflow checking on address arithmetic, exception logging for diagnostics, and automatic propagation of the method to all existing RemoteRttiType instances.

Original prompt

This section details on the original issue you should resolve

<issue_title>Feature request: define custom functions</issue_title>
<issue_description>Users of the RemoteApp API should be able to define custom functions on RemoteTypes
This should be implemented by forwarding the function definition request to the scuba diver and adding the info of said new function the type info on the divers side.

For unmanaged targets, the register request should include:
Parent type
Address of the function (as module name + offset)
Return type
Args types list

</issue_description>

Comments on the Issue (you are @copilot in this section)


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 6 commits November 2, 2025 16:23
Co-authored-by: theXappy <10898152+theXappy@users.noreply.github.com>
Co-authored-by: theXappy <10898152+theXappy@users.noreply.github.com>
Co-authored-by: theXappy <10898152+theXappy@users.noreply.github.com>
…, and missing using

Co-authored-by: theXappy <10898152+theXappy@users.noreply.github.com>
Co-authored-by: theXappy <10898152+theXappy@users.noreply.github.com>
Copilot AI changed the title [WIP] Add support for defining custom functions in RemoteApp API Add custom function registration for unmanaged C++ targets Nov 2, 2025
Copilot AI requested a review from theXappy November 2, 2025 16:35
Copilot finished work on behalf of theXappy November 2, 2025 16:35
@theXappy
Copy link
Owner

theXappy commented Nov 2, 2025

@copilot The changes should be reflected in any "RemoteType" (or subclass) that the use of the RemoteApp API might've already fetched.

Make sure we keep trace of created RemoteType (I belive it's 'Remote RTTI Type') and also update them with the new Method.
Remember the first argument to the function is a Type. MAke sure it's a Remote RTTI one and then modify it.

to keep things consistent, change the API towards the Diver to get back that existing "Method Dump" object (for when you use the "Type Dump" API) and feed that to the same code that generated the rest of the members in the existing Type, to be added as a new member to it.
If you need to refactor the way we create Remote RTTI Types for this to be easily and cleanly exposable at that new point in the code, do that.

… instances

- Modified response to return TypeDump.TypeMethod instead of just success/failure
- Updated UnmanagedRemoteApp to verify Type is RemoteRttiType and add method to it
- Use RttiTypesFactory.AddFunctionImpl to ensure consistent method creation
- Updated DiverCommunicator with overload to return method dump
- Updated tests to validate RegisteredMethod property
- Updated documentation to clarify that existing type instances are updated

Co-authored-by: theXappy <10898152+theXappy@users.noreply.github.com>
Copy link
Author

Copilot AI commented Nov 2, 2025

@copilot The changes should be reflected in any "RemoteType" (or subclass) that the use of the RemoteApp API might've already fetched.

Make sure we keep trace of created RemoteType (I belive it's '...

Updated in cd3cef2. The implementation now:

  1. Verifies Type is RemoteRttiType - Throws ArgumentException if not
  2. Returns TypeMethod from diver - Response includes RegisteredMethod property with full method dump
  3. Updates existing RemoteRttiType - Uses RttiTypesFactory.AddFunctionImpl (same code path that creates RTTI methods) to add the method to the client-side type
  4. Consistent method creation - No separate code path, uses existing factory method with TypeDump.TypeMethod

All existing instances of the type automatically get the new method since they reference the same RemoteRttiType object.

Copilot AI changed the title Add custom function registration for unmanaged C++ targets Add custom function registration for unmanaged C++ targets with RemoteRttiType updates Nov 2, 2025
Copilot finished work on behalf of theXappy November 2, 2025 17:45
@theXappy
Copy link
Owner

theXappy commented Nov 2, 2025

@copilot Change the UnmangedRemoteApp API func from this:

        public bool RegisterCustomFunction(

To return a MethodInfo, which will represent the new created MethodInfo added to the local 'Remote RTTI Type', as a convinience shortcut for the callers.
On error, return null (you used to return false)

Also try to fix these compilation errors that occurred when we ran the 'GitHub Action' to try and compile:

<html>
<body>
<!--StartFragment-->
build (Release): src/ScubaDiver/MsvcPrimitives/MsvcTypesManager.cs#L517The type or namespace name 'CustomUndecoratedFunction' could not be found (are you missing a using directive or an assembly reference?)
--
build (Release): src/ScubaDiver/MsvcPrimitives/MsvcTypesManager.cs#L517The type or namespace name 'CustomUndecoratedFunction' could not be found (are you missing a using directive or an assembly reference?)
build (Release): src/ScubaDiver/MsvcPrimitives/MsvcTypesManager.cs#L508The name 'Filter' does not exist in the current context
build (Release): src/ScubaDiver/MsvcPrimitives/MsvcTypesManager.cs#L498The name 'Filter' does not exist in the current context
build (Release): src/ScubaDiver/MsvcPrimitives/MsvcTypesManager.cs#L497The name 'Filter' does not exist in the current context
build (Release): src/ScubaDiver/MsvcPrimitives/MsvcTypesManager.cs#L517The type or namespace name 'CustomUndecoratedFunction' could not be found (are you missing a using directive or an assembly reference?)
build (Release): src/ScubaDiver/MsvcPrimitives/MsvcTypesManager.cs#L517The type or namespace name 'CustomUndecoratedFunction' could not be found (are you missing a using directive or an assembly reference?)
build (Release): src/ScubaDiver/MsvcPrimitives/MsvcTypesManager.cs#L508The name 'Filter' does not exist in the current context
build (Release): src/ScubaDiver/MsvcPrimitives/MsvcTypesManager.cs#L498The name 'Filter' does not exist in the current context
build (Release): src/ScubaDiver/MsvcPrimitives/MsvcTypesManager.cs#L497The name 'Filter' does not exist in the current context

<!--EndFragment-->

…n errors

- Changed return type from bool to MethodInfo (returns null on error)
- Added using ScubaDiver.API.Utils to MsvcTypesManager for Filter class
- Added using System.Reflection to UnmanagedRemoteApp
- Method now returns the newly registered MethodInfo as a convenience
- Fixed compilation errors: Filter and CustomUndecoratedFunction now accessible
- Updated README with new return type and null-check example

Co-authored-by: theXappy <10898152+theXappy@users.noreply.github.com>
Copy link
Author

Copilot AI commented Nov 2, 2025

@copilot Change the UnmangedRemoteApp API func from this:

        public bool RegisterCustomFunction(

...

Updated in 6f0bcf3:

  1. Return type changed - RegisterCustomFunction now returns MethodInfo (the newly registered method) or null on error
  2. Compilation errors fixed:
    • Added using ScubaDiver.API.Utils to MsvcTypesManager.cs for Filter class
    • Added using System.Reflection to UnmanagedRemoteApp.cs
    • Both Filter and CustomUndecoratedFunction are now accessible

The method finds and returns the newly added MethodInfo from the type's method list after successful registration.

Copilot finished work on behalf of theXappy November 2, 2025 18:31
@theXappy
Copy link
Owner

theXappy commented Nov 2, 2025

@copilot This is silly:

            // Use the existing factory method to add the function to the RemoteRttiType
            // AddFunctionImpl will add the method to rttiType's internal methods list
            RttiTypesFactory.AddFunctionImpl(this, parentTypeDump, methodDump, rttiType, areConstructors: false);

            // Find and return the newly added method
            var methods = rttiType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
            return methods.FirstOrDefault(m => m.Name == functionName);

Please make it so RttiTypesFactory.AddFunctionImpl simply returns the new MethodInfo it generated and cut the O(n) search (Which might fail because you don't even validate the parameters.)

1 similar comment
@theXappy
Copy link
Owner

theXappy commented Nov 2, 2025

@copilot This is silly:

            // Use the existing factory method to add the function to the RemoteRttiType
            // AddFunctionImpl will add the method to rttiType's internal methods list
            RttiTypesFactory.AddFunctionImpl(this, parentTypeDump, methodDump, rttiType, areConstructors: false);

            // Find and return the newly added method
            var methods = rttiType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
            return methods.FirstOrDefault(m => m.Name == functionName);

Please make it so RttiTypesFactory.AddFunctionImpl simply returns the new MethodInfo it generated and cut the O(n) search (Which might fail because you don't even validate the parameters.)

- Changed AddFunctionImpl signature to return MethodInfo instead of void
- Returns the newly created RemoteRttiMethodInfo or RemoteRttiConstructorInfo
- UnmanagedRemoteApp now directly returns the MethodInfo from AddFunctionImpl
- Removed inefficient O(n) search through all methods by name
- More efficient and safer since it returns the exact method that was created

Co-authored-by: theXappy <10898152+theXappy@users.noreply.github.com>
Copy link
Author

Copilot AI commented Nov 2, 2025

@copilot This is silly:

            // Use the existing factory method to add the function to the RemoteRttiType

...

Fixed in caa5782. AddFunctionImpl now returns MethodInfo instead of void. The O(n) search has been removed - the method directly returns the newly created RemoteRttiMethodInfo or RemoteRttiConstructorInfo.

@copilot This is silly:

            // Use the existing factory method to add the function to the RemoteRttiType

...

Fixed in caa5782. AddFunctionImpl now returns MethodInfo instead of void. The O(n) search has been removed - the method directly returns the newly created RemoteRttiMethodInfo or RemoteRttiConstructorInfo.

Copilot finished work on behalf of theXappy November 2, 2025 18:54
@theXappy
Copy link
Owner

theXappy commented Nov 2, 2025

@copilot
Build still fails because:

The type or namespace name 'CustomUndecoratedFunction' could not be found (are you missing a using directive or an assembly reference?)

specifically in these 2 projects: ScubaDiver_Net6_x64, ScubaDiver_Net6_86
The way the ScubaDivers' projects are written in this repo is weird: they share the same .cs file but all point to them individually. You'd need to go over the csproj files and add 'pointers' to any new class that you've added as part of this change to them.

- Added Compile reference to project_net6_x64/ScubaDiver_Net6_x64.csproj
- Added Compile reference to project_net6_x86/ScubaDiver_Net6_x86.csproj
- Fixes build error: CustomUndecoratedFunction type not found
- Projects use explicit file references, so new files must be added manually

Co-authored-by: theXappy <10898152+theXappy@users.noreply.github.com>
Copy link
Author

Copilot AI commented Nov 2, 2025

@copilot
Build still fails because:

...

Fixed in 4aa39db. Added <Compile Include="..\MsvcPrimitives\CustomUndecoratedFunction.cs" Link="MsvcPrimitives\CustomUndecoratedFunction.cs" /> to both ScubaDiver_Net6_x64.csproj and ScubaDiver_Net6_x86.csproj. The CustomUndecoratedFunction build error is now resolved.

Copilot finished work on behalf of theXappy November 2, 2025 19:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request: define custom functions

2 participants