41 lines
1.7 KiB
C++
41 lines
1.7 KiB
C++
#include <FunctionHook/Hook.h>
|
|
#include <sys/mman.h>
|
|
#include <csignal>
|
|
#include <cstring>
|
|
|
|
void FunctionHooking::Detour::createHook(void* source_address, void* destination_address) {
|
|
source = source_address;
|
|
destination = destination_address;
|
|
|
|
hook_bytes.insert(hook_bytes.begin(), { 0x17, 0x05, 0x00, 0x00, 0x03, 0x25, 0x05, 0x00, 0x67, 0x00, 0x0a, 0x00} );
|
|
|
|
overwritten_bytes.resize(hook_bytes.size() + 8);
|
|
|
|
//Save the bytes to be overwritten from the function prelude
|
|
memcpy(overwritten_bytes.data(), source_address, hook_bytes.size());
|
|
|
|
//Calculate the offset.
|
|
intptr_t offset = (intptr_t)destination_address - (intptr_t)source_address;
|
|
|
|
//Place the offset into the auipc instruction
|
|
memcpy(&hook_bytes[1], &offset, sizeof(uint32_t));
|
|
|
|
//Append the destination address after the instructions
|
|
hook_bytes.insert(hook_bytes.end(), (uint8_t*)&destination_address, (uint8_t*)&destination_address + sizeof(void*));
|
|
|
|
//Save the bytes to be overwritten from the function prelude.
|
|
memcpy(overwritten_bytes.data(), source_address, hook_bytes.size());
|
|
|
|
//Put the destination address into the jump.
|
|
memcpy(&hook_bytes[2], &destination_address, sizeof(void*));
|
|
|
|
//Make the target memory page writable.
|
|
mprotect((void*)((uintptr_t)source_address & ~(sysconf(_SC_PAGE_SIZE)-1)), sysconf(_SC_PAGE_SIZE), PROT_READ|PROT_WRITE|PROT_EXEC);
|
|
|
|
//Write the jmp to the beginning of the function prelude.
|
|
memcpy(source_address, hook_bytes.data(), hook_bytes.size());
|
|
|
|
//Make the memory page non-writable again.
|
|
mprotect((void*)((uintptr_t)source_address & ~(sysconf(_SC_PAGE_SIZE)-1)), sysconf(_SC_PAGE_SIZE), PROT_READ|PROT_EXEC);
|
|
}
|