Skip to content

Commit 3524a93

Browse files
refactor: use trampoline for sw breakpoints
1 parent d74d6c7 commit 3524a93

File tree

2 files changed

+19
-5
lines changed

2 files changed

+19
-5
lines changed

include/blook/hook.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ class VEHHookManager {
114114
SoftwareBreakpoint bp;
115115
BreakpointCallback callback;
116116
std::vector<uint8_t> original_bytes;
117+
Trampoline trampoline;
117118
};
118119

119120
struct PagefaultBreakpointInformation {

src/hook.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -135,10 +135,7 @@ static LONG blook_VectoredExceptionHandler(_EXCEPTION_POINTERS *ExceptionInfo) {
135135
if (manager.thread_bp_in_progress.contains(thread_id)) {
136136
void *bp_address = manager.thread_bp_in_progress.at(thread_id);
137137

138-
if (manager.sw_breakpoints.contains(bp_address)) {
139-
uint8_t int3 = 0xCC;
140-
Pointer(bp_address).write(nullptr, std::span(&int3, 1));
141-
} else if (manager.pf_breakpoints.contains(bp_address)) {
138+
if (manager.pf_breakpoints.contains(bp_address)) {
142139
auto &bp = manager.pf_breakpoints.at(bp_address);
143140
DWORD old_protect;
144141
VirtualProtect(bp_address, 1, bp.origin_protection | PAGE_GUARD,
@@ -148,7 +145,7 @@ static LONG blook_VectoredExceptionHandler(_EXCEPTION_POINTERS *ExceptionInfo) {
148145
return EXCEPTION_CONTINUE_EXECUTION;
149146
}
150147

151-
// If not a re-enable step, check for a hardware breakpoint
148+
// If not a re-enable step, check for a hardware breakpoint or software bp
152149
for (auto &bp_opt : manager.hw_breakpoints) {
153150
if (bp_opt.has_value() && bp_opt->bp.address == address) {
154151
if (bp_opt->callback) {
@@ -164,6 +161,21 @@ static LONG blook_VectoredExceptionHandler(_EXCEPTION_POINTERS *ExceptionInfo) {
164161
}
165162
}
166163

164+
for (auto &[addr, bp] : manager.sw_breakpoints) {
165+
if (addr == address) {
166+
if (bp.callback) {
167+
size_t origRip = ExceptionInfo->ContextRecord->Rip;
168+
VEHHookManager::VEHHookContext ctx(ExceptionInfo);
169+
bp.callback(ctx);
170+
if (ExceptionInfo->ContextRecord->Rip == origRip) {
171+
ExceptionInfo->ContextRecord->Rip =
172+
(size_t)bp.trampoline.pTrampoline.data();
173+
}
174+
}
175+
return EXCEPTION_CONTINUE_EXECUTION;
176+
}
177+
}
178+
167179
} else if (code == EXCEPTION_BREAKPOINT) {
168180
if (manager.sw_breakpoints.contains(address)) {
169181
auto &bp = manager.sw_breakpoints.at(address);
@@ -254,6 +266,7 @@ VEHHookManager::add_breakpoint(SoftwareBreakpoint bp,
254266
"Failed to read original byte for software breakpoint.");
255267
}
256268
info.original_bytes.push_back(*original_byte);
269+
info.trampoline = Trampoline::make(bp.address, 1, true);
257270

258271
uint8_t int3 = 0xCC;
259272
if (!Pointer(bp.address).write(nullptr, std::span(&int3, 1))) {

0 commit comments

Comments
 (0)