-
Notifications
You must be signed in to change notification settings - Fork 18
/
dpContext.cpp
123 lines (108 loc) · 3.47 KB
/
dpContext.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
111
112
113
114
115
116
117
118
119
120
121
122
123
// created by i-saint
// distributed under Creative Commons Attribution (CC BY) license.
// https://github.com/i-saint/DynamicPatcher
#include "DynamicPatcher.h"
#include "dpInternal.h"
dpContext::dpContext()
{
m_builder = new dpBuilder(this);
m_patcher = new dpPatcher(this);
m_loader = new dpLoader(this);
}
dpContext::~dpContext()
{
m_builder->stopAutoBuild();
m_builder->stopPreload();
// バイナリ unload 時に適切に unpatch するには patcher より先に loader を破棄する必要がある
delete m_loader; m_loader=nullptr;
delete m_patcher; m_patcher=nullptr;
delete m_builder; m_builder=nullptr;
}
dpBuilder* dpContext::getBuilder() { return m_builder; }
dpPatcher* dpContext::getPatcher() { return m_patcher; }
dpLoader* dpContext::getLoader() { return m_loader; }
size_t dpContext::load(const char *path)
{
size_t ret = 0;
dpGlob(path, [&](const std::string &p){
if(m_loader->load(p.c_str())) { ++ret; }
});
return ret;
}
size_t dpContext::patchByFile(const char *filename, const char *filter_regex)
{
if(dpBinary *bin=m_loader->findBinary(filename)) {
std::regex reg(filter_regex);
m_patcher->patchByBinary(bin,
[&](const dpSymbolS &sym){
return std::regex_search(sym.name, reg);
});
return true;
}
return false;
}
size_t dpContext::patchByFile(const char *filename, const std::function<bool (const dpSymbolS&)> &condition)
{
if(dpBinary *bin=m_loader->findBinary(filename)) {
m_patcher->patchByBinary(bin, condition);
return true;
}
return false;
}
bool dpContext::patchNameToName(const char *target_name, const char *hook_name)
{
dpSymbol *target = m_loader->findHostSymbolByName(target_name);
dpSymbol *hook = m_loader->findSymbolByName(hook_name);
if(target && hook) {
return m_patcher->patch(target, hook)!=nullptr;
}
return false;
}
bool dpContext::patchAddressToName(const char *target_name, void *hook_addr)
{
dpSymbol *target = m_loader->findHostSymbolByName(target_name);
dpSymbol *hook = m_loader->findSymbolByAddress(hook_addr);
if(target && hook) {
return m_patcher->patch(target, hook)!=nullptr;
}
return false;
}
bool dpContext::patchAddressToAddress(void *target_addr, void *hook_addr)
{
dpSymbol *target = m_loader->findHostSymbolByAddress(target_addr);
dpSymbol *hook = m_loader->findSymbolByAddress(hook_addr);
if(target && hook) {
return m_patcher->patch(target, hook)!=nullptr;
}
return false;
}
bool dpContext::patchByAddress(void *hook_addr)
{
if(dpSymbol *hook=m_loader->findSymbolByAddress(hook_addr)) {
if(dpSymbol *target=m_loader->findHostSymbolByName(hook->name)) {
return m_patcher->patch(target, hook)!=nullptr;
}
}
return false;
}
bool dpContext::unpatchByAddress(void *target_or_hook_addr)
{
return m_patcher->unpatchByAddress(target_or_hook_addr);
}
void dpContext::unpatchAll()
{
return m_patcher->unpatchAll();
}
void* dpContext::getUnpatched(void *target)
{
#ifdef dpWithTDisasm
if(dpPatchData *pd = m_patcher->findPatchByAddress(target)) {
return pd->unpatched;
}
#endif // dpWithTDisasm
return nullptr;
}
void dpContext::addForceHostSymbolPattern(const char *pattern)
{
m_loader->addForceHostSymbolPattern(pattern);
}