Example #1
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));

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

            /* Create Hook instance. */
            hook.OriginalFunctionAddress        = icedPatcher.GetFunctionAddress();
            hook.OriginalFunction               = Wrapper.Create <TFunction>((long)icedPatcher.GetFunctionAddress(), out IntPtr originalFunctionWrapperAddress);
            hook.OriginalFunctionWrapperAddress = originalFunctionWrapperAddress;

            hook.ReverseWrapper    = reverseWrapper;
            hook._otherHookPatches = functionPatch.Patches;
            hook._hookPatch        = new Patch((IntPtr)functionAddress, jumpOpcodes.ToArray());

            Mutex.MakeHookMutex.ReleaseMutex();
        }
Example #2
0
        private static void Create(Hook <TFunction> hook, ReverseWrapper <TFunction> reverseWrapper, long functionAddress, int minHookLength = -1)
        {
            /*
             *  === 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.
             */


            Mutex.MakeHookMutex.WaitOne();

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

            /* Calculate Hook Length (Unless Explicit) */

            if (minHookLength == -1)
            {
                minHookLength = Utilities.GetHookLength((IntPtr)functionAddress, jumpOpcodes.Count, ArchitectureMode.x86_32);
            }

            // 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_32);
            var functionPatch   = functionPatcher.Patch(originalFunction.ToList(), (IntPtr)functionAddress);

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

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

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

            /* Create Hook instance. */
            hook.OriginalFunctionAddress        = icedPatcher.GetFunctionAddress();
            hook.OriginalFunction               = Wrapper.Create <TFunction>((long)icedPatcher.GetFunctionAddress(), out IntPtr originalFunctionWrapperAddress);
            hook.OriginalFunctionWrapperAddress = originalFunctionWrapperAddress;

            hook.ReverseWrapper    = reverseWrapper;
            hook._otherHookPatches = functionPatch.Patches;
            hook._hookPatch        = new Patch((IntPtr)functionAddress, jumpOpcodes.ToArray());

            Mutex.MakeHookMutex.ReleaseMutex();
        }