@@ -166,6 +166,7 @@ namespace Detours {
166166 m_unSize = 0;
167167 m_bPendingRestore = false;
168168 m_bPendingDeletion = false;
169+ m_bCancelRestore = false;
169170 }
170171
171172 DWORD m_unThreadID;
@@ -176,6 +177,7 @@ namespace Detours {
176177 unsigned char m_unSize;
177178 bool m_bPendingRestore;
178179 bool m_bPendingDeletion;
180+ bool m_bCancelRestore;
179181 } HARDWARE_HOOK_RECORD, *PHARDWARE_HOOK_RECORD;
180182
181183 // ----------------------------------------------------------------
@@ -7149,60 +7151,29 @@ namespace Detours {
71497151 }
71507152
71517153 const DWORD unCurrentTID = GetCurrentThreadId();
7152-
71537154 auto& dr6 = *reinterpret_cast<REGISTER_DR6*>(&pCTX->Dr6);
71547155 auto& dr7 = *reinterpret_cast<REGISTER_DR7*>(&pCTX->Dr7);
71557156 auto& eflags = *reinterpret_cast<REGISTER_FLAGS*>(&pCTX->EFlags);
71567157
71577158 bool bRestored = false;
71587159
7159- for (auto& pRecord : g_HardwareHookRecords) {
7160- if (!pRecord || pRecord->m_bPendingDeletion) {
7160+ for (auto it = g_HardwareHookRecords.begin(); it != g_HardwareHookRecords.end(); ) {
7161+ auto& pRecord = *it;
7162+ if (!pRecord || (pRecord->m_unThreadID != unCurrentTID) || !pRecord->m_bPendingRestore) {
7163+ ++it;
71617164 continue;
71627165 }
71637166
7164- if (pRecord->m_unThreadID != unCurrentTID) {
7167+ if (pRecord->m_bCancelRestore) {
7168+ pRecord->m_bPendingRestore = false;
7169+ pRecord->m_bCancelRestore = false;
7170+ eflags.m_unTF = 0;
7171+ dr6.m_unBS = 0;
7172+ it = g_HardwareHookRecords.erase(it);
7173+ bRestored = true;
71657174 continue;
71667175 }
71677176
7168- if (!pRecord->m_bPendingRestore) {
7169- continue;
7170- }
7171-
7172- switch (pRecord->m_unRegister) {
7173- case HARDWARE_HOOK_REGISTER::REGISTER_DR0:
7174- #ifdef _M_X64
7175- pCTX->Dr0 = reinterpret_cast<DWORD64>(pRecord->m_pAddress);
7176- #elif _M_IX86
7177- pCTX->Dr0 = reinterpret_cast<DWORD>(pRecord->m_pAddress);
7178- #endif
7179- break;
7180-
7181- case HARDWARE_HOOK_REGISTER::REGISTER_DR1:
7182- #ifdef _M_X64
7183- pCTX->Dr1 = reinterpret_cast<DWORD64>(pRecord->m_pAddress);
7184- #elif _M_IX86
7185- pCTX->Dr1 = reinterpret_cast<DWORD>(pRecord->m_pAddress);
7186- #endif
7187- break;
7188-
7189- case HARDWARE_HOOK_REGISTER::REGISTER_DR2:
7190- #ifdef _M_X64
7191- pCTX->Dr2 = reinterpret_cast<DWORD64>(pRecord->m_pAddress);
7192- #elif _M_IX86
7193- pCTX->Dr2 = reinterpret_cast<DWORD>(pRecord->m_pAddress);
7194- #endif
7195- break;
7196-
7197- case HARDWARE_HOOK_REGISTER::REGISTER_DR3:
7198- #ifdef _M_X64
7199- pCTX->Dr3 = reinterpret_cast<DWORD64>(pRecord->m_pAddress);
7200- #elif _M_IX86
7201- pCTX->Dr3 = reinterpret_cast<DWORD>(pRecord->m_pAddress);
7202- #endif
7203- break;
7204- }
7205-
72067177 unsigned char unTypeValue = 0;
72077178 switch (pRecord->m_unType) {
72087179 case HARDWARE_HOOK_TYPE::TYPE_EXECUTE:
@@ -7241,24 +7212,44 @@ namespace Detours {
72417212
72427213 switch (pRecord->m_unRegister) {
72437214 case HARDWARE_HOOK_REGISTER::REGISTER_DR0:
7215+ #ifdef _M_X64
7216+ pCTX->Dr0 = reinterpret_cast<DWORD64>(pRecord->m_pAddress);
7217+ #else
7218+ pCTX->Dr0 = reinterpret_cast<DWORD>(pRecord->m_pAddress);
7219+ #endif
72447220 dr7.m_unL0 = 1;
72457221 dr7.m_unRW0 = unTypeValue;
72467222 dr7.m_unLEN0 = unSizeValue;
72477223 break;
72487224
72497225 case HARDWARE_HOOK_REGISTER::REGISTER_DR1:
7226+ #ifdef _M_X64
7227+ pCTX->Dr1 = reinterpret_cast<DWORD64>(pRecord->m_pAddress);
7228+ #else
7229+ pCTX->Dr1 = reinterpret_cast<DWORD>(pRecord->m_pAddress);
7230+ #endif
72507231 dr7.m_unL1 = 1;
72517232 dr7.m_unRW1 = unTypeValue;
72527233 dr7.m_unLEN1 = unSizeValue;
72537234 break;
72547235
72557236 case HARDWARE_HOOK_REGISTER::REGISTER_DR2:
7237+ #ifdef _M_X64
7238+ pCTX->Dr2 = reinterpret_cast<DWORD64>(pRecord->m_pAddress);
7239+ #else
7240+ pCTX->Dr2 = reinterpret_cast<DWORD>(pRecord->m_pAddress);
7241+ #endif
72567242 dr7.m_unL2 = 1;
72577243 dr7.m_unRW2 = unTypeValue;
72587244 dr7.m_unLEN2 = unSizeValue;
72597245 break;
72607246
72617247 case HARDWARE_HOOK_REGISTER::REGISTER_DR3:
7248+ #ifdef _M_X64
7249+ pCTX->Dr3 = reinterpret_cast<DWORD64>(pRecord->m_pAddress);
7250+ #else
7251+ pCTX->Dr3 = reinterpret_cast<DWORD>(pRecord->m_pAddress);
7252+ #endif
72627253 dr7.m_unL3 = 1;
72637254 dr7.m_unRW3 = unTypeValue;
72647255 dr7.m_unLEN3 = unSizeValue;
@@ -7270,22 +7261,18 @@ namespace Detours {
72707261 dr7.m_unGD = 0;
72717262
72727263 pRecord->m_bPendingRestore = false;
7273-
72747264 bRestored = true;
7265+
7266+ if (pRecord->m_bPendingDeletion) {
7267+ it = g_HardwareHookRecords.erase(it);
7268+ } else {
7269+ ++it;
7270+ }
72757271 }
72767272
72777273 if (bRestored) {
72787274 dr6.m_unBS = 0;
72797275 eflags.m_unTF = 0;
7280-
7281- for (auto it = g_HardwareHookRecords.begin(); it != g_HardwareHookRecords.end(); ) {
7282- if ((*it)->m_bPendingDeletion && (*it)->m_unThreadID == unCurrentTID && !(*it)->m_bPendingRestore) {
7283- it = g_HardwareHookRecords.erase(it);
7284- return true;
7285- } else {
7286- ++it;
7287- }
7288- }
72897276 }
72907277
72917278 HARDWARE_HOOK_REGISTER unRegister = HARDWARE_HOOK_REGISTER::REGISTER_DR0;
@@ -7316,6 +7303,7 @@ namespace Detours {
73167303 }
73177304
73187305 bool bEnabled = false;
7306+
73197307 switch (unRegister) {
73207308 case HARDWARE_HOOK_REGISTER::REGISTER_DR0:
73217309 bEnabled = (dr7.m_unL0 || dr7.m_unG0);
@@ -7343,42 +7331,27 @@ namespace Detours {
73437331 switch (unRegister) {
73447332 case HARDWARE_HOOK_REGISTER::REGISTER_DR0:
73457333 dr6.m_unB0 = 0;
7346- break;
7347-
7348- case HARDWARE_HOOK_REGISTER::REGISTER_DR1:
7349- dr6.m_unB1 = 0;
7350- break;
7351-
7352- case HARDWARE_HOOK_REGISTER::REGISTER_DR2:
7353- dr6.m_unB2 = 0;
7354- break;
7355-
7356- case HARDWARE_HOOK_REGISTER::REGISTER_DR3:
7357- dr6.m_unB3 = 0;
7358- break;
7359- }
7360-
7361- switch (unRegister) {
7362- case HARDWARE_HOOK_REGISTER::REGISTER_DR0:
73637334 dr7.m_unL0 = 0;
73647335 dr7.m_unG0 = 0;
73657336 break;
73667337
73677338 case HARDWARE_HOOK_REGISTER::REGISTER_DR1:
7339+ dr6.m_unB1 = 0;
73687340 dr7.m_unL1 = 0;
73697341 dr7.m_unG1 = 0;
73707342 break;
73717343
73727344 case HARDWARE_HOOK_REGISTER::REGISTER_DR2:
7345+ dr6.m_unB2 = 0;
73737346 dr7.m_unL2 = 0;
73747347 dr7.m_unG2 = 0;
73757348 break;
73767349
73777350 case HARDWARE_HOOK_REGISTER::REGISTER_DR3:
7351+ dr6.m_unB3 = 0;
73787352 dr7.m_unL3 = 0;
73797353 dr7.m_unG3 = 0;
73807354 break;
7381-
73827355 }
73837356
73847357 eflags.m_unTF = 1;
@@ -84792,87 +84765,81 @@ namespace Detours {
8479284765 }
8479384766
8479484767 for (auto it = g_HardwareHookRecords.begin(); it != g_HardwareHookRecords.end(); ++it) {
84795- if ((*it)->m_bPendingDeletion) {
84768+ auto& pRecord = *it;
84769+ if (!pRecord || pRecord->m_bPendingDeletion) {
8479684770 continue;
8479784771 }
8479884772
84799- if (((*it)->m_unThreadID == unThreadID) && ((*it)->m_unRegister == unRegister)) {
84800- HANDLE hThread = OpenThread(THREAD_GET_CONTEXT | THREAD_SET_CONTEXT, FALSE, unThreadID);
84801- if (!hThread) {
84802- g_Suspender.Resume();
84803- return true;
84804- }
84805-
84806- if (hThread == INVALID_HANDLE_VALUE) {
84807- g_Suspender.Resume();
84808- return false;
84809- }
84810-
84811- CONTEXT ctx = { 0 };
84812- ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
84813-
84814- if (GetThreadContext(hThread, &ctx)) {
84815- unsigned char unDRIndex = 0;
84816- switch ((*it)->m_unRegister) {
84817- case HARDWARE_HOOK_REGISTER::REGISTER_DR0:
84818- ctx.Dr0 = 0;
84819- unDRIndex = 0;
84820- break;
84821-
84822- case HARDWARE_HOOK_REGISTER::REGISTER_DR1:
84823- ctx.Dr1 = 0;
84824- unDRIndex = 1;
84825- break;
84826-
84827- case HARDWARE_HOOK_REGISTER::REGISTER_DR2:
84828- ctx.Dr2 = 0;
84829- unDRIndex = 2;
84830- break;
84773+ if (pRecord->m_unThreadID != unThreadID) {
84774+ continue;
84775+ }
8483184776
84832- case HARDWARE_HOOK_REGISTER::REGISTER_DR3:
84833- ctx.Dr3 = 0;
84834- unDRIndex = 3;
84835- break;
84836- }
84777+ if (pRecord->m_unRegister != unRegister) {
84778+ continue;
84779+ }
8483784780
84838- auto& dr7 = *reinterpret_cast<REGISTER_DR7*>(&ctx.Dr7);
84781+ if (pRecord->m_bPendingRestore) {
84782+ pRecord->m_bCancelRestore = true;
84783+ pRecord->m_bPendingDeletion = true;
84784+ g_Suspender.Resume();
84785+ return true;
84786+ }
8483984787
84840- switch (unDRIndex) {
84841- case 0:
84842- dr7.m_unL0 = 0;
84843- dr7.m_unRW0 = 0;
84844- dr7.m_unLEN0 = 0;
84845- break;
84788+ HANDLE hThread = OpenThread(THREAD_GET_CONTEXT | THREAD_SET_CONTEXT, FALSE, unThreadID);
84789+ if (!hThread || hThread == INVALID_HANDLE_VALUE) {
84790+ pRecord->m_bPendingDeletion = true;
84791+ g_HardwareHookRecords.erase(it);
84792+ g_Suspender.Resume();
84793+ return true;
84794+ }
8484684795
84847- case 1:
84848- dr7.m_unL1 = 0;
84849- dr7.m_unRW1 = 0;
84850- dr7.m_unLEN1 = 0;
84851- break;
84796+ CONTEXT ctx = {};
84797+ ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
84798+ if (GetThreadContext(hThread, &ctx)) {
84799+ auto& dr7 = *reinterpret_cast<REGISTER_DR7*>(&ctx.Dr7);
84800+ switch (unRegister) {
84801+ case HARDWARE_HOOK_REGISTER::REGISTER_DR0:
84802+ ctx.Dr0 = 0;
84803+ dr7.m_unL0 = 0;
84804+ dr7.m_unG0 = 0;
84805+ dr7.m_unRW0 = 0;
84806+ dr7.m_unLEN0 = 0;
84807+ break;
8485284808
84853- case 2:
84854- dr7.m_unL2 = 0;
84855- dr7.m_unRW2 = 0;
84856- dr7.m_unLEN2 = 0;
84857- break;
84809+ case HARDWARE_HOOK_REGISTER::REGISTER_DR1:
84810+ ctx.Dr1 = 0;
84811+ dr7.m_unL1 = 0;
84812+ dr7.m_unG1 = 0;
84813+ dr7.m_unRW1 = 0;
84814+ dr7.m_unLEN1 = 0;
84815+ break;
8485884816
84859- case 3:
84860- dr7.m_unL3 = 0;
84861- dr7.m_unRW3 = 0;
84862- dr7.m_unLEN3 = 0;
84863- break;
84864- }
84817+ case HARDWARE_HOOK_REGISTER::REGISTER_DR2:
84818+ ctx.Dr2 = 0;
84819+ dr7.m_unL2 = 0;
84820+ dr7.m_unG2 = 0;
84821+ dr7.m_unRW2 = 0;
84822+ dr7.m_unLEN2 = 0;
84823+ break;
8486584824
84866- SetThreadContext(hThread, &ctx);
84825+ case HARDWARE_HOOK_REGISTER::REGISTER_DR3:
84826+ ctx.Dr3 = 0;
84827+ dr7.m_unL3 = 0;
84828+ dr7.m_unG3 = 0;
84829+ dr7.m_unRW3 = 0;
84830+ dr7.m_unLEN3 = 0;
84831+ break;
8486784832 }
8486884833
84869- CloseHandle(hThread);
84834+ SetThreadContext(hThread, &ctx);
84835+ }
8487084836
84871- (*it)->m_bPendingDeletion = true ;
84837+ CloseHandle(hThread) ;
8487284838
84873- g_Suspender.Resume();
84874- return true;
84875- }
84839+ pRecord->m_bPendingDeletion = true;
84840+ g_HardwareHookRecords.erase(it);
84841+ g_Suspender.Resume();
84842+ return true;
8487684843 }
8487784844
8487884845 g_Suspender.Resume();
0 commit comments