34 lines
1.4 KiB
C++
34 lines
1.4 KiB
C++
#pragma once
|
|
#include <cstdint>
|
|
#include <type_traits>
|
|
|
|
namespace FunctionHooking {
|
|
class Detour {
|
|
private:
|
|
void* source = nullptr; //The function to be hooked.
|
|
void* destination = nullptr; //The function we are redirecting execution to.
|
|
uint8_t overwritten_bytes[13] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
|
uint8_t hook_bytes[13] = {0x49, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x41, 0xFF, 0xE2};
|
|
void createHook(void* source_address, void* destination_address);
|
|
public:
|
|
void removeHook();
|
|
Detour(void* source_address, void* destination_address);
|
|
Detour() = default;
|
|
|
|
//TODO This is *technically* not thread safe.
|
|
template <typename T, typename... Args>
|
|
inline typename std::enable_if<!std::is_void<T>::value, T>::type callOriginal(Args... args) {
|
|
removeHook();
|
|
const T result = reinterpret_cast<T(*)(Args...)>(source)(args...);
|
|
createHook(source, destination);
|
|
return result;
|
|
}
|
|
|
|
template <typename T, typename... Args>
|
|
inline typename std::enable_if<std::is_void<T>::value, void>::type callOriginal(Args... args) {
|
|
removeHook();
|
|
reinterpret_cast<void(*)(Args...)>(source)(args...);
|
|
createHook(source, destination);
|
|
}
|
|
};
|
|
} |