钩子汇编指令:JMP RVA
Linux 平台(GCC ##AMD64)
#include <unistd.h>
#include <sys/mman.h>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <assert.h>
#include <stdexcept>
#define PAGE_START(x, pagesize) ((x) & ~((pagesize) - 1))
static void AdjustProtectMemoryPermissions(void* func, int permissions)
{
int pagesize = getpagesize();
int64_t start = PAGE_START((int64_t)func, pagesize);
if (mprotect((void*)start, (size_t)pagesize, permissions) < 0)
{
throw std::runtime_error("mprotect error");
}
}
static void InstallHooker(char* func, char* jump)
{
int RVA = ((int64_t)func) + 5;
RVA = (int64_t)(jump) - RVA;
AdjustProtectMemoryPermissions(func, PROT_READ | PROT_WRITE | PROT_EXEC);
func[0] = 0xE9;
*(int*)(func + 1) = RVA;
AdjustProtectMemoryPermissions(func, PROT_READ | PROT_EXEC);
}
static void test(int x)
{
printf("%s: %d\n", __FUNCTION__, x);
}
static void test_dohooker(int x)
{
printf("%s: %d\n", __FUNCTION__, x);
}
int main(int argc, const char* argv[]) noexcept
{
InstallHooker((char*)&test, (char*)&test_dohooker);
test(100);
return 0;
}
钩子汇编指令:MOV RAX; JMP RAX
Windows 平台(VC++ ##AMD64)
#include <cstdio>
#include <Windows.h>
#include <stdexcept>
static void AdjustProtectMemoryPermissions(void* func, int permissions)
{
DWORD permissions_ = 0;
if (!VirtualProtect(func, 12, permissions, &permissions_))
{
throw std::runtime_error("VirtualProtect error");
}
}
static void InstallHooker(char* func, char* jump)
{
AdjustProtectMemoryPermissions(func, PAGE_EXECUTE_READWRITE);
func[0] = 0x48;
func[1] = 0xB8;
*(char**)(func + 2) = jump;
func[10] = 0xFF;
func[11] = 0xE0;
AdjustProtectMemoryPermissions(func, PAGE_EXECUTE_READ);
}
static void test(int x)
{
printf("%s: %d\n", __FUNCTION__, x);
}
static void test_dohooker(int x)
{
printf("%s: %d\n", __FUNCTION__, x);
}
int main(int argc, const char* argv[]) noexcept
{
InstallHooker((char*)&test, (char*)&test_dohooker);
test(100);
return 0;
}