@@ -192,17 +192,20 @@ namespace Detours {
192192			m_pCallBack = nullptr;
193193			m_pAddress = nullptr;
194194			m_unSize = 0;
195+ 			m_unActiveThreads = 0;
195196			m_bPendingDeletion = false;
197+ 			InitializeSRWLock(&m_Lock);
196198		}
197199
198200		fnMemoryHookCallBack m_pCallBack;
199201		void* m_pAddress;
200202		size_t m_unSize;
201203		std::deque<std::unique_ptr<Page>> m_Pages;
204+ 		std::atomic<DWORD> m_unActiveThreads;
202205		bool m_bPendingDeletion;
203- 		std::unordered_set<DWORD> m_PendingRestoreThreads ;
206+ 		SRWLOCK m_Lock ;
204207	} MEMORY_HOOK_RECORD, *PMEMORY_HOOK_RECORD;
205- 	 
208+ 
206209	// ----------------------------------------------------------------
207210	// INTERRUPT_HOOK_RECORD
208211	// ----------------------------------------------------------------
@@ -217,10 +220,19 @@ namespace Detours {
217220		unsigned char m_unInterrupt;
218221	} INTERRUPT_HOOK_RECORD, *PINTERRUPT_HOOK_RECORD;
219222
223+ 	// ----------------------------------------------------------------
224+ 	// Locks
225+ 	// ----------------------------------------------------------------
226+ 
227+ 	static SRWLOCK g_MemoryHookRecordsLock = SRWLOCK_INIT;
228+ 	static SRWLOCK g_MemoryHookStacksLock = SRWLOCK_INIT;
229+ 
220230	// ----------------------------------------------------------------
221231	// Storage
222232	// ----------------------------------------------------------------
223233
234+ 	static std::unordered_map<DWORD, std::vector<PMEMORY_HOOK_RECORD>> g_MemoryHookOpenedStacks;
235+ 
224236	static std::deque<std::unique_ptr<HARDWARE_HOOK_RECORD>> g_HardwareHookRecords;
225237	static std::deque<std::unique_ptr<MEMORY_HOOK_RECORD>> g_MemoryHookRecords;
226238	static std::deque<std::unique_ptr<INTERRUPT_HOOK_RECORD>> g_InterruptHookRecords;
@@ -7357,39 +7369,69 @@ namespace Detours {
73577369				return false;
73587370			}
73597371
7360- 			const DWORD unCurrentTID = GetCurrentThreadId();
73617372			auto& eflags = *reinterpret_cast<REGISTER_FLAGS*>(&pCTX->EFlags);
7373+ 			const DWORD unCurrentTID = GetCurrentThreadId();
73627374
73637375			if (Exception.ExceptionCode == EXCEPTION_SINGLE_STEP) {
7364- 				for (auto it = g_MemoryHookRecords.begin(); it != g_MemoryHookRecords.end(); ++it) {
7365- 					const auto& pRecord = *it;
7366- 					if (!pRecord) {
7367- 						continue;
7376+ 				eflags.m_unTF = 0;
7377+ 
7378+ 				PMEMORY_HOOK_RECORD pRecord = nullptr;
7379+ 
7380+ 				AcquireSRWLockExclusive(&g_MemoryHookStacksLock);
7381+ 
7382+ 				{
7383+ 					auto it = g_MemoryHookOpenedStacks.find(unCurrentTID);
7384+ 					if (it != g_MemoryHookOpenedStacks.end() && !it->second.empty()) {
7385+ 						pRecord = it->second.back();
7386+ 						it->second.pop_back();
7387+ 						if (it->second.empty()) {
7388+ 							g_MemoryHookOpenedStacks.erase(it);
7389+ 						}
73687390					}
7391+ 				}
7392+ 
7393+ 				ReleaseSRWLockExclusive(&g_MemoryHookStacksLock);
7394+ 
7395+ 				if (!pRecord) {
7396+ 					return false;
7397+ 				}
73697398
7370- 					auto pit = pRecord->m_PendingRestoreThreads.find(unCurrentTID);
7371- 					if (pit != pRecord->m_PendingRestoreThreads.end()) {
7372- 						eflags.m_unTF = 0;
7399+ 				bool bNeedErase = false;
73737400
7401+ 				AcquireSRWLockExclusive(&pRecord->m_Lock);
7402+ 
7403+ 				{
7404+ 					const uint32_t unPrev = pRecord->m_unActiveThreads.fetch_sub(1, std::memory_order_acq_rel);
7405+ 					if (unPrev == 1) {
73747406						if (!pRecord->m_bPendingDeletion) {
73757407							for (const auto& pPage : pRecord->m_Pages) {
73767408								if (!pPage || !pPage->ChangeProtection(PAGE_NOACCESS)) {
7409+ 									ReleaseSRWLockExclusive(&pRecord->m_Lock);
73777410									return false;
73787411								}
73797412							}
7413+ 						} else {
7414+ 							bNeedErase = true;
73807415						}
7416+ 					}
7417+ 				}
73817418
7382- 						 pRecord->m_PendingRestoreThreads.erase(pit );
7419+ 				ReleaseSRWLockExclusive(& pRecord->m_Lock );
73837420
7384- 						if (pRecord->m_bPendingDeletion && pRecord->m_PendingRestoreThreads.empty()) {
7421+ 				if (bNeedErase) {
7422+ 					AcquireSRWLockExclusive(&g_MemoryHookRecordsLock);
7423+ 
7424+ 					for (auto it = g_MemoryHookRecords.begin(); it != g_MemoryHookRecords.end(); ++it) {
7425+ 						if (it->get() == pRecord) {
73857426							g_MemoryHookRecords.erase(it);
7427+ 							break;
73867428						}
7387- 
7388- 						return true;
73897429					}
7430+ 
7431+ 					ReleaseSRWLockExclusive(&g_MemoryHookRecordsLock);
73907432				}
73917433
7392- 				return false ;
7434+ 				return true ;
73937435			}
73947436
73957437			if ((Exception.ExceptionCode != EXCEPTION_ACCESS_VIOLATION) || (Exception.NumberParameters < 2)) {
@@ -7401,12 +7443,12 @@ namespace Detours {
74017443				return false;
74027444			}
74037445
7404- 			const  void* pFaultAddress = reinterpret_cast<void*>(Exception.ExceptionInformation[1]);
7446+ 			void* pFaultAddress = reinterpret_cast<void*>(Exception.ExceptionInformation[1]);
74057447			if (!pFaultAddress || (pFaultAddress == reinterpret_cast<void*>(-1))) {
74067448				return false;
74077449			}
74087450
7409- 			const  void* pExceptionAddress = reinterpret_cast<void*>(Exception.ExceptionAddress);
7451+ 			void* pExceptionAddress = reinterpret_cast<void*>(Exception.ExceptionAddress);
74107452
74117453			MEMORY_HOOK_OPERATION unOperation = MEMORY_HOOK_OPERATION::MEMORY_READ;
74127454			if (unAccessType == 1) {
@@ -7416,36 +7458,55 @@ namespace Detours {
74167458			}
74177459
74187460			PMEMORY_HOOK_RECORD pTargetRecord = nullptr;
7419- 			for (const auto& pRecord : g_MemoryHookRecords) {
7420- 				if (!pRecord) {
7421- 					continue;
7422- 				}
74237461
7424- 				for (const auto& pPage : pRecord->m_Pages) {
7425- 					if (pPage && __is_in_range(pPage->GetPageAddress(), pPage->GetPageCapacity(), pFaultAddress)) {
7426- 						pTargetRecord = pRecord.get();
7427- 						break;
7462+ 			AcquireSRWLockShared(&g_MemoryHookRecordsLock);
7463+ 
7464+ 			{
7465+ 				for (const auto& pRecord : g_MemoryHookRecords) {
7466+ 					if (!pRecord) {
7467+ 						continue;
74287468					}
7429- 				}
74307469
7431- 				if (pTargetRecord) {
7432- 					break;
7470+ 					for (const auto& pPage : pRecord->m_Pages) {
7471+ 						if (pPage && __is_in_range(pPage->GetPageAddress(), pPage->GetPageCapacity(), pFaultAddress)) {
7472+ 							pTargetRecord = pRecord.get();
7473+ 							break;
7474+ 						}
7475+ 					}
7476+ 
7477+ 					if (pTargetRecord) {
7478+ 						break;
7479+ 					}
74337480				}
74347481			}
74357482
7483+ 			ReleaseSRWLockShared(&g_MemoryHookRecordsLock);
7484+ 
74367485			if (!pTargetRecord) {
74377486				return false;
74387487			}
74397488
7440- 			pTargetRecord->m_PendingRestoreThreads.insert(unCurrentTID );
7489+ 			AcquireSRWLockExclusive(& pTargetRecord->m_Lock );
74417490
7442- 			for (const auto& pPage : pTargetRecord->m_Pages) {
7443- 				if (!pPage || !pPage->RestoreProtection()) {
7444- 					pTargetRecord->m_PendingRestoreThreads.erase(unCurrentTID);
7445- 					return false;
7491+ 			{
7492+ 				const uint32_t unPrev = pTargetRecord->m_unActiveThreads.load(std::memory_order_acquire);
7493+ 				if (unPrev == 0) {
7494+ 					for (const auto& pPage : pTargetRecord->m_Pages) {
7495+ 						if (!pPage || !pPage->RestoreProtection()) {
7496+ 							ReleaseSRWLockExclusive(&pTargetRecord->m_Lock);
7497+ 							return false;
7498+ 						}
7499+ 					}
74467500				}
7501+ 				pTargetRecord->m_unActiveThreads.fetch_add(1, std::memory_order_acq_rel);
74477502			}
74487503
7504+ 			ReleaseSRWLockExclusive(&pTargetRecord->m_Lock);
7505+ 
7506+ 			AcquireSRWLockExclusive(&g_MemoryHookStacksLock);
7507+ 			g_MemoryHookOpenedStacks[unCurrentTID].push_back(pTargetRecord);
7508+ 			ReleaseSRWLockExclusive(&g_MemoryHookStacksLock);
7509+ 
74497510			eflags.m_unTF = 1;
74507511
74517512			if (__is_in_range(pTargetRecord->m_pAddress, pTargetRecord->m_unSize, pFaultAddress)) {
@@ -84865,62 +84926,74 @@ namespace Detours {
8486584926				return false;
8486684927			}
8486784928
84868- 			for (auto& pRecord : g_MemoryHookRecords) {
84869- 				if (pRecord->m_bPendingDeletion) {
84870- 					continue;
84871- 				}
84929+ 			AcquireSRWLockExclusive(&g_MemoryHookRecordsLock);
8487284930
84873- 				if (pRecord->m_pCallBack == pCallBack) {
84874- 					g_Suspender.Resume();
84875- 					return false;
84876- 				}
84931+ 			{
84932+ 				for (auto& pRecord : g_MemoryHookRecords) {
84933+ 					if (pRecord->m_bPendingDeletion) {
84934+ 						continue;
84935+ 					}
8487784936
84878- 				if (__is_range_in_range(pRecord->m_pAddress, pRecord->m_unSize, pAddress, unSize)) {
84879- 					g_Suspender.Resume();
84880- 					return false;
84881- 				}
84937+ 					if (pRecord->m_pCallBack == pCallBack) {
84938+ 						ReleaseSRWLockExclusive(&g_MemoryHookRecordsLock);
84939+ 						g_Suspender.Resume();
84940+ 						return false;
84941+ 					}
8488284942
84883- 				auto vecRecordPages = __get_pages_info(pRecord->m_pAddress, pRecord->m_unSize, true);
84884- 				if (vecRecordPages.empty()) {
84885- 					continue;
84886- 				}
84943+ 					if (__is_range_in_range(pRecord->m_pAddress, pRecord->m_unSize, pAddress, unSize)) {
84944+ 						ReleaseSRWLockExclusive(&g_MemoryHookRecordsLock);
84945+ 						g_Suspender.Resume();
84946+ 						return false;
84947+ 					}
8488784948
84888- 				for (const auto& pPage : vecPages) {
84889- 					for (const auto& pRecordPage : vecRecordPages) {
84890- 						if (__is_range_in_range(pRecordPage.m_pBaseAddress, pRecordPage.m_unSize, pPage.m_pBaseAddress, pPage.m_unSize)) {
84891- 							g_Suspender.Resume();
84892- 							return false;
84949+ 					auto vecRecordPages = __get_pages_info(pRecord->m_pAddress, pRecord->m_unSize, true);
84950+ 					if (vecRecordPages.empty()) {
84951+ 						continue;
84952+ 					}
84953+ 
84954+ 					for (const auto& pPage : vecPages) {
84955+ 						for (const auto& pRecordPage : vecRecordPages) {
84956+ 							if (__is_range_in_range(pRecordPage.m_pBaseAddress, pRecordPage.m_unSize, pPage.m_pBaseAddress, pPage.m_unSize)) {
84957+ 								ReleaseSRWLockExclusive(&g_MemoryHookRecordsLock);
84958+ 								g_Suspender.Resume();
84959+ 								return false;
84960+ 							}
8489384961						}
8489484962					}
8489584963				}
84896- 			}
84897- 
84898- 			auto pRecord = std::make_unique<MEMORY_HOOK_RECORD>();
84899- 			if (!pRecord) {
84900- 				g_Suspender.Resume();
84901- 				return false;
84902- 			}
84903- 
84904- 			pRecord->m_pCallBack = pCallBack;
84905- 			pRecord->m_pAddress = pAddress;
84906- 			pRecord->m_unSize = unSize;
8490784964
84908- 			for ( auto& pi : vecPages) { 
84909- 				auto pPage = std::make_unique<Page>(pi.m_pBaseAddress, false); 
84910- 				if (!pPage) { 
84965+ 				 auto pRecord = std::make_unique<MEMORY_HOOK_RECORD>(); 
84966+ 				if (!pRecord) { 
84967+ 					ReleaseSRWLockExclusive(&g_MemoryHookRecordsLock); 
8491184968					g_Suspender.Resume();
8491284969					return false;
8491384970				}
8491484971
84915- 				if (!pPage->ChangeProtection(PAGE_NOACCESS)) {
84916- 					g_Suspender.Resume();
84917- 					return false;
84972+ 				pRecord->m_pCallBack = pCallBack;
84973+ 				pRecord->m_pAddress = pAddress;
84974+ 				pRecord->m_unSize = unSize;
84975+ 
84976+ 				for (auto& pi : vecPages) {
84977+ 					auto pPage = std::make_unique<Page>(pi.m_pBaseAddress, false);
84978+ 					if (!pPage) {
84979+ 						ReleaseSRWLockExclusive(&g_MemoryHookRecordsLock);
84980+ 						g_Suspender.Resume();
84981+ 						return false;
84982+ 					}
84983+ 
84984+ 					if (!pPage->ChangeProtection(PAGE_NOACCESS)) {
84985+ 						ReleaseSRWLockExclusive(&g_MemoryHookRecordsLock);
84986+ 						g_Suspender.Resume();
84987+ 						return false;
84988+ 					}
84989+ 
84990+ 					pRecord->m_Pages.emplace_back(std::move(pPage));
8491884991				}
8491984992
84920- 				pRecord->m_Pages .emplace_back(std::move(pPage ));
84993+ 				g_MemoryHookRecords .emplace_back(std::move(pRecord ));
8492184994			}
8492284995
84923- 			g_MemoryHookRecords.emplace_back(std::move(pRecord) );
84996+ 			ReleaseSRWLockExclusive(&g_MemoryHookRecordsLock );
8492484997
8492584998			g_Suspender.Resume();
8492684999			return true;
@@ -84936,34 +85009,52 @@ namespace Detours {
8493685009				return false;
8493785010			}
8493885011
85012+ 			AcquireSRWLockExclusive(&g_MemoryHookRecordsLock);
85013+ 
8493985014			for (auto it = g_MemoryHookRecords.begin(); it != g_MemoryHookRecords.end(); ++it) {
84940- 				if ((*it)->m_pCallBack == pCallBack) {
84941- 					if ((*it)->m_bPendingDeletion) {
84942- 						continue;
85015+ 				auto& pRecord = *it;
85016+ 				if (pRecord && pRecord->m_pCallBack == pCallBack) {
85017+ 
85018+ 					AcquireSRWLockExclusive(&pRecord->m_Lock);
85019+ 
85020+ 					if (pRecord->m_bPendingDeletion) {
85021+ 						ReleaseSRWLockExclusive(&pRecord->m_Lock);
85022+ 						ReleaseSRWLockExclusive(&g_MemoryHookRecordsLock);
85023+ 						g_Suspender.Resume();
85024+ 						return true;
8494385025					}
8494485026
84945- 					for (auto& pPage : (*it) ->m_Pages) {
85027+ 					for (auto& pPage : pRecord ->m_Pages) {
8494685028						if (!pPage || !pPage->RestoreProtection()) {
85029+ 							ReleaseSRWLockExclusive(&pRecord->m_Lock);
85030+ 							ReleaseSRWLockExclusive(&g_MemoryHookRecordsLock);
8494785031							g_Suspender.Resume();
8494885032							return false;
8494985033						}
8495085034					}
8495185035
84952- 					(*it) ->m_bPendingDeletion = true;
85036+ 					pRecord ->m_bPendingDeletion = true;
8495385037
84954- 					if ((*it)->m_PendingRestoreThreads.empty()) {
85038+ 					if (pRecord->m_unActiveThreads.load(std::memory_order_acquire) == 0) {
85039+ 						ReleaseSRWLockExclusive(&pRecord->m_Lock);
8495585040						g_MemoryHookRecords.erase(it);
85041+ 					} else {
85042+ 						ReleaseSRWLockExclusive(&pRecord->m_Lock);
8495685043					}
8495785044
85045+ 					ReleaseSRWLockExclusive(&g_MemoryHookRecordsLock);
8495885046					g_Suspender.Resume();
8495985047					return true;
8496085048				}
8496185049			}
8496285050
85051+ 			ReleaseSRWLockExclusive(&g_MemoryHookRecordsLock);
85052+ 
8496385053			g_Suspender.Resume();
8496485054			return false;
8496585055		}
8496685056
85057+ 
8496785058		// ----------------------------------------------------------------
8496885059		// Interrupt Hook
8496985060		// ----------------------------------------------------------------
0 commit comments