Advertisement
GoodiesHQ

EasyHook.hpp

May 6th, 2016
51
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #ifndef EASYHOOK_HPP
  2. #define EASYHOOK_HPP
  3. #include <array>
  4. #include <cstdio>
  5. #include <iostream>
  6. #include <Windows.h>
  7. #include <winternl.h>
  8.  
  9. namespace EasyHook {
  10. #   define PACKED(s) __pragma(pack(push, 1)) s __pragma(pack(pop))
  11. #   define FUNCTOR(function) decltype(&function)
  12.  
  13.     union prologue {
  14.         PACKED(struct {
  15.             CHAR jmp;
  16.             ULONG addr;
  17.         }) parts;
  18.         CHAR bytes[sizeof(ULONGLONG)];
  19.         ULONGLONG full = 0;
  20.     };
  21.  
  22. #   define FUNCTORVAR(functor_type, function, trampoline_name, prologue_name) using functor_type = decltype(&function); functor_type trampoline_name = NULL; EasyHook::prologue prologue_name;
  23.  
  24.     enum opcode {
  25.         LONGJUMP_SIZE = 0x05,
  26.         RELJUMP = 0xe9,
  27.         NOP = 0x90,
  28.     };
  29.  
  30.     class Hook32 {
  31.         static const SIZE_T jumpSize = 5;
  32.     public:
  33.         Hook32() {};
  34.  
  35.         LPVOID hook(LPVOID target, prologue &original, LPVOID hook) const {
  36.             LPVOID trampoline = NULL;
  37.             DWORD oldProtection = 0;
  38.             if (jumpSize < 5)
  39.                 return 0; // minimum jump size of 5. Necessary for 32-bit programs
  40.             if (!VirtualProtect((LPVOID)target, 1, PAGE_EXECUTE_READWRITE, &oldProtection))
  41.                 return NULL;
  42.             if (!(trampoline = VirtualAlloc(NULL, jumpSize + sizeof prologue, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE)))
  43.                 return VirtualProtect((LPVOID)target, 1, oldProtection, &oldProtection), NULL;
  44.  
  45.             // set up the trampoline first so by the time the atomic function is called, it's already set up.
  46.             memcpy(trampoline, target, jumpSize); // save the first 5 bytes of the original function in the trampoline
  47.             *((PCHAR)((ULONG)trampoline + jumpSize)) = opcode::RELJUMP; // relative jump on the 6th byte...
  48.             *((PULONG)((ULONG)trampoline + jumpSize + 1)) = (ULONG)target - (ULONG)trampoline - opcode::LONGJUMP_SIZE; // return back to the target
  49.  
  50.             memcpy(&original, target, sizeof original); // save the full original first 8 bytes from the function in a member variable
  51.             prologue tmp = original; // copy the original 8 bytes so we don't overwrite anything important.
  52.             tmp.parts.jmp = opcode::RELJUMP; // set the first byte to a relative jmp
  53.             *(PULONG)(tmp.bytes + 1) = (ULONG)hook - (ULONG)target - opcode::LONGJUMP_SIZE; // jmp to the trampoline
  54.             InterlockedExchange64((PLONGLONG)target, tmp.full); // atomically exchange the first 8 bytes of the original instruction
  55.  
  56.             VirtualProtect((LPVOID)target, 1, oldProtection, &oldProtection); // reset the target permissions
  57.             return trampoline;
  58.         }
  59.  
  60.         bool unhook(LPVOID trampoline, prologue original) const {
  61.             DWORD oldProtection = 0;
  62.             prologue origFunc; // a place to restore the original function to retrieve the address
  63.             memcpy(&origFunc, (LPVOID)((ULONG)trampoline + jumpSize), sizeof origFunc); // get the 8 bytes from the trampoline
  64.             PULONG target = (PULONG)(origFunc.parts.addr + opcode::LONGJUMP_SIZE + (ULONG)trampoline); // get the address and offset it to get the original
  65.             if (!VirtualProtect((LPVOID)target, 1, PAGE_EXECUTE_READWRITE, &oldProtection)) // give RWX permissions to the target function
  66.                 return false;
  67.             InterlockedExchange64((PLONGLONG)target, original.full); // replace the 8 bytes of the original function with the original bytes.
  68.             VirtualProtect((LPVOID)target, 1, oldProtection, &oldProtection); // restore the original function permissions
  69.             return true;
  70.         }
  71.     };
  72. }
  73. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement