Skip to content

Commit 2d6b473

Browse files
committed
Minor changes
1 parent 3109868 commit 2d6b473

File tree

1 file changed

+170
-79
lines changed

1 file changed

+170
-79
lines changed

Detours.cpp

Lines changed: 170 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)