-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinterface.cpp
110 lines (90 loc) · 2.49 KB
/
interface.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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include <interface.hpp>
#include <cstring>
#include <iostream>
#include <memory.hpp>
#include <sdk.hpp>
Interface::Interface() :
baseclass(nullptr),
vtable(nullptr),
vtableSize(0),
isHooked(false),
copy(nullptr)
{
}
Interface::Interface(void* baseclass, bool copyVtable, bool autoHook) : Interface() {
this->baseclass = reinterpret_cast<uintptr_t**>(baseclass);
this->vtable = *this->baseclass;
while(this->vtable[this->vtableSize]) {
++this->vtableSize;
}
if(copyVtable) {
this->CopyVtable();
if(autoHook) {
this->EnableHooks();
}
}
}
Interface::~Interface() {
this->DisableHooks();
if(this->copy) {
this->copy.reset();
}
}
void Interface::CopyVtable() {
if(!this->copy) {
this->copy = std::make_unique<uintptr_t[]>(this->vtableSize + 1);
std::memcpy(this->copy.get(), this->vtable - 1, sizeof(uintptr_t) + this->vtableSize * sizeof(uintptr_t));
}
}
void Interface::EnableHooks() {
if(!this->isHooked) {
*this->baseclass = this->copy.get() + 1;
this->isHooked = true;
}
}
void Interface::DisableHooks() {
if(!this->isHooked) {
*this->baseclass = this->vtable;
this->isHooked = false;
}
}
bool Interface::Unhook(int index) {
if(index >= 0 && index < this->vtableSize) {
this->copy[index + 1] = this->vtable[index];
return true;
}
return false;
}
Interface* Interface::Create(void* ptr, bool copyVtable, bool autoHook) {
return (ptr) ? new Interface(ptr, copyVtable, autoHook) : nullptr;
}
Interface* Interface::Create(const char* filename, const char* interfaceSymbol, bool copyVtable, bool autoHook) {
auto ptr = Interface::GetPtr(filename, interfaceSymbol);
return (ptr) ? new Interface(ptr, copyVtable, autoHook) : nullptr;
}
void Interface::Delete(Interface* ptr) {
if(ptr) {
delete ptr;
ptr = nullptr;
}
}
void* Interface::GetPtr(const char* filename, const char* interfaceSymbol) {
auto handle = Memory::GetModuleHandleByName(filename);
if(!handle) {
std::cerr << "Plug: failed to open module " << filename << "!" << std::endl;
return nullptr;
}
auto CreateInterface = Memory::GetSymbolAddress<CreateInterfaceFn>(handle, "CreateInterface");
Memory::CloseModuleHandle(handle);
if (!CreateInterface) {
std::cerr << "Plug: failed to find symbol CreateInterface for " << filename << "!" << std::endl;
return nullptr;
}
int ret;
void *fn = CreateInterface(interfaceSymbol, &ret);
if(ret) {
std::cerr << "Plug: failed to find interface with symbol " << interfaceSymbol << " in " << filename << "!" << std::endl;
return nullptr;
}
return fn;
}