Files
FunctionHooking/src/linuxRV64/Hook.cpp

42 lines
1.6 KiB
C++

#include <FunctionHook/Hook.h>
#include <sys/mman.h>
#include <csignal>
#include <cstring>
constexpr uint32_t JAL_OPCODE = 0b1101111;
constexpr int JAL_OFFSET_SHIFT = 12;
constexpr int JAL_MASK = 0xfff;
void FunctionHooking::Detour::CreateHook(void* source_address, void* destination_address) {
intptr_t target_addr = reinterpret_cast<intptr_t>(source_address);
intptr_t hook_addr = reinterpret_cast<intptr_t>(destination_address);
int32_t offset = (hook_addr - target_addr) >> 1;
// Encode the offset for the JAL instruction
uint32_t instruction = (JAL_OPCODE & JAL_MASK) |
((offset & 0x7fe) << 20) | // bits 1 to 10 of offset
((offset & 0x800) << 9) | // bit 11 of offset
((offset & 0xff000) << 9); // bits 12 to 19 of offset
hook_bytes.resize(sizeof(instruction));
std::memcpy(hook_bytes.data(), &instruction, sizeof(instruction));
overwritten_bytes.resize(sizeof(instruction));
std::memcpy(overwritten_bytes.data(), source_address, sizeof(instruction));
// Determine the page size and page containing the target function
long page_size = sysconf(_SC_PAGESIZE);
void* page_start = reinterpret_cast<void*>(target_addr & ~(page_size - 1));
// Change memory protection to allow writing
if (mprotect(page_start, page_size, PROT_READ | PROT_WRITE | PROT_EXEC) == -1)
return;
// Write the instruction to the target function
std::memcpy(source_address, &instruction, sizeof(instruction));
// Restore original memory protection
if (mprotect(page_start, page_size, PROT_READ | PROT_EXEC) == -1)
return;
}