-
Notifications
You must be signed in to change notification settings - Fork 900
/
Copy pathInterceptRouting.cpp
97 lines (80 loc) · 2.74 KB
/
InterceptRouting.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
#include "dobby/dobby_internal.h"
#include "InterceptRouting/InterceptRouting.h"
#include "InterceptRouting/RoutingPlugin/RoutingPlugin.h"
using namespace zz;
void log_hex_format(uint8_t *buffer, uint32_t buffer_size) {
char output[1024] = {0};
for (int i = 0; i < buffer_size && i < sizeof(output); i++) {
snprintf(output + strlen(output), 3, "%02x ", *((uint8_t *)buffer + i));
}
DEBUG_LOG("%s", output);
};
void InterceptRouting::Prepare() {
}
// generate relocated code
bool InterceptRouting::GenerateRelocatedCode() {
uint32_t tramp_size = GetTrampolineBuffer()->GetBufferSize();
origin_ = new CodeMemBlock(entry_->patched_addr, tramp_size);
relocated_ = new CodeMemBlock();
auto buffer = (void *)entry_->patched_addr;
#if defined(TARGET_ARCH_ARM)
if (entry_->thumb_mode) {
buffer = (void *)((addr_t)buffer + 1);
}
#endif
GenRelocateCodeAndBranch(buffer, origin_, relocated_);
if (relocated_->size == 0) {
ERROR_LOG("[insn relocate]] failed");
return false;
}
// set the relocated instruction address
entry_->relocated_addr = relocated_->addr;
// save original prologue
memcpy((void *)entry_->origin_insns, (void *)origin_->addr, origin_->size);
entry_->origin_insn_size = origin_->size;
// log
DEBUG_LOG("[insn relocate] origin %p - %d", origin_->addr, origin_->size);
log_hex_format((uint8_t *)origin_->addr, origin_->size);
DEBUG_LOG("[insn relocate] relocated %p - %d", relocated_->addr, relocated_->size);
log_hex_format((uint8_t *)relocated_->addr, relocated_->size);
return true;
}
bool InterceptRouting::GenerateTrampolineBuffer(addr_t src, addr_t dst) {
// if near branch trampoline plugin enabled
if (RoutingPluginManager::near_branch_trampoline) {
auto plugin = static_cast<RoutingPluginInterface *>(RoutingPluginManager::near_branch_trampoline);
if (plugin->GenerateTrampolineBuffer(this, src, dst) == false) {
DEBUG_LOG("Failed enable near branch trampoline plugin");
}
}
if (GetTrampolineBuffer() == nullptr) {
auto tramp_buffer = GenerateNormalTrampolineBuffer(src, dst);
SetTrampolineBuffer(tramp_buffer);
}
return true;
}
// active routing, patch origin instructions as trampoline
void InterceptRouting::Active() {
auto ret = DobbyCodePatch((void *)entry_->patched_addr, trampoline_buffer_->GetBuffer(),
trampoline_buffer_->GetBufferSize());
if (ret == -1) {
ERROR_LOG("[intercept routing] active failed");
return;
}
DEBUG_LOG("[intercept routing] active");
}
void InterceptRouting::Commit() {
this->Active();
}
#if 0
int InterceptRouting::PredefinedTrampolineSize() {
#if __arm64__
return 12;
#elif __arm__
return 8;
#endif
}
#endif
InterceptEntry *InterceptRouting::GetInterceptEntry() {
return entry_;
};