Esempio n. 1
0
        /// <inheritdoc />
        public unsafe IHook <TFunction> CreateHook <
#if NET5_0_OR_GREATER
            [DynamicallyAccessedMembers(Trimming.ReloadedAttributeTypes)]
#endif
            TFunction>(
#if NET5_0_OR_GREATER
            [DynamicallyAccessedMembers(Trimming.Methods)]
#endif
            Type type, string methodName, long functionAddress, int minHookLength, FunctionHookOptions options) => CreateHook <TFunction>(Instance.Utilities.GetFunctionPointer(type, methodName), functionAddress, minHookLength, options);
Esempio n. 2
0
        /// <summary>
        /// Creates a hook for a function at a given address.
        /// </summary>
        /// <param name="functionAddress">The address of the function to hook.</param>
        /// <param name="minHookLength">Optional explicit length of hook. Use only in rare cases where auto-length check overflows a jmp/call opcode.</param>
        /// <param name="options">Options which control the hook generation procedure.</param>
        private void CreateHook(nuint functionAddress, int minHookLength = -1, FunctionHookOptions options = null)
        {
            // Set options if not passed in.
            if (options == null)
            {
                Misc.TryGetAttribute <TFunction, FunctionHookOptions>(out options);
                options ??= new FunctionHookOptions();
            }

            /*
             * === Hook Summary ===
             *
             * A. Insert Absolute Jump to ReverseWrapper (Convention => CDECL Marshaller)
             *     A1. Backup original bytes and patch between start and end of JMP for (B).
             *
             * B. Setup Wrapper to call original function (CDECL => Convention Marshaller)
             *     B1. Take bytes backed up from A, and create stub function with those
             *         bytes and JMP to end of hook.
             *     B2. Assign OriginalFunction to that function stub.
             *
             * Note: For X64 the same principles apply, just replace CDECL with Microsoft calling convention.
             */

            /* Create Target Convention => TFunction Wrapper. */
            var jumpOpcodes = options.PreferRelativeJump ?
                              Utilities.TryAssembleRelativeJump(functionAddress, ReverseWrapper.WrapperPointer.ToUnsigned(), _is64Bit, out _) :
                              Utilities.AssembleAbsoluteJump(ReverseWrapper.WrapperPointer.ToUnsigned(), _is64Bit).ToList();

            /* Calculate Hook Length (Unless Explicit) */
            if (minHookLength == -1)
            {
                minHookLength = Utilities.GetHookLength(functionAddress, jumpOpcodes.Count, _is64Bit);
            }

            // Sometimes our hook can be larger than the amount of bytes taken by the jmp opcode.
            // We need to fill the remaining bytes with NOPs.
            Utilities.FillArrayUntilSize <byte>(jumpOpcodes, 0x90, minHookLength);

            /* Get bytes from original function prologue and patch them. */
            CurrentProcess.SafeReadRaw(functionAddress, out byte[] originalFunction, minHookLength);

            var   functionPatcher = new FunctionPatcher(_is64Bit, options);
            var   functionPatch   = functionPatcher.Patch(originalFunction.ToList(), functionAddress);
            nuint hookEndAddress  = functionAddress + (nuint)minHookLength;

            /* Second wave of patching. */
            var icedPatcher = new IcedPatcher(_is64Bit, functionPatch.NewFunction.ToArray(), functionAddress);

            /* Create Hook instance. */
            OriginalFunctionAddress        = icedPatcher.ToMemoryBuffer(hookEndAddress).ToSigned();
            OriginalFunction               = CreateWrapper(icedPatcher.ToMemoryBuffer(null), out nuint originalFunctionWrapperAddress);
            OriginalFunctionWrapperAddress = originalFunctionWrapperAddress.ToSigned();

            _otherHookPatches = functionPatch.Patches;
            _hookPatch        = new Patch(functionAddress, jumpOpcodes.ToArray());
        }
        private void TestHookAdd_Internal(FunctionHookOptions options)
        {
            for (int x = 0; x < HookCount; x++)
            {
                IHook <NativeCalculator.AddFunction> addHook = null;
                addHook = ReloadedHooks.Instance.CreateHook <NativeCalculator.AddFunction>((a, b) => addHook.OriginalFunction(a, b) + 1, (long)_nativeCalculator.Add, -1, options).Activate();
                manyHooks.Add(addHook);
            }

            for (int x = 0; x < 100; x++)
            {
                for (int y = 1; y < 100;)
                {
                    int expected = (x + y) + HookCount;
                    int result   = _addFunction(x, y);

                    Assert.Equal(expected, result);
                    y += 2;
                }
            }
        }
Esempio n. 4
0
        private void RegularHook_SupportsLongJump_Internal(FunctionHookOptions options)
        {
            AssertLargeAddressAware();

            int Hookfunction(int a, int b)
            {
                return(_addDelegateHook.OriginalFunction(a, b) + 1);
            }

            _addDelegateHook = ReloadedHooks.Instance.CreateHook <NativeCalculator.AddFunction>(Hookfunction, (long)_highMemCalculator.Add, -1, options).Activate();

            for (int x = 0; x < 100; x++)
            {
                for (int y = 1; y < 100;)
                {
                    int expected = (x + y) + 1;
                    int result   = _addFunction(x, y);

                    Assert.Equal(expected, result);
                    y += 2;
                }
            }
        }
Esempio n. 5
0
 /// <inheritdoc />
 public unsafe IHook <TFunction> CreateHook <TFunction>(Type type, string methodName, long functionAddress, int minHookLength, FunctionHookOptions options) => CreateHook <TFunction>(Instance.Utilities.GetFunctionPointer(type, methodName), functionAddress, minHookLength, options);
Esempio n. 6
0
 public unsafe IHook <TFunction> CreateHook <TFunction>(void *targetAddress, long functionAddress, int minHookLength, FunctionHookOptions options) => new Hook <TFunction>(targetAddress, functionAddress, minHookLength, options);
Esempio n. 7
0
 public IHook <TFunction> CreateHook <TFunction>(TFunction function, long functionAddress, int minHookLength, FunctionHookOptions options) => new Hook <TFunction>(function, functionAddress, minHookLength, options);
Esempio n. 8
0
 internal unsafe void FunctionPointerHook_SupportsLongJump_Internal(FunctionHookOptions options)
 {
     AssertLargeAddressAware();
Esempio n. 9
0
 public FunctionPatcher(ArchitectureMode mode, FunctionHookOptions options = null)
 {
     _architecture = mode;
     _options      = options ?? new FunctionHookOptions();
 }
Esempio n. 10
0
 public FunctionPatcher(bool is64Bit, FunctionHookOptions options = null)
 {
     _architecture = is64Bit ? ArchitectureMode.x86_64
                             : ArchitectureMode.x86_32;
     _options = options ?? new FunctionHookOptions();
 }
Esempio n. 11
0
 /// <summary>
 /// Creates a hook for a function at a given address.
 /// </summary>
 /// <param name="targetAddress">Address of the function to detour the original function to.</param>
 /// <param name="functionAddress">The address of the function to hook.</param>
 /// <param name="minHookLength">Optional explicit length of hook. Use only in rare cases where auto-length check overflows a jmp/call opcode.</param>
 /// <param name="options">Options which control the hook generation procedure.</param>
 public unsafe Hook(void *targetAddress, nuint functionAddress, int minHookLength = -1, FunctionHookOptions options = null)
 {
     _is64Bit       = sizeof(IntPtr) == 8;
     ReverseWrapper = CreateReverseWrapper(targetAddress);
     CreateHook(functionAddress, minHookLength, options);
 }
Esempio n. 12
0
 /// <summary>
 /// Creates a hook for a function at a given address.
 /// </summary>
 /// <param name="function">The function to detour the original function to.</param>
 /// <param name="functionAddress">The address of the function to hook.</param>
 /// <param name="minHookLength">Optional explicit length of hook. Use only in rare cases where auto-length check overflows a jmp/call opcode.</param>
 /// <param name="options">Options which control the hook generation procedure.</param>
 public unsafe Hook(TFunction function, long functionAddress, int minHookLength = -1, FunctionHookOptions options = null)
 {
     _is64Bit       = sizeof(IntPtr) == 8;
     ReverseWrapper = CreateReverseWrapper(function);
     CreateHook(functionAddress, minHookLength, options);
 }
Esempio n. 13
0
 public FunctionPatcher(bool is64Bit, FunctionHookOptions options = null)
 {
     _is64Bit = is64Bit;
     _options = options ?? new FunctionHookOptions();
 }
Esempio n. 14
0
        public unsafe IHook <TFunction> CreateHook <
#if NET5_0_OR_GREATER
            [DynamicallyAccessedMembers(Trimming.ReloadedAttributeTypes)]
#endif
            TFunction>(void *targetAddress, long functionAddress, int minHookLength, FunctionHookOptions options) => new Hook <TFunction>(targetAddress, (nuint)functionAddress.ToUnsigned(), minHookLength, options);