Skip to content

Commit 98b66ca

Browse files
authored
Add files via upload
1 parent 9da721b commit 98b66ca

File tree

3 files changed

+232
-97
lines changed

3 files changed

+232
-97
lines changed

Detours.cpp

Lines changed: 173 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -158,14 +158,15 @@ namespace Detours {
158158
m_pCallBack = nullptr;
159159
m_pAddress = nullptr;
160160
m_unSize = 0;
161-
m_bSupportTrampoline = false;
161+
m_bAllowVirtualAddress = false;
162162
}
163163

164164
fnMemoryHookCallBack m_pCallBack;
165165
void* m_pAddress;
166166
size_t m_unSize;
167-
bool m_bSupportTrampoline;
167+
bool m_bAllowVirtualAddress;
168168
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;
169170
} MEMORY_HOOK_RECORD, *PMEMORY_HOOK_RECORD;
170171

171172
// ----------------------------------------------------------------
@@ -5253,7 +5254,7 @@ namespace Detours {
52535254
// __get_pages_info
52545255
// ----------------------------------------------------------------
52555256

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) {
52575258
std::vector<PAGE_INFO> vecPages;
52585259
if (!pAddress || !unSize) {
52595260
return vecPages;
@@ -5268,11 +5269,12 @@ namespace Detours {
52685269
unAllocationGranularity = sysinf.dwAllocationGranularity;
52695270
}
52705271

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;
52735274

52745275
PAGE_INFO pi;
52755276
memset(&pi, 0, sizeof(pi));
5277+
52765278
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))) {
52775279
if (!__get_page_info(reinterpret_cast<void*>(unAddress), &pi)) {
52785280
break;
@@ -5288,7 +5290,7 @@ namespace Detours {
52885290
// __get_regions_info
52895291
// ----------------------------------------------------------------
52905292

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) {
52925294
std::vector<REGION_INFO> vecRegions;
52935295
if (!pAddress || !unSize) {
52945296
return vecRegions;
@@ -5303,10 +5305,12 @@ namespace Detours {
53035305
unAllocationGranularity = sysinf.dwAllocationGranularity;
53045306
}
53055307

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+
53085311
REGION_INFO ri;
53095312
memset(&ri, 0, sizeof(ri));
5313+
53105314
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))) {
53115315
if (!__get_region_info(reinterpret_cast<void*>(unAddress), &ri)) {
53125316
break;
@@ -7677,21 +7681,21 @@ namespace Detours {
76777681
}
76787682

76797683
if (reinterpret_cast<ULONG_PTR>(pAddress) == unBase + unIndex + unDisp) {
7680-
if (unBase) {
7684+
//if (unBase) {
76817685
const size_t unOffset = reinterpret_cast<size_t>(pAddress) - unBase;
76827686
SetRegisterValue(pCTX, pReadOperand->Info.Memory.Base, pReadOperand->Info.Memory.BaseSize, reinterpret_cast<size_t>(pNewAddress) - unOffset);
76837687
pReadOperand->Info.Memory.HasIndex = false;
76847688
g_CachedOperations.emplace_back(const_cast<void*>(pExceptionAddress), unOperation, const_cast<void*>(pAddress), *pReadOperand, static_cast<char*>(pNewAddress) - unOffset);
76857689
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+
//}
76957699
}
76967700
}
76977701
break;
@@ -7825,21 +7829,21 @@ namespace Detours {
78257829
}
78267830

78277831
if (reinterpret_cast<ULONG_PTR>(pAddress) == unBase + unIndex + unDisp) {
7828-
if (unBase) {
7832+
//if (unBase) {
78297833
const size_t unOffset = reinterpret_cast<size_t>(pAddress) - unBase;
78307834
SetRegisterValue(pCTX, pWriteOperand->Info.Memory.Base, pWriteOperand->Info.Memory.BaseSize, reinterpret_cast<size_t>(pNewAddress) - unOffset);
78317835
pWriteOperand->Info.Memory.HasIndex = false;
78327836
g_CachedOperations.emplace_back(const_cast<void*>(pExceptionAddress), unOperation, const_cast<void*>(pAddress), *pWriteOperand, static_cast<char*>(pNewAddress) - unOffset);
78337837
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+
//}
78437847
}
78447848
}
78457849
break;
@@ -7998,37 +8002,84 @@ namespace Detours {
79988002
return false;
79998003
}
80008004

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+
80018016
for (auto it = g_MemoryHookRecords.begin(); it != g_MemoryHookRecords.end(); ++it) {
80028017
const auto& pRecord = *it;
80038018
if (!pRecord) {
80048019
continue;
80058020
}
80068021

8022+
if (bIsVirtualAddress && !pRecord->m_bAllowVirtualAddress) {
8023+
continue;
8024+
}
8025+
80078026
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;
80138027

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;
80198031

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;
80248035

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);
80288045
}
8046+
8047+
//if (pRecord->m_bSupportTrampoline) {
8048+
// if (!PagePair.first->ChangeProtection(PAGE_NOACCESS)) {
8049+
// return false;
8050+
// }
8051+
//}
8052+
8053+
return bResult;
80298054
}
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+
//}
80308080

8031-
return bResult;
8081+
return bResult;
8082+
}
80328083
}
80338084
}
80348085

@@ -8037,13 +8088,26 @@ namespace Detours {
80378088

80388089
void* pNewAddress = nullptr;
80398090
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+
}
80478111
}
80488112
}
80498113

@@ -85126,7 +85190,7 @@ namespace Detours {
8512685190
// Memory Hook
8512785191
// ----------------------------------------------------------------
8512885192

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) {
8513085194
if (!pCallBack || !pAddress || !unSize) {
8513185195
return false;
8513285196
}
@@ -85137,21 +85201,39 @@ namespace Detours {
8513785201
}
8513885202
}
8513985203

85140-
auto vecPages = __get_pages_info(pAddress, unSize);
85204+
auto vecPages = __get_pages_info(pAddress, unSize, true);
8514185205
if (vecPages.empty()) {
8514285206
return false;
8514385207
}
8514485208

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) {
8514885222
return false;
8514985223
}
8515085224

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+
}
8515585237
}
8515685238
}
8515785239
}
@@ -85164,28 +85246,37 @@ namespace Detours {
8516485246
pRecord->m_pCallBack = pCallBack;
8516585247
pRecord->m_pAddress = pAddress;
8516685248
pRecord->m_unSize = unSize;
85167-
pRecord->m_bSupportTrampoline = bSupportTrampoline;
85249+
pRecord->m_bAllowVirtualAddress = bAllowVirtualAddress;
8516885250

8516985251
for (auto& PageInfo : vecPages) {
85170-
auto pOriginalPage = std::make_unique<Page>(PageInfo.m_pBaseAddress, false);
85171-
if (!pOriginalPage) {
85172-
return false;
85173-
}
8517485252

8517585253
auto pPage = std::make_unique<Page>();
8517685254
if (!pPage) {
8517785255
return false;
8517885256
}
8517985257

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+
}
8518385263

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+
}
8518785271

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+
}
8518985280
}
8519085281

8519185282
g_MemoryHookRecords.emplace_back(std::move(pRecord));
@@ -85199,13 +85290,15 @@ namespace Detours {
8519985290

8520085291
for (auto it = g_MemoryHookRecords.begin(); it != g_MemoryHookRecords.end(); ++it) {
8520185292
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+
}
8520685298

85207-
if (!PagePair.first->RestoreProtection()) {
85208-
return false;
85299+
if (!PagePair.first->RestoreProtection()) {
85300+
return false;
85301+
}
8520985302
}
8521085303
}
8521185304

0 commit comments

Comments
 (0)