hook.cpp (2264B)
1 #include "hook.hpp" 2 #include <new> 3 #include <stdexcept> 4 #include <cstdlib> 5 6 #define LIBSHIT_LOG_NAME "hook" 7 #include <libshit/logger_helper.hpp> 8 9 #define WIN32_LEAN_AND_MEAN 10 #include <windows.h> 11 12 namespace Neptools 13 { 14 15 Byte* image_base; 16 static HANDLE heap = HeapCreate(HEAP_CREATE_ENABLE_EXECUTE, 0, 0); 17 18 static constexpr size_t JMP_SIZE = 5; 19 20 size_t GetImageSize() noexcept 21 { 22 auto dos_hdr = reinterpret_cast<IMAGE_DOS_HEADER*>(image_base); 23 auto hdr = reinterpret_cast<IMAGE_NT_HEADERS32*>(image_base + dos_hdr->e_lfanew); 24 DBG(1) << "Image size: " << hdr->OptionalHeader.SizeOfImage << std::endl; 25 return hdr->OptionalHeader.SizeOfImage; 26 } 27 28 Byte* GetEntryPoint() noexcept 29 { 30 auto dos_hdr = reinterpret_cast<IMAGE_DOS_HEADER*>(image_base); 31 auto hdr = reinterpret_cast<IMAGE_NT_HEADERS32*>(image_base + dos_hdr->e_lfanew); 32 auto ret = image_base + hdr->OptionalHeader.AddressOfEntryPoint; 33 DBG(1) << "OEP: " << ret << std::endl; 34 return ret; 35 } 36 37 void* Hook(void* fun, void* dst, size_t copy) 38 { 39 DBG(2) << "Hooking " << fun << " to " << dst << " (" << copy << " bytes)" 40 << std::endl; 41 42 char* addr = reinterpret_cast<char*>(fun); 43 44 char* ret = nullptr; 45 if (copy) 46 { 47 ret = static_cast<char*>(HeapAlloc(heap, 0, copy + JMP_SIZE)); 48 if (!ret) LIBSHIT_THROW(std::bad_alloc, std::make_tuple()); 49 memcpy(ret, addr, copy); 50 ret[copy] = 0xe9; // jmp 51 auto base = ret + copy + JMP_SIZE; 52 auto tgt = addr + copy; 53 As<int>(ret+copy+1) = tgt - base; 54 } 55 56 try 57 { 58 Unprotect up{addr, 5}; 59 addr[0] = 0xe9; // jmp 60 As<int>(addr+1) = reinterpret_cast<char*>(dst) - addr - JMP_SIZE; 61 } 62 catch (...) 63 { 64 if (ret) HeapFree(heap, 0, ret); 65 throw; 66 } 67 68 DBG(4) << "done" << std::endl; 69 return ret; 70 } 71 72 Unprotect::Unprotect(void* ptr, size_t len) : ptr{ptr}, len{len} 73 { 74 if (!VirtualProtect(ptr, len, PAGE_EXECUTE_READWRITE, &orig_prot)) 75 LIBSHIT_THROW(std::runtime_error, "Unprotect: VirtualProtect"); 76 } 77 78 Unprotect::~Unprotect() 79 { 80 if (!VirtualProtect(ptr, len, orig_prot, &orig_prot)) 81 MessageBoxA(nullptr, "Failed to unprotect memory", "Neptools", 82 MB_OK | MB_ICONERROR); 83 } 84 85 }