forked from danielkrupinski/Osiris
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathVmtHook.cpp
42 lines (36 loc) · 1.19 KB
/
VmtHook.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <algorithm>
#include <Platform/Macros/IsPlatform.h>
#if IS_WIN32()
#include <Windows.h>
#endif
#include "VmtHook.h"
#include "../Helpers.h"
void VmtHook::init(void* base) noexcept
{
this->base = base;
auto vmt = *reinterpret_cast<std::uintptr_t**>(base);
length = Helpers::calculateVmtLength(vmt);
oldVmt = std::make_unique<std::uintptr_t[]>(length);
std::copy(vmt, vmt + length, oldVmt.get());
}
void VmtHook::restore() const noexcept
{
auto vmt = *reinterpret_cast<std::uintptr_t**>(base);
#if IS_WIN32()
if (DWORD oldProtection; VirtualProtect(vmt, length, PAGE_EXECUTE_READWRITE, &oldProtection)) {
std::copy(oldVmt.get(), oldVmt.get() + length, vmt);
VirtualProtect(vmt, length, oldProtection, nullptr);
}
#endif
}
std::uintptr_t VmtHook::hookAt(std::size_t index, void* fun) const noexcept
{
auto address = *reinterpret_cast<std::uintptr_t**>(base) + index;
#if IS_WIN32()
if (DWORD oldProtection; VirtualProtect(address, sizeof(address), PAGE_EXECUTE_READWRITE, &oldProtection)) {
*address = std::uintptr_t(fun);
VirtualProtect(address, sizeof(address), oldProtection, nullptr);
}
#endif
return oldVmt[index];
}