private static void Create(ReverseWrapper <TFunction> reverseFunctionWrapper, IntPtr functionPtr)
        {
            var reloadedFunctionAttribute = FunctionAttribute.GetAttribute <TFunction>();

            // Microsoft X64 is hot path, as our TFunction will already be Microsoft X64, we marshal if it's anything else.
            if (!reloadedFunctionAttribute.Equals(new FunctionAttribute(CallingConventions.Microsoft)))
            {
                reverseFunctionWrapper.WrapperPointer = Wrapper.Create <TFunction>(functionPtr, new FunctionAttribute(CallingConventions.Microsoft), reloadedFunctionAttribute);
            }
        }
示例#2
0
        private static void Create(ReverseWrapper <TFunction> reverseFunctionWrapper, nuint functionPtr)
        {
            var reloadedFunctionAttribute = FunctionAttribute.GetAttribute <TFunction>();

            // Microsoft X64 is hot path, as our TFunction will already be Microsoft X64, we marshal if it's anything else.
            if (!reloadedFunctionAttribute.Equals(FunctionAttribute.Microsoft))
            {
                reverseFunctionWrapper.WrapperPointer = Wrapper.Create <TFunction>(functionPtr, FunctionAttribute.Microsoft, reloadedFunctionAttribute).ToSigned();
            }
            else
            {
                reverseFunctionWrapper.WrapperPointer = Utilities.CreateJump(functionPtr, true, Constants.MaxAbsJmpSize).ToSigned();
            }
        }
示例#3
0
        private static void Create(Hook <TFunction> hook, ReverseWrapper <TFunction> reverseWrapper, long functionAddress, int minHookLength = -1)
        {
            Mutex.MakeHookMutex.WaitOne();

            /* Create Convention => CDECL Wrapper. */
            List <byte> jumpOpcodes = Utilities.AssembleAbsoluteJump(reverseWrapper.WrapperPointer, true).ToList();

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

            // 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.
            if (minHookLength > jumpOpcodes.Count)
            {
                int nopBytes = minHookLength - jumpOpcodes.Count;

                for (int x = 0; x < nopBytes; x++)
                {
                    jumpOpcodes.Add(0x90);
                }
            }

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

            var functionPatcher = new FunctionPatcher(ArchitectureMode.x86_64);
            var functionPatch   = functionPatcher.Patch(originalFunction.ToList(), (IntPtr)functionAddress);

            IntPtr hookEndAddress = (IntPtr)(functionAddress + minHookLength);

            functionPatch.NewFunction.AddRange(Utilities.AssembleAbsoluteJump(hookEndAddress, true));

            /* Commit the original modified function to memory. */
            byte[] patchedFunction        = functionPatch.NewFunction.ToArray();
            var    buffer                 = Utilities.FindOrCreateBufferInRange(patchedFunction.Length, 1, long.MaxValue);
            var    patchedFunctionAddress = buffer.Add(patchedFunction);

            /* Create Hook instance. */
            hook.OriginalFunctionAddress = patchedFunctionAddress;
            hook.OriginalFunction        = Wrapper.Create <TFunction>((long)patchedFunctionAddress);
            hook.ReverseWrapper          = reverseWrapper;
            hook._otherHookPatches       = functionPatch.Patches;
            hook._hookPatch = new Patch((IntPtr)functionAddress, jumpOpcodes.ToArray());

            Mutex.MakeHookMutex.ReleaseMutex();
        }
示例#4
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>
        public Hook(TFunction function, long functionAddress, int minHookLength = -1)
        {
            var reverseWrapper = new ReverseWrapper <TFunction>(function);

            Create(this, reverseWrapper, functionAddress, minHookLength);
        }