@@ -39,15 +39,10 @@ class VEHHookManager
3939
4040 return nullptr ;
4141 }
42- Page* getPage (uintptr_t adr)
42+ bool isPageHooked (uintptr_t adr)
4343 {
44- std::lock_guard<std::mutex> lock (m_pagesMutex);
45-
46- auto it = m_pages.upper_bound (adr);
47- if (it != m_pages.end ())
48- return (--it)->second .get ();
49-
50- return nullptr ;
44+ std::lock_guard lock (m_pagesMutex);
45+ return getPage (adr) != nullptr ;
5146 }
5247 void addHook (uintptr_t adr, hl::Hooker::HookCallback_t cbHook)
5348 {
@@ -63,6 +58,7 @@ class VEHHookManager
6358 }
6459 }
6560
61+ std::lock_guard lock (m_pagesMutex);
6662 auto page = getPage (adr);
6763 if (page)
6864 {
@@ -74,42 +70,45 @@ class VEHHookManager
7470 uintptr_t lowerBound = region.base ;
7571 uintptr_t upperBound = lowerBound + hl::GetPageSize ();
7672
77- std::lock_guard<std::mutex> lock (m_pagesMutex);
7873 m_pages[lowerBound] = std::make_unique<Page>(lowerBound, upperBound);
79- m_pages[ upperBound] = nullptr ;
74+ m_pages. try_emplace ( upperBound, nullptr ) ;
8075 }
8176 }
8277 void removeHook (uintptr_t adr)
8378 {
8479 m_hooks.erase (adr);
8580
86- auto page = getPage (adr);
87- if (page)
8881 {
89- if (page->m_refs == 1 )
82+ std::unique_lock lock (m_pagesMutex);
83+ auto page = getPage (adr);
84+ if (page)
9085 {
91- // Trigger the guard page violation to remove it. VEH will not handle the
92- // exception so we can be sure the guard page protection was removed.
93- [&] {
94- __try
86+ if (page->m_refs == 1 )
87+ {
88+ lock.unlock ();
89+ // Trigger the guard page violation to remove it. VEH will not handle the
90+ // exception so we can be sure the guard page protection was removed.
91+ [&]
9592 {
96- while ( true )
93+ __try
9794 {
98- auto x = *(volatile int *)adr;
95+ while (true )
96+ {
97+ auto x = *(volatile int *)adr;
98+ }
9999 }
100- }
101- __except (EXCEPTION_EXECUTE_HANDLER)
102- {
103- }
104- }();
105-
106- std::lock_guard<std::mutex> lock (m_pagesMutex);
107- m_pages.erase (page->m_end );
108- m_pages.erase (page->m_begin );
109- }
110- else
111- {
112- page->m_refs --;
100+ __except (EXCEPTION_EXECUTE_HANDLER)
101+ {
102+ }
103+ }();
104+
105+ lock.lock ();
106+ m_pages.erase (page->m_begin );
107+ }
108+ else
109+ {
110+ page->m_refs --;
111+ }
113112 }
114113 }
115114
@@ -121,6 +120,17 @@ class VEHHookManager
121120 }
122121 }
123122
123+ private:
124+ // Caller must lock.
125+ Page* getPage (uintptr_t adr)
126+ {
127+ auto it = m_pages.upper_bound (adr);
128+ if (it != m_pages.end ())
129+ return (--it)->second .get ();
130+
131+ return nullptr ;
132+ }
133+
124134private:
125135 PVOID m_pExHandler = nullptr ;
126136 std::map<uintptr_t , hl::Hooker::HookCallback_t> m_hooks;
@@ -243,7 +253,7 @@ static void checkForHookAndCall(uintptr_t adr, CONTEXT* pCtx)
243253
244254static LONG CALLBACK VectoredHandler (PEXCEPTION_POINTERS exc)
245255{
246- static uintptr_t guardFaultAdr;
256+ thread_local uintptr_t guardFaultAdr;
247257
248258 CONTEXT* pCtx = exc->ContextRecord ;
249259
@@ -285,7 +295,7 @@ static LONG CALLBACK VectoredHandler(PEXCEPTION_POINTERS exc)
285295 // Single-step exeption occured. Single-step flag is cleared now.
286296
287297 // Check if we are within a page that contains hooks.
288- if (g_vehHookManager.getPage (pCtx->REG_INSTRUCTIONPTR ))
298+ if (g_vehHookManager.isPageHooked (pCtx->REG_INSTRUCTIONPTR ))
289299 {
290300 // We are still on a hooked page. Continue single-stepping.
291301 pCtx->EFlags |= 0x100 ;
@@ -296,7 +306,7 @@ static LONG CALLBACK VectoredHandler(PEXCEPTION_POINTERS exc)
296306 {
297307 // We stepped out of a hooked page.
298308 // Check if the page that was last guarded still contains a hook.
299- if (g_vehHookManager.getPage (guardFaultAdr))
309+ if (g_vehHookManager.isPageHooked (guardFaultAdr))
300310 {
301311 // Restore guard page protection.
302312 DWORD oldProt;
0 commit comments