Beispiel #1
0
        /// <inheritdoc />
        public override MethodBase DetourTo(MethodBase replacement)
        {
            // Unpatch an existing detour if it exists

            nativeDetour?.Dispose();

            // Generate a new DMD of the modified unhollowed method, and apply harmony patches to it

            var copiedDmd = CopyOriginal();

            HarmonyManipulator.Manipulate(copiedDmd.OriginalMethod, copiedDmd.OriginalMethod.GetPatchInfo(), new ILContext(copiedDmd.Definition));


            // Generate the MethodInfo instances

            var managedHookedMethod       = copiedDmd.Generate();
            var unmanagedTrampolineMethod = GenerateNativeToManagedTrampoline(managedHookedMethod).Generate();


            // Apply a detour from the unmanaged implementation to the patched harmony method

            var unmanagedDelegateType = DelegateTypeFactory.instance.CreateDelegateType(unmanagedTrampolineMethod,
                                                                                        CallingConvention.Cdecl);

            var detourPtr = Marshal.GetFunctionPointerForDelegate(unmanagedTrampolineMethod.CreateDelegate(unmanagedDelegateType));

            nativeDetour = new FastNativeDetour(originalNativeMethodInfo->methodPointer, detourPtr);

            nativeDetour.Apply();

            // TODO: Add an ILHook for the original unhollowed method to go directly to managedHookedMethod
            // Right now it goes through three times as much interop conversion as it needs to, when being called from managed side

            return(managedHookedMethod);
        }
Beispiel #2
0
        public static FastNativeDetour CreateAndApply <T>(IntPtr from, T to, out T original, CallingConvention?callingConvention = null) where T : Delegate
        {
            var toPtr = callingConvention != null?MonoExtensions.GetFunctionPointerForDelegate(to, callingConvention.Value) : Marshal.GetFunctionPointerForDelegate(to);

            var result = new FastNativeDetour(from, toPtr);

            original = result.GenerateTrampoline <T>();
            result.Apply();
            return(result);
        }
 public T Detour <T>(IntPtr from, T to) where T : Delegate
 {
     FastNativeDetour.CreateAndApply(from, to, out var original);
     return(original);
 }