@@ -158,14 +158,15 @@ namespace Detours {
158
158
m_pCallBack = nullptr;
159
159
m_pAddress = nullptr;
160
160
m_unSize = 0;
161
- m_bSupportTrampoline = false;
161
+ m_bAllowVirtualAddress = false;
162
162
}
163
163
164
164
fnMemoryHookCallBack m_pCallBack;
165
165
void* m_pAddress;
166
166
size_t m_unSize;
167
- bool m_bSupportTrampoline ;
167
+ bool m_bAllowVirtualAddress ;
168
168
std::deque<std::pair<std::unique_ptr<Page>, std::unique_ptr<Page>>> m_Pages;
169
+ std::deque<std::pair<std::pair<void*, size_t>, std::unique_ptr<Page>>> m_VirtualPages;
169
170
} MEMORY_HOOK_RECORD, *PMEMORY_HOOK_RECORD;
170
171
171
172
// ----------------------------------------------------------------
@@ -5253,7 +5254,7 @@ namespace Detours {
5253
5254
// __get_pages_info
5254
5255
// ----------------------------------------------------------------
5255
5256
5256
- static inline std::vector<PAGE_INFO> __get_pages_info(void* pAddress, size_t unSize) {
5257
+ static inline std::vector<PAGE_INFO> __get_pages_info(void* pAddress, size_t unSize, bool bUnLimitBounds = false ) {
5257
5258
std::vector<PAGE_INFO> vecPages;
5258
5259
if (!pAddress || !unSize) {
5259
5260
return vecPages;
@@ -5268,11 +5269,12 @@ namespace Detours {
5268
5269
unAllocationGranularity = sysinf.dwAllocationGranularity;
5269
5270
}
5270
5271
5271
- const size_t unBegin = MAX(reinterpret_cast<size_t>(pMinimumApplicationAddress), reinterpret_cast<size_t>(pAddress));
5272
- const size_t unEnd = MIN(reinterpret_cast<size_t>(pMaximumApplicationAddress), reinterpret_cast<size_t>(pAddress) + unSize);
5272
+ const size_t unBegin = !bUnLimitBounds ? MAX(reinterpret_cast<size_t>(pMinimumApplicationAddress), reinterpret_cast<size_t>(pAddress)) : reinterpret_cast<size_t>(pAddress );
5273
+ const size_t unEnd = !bUnLimitBounds ? MIN(reinterpret_cast<size_t>(pMaximumApplicationAddress), reinterpret_cast<size_t>(pAddress) + unSize) : reinterpret_cast<size_t>(pAddress) + unSize ;
5273
5274
5274
5275
PAGE_INFO pi;
5275
5276
memset(&pi, 0, sizeof(pi));
5277
+
5276
5278
for (size_t unAddress = unBegin; unAddress < unEnd; unAddress = __align_up(MIN(unAddress, reinterpret_cast<size_t>(pi.m_pBaseAddress)) + pi.m_unSize, static_cast<size_t>(unPageSize))) {
5277
5279
if (!__get_page_info(reinterpret_cast<void*>(unAddress), &pi)) {
5278
5280
break;
@@ -5288,7 +5290,7 @@ namespace Detours {
5288
5290
// __get_regions_info
5289
5291
// ----------------------------------------------------------------
5290
5292
5291
- static inline std::vector<REGION_INFO> __get_regions_info(void* pAddress, size_t unSize, bool bCombine = false) {
5293
+ static inline std::vector<REGION_INFO> __get_regions_info(void* pAddress, size_t unSize, bool bCombine = false, bool bUnLimitBounds = false ) {
5292
5294
std::vector<REGION_INFO> vecRegions;
5293
5295
if (!pAddress || !unSize) {
5294
5296
return vecRegions;
@@ -5303,10 +5305,12 @@ namespace Detours {
5303
5305
unAllocationGranularity = sysinf.dwAllocationGranularity;
5304
5306
}
5305
5307
5306
- const size_t unBegin = MAX(reinterpret_cast<size_t>(pMinimumApplicationAddress), reinterpret_cast<size_t>(pAddress));
5307
- const size_t unEnd = MIN(reinterpret_cast<size_t>(pMaximumApplicationAddress), reinterpret_cast<size_t>(pAddress) + unSize);
5308
+ const size_t unBegin = !bUnLimitBounds ? MAX(reinterpret_cast<size_t>(pMinimumApplicationAddress), reinterpret_cast<size_t>(pAddress)) : reinterpret_cast<size_t>(pAddress);
5309
+ const size_t unEnd = !bUnLimitBounds ? MIN(reinterpret_cast<size_t>(pMaximumApplicationAddress), reinterpret_cast<size_t>(pAddress) + unSize) : reinterpret_cast<size_t>(pAddress) + unSize;
5310
+
5308
5311
REGION_INFO ri;
5309
5312
memset(&ri, 0, sizeof(ri));
5313
+
5310
5314
for (size_t unAddress = unBegin; unAddress < unEnd; unAddress = __align_up(MIN(unAddress, reinterpret_cast<size_t>(ri.m_pBaseAddress)) + ri.m_unSize, static_cast<size_t>(unAllocationGranularity))) {
5311
5315
if (!__get_region_info(reinterpret_cast<void*>(unAddress), &ri)) {
5312
5316
break;
@@ -7677,21 +7681,21 @@ namespace Detours {
7677
7681
}
7678
7682
7679
7683
if (reinterpret_cast<ULONG_PTR>(pAddress) == unBase + unIndex + unDisp) {
7680
- if (unBase) {
7684
+ // if (unBase) {
7681
7685
const size_t unOffset = reinterpret_cast<size_t>(pAddress) - unBase;
7682
7686
SetRegisterValue(pCTX, pReadOperand->Info.Memory.Base, pReadOperand->Info.Memory.BaseSize, reinterpret_cast<size_t>(pNewAddress) - unOffset);
7683
7687
pReadOperand->Info.Memory.HasIndex = false;
7684
7688
g_CachedOperations.emplace_back(const_cast<void*>(pExceptionAddress), unOperation, const_cast<void*>(pAddress), *pReadOperand, static_cast<char*>(pNewAddress) - unOffset);
7685
7689
return;
7686
- }
7687
-
7688
- if (unIndex) {
7689
- const size_t unOffset = reinterpret_cast<size_t>(pAddress) - unIndex;
7690
- SetRegisterValue(pCTX, pReadOperand->Info.Memory.Index, pReadOperand->Info.Memory.IndexSize, reinterpret_cast<size_t>(pNewAddress) - unOffset);
7691
- pReadOperand->Info.Memory.HasBase = false;
7692
- g_CachedOperations.emplace_back(const_cast<void*>(pExceptionAddress), unOperation, const_cast<void*>(pAddress), *pReadOperand, static_cast<char*>(pNewAddress) - unOffset);
7693
- return;
7694
- }
7690
+ // }
7691
+
7692
+ // if (unIndex) {
7693
+ // const size_t unOffset = reinterpret_cast<size_t>(pAddress) - unIndex;
7694
+ // SetRegisterValue(pCTX, pReadOperand->Info.Memory.Index, pReadOperand->Info.Memory.IndexSize, reinterpret_cast<size_t>(pNewAddress) - unOffset);
7695
+ // pReadOperand->Info.Memory.HasBase = false;
7696
+ // g_CachedOperations.emplace_back(const_cast<void*>(pExceptionAddress), unOperation, const_cast<void*>(pAddress), *pReadOperand, static_cast<char*>(pNewAddress) - unOffset);
7697
+ // return;
7698
+ // }
7695
7699
}
7696
7700
}
7697
7701
break;
@@ -7825,21 +7829,21 @@ namespace Detours {
7825
7829
}
7826
7830
7827
7831
if (reinterpret_cast<ULONG_PTR>(pAddress) == unBase + unIndex + unDisp) {
7828
- if (unBase) {
7832
+ // if (unBase) {
7829
7833
const size_t unOffset = reinterpret_cast<size_t>(pAddress) - unBase;
7830
7834
SetRegisterValue(pCTX, pWriteOperand->Info.Memory.Base, pWriteOperand->Info.Memory.BaseSize, reinterpret_cast<size_t>(pNewAddress) - unOffset);
7831
7835
pWriteOperand->Info.Memory.HasIndex = false;
7832
7836
g_CachedOperations.emplace_back(const_cast<void*>(pExceptionAddress), unOperation, const_cast<void*>(pAddress), *pWriteOperand, static_cast<char*>(pNewAddress) - unOffset);
7833
7837
return;
7834
- }
7835
-
7836
- if (unIndex) {
7837
- const size_t unOffset = reinterpret_cast<size_t>(pAddress) - unIndex;
7838
- SetRegisterValue(pCTX, pWriteOperand->Info.Memory.Index, pWriteOperand->Info.Memory.IndexSize, reinterpret_cast<size_t>(pNewAddress) - unOffset);
7839
- pWriteOperand->Info.Memory.HasBase = false;
7840
- g_CachedOperations.emplace_back(const_cast<void*>(pExceptionAddress), unOperation, const_cast<void*>(pAddress), *pWriteOperand, static_cast<char*>(pNewAddress) - unOffset);
7841
- return;
7842
- }
7838
+ // }
7839
+
7840
+ // if (unIndex) {
7841
+ // const size_t unOffset = reinterpret_cast<size_t>(pAddress) - unIndex;
7842
+ // SetRegisterValue(pCTX, pWriteOperand->Info.Memory.Index, pWriteOperand->Info.Memory.IndexSize, reinterpret_cast<size_t>(pNewAddress) - unOffset);
7843
+ // pWriteOperand->Info.Memory.HasBase = false;
7844
+ // g_CachedOperations.emplace_back(const_cast<void*>(pExceptionAddress), unOperation, const_cast<void*>(pAddress), *pWriteOperand, static_cast<char*>(pNewAddress) - unOffset);
7845
+ // return;
7846
+ // }
7843
7847
}
7844
7848
}
7845
7849
break;
@@ -7998,37 +8002,84 @@ namespace Detours {
7998
8002
return false;
7999
8003
}
8000
8004
8005
+ bool bIsVirtualAddress = false;
8006
+
8007
+ PAGE_INFO pi;
8008
+ if (!__get_page_info(const_cast<void*>(pAddress), &pi)) {
8009
+ return false;
8010
+ }
8011
+
8012
+ if ((pi.m_unState == MEM_FREE) && (pi.m_unProtection == PAGE_NOACCESS) && (pi.m_unType == 0)) {
8013
+ bIsVirtualAddress = true;
8014
+ }
8015
+
8001
8016
for (auto it = g_MemoryHookRecords.begin(); it != g_MemoryHookRecords.end(); ++it) {
8002
8017
const auto& pRecord = *it;
8003
8018
if (!pRecord) {
8004
8019
continue;
8005
8020
}
8006
8021
8022
+ if (bIsVirtualAddress && !pRecord->m_bAllowVirtualAddress) {
8023
+ continue;
8024
+ }
8025
+
8007
8026
if (__is_in_range(pRecord->m_pAddress, pRecord->m_unSize, pAddress)) {
8008
- for (auto& PagePair : pRecord->m_Pages) {
8009
- const auto& Page = PagePair.first;
8010
- if (__is_in_range(Page->GetPageAddress(), Page->GetPageCapacity(), pAddress)) {
8011
- const size_t unOffset = reinterpret_cast<size_t>(pAddress) - reinterpret_cast<size_t>(Page->GetPageAddress());
8012
- void* pNewAddress = reinterpret_cast<char*>(PagePair.second->GetPageAddress()) + unOffset;
8013
8027
8014
- if (pRecord->m_bSupportTrampoline) {
8015
- if (!PagePair.first->RestoreProtection()) {
8016
- return false;
8017
- }
8018
- }
8028
+ if (!bIsVirtualAddress) {
8029
+ for (auto& PagePair : pRecord->m_Pages) {
8030
+ const auto& Page = PagePair.first;
8019
8031
8020
- const bool bResult = pRecord->m_pCallBack(pCTX, pExceptionAddress, unOperation, pRecord->m_pAddress, pAddress, &pNewAddress);
8021
- if (bResult) {
8022
- FixMemoryHookAddress(pCTX, pExceptionAddress, unOperation, pAddress, pNewAddress);
8023
- }
8032
+ if (__is_in_range(Page->GetPageAddress(), Page->GetPageCapacity(), pAddress)) {
8033
+ const size_t unOffset = reinterpret_cast<size_t>(pAddress) - reinterpret_cast<size_t>(Page->GetPageAddress());
8034
+ void* pNewAddress = reinterpret_cast<char*>(PagePair.second->GetPageAddress()) + unOffset;
8024
8035
8025
- if (pRecord->m_bSupportTrampoline) {
8026
- if (!PagePair.first->ChangeProtection(PAGE_NOACCESS)) {
8027
- return false;
8036
+ //if (pRecord->m_bSupportTrampoline) {
8037
+ // if (!PagePair.first->RestoreProtection()) {
8038
+ // return false;
8039
+ // }
8040
+ //}
8041
+
8042
+ const bool bResult = pRecord->m_pCallBack(pCTX, pExceptionAddress, unOperation, pRecord->m_pAddress, pAddress, &pNewAddress);
8043
+ if (bResult) {
8044
+ FixMemoryHookAddress(pCTX, pExceptionAddress, unOperation, pAddress, pNewAddress);
8028
8045
}
8046
+
8047
+ //if (pRecord->m_bSupportTrampoline) {
8048
+ // if (!PagePair.first->ChangeProtection(PAGE_NOACCESS)) {
8049
+ // return false;
8050
+ // }
8051
+ //}
8052
+
8053
+ return bResult;
8029
8054
}
8055
+ }
8056
+ } else {
8057
+ for (auto& PagePair : pRecord->m_VirtualPages) {
8058
+ const auto& Page = PagePair.first;
8059
+
8060
+ if (__is_in_range(Page.first, Page.second, pAddress)) {
8061
+ const size_t unOffset = reinterpret_cast<size_t>(pAddress) - reinterpret_cast<size_t>(Page.first);
8062
+ void* pNewAddress = reinterpret_cast<char*>(PagePair.second->GetPageAddress()) + unOffset;
8063
+
8064
+ //if (pRecord->m_bSupportTrampoline) {
8065
+ // if (!PagePair.first->RestoreProtection()) {
8066
+ // return false;
8067
+ // }
8068
+ //}
8069
+
8070
+ const bool bResult = pRecord->m_pCallBack(pCTX, pExceptionAddress, unOperation, pRecord->m_pAddress, pAddress, &pNewAddress);
8071
+ if (bResult) {
8072
+ FixMemoryHookAddress(pCTX, pExceptionAddress, unOperation, pAddress, pNewAddress);
8073
+ }
8074
+
8075
+ //if (pRecord->m_bSupportTrampoline) {
8076
+ // if (!PagePair.first->ChangeProtection(PAGE_NOACCESS)) {
8077
+ // return false;
8078
+ // }
8079
+ //}
8030
8080
8031
- return bResult;
8081
+ return bResult;
8082
+ }
8032
8083
}
8033
8084
}
8034
8085
@@ -8037,13 +8088,26 @@ namespace Detours {
8037
8088
8038
8089
void* pNewAddress = nullptr;
8039
8090
bool bAround = false;
8040
- for (auto& PagePair : pRecord->m_Pages) {
8041
- const auto& Page = PagePair.first;
8042
- if (__is_in_range(Page->GetPageAddress(), Page->GetPageCapacity(), pAddress)) {
8043
- const size_t unOffset = reinterpret_cast<size_t>(pAddress) - reinterpret_cast<size_t>(Page->GetPageAddress());
8044
- pNewAddress = reinterpret_cast<char*>(PagePair.second->GetPageAddress()) + unOffset;
8045
- bAround = true;
8046
- break;
8091
+
8092
+ if (!bIsVirtualAddress) {
8093
+ for (auto& PagePair : pRecord->m_Pages) {
8094
+ const auto& Page = PagePair.first;
8095
+ if (__is_in_range(Page->GetPageAddress(), Page->GetPageCapacity(), pAddress)) {
8096
+ const size_t unOffset = reinterpret_cast<size_t>(pAddress) - reinterpret_cast<size_t>(Page->GetPageAddress());
8097
+ pNewAddress = reinterpret_cast<char*>(PagePair.second->GetPageAddress()) + unOffset;
8098
+ bAround = true;
8099
+ break;
8100
+ }
8101
+ }
8102
+ } else {
8103
+ for (auto& PagePair : pRecord->m_VirtualPages) {
8104
+ const auto& Page = PagePair.first;
8105
+ if (__is_in_range(Page.first, Page.second, pAddress)) {
8106
+ const size_t unOffset = reinterpret_cast<size_t>(pAddress) - reinterpret_cast<size_t>(Page.first);
8107
+ pNewAddress = reinterpret_cast<char*>(PagePair.second->GetPageAddress()) + unOffset;
8108
+ bAround = true;
8109
+ break;
8110
+ }
8047
8111
}
8048
8112
}
8049
8113
@@ -85126,7 +85190,7 @@ namespace Detours {
85126
85190
// Memory Hook
85127
85191
// ----------------------------------------------------------------
85128
85192
85129
- bool HookMemory(const fnMemoryHookCallBack pCallBack, void* pAddress, size_t unSize, bool bSupportTrampoline ) {
85193
+ bool HookMemory(const fnMemoryHookCallBack pCallBack, void* pAddress, size_t unSize, bool bAllowVirtualAddress ) {
85130
85194
if (!pCallBack || !pAddress || !unSize) {
85131
85195
return false;
85132
85196
}
@@ -85137,21 +85201,39 @@ namespace Detours {
85137
85201
}
85138
85202
}
85139
85203
85140
- auto vecPages = __get_pages_info(pAddress, unSize);
85204
+ auto vecPages = __get_pages_info(pAddress, unSize, true );
85141
85205
if (vecPages.empty()) {
85142
85206
return false;
85143
85207
}
85144
85208
85145
- DWORD unDEPPolicy = 0;
85146
- BOOL bPermament = FALSE;
85147
- if (!GetProcessDEPPolicy(reinterpret_cast<HANDLE>(-1), &unDEPPolicy, &bPermament)) {
85209
+ bool bIsVirtualAddress = false;
85210
+
85211
+ auto& FrontPageInfo = vecPages.front();
85212
+ if ((FrontPageInfo.m_unState == MEM_FREE) && (FrontPageInfo.m_unProtection == PAGE_NOACCESS) && (FrontPageInfo.m_unType == 0)) {
85213
+ bIsVirtualAddress = true;
85214
+ }
85215
+
85216
+ auto& BackPageInfo = vecPages.back();
85217
+ if ((BackPageInfo.m_unState == MEM_FREE) && (BackPageInfo.m_unProtection == PAGE_NOACCESS) && (BackPageInfo.m_unType == 0)) {
85218
+ bIsVirtualAddress = true;
85219
+ }
85220
+
85221
+ if (bIsVirtualAddress && !bAllowVirtualAddress) {
85148
85222
return false;
85149
85223
}
85150
85224
85151
- if (!unDEPPolicy) {
85152
- for (auto& PageInfo : vecPages) {
85153
- if (PageInfo.m_unProtection & (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)) {
85154
- return false;
85225
+ if (!bIsVirtualAddress) {
85226
+ DWORD unDEPPolicy = 0;
85227
+ BOOL bPermament = FALSE;
85228
+ if (!GetProcessDEPPolicy(reinterpret_cast<HANDLE>(-1), &unDEPPolicy, &bPermament)) {
85229
+ return false;
85230
+ }
85231
+
85232
+ if (!unDEPPolicy) {
85233
+ for (auto& PageInfo : vecPages) {
85234
+ if (PageInfo.m_unProtection & (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)) {
85235
+ return false;
85236
+ }
85155
85237
}
85156
85238
}
85157
85239
}
@@ -85164,28 +85246,37 @@ namespace Detours {
85164
85246
pRecord->m_pCallBack = pCallBack;
85165
85247
pRecord->m_pAddress = pAddress;
85166
85248
pRecord->m_unSize = unSize;
85167
- pRecord->m_bSupportTrampoline = bSupportTrampoline ;
85249
+ pRecord->m_bAllowVirtualAddress = bAllowVirtualAddress ;
85168
85250
85169
85251
for (auto& PageInfo : vecPages) {
85170
- auto pOriginalPage = std::make_unique<Page>(PageInfo.m_pBaseAddress, false);
85171
- if (!pOriginalPage) {
85172
- return false;
85173
- }
85174
85252
85175
85253
auto pPage = std::make_unique<Page>();
85176
85254
if (!pPage) {
85177
85255
return false;
85178
85256
}
85179
85257
85180
- if (!pPage->CloneFrom(pOriginalPage.get())) {
85181
- return false;
85182
- }
85258
+ if (!bIsVirtualAddress) {
85259
+ auto pOriginalPage = std::make_unique<Page>(PageInfo.m_pBaseAddress, false);
85260
+ if (!pOriginalPage) {
85261
+ return false;
85262
+ }
85183
85263
85184
- if (!pOriginalPage->ChangeProtection(PAGE_NOACCESS)) {
85185
- return false;
85186
- }
85264
+ if (!pPage->CloneFrom(pOriginalPage.get())) {
85265
+ return false;
85266
+ }
85267
+
85268
+ if (!pOriginalPage->ChangeProtection(PAGE_NOACCESS)) {
85269
+ return false;
85270
+ }
85187
85271
85188
- pRecord->m_Pages.emplace_back(std::make_pair(std::move(pOriginalPage), std::move(pPage)));
85272
+ pRecord->m_Pages.emplace_back(std::make_pair(std::move(pOriginalPage), std::move(pPage)));
85273
+ } else {
85274
+ if (!pPage->ChangeProtection(PAGE_EXECUTE_READWRITE)) {
85275
+ return false;
85276
+ }
85277
+
85278
+ pRecord->m_VirtualPages.emplace_back(std::make_pair(std::make_pair(PageInfo.m_pBaseAddress, PageInfo.m_unSize), std::move(pPage)));
85279
+ }
85189
85280
}
85190
85281
85191
85282
g_MemoryHookRecords.emplace_back(std::move(pRecord));
@@ -85199,13 +85290,15 @@ namespace Detours {
85199
85290
85200
85291
for (auto it = g_MemoryHookRecords.begin(); it != g_MemoryHookRecords.end(); ++it) {
85201
85292
if ((*it)->m_pCallBack == pCallBack) {
85202
- for (auto& PagePair : (*it)->m_Pages) {
85203
- if (!PagePair.second->CloneTo(PagePair.first.get())) {
85204
- return false;
85205
- }
85293
+ if (!(*it)->m_bAllowVirtualAddress) {
85294
+ for (auto& PagePair : (*it)->m_Pages) {
85295
+ if (!PagePair.second->CloneTo(PagePair.first.get())) {
85296
+ return false;
85297
+ }
85206
85298
85207
- if (!PagePair.first->RestoreProtection()) {
85208
- return false;
85299
+ if (!PagePair.first->RestoreProtection()) {
85300
+ return false;
85301
+ }
85209
85302
}
85210
85303
}
85211
85304
0 commit comments