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(); }
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(); }