@@ -254,21 +254,128 @@ TEST(BlookModuleTests, ExportParsing) {
254254 EXPECT_EQ (exported_func->data <void *>(), (void *)&f_test_exports);
255255}
256256
257- class VEHHookTest : public ::testing::Test {
258- protected:
259- std::shared_ptr<blook::InlineHook> hook_AplusB;
260- std::shared_ptr<blook::InlineHook> hook_GetTickCount;
257+ #pragma optimize("", off)
258+ int veh_test_target_func (int a, int b) { return a * b + 42 ; }
259+ int veh_test_target_func2 (int a, int b) { return a * b + 423 ; }
260+ int veh_test_target_func3 (int a, int b) { return a * b + 412 ; }
261+ int veh_test_target_func4 (int a, int b) { return a * b + 426 ; }
262+ #pragma optimize("", on)
261263
262- void TearDown () override {
264+ TEST (VEHHookTest, HookFunction) {
265+ bool called = false ;
266+ auto handler = blook::VEHHookManager::instance ().add_breakpoint (
267+ blook::VEHHookManager::HardwareBreakpoint{
268+ .address = (void *)veh_test_target_func},
269+ [&](blook::VEHHookManager::VEHHookContext &ctx) { called = true ; });
263270
264- if (hook_AplusB && hook_AplusB->is_installed ()) {
265- hook_AplusB->uninstall ();
266- }
267- if (hook_GetTickCount && hook_GetTickCount->is_installed ()) {
268- hook_GetTickCount->uninstall ();
271+ ASSERT_TRUE (
272+ std::holds_alternative<blook::VEHHookManager::HardwareBreakpointHandler>(
273+ handler));
274+
275+ veh_test_target_func (3 , 5 );
276+
277+ ASSERT_TRUE (called);
278+
279+ blook::VEHHookManager::instance ().remove_breakpoint (handler);
280+
281+ auto result = veh_test_target_func (2 , 4 );
282+ EXPECT_EQ (result, 2 * 4 + 42 );
283+ }
284+
285+ TEST (VEHHookTest, HookFunctionInAnotherThread) {
286+ bool called = false ;
287+ auto handler = blook::VEHHookManager::instance ().add_breakpoint (
288+ blook::VEHHookManager::HardwareBreakpoint{
289+ .address = (void *)veh_test_target_func},
290+ [&](blook::VEHHookManager::VEHHookContext &ctx) {
291+ called = true ;
292+ ExitThread (0 );
293+ });
294+
295+ ASSERT_TRUE (
296+ std::holds_alternative<blook::VEHHookManager::HardwareBreakpointHandler>(
297+ handler));
298+
299+ std::thread t ([]() {
300+ while (true ) {
301+ veh_test_target_func (7 , 8 );
269302 }
270- }
271- };
303+ });
304+ blook::VEHHookManager::instance ().sync_hw_breakpoints ();
305+ t.join ();
306+
307+ ASSERT_TRUE (called);
308+
309+ blook::VEHHookManager::instance ().remove_breakpoint (handler);
310+ }
311+
312+ TEST (VEHHookTest, HookMultipleFunctions) {
313+ bool called1 = false ;
314+ bool called2 = false ;
315+ bool called3 = false ;
316+ bool called4 = false ;
317+
318+ auto handler1 = blook::VEHHookManager::instance ().add_breakpoint (
319+ blook::VEHHookManager::HardwareBreakpoint{
320+ .address = (void *)veh_test_target_func},
321+ [&](blook::VEHHookManager::VEHHookContext &ctx) { called1 = true ; });
322+
323+ auto handler2 = blook::VEHHookManager::instance ().add_breakpoint (
324+ blook::VEHHookManager::HardwareBreakpoint{
325+ .address = (void *)veh_test_target_func2},
326+ [&](blook::VEHHookManager::VEHHookContext &ctx) { called2 = true ; });
327+
328+ auto handler3 = blook::VEHHookManager::instance ().add_breakpoint (
329+ blook::VEHHookManager::HardwareBreakpoint{
330+ .address = (void *)veh_test_target_func3},
331+ [&](blook::VEHHookManager::VEHHookContext &ctx) { called3 = true ; });
332+
333+ auto handler4 = blook::VEHHookManager::instance ().add_breakpoint (
334+ blook::VEHHookManager::HardwareBreakpoint{
335+ .address = (void *)veh_test_target_func4},
336+ [&](blook::VEHHookManager::VEHHookContext &ctx) { called4 = true ; });
337+
338+ ASSERT_TRUE (
339+ std::holds_alternative<blook::VEHHookManager::HardwareBreakpointHandler>(
340+ handler1));
341+ ASSERT_TRUE (
342+ std::holds_alternative<blook::VEHHookManager::HardwareBreakpointHandler>(
343+ handler2));
344+ ASSERT_TRUE (
345+ std::holds_alternative<blook::VEHHookManager::HardwareBreakpointHandler>(
346+ handler3));
347+ ASSERT_TRUE (
348+ std::holds_alternative<blook::VEHHookManager::HardwareBreakpointHandler>(
349+ handler4));
350+
351+ veh_test_target_func (3 , 5 );
352+ veh_test_target_func2 (6 , 7 );
353+ veh_test_target_func3 (8 , 9 );
354+ veh_test_target_func4 (10 , 11 );
355+
356+ ASSERT_TRUE (called1);
357+ ASSERT_TRUE (called2);
358+ ASSERT_TRUE (called3);
359+ ASSERT_TRUE (called4);
360+
361+ blook::VEHHookManager::instance ().remove_breakpoint (handler1);
362+ blook::VEHHookManager::instance ().remove_breakpoint (handler2);
363+ blook::VEHHookManager::instance ().remove_breakpoint (handler3);
364+ blook::VEHHookManager::instance ().remove_breakpoint (handler4);
365+ called1 = called2 = called3 = called4 = false ;
366+ veh_test_target_func (2 , 4 );
367+ veh_test_target_func2 (3 , 5 );
368+ veh_test_target_func3 (4 , 6 );
369+ veh_test_target_func4 (5 , 7 );
370+ EXPECT_EQ (veh_test_target_func (2 , 4 ), 2 * 4 + 42 );
371+ EXPECT_EQ (veh_test_target_func2 (3 , 5 ), 3 * 5 + 423 );
372+ EXPECT_EQ (veh_test_target_func3 (4 , 6 ), 4 * 6 + 412 );
373+ EXPECT_EQ (veh_test_target_func4 (5 , 7 ), 5 * 7 + 426 );
374+ ASSERT_FALSE (called1);
375+ ASSERT_FALSE (called2);
376+ ASSERT_FALSE (called3);
377+ ASSERT_FALSE (called4);
378+ }
272379
273380int main (int argc, char **argv) {
274381 ::testing::InitGoogleTest (&argc, argv);
0 commit comments