diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9041245 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*/ +*.sln +*.vcxproj* \ No newline at end of file diff --git a/inthook.hpp b/inthook.hpp index 7930dcd..d2e7c07 100644 --- a/inthook.hpp +++ b/inthook.hpp @@ -4,7 +4,35 @@ #define INT3 0xCC +// todo: fix x64 namespace inthook { + UCHAR original_call[]{ +#ifdef _WIN64 + 0x51, // push rcx + 0x52, // push rdx + 0x41, 0x50, // push r8 + 0x41, 0x51, // push r9 + 0x50, // push rax + 0x48, 0xB9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov rcx, function + 0x48, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov rax, inthook::ignore + 0xFF, 0xD0, // call rax + 0x58, // pop rax + 0x41, 0x59, // pop r9 + 0x41, 0x58, // pop r8 + 0x5A, // pop rdx + 0x59, // pop rcx + 0x48, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov rax, function + 0xFF, 0xE0 // jmp rax +#elif _WIN32 + 0x68, 0x00, 0x00, 0x00, 0x00, // push function + 0xB8, 0xFF, 0xFF, 0xFF, 0xFF, // mov eax, inthook::ignore + 0xFF, 0xD0, // call eax + 0x58, // pop eax + 0xB8, 0x00, 0x00, 0x00, 0x00, // mov eax, function + 0xFF, 0xE0 // jmp eax +#endif + }; + struct info { PVOID function; PVOID hook; @@ -49,7 +77,34 @@ namespace inthook { return EXCEPTION_CONTINUE_SEARCH; } - bool create(void* function, void* hook) { + bool ignore(void* function) { + for (info& cur : hooks) { + if (function != cur.function && cur.disabled) + continue; + cur.ignore = true; + return true; + } + return false; + } + + void* original(void* function) { + void* address = VirtualAlloc(0, sizeof(original_call), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); + if (!address) + return 0; + memcpy(address, &original_call, sizeof(original_call)); +#ifdef _WIN64 + *(DWORD64*)((DWORD64)address + 9) = (DWORD64)function; + *(DWORD64*)((DWORD64)address + 19) = (DWORD64)inthook::ignore; + *(DWORD64*)((DWORD64)address + 38) = (DWORD64)function; +#elif _WIN32 + *(DWORD*)((DWORD)address + 1) = (DWORD)function; + *(DWORD*)((DWORD)address + 6) = (DWORD)inthook::ignore; + *(DWORD*)((DWORD)address + 14) = (DWORD)function; +#endif + return address; + } + + bool create(void* function, void* hook, void* &original) { info new_hook = { function, hook }; if (!VirtualProtect(new_hook.function, 0x1, PAGE_EXECUTE_READWRITE, &new_hook.old_protect)) return false; @@ -57,6 +112,10 @@ namespace inthook { new_hook.old_byte = *(UCHAR*)new_hook.function; *(UCHAR*)new_hook.function = INT3; // set int3 byte + original = inthook::original(new_hook.function); + if (!original) + return false; + hooks.push_back(new_hook); return true; } @@ -74,16 +133,6 @@ namespace inthook { return false; } - bool ignore(void* function) { - for (info& cur : hooks) { - if (function != cur.function && cur.disabled) - continue; - cur.ignore = true; - return true; - } - return false; - } - bool init() { seh = AddVectoredExceptionHandler(1, vectored_handler); return seh != 0; @@ -101,4 +150,4 @@ namespace inthook { hooks.clear(); return RemoveVectoredExceptionHandler(seh) != 0; } -} \ No newline at end of file +} diff --git a/main.cpp b/main.cpp index d843fd3..072be10 100644 --- a/main.cpp +++ b/main.cpp @@ -1,19 +1,19 @@ #include -#include #include "inthook.hpp" +typedef int (WINAPI* tMessageBoxA)(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType); +tMessageBoxA oMessageBoxA; int WINAPI hMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType) { printf(":)"); - inthook::ignore(MessageBoxA); - return MessageBoxA(hWnd, "hooked", lpCaption, MB_ICONWARNING | uType); + return oMessageBoxA(hWnd, "hooked", lpCaption, MB_ICONWARNING | uType); } int main() { if (!inthook::init()) return 1; - if (!inthook::create(MessageBoxA, hMessageBoxA)) + if (!inthook::create(MessageBoxA, &hMessageBoxA, reinterpret_cast(oMessageBoxA))) return 2; MessageBoxA(0, "hello world", "hello world", MB_OK);