Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mpc-hc/mpc-hc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Marsev <alex.marsev@gmail.com>2014-03-30 18:50:13 +0400
committerAlex Marsev <alex.marsev@gmail.com>2014-03-30 21:49:50 +0400
commit4524c7ddbbd06ae471dbb3221e9a40d067ad2840 (patch)
tree5666ee1a3703e2df10305e5bef96dc18cafaeac7 /src/thirdparty/mhook
parent513b017859353d613cb4bae7b30fbc030d49f766 (diff)
mhook: backport version 2.4 changes
Obsoletes one of our hacks.
Diffstat (limited to 'src/thirdparty/mhook')
-rw-r--r--src/thirdparty/mhook/mhook-lib/mhook.cpp310
-rw-r--r--src/thirdparty/mhook/mhook-lib/mhook.h3
-rw-r--r--src/thirdparty/mhook/mhook.vcxproj4
3 files changed, 210 insertions, 107 deletions
diff --git a/src/thirdparty/mhook/mhook-lib/mhook.cpp b/src/thirdparty/mhook/mhook-lib/mhook.cpp
index 097a77c56..25cf35f11 100644
--- a/src/thirdparty/mhook/mhook-lib/mhook.cpp
+++ b/src/thirdparty/mhook/mhook-lib/mhook.cpp
@@ -110,9 +110,10 @@ struct MHOOKS_TRAMPOLINE {
// in the original location
BYTE codeUntouched[MHOOKS_MAX_CODE_BYTES]; // placeholder for unmodified original code
// (we patch IP-relative addressing)
+ MHOOKS_TRAMPOLINE* pPrevTrampoline; // When in the free list, thess are pointers to the prev and next entry.
+ MHOOKS_TRAMPOLINE* pNextTrampoline; // When not in the free list, this is a pointer to the prev and next trampoline in use.
};
-
//=========================================================================
// The patch data structures - store info about rip-relative instructions
// during hook placement
@@ -134,26 +135,28 @@ struct MHOOKS_PATCHDATA
// Global vars
static BOOL g_bVarsInitialized = FALSE;
static CRITICAL_SECTION g_cs;
-static MHOOKS_TRAMPOLINE* g_pHooks[MHOOKS_MAX_SUPPORTED_HOOKS];
+static MHOOKS_TRAMPOLINE* g_pHooks = NULL;
+static MHOOKS_TRAMPOLINE* g_pFreeList = NULL;
static DWORD g_nHooksInUse = 0;
static HANDLE* g_hThreadHandles = NULL;
static DWORD g_nThreadHandles = 0;
#define MHOOK_JMPSIZE 5
+#define MHOOK_MINALLOCSIZE 4096
//=========================================================================
// Toolhelp defintions so the functions can be dynamically bound to
typedef HANDLE (WINAPI * _CreateToolhelp32Snapshot)(
- DWORD dwFlags,
+ DWORD dwFlags,
DWORD th32ProcessID
);
typedef BOOL (WINAPI * _Thread32First)(
- HANDLE hSnapshot,
+ HANDLE hSnapshot,
LPTHREADENTRY32 lpte
);
typedef BOOL (WINAPI * _Thread32Next)(
- HANDLE hSnapshot,
+ HANDLE hSnapshot,
LPTHREADENTRY32 lpte
);
@@ -164,10 +167,47 @@ _Thread32First fnThread32First = (_Thread32First) GetProcAddress(GetModuleHandle
_Thread32Next fnThread32Next = (_Thread32Next) GetProcAddress(GetModuleHandle(L"kernel32"), "Thread32Next");
//=========================================================================
+// Internal function:
+//
+// Remove the trampoline from the specified list, updating the head pointer
+// if necessary.
+//=========================================================================
+static VOID ListRemove(MHOOKS_TRAMPOLINE** pListHead, MHOOKS_TRAMPOLINE* pNode) {
+ if (pNode->pPrevTrampoline) {
+ pNode->pPrevTrampoline->pNextTrampoline = pNode->pNextTrampoline;
+ }
+
+ if (pNode->pNextTrampoline) {
+ pNode->pNextTrampoline->pPrevTrampoline = pNode->pPrevTrampoline;
+ }
+
+ if ((*pListHead) == pNode) {
+ (*pListHead) = pNode->pNextTrampoline;
+ assert((*pListHead)->pPrevTrampoline == NULL);
+ }
+
+ pNode->pPrevTrampoline = NULL;
+ pNode->pNextTrampoline = NULL;
+}
+
+//=========================================================================
+// Internal function:
+//
+// Prepend the trampoline from the specified list and update the head pointer.
+//=========================================================================
+static VOID ListPrepend(MHOOKS_TRAMPOLINE** pListHead, MHOOKS_TRAMPOLINE* pNode) {
+ pNode->pPrevTrampoline = NULL;
+ pNode->pNextTrampoline = (*pListHead);
+ if ((*pListHead)) {
+ (*pListHead)->pPrevTrampoline = pNode;
+ }
+ (*pListHead) = pNode;
+}
+
+//=========================================================================
static VOID EnterCritSec() {
if (!g_bVarsInitialized) {
InitializeCriticalSection(&g_cs);
- ZeroMemory(g_pHooks, sizeof(g_pHooks));
g_bVarsInitialized = TRUE;
}
EnterCriticalSection(&g_cs);
@@ -185,7 +225,17 @@ static VOID LeaveCritSec() {
// jump tables, etc.
//=========================================================================
static PBYTE SkipJumps(PBYTE pbCode) {
+ PBYTE pbOrgCode = pbCode;
#ifdef _M_IX86_X64
+#ifdef _M_IX86
+ //mov edi,edi: hot patch point
+ if (pbCode[0] == 0x8b && pbCode[1] == 0xff)
+ pbCode += 2;
+ // push ebp; mov ebp, esp; pop ebp;
+ // "collapsed" stackframe generated by MSVC
+ if (pbCode[0] == 0x55 && pbCode[1] == 0x8b && pbCode[2] == 0xec && pbCode[3] == 0x5d)
+ pbCode += 4;
+#endif
if (pbCode[0] == 0xff && pbCode[1] == 0x25) {
#ifdef _M_IX86
// on x86 we have an absolute pointer...
@@ -197,6 +247,11 @@ static PBYTE SkipJumps(PBYTE pbCode) {
INT32 lOffset = *(INT32 *)&pbCode[2];
// ... that shows us an absolute pointer
return SkipJumps(*(PBYTE*)(pbCode + 6 + lOffset));
+ } else if (pbCode[0] == 0x48 && pbCode[1] == 0xff && pbCode[2] == 0x25) {
+ // or we can have the same with a REX prefix
+ INT32 lOffset = *(INT32 *)&pbCode[3];
+ // ... that shows us an absolute pointer
+ return SkipJumps(*(PBYTE*)(pbCode + 7 + lOffset));
#endif
} else if (pbCode[0] == 0xe9) {
// here the behavior is identical, we have...
@@ -209,7 +264,7 @@ static PBYTE SkipJumps(PBYTE pbCode) {
#else
#error unsupported platform
#endif
- return pbCode;
+ return pbOrgCode;
}
//=========================================================================
@@ -250,66 +305,128 @@ static PBYTE EmitJump(PBYTE pbCode, PBYTE pbJumpTo) {
return pbCode;
}
+
//=========================================================================
// Internal function:
//
-// Will try to allocate the trampoline structure within 2 gigabytes of
-// the target function.
+// Round down to the next multiple of rndDown
//=========================================================================
-static MHOOKS_TRAMPOLINE* TrampolineAlloc(PBYTE pSystemFunction, S64 nLimitUp, S64 nLimitDown) {
+static size_t RoundDown(size_t addr, size_t rndDown)
+{
+ return (addr / rndDown) * rndDown;
+}
- MHOOKS_TRAMPOLINE* pTrampoline = NULL;
+//=========================================================================
+// Internal function:
+//
+// Will attempt allocate a block of memory within the specified range, as
+// near as possible to the specified function.
+//=========================================================================
+static MHOOKS_TRAMPOLINE* BlockAlloc(PBYTE pSystemFunction, PBYTE pbLower, PBYTE pbUpper) {
+ SYSTEM_INFO sSysInfo = {0};
+ ::GetSystemInfo(&sSysInfo);
+
+ // Always allocate in bulk, in case the system actually has a smaller allocation granularity than MINALLOCSIZE.
+ const ptrdiff_t cAllocSize = max(sSysInfo.dwAllocationGranularity, MHOOK_MINALLOCSIZE);
+
+ MHOOKS_TRAMPOLINE* pRetVal = NULL;
+ PBYTE pModuleGuess = (PBYTE) RoundDown((size_t)pSystemFunction, cAllocSize);
+ int loopCount = 0;
+ for (PBYTE pbAlloc = pModuleGuess; pbLower < pbAlloc && pbAlloc < pbUpper; ++loopCount) {
+ // determine current state
+ MEMORY_BASIC_INFORMATION mbi;
+ ODPRINTF((L"mhooks: BlockAlloc: Looking at address %p", pbAlloc));
+ if (!VirtualQuery(pbAlloc, &mbi, sizeof(mbi)))
+ break;
+ // free & large enough?
+ if (mbi.State == MEM_FREE && mbi.RegionSize >= (unsigned)cAllocSize) {
+ // and then try to allocate it
+ pRetVal = (MHOOKS_TRAMPOLINE*) VirtualAlloc(pbAlloc, cAllocSize, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE);
+ if (pRetVal) {
+ size_t trampolineCount = cAllocSize / sizeof(MHOOKS_TRAMPOLINE);
+ ODPRINTF((L"mhooks: BlockAlloc: Allocated block at %p as %d trampolines", pRetVal, trampolineCount));
+
+ pRetVal[0].pPrevTrampoline = NULL;
+ pRetVal[0].pNextTrampoline = &pRetVal[1];
+
+ // prepare them by having them point down the line at the next entry.
+ for (size_t s = 1; s < trampolineCount; ++s) {
+ pRetVal[s].pPrevTrampoline = &pRetVal[s - 1];
+ pRetVal[s].pNextTrampoline = &pRetVal[s + 1];
+ }
- // do we have room to store this guy?
- if (g_nHooksInUse < MHOOKS_MAX_SUPPORTED_HOOKS) {
-
- // determine lower and upper bounds for the allocation locations.
- // in the basic scenario this is +/- 2GB but IP-relative instructions
- // found in the original code may require a smaller window.
- PBYTE pLower = pSystemFunction + nLimitUp;
- pLower = pLower < (PBYTE)(DWORD_PTR)0x0000000080000000 ?
- (PBYTE)(0x1) : (PBYTE)(pLower - (PBYTE)0x7fff0000);
- PBYTE pUpper = pSystemFunction + nLimitDown;
- pUpper = pUpper < (PBYTE)(DWORD_PTR)0xffffffff80000000 ?
- (PBYTE)(pUpper + (DWORD_PTR)0x7ff80000) : (PBYTE)(DWORD_PTR)0xfffffffffff80000;
- ODPRINTF((L"mhooks: TrampolineAlloc: Allocating for %p between %p and %p", pSystemFunction, pLower, pUpper));
-
- SYSTEM_INFO sSysInfo = {0};
- ::GetSystemInfo(&sSysInfo);
-
- // go through the available memory blocks and try to allocate a chunk for us
- for (PBYTE pbAlloc = pLower; pbAlloc < pUpper;) {
- // determine current state
- MEMORY_BASIC_INFORMATION mbi;
- ODPRINTF((L"mhooks: TrampolineAlloc: Looking at address %p", pbAlloc));
- if (!VirtualQuery(pbAlloc, &mbi, sizeof(mbi)))
+ // last entry points to the current head of the free list
+ pRetVal[trampolineCount - 1].pNextTrampoline = g_pFreeList;
break;
- // free & large enough?
- if (mbi.State == MEM_FREE && mbi.RegionSize >= sizeof(MHOOKS_TRAMPOLINE) && mbi.RegionSize >= sSysInfo.dwAllocationGranularity) {
- // yes, align the pointer to the 64K boundary first
- pbAlloc = (PBYTE)(ULONG_PTR((ULONG_PTR(pbAlloc) + (sSysInfo.dwAllocationGranularity-1)) / sSysInfo.dwAllocationGranularity) * sSysInfo.dwAllocationGranularity);
- // and then try to allocate it
- pTrampoline = (MHOOKS_TRAMPOLINE*)VirtualAlloc(pbAlloc, sizeof(MHOOKS_TRAMPOLINE), MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READ);
- if (pTrampoline) {
- ODPRINTF((L"mhooks: TrampolineAlloc: Allocated block at %p as the trampoline", pTrampoline));
- break;
- }
}
- // continue the search
- pbAlloc = (PBYTE)mbi.BaseAddress + mbi.RegionSize;
}
+
+ // This is a spiral, should be -1, 1, -2, 2, -3, 3, etc. (* cAllocSize)
+ ptrdiff_t bytesToOffset = (cAllocSize * (loopCount + 1) * ((loopCount % 2 == 0) ? -1 : 1));
+ pbAlloc = pbAlloc + bytesToOffset;
+ }
+
+ return pRetVal;
+}
- // found and allocated a trampoline?
- if (pTrampoline) {
- // put it into our list so we know we'll have to free it
- for (DWORD i=0; i<MHOOKS_MAX_SUPPORTED_HOOKS; i++) {
- if (g_pHooks[i] == NULL) {
- g_pHooks[i] = pTrampoline;
- g_nHooksInUse++;
- break;
- }
- }
+//=========================================================================
+// Internal function:
+//
+// Will try to allocate a big block of memory inside the required range.
+//=========================================================================
+static MHOOKS_TRAMPOLINE* FindTrampolineInRange(PBYTE pLower, PBYTE pUpper) {
+ if (!g_pFreeList) {
+ return NULL;
+ }
+
+ // This is a standard free list, except we're doubly linked to deal with soem return shenanigans.
+ MHOOKS_TRAMPOLINE* curEntry = g_pFreeList;
+ while (curEntry) {
+ if ((MHOOKS_TRAMPOLINE*) pLower < curEntry && curEntry < (MHOOKS_TRAMPOLINE*) pUpper) {
+ ListRemove(&g_pFreeList, curEntry);
+
+ return curEntry;
}
+
+ curEntry = curEntry->pNextTrampoline;
+ }
+
+ return NULL;
+}
+
+//=========================================================================
+// Internal function:
+//
+// Will try to allocate the trampoline structure within 2 gigabytes of
+// the target function.
+//=========================================================================
+static MHOOKS_TRAMPOLINE* TrampolineAlloc(PBYTE pSystemFunction, S64 nLimitUp, S64 nLimitDown) {
+
+ MHOOKS_TRAMPOLINE* pTrampoline = NULL;
+
+ // determine lower and upper bounds for the allocation locations.
+ // in the basic scenario this is +/- 2GB but IP-relative instructions
+ // found in the original code may require a smaller window.
+ PBYTE pLower = pSystemFunction + nLimitUp;
+ pLower = pLower < (PBYTE)(DWORD_PTR)0x0000000080000000 ?
+ (PBYTE)(0x1) : (PBYTE)(pLower - (PBYTE)0x7fff0000);
+ PBYTE pUpper = pSystemFunction + nLimitDown;
+ pUpper = pUpper < (PBYTE)(DWORD_PTR)0xffffffff80000000 ?
+ (PBYTE)(pUpper + (DWORD_PTR)0x7ff80000) : (PBYTE)(DWORD_PTR)0xfffffffffff80000;
+ ODPRINTF((L"mhooks: TrampolineAlloc: Allocating for %p between %p and %p", pSystemFunction, pLower, pUpper));
+
+ // try to find a trampoline in the specified range
+ pTrampoline = FindTrampolineInRange(pLower, pUpper);
+ if (!pTrampoline) {
+ // if it we can't find it, then we need to allocate a new block and
+ // try again. Just fail if that doesn't work
+ g_pFreeList = BlockAlloc(pSystemFunction, pLower, pUpper);
+ pTrampoline = FindTrampolineInRange(pLower, pUpper);
+ }
+
+ // found and allocated a trampoline?
+ if (pTrampoline) {
+ ListPrepend(&g_pHooks, pTrampoline);
}
return pTrampoline;
@@ -321,12 +438,16 @@ static MHOOKS_TRAMPOLINE* TrampolineAlloc(PBYTE pSystemFunction, S64 nLimitUp, S
// Return the internal trampoline structure that belongs to a hooked function.
//=========================================================================
static MHOOKS_TRAMPOLINE* TrampolineGet(PBYTE pHookedFunction) {
- for (DWORD i=0; i<MHOOKS_MAX_SUPPORTED_HOOKS; i++) {
- if (g_pHooks[i]) {
- if (g_pHooks[i]->codeTrampoline == pHookedFunction)
- return g_pHooks[i];
+ MHOOKS_TRAMPOLINE* pCurrent = g_pHooks;
+
+ while (pCurrent) {
+ if (pCurrent->pHookFunction == pHookedFunction) {
+ return pCurrent;
}
+
+ pCurrent = pCurrent->pNextTrampoline;
}
+
return NULL;
}
@@ -336,20 +457,17 @@ static MHOOKS_TRAMPOLINE* TrampolineGet(PBYTE pHookedFunction) {
// Free a trampoline structure.
//=========================================================================
static VOID TrampolineFree(MHOOKS_TRAMPOLINE* pTrampoline, BOOL bNeverUsed) {
- for (DWORD i=0; i<MHOOKS_MAX_SUPPORTED_HOOKS; i++) {
- if (g_pHooks[i] == pTrampoline) {
- g_pHooks[i] = NULL;
- // It might be OK to call VirtualFree, but quite possibly it isn't:
- // If a thread has some of our trampoline code on its stack
- // and we yank the region from underneath it then it will
- // surely crash upon returning. So instead of freeing the
- // memory we just let it leak. Ugly, but safe.
- if (bNeverUsed)
- VirtualFree(pTrampoline, 0, MEM_RELEASE);
- g_nHooksInUse--;
- break;
- }
+ ListRemove(&g_pHooks, pTrampoline);
+
+ // If a thread could feasinbly have some of our trampoline code
+ // on its stack and we yank the region from underneath it then it will
+ // surely crash upon returning. So instead of freeing the
+ // memory we just let it leak. Ugly, but safe.
+ if (bNeverUsed) {
+ ListPrepend(&g_pFreeList, pTrampoline);
}
+
+ g_nHooksInUse--;
}
//=========================================================================
@@ -558,27 +676,17 @@ static DWORD DisassembleAndSkip(PVOID pFunction, DWORD dwMinLen, MHOOKS_PATCHDAT
ODPRINTF((L"mhooks: DisassembleAndSkip: Disassembling %p", pLoc));
while ( (dwRet < dwMinLen) && (pins = GetInstruction(&dis, (ULONG_PTR)pLoc, pLoc, dwFlags)) ) {
- ODPRINTF(("mhooks: DisassembleAndSkip: %p: %s", pLoc, pins->String));
+ ODPRINTF(("mhooks: DisassembleAndSkip: %p:(0x%2.2x) %s", pLoc, pins->Length, pins->String));
if (pins->Type == ITYPE_RET ) break;
- #if !defined _M_X64 // MPC-HC hack
- if (pins->Type == ITYPE_BRANCH) break;
- #endif
+ if (pins->Type == ITYPE_BRANCH ) break;
if (pins->Type == ITYPE_BRANCHCC) break;
if (pins->Type == ITYPE_CALL ) break;
if (pins->Type == ITYPE_CALLCC ) break;
#if defined _M_X64
BOOL bProcessRip = FALSE;
- if (pins->Type == ITYPE_BRANCH) { // MPC-HC hack
- if (dwRet == 0 && pins->OperandCount == 1 && (pins->Operands[0].Flags & OP_IPREL) && pins->Length >= dwMinLen) {
- ODPRINTF((L"mhooks: DisassembleAndSkip: hooking the function using MPC-HC hack"));
- bProcessRip = TRUE;
- } else {
- break;
- }
- }
// mov or lea to register from rip+imm32
- else if ((pins->Type == ITYPE_MOV || pins->Type == ITYPE_LEA) && (pins->X86.Relative) &&
+ if ((pins->Type == ITYPE_MOV || pins->Type == ITYPE_LEA) && (pins->X86.Relative) &&
(pins->X86.OperandSize == 8) && (pins->OperandCount == 2) &&
(pins->Operands[1].Flags & OP_IPREL) && (pins->Operands[1].Register == AMD64_REG_RIP))
{
@@ -681,15 +789,13 @@ BOOL Mhook_SetHook(PVOID *ppSystemFunction, PVOID pHookFunction) {
pTrampoline = TrampolineAlloc((PBYTE)pSystemFunction, patchdata.nLimitUp, patchdata.nLimitDown);
if (pTrampoline) {
ODPRINTF((L"mhooks: Mhook_SetHook: allocated structure at %p", pTrampoline));
- // open ourselves so we can VirtualProtectEx
- HANDLE hProc = GetCurrentProcess();
DWORD dwOldProtectSystemFunction = 0;
DWORD dwOldProtectTrampolineFunction = 0;
// set the system function to PAGE_EXECUTE_READWRITE
- if (VirtualProtectEx(hProc, pSystemFunction, dwInstructionLength, PAGE_EXECUTE_READWRITE, &dwOldProtectSystemFunction)) {
+ if (VirtualProtect(pSystemFunction, dwInstructionLength, PAGE_EXECUTE_READWRITE, &dwOldProtectSystemFunction)) {
ODPRINTF((L"mhooks: Mhook_SetHook: readwrite set on system function"));
// mark our trampoline buffer to PAGE_EXECUTE_READWRITE
- if (VirtualProtectEx(hProc, pTrampoline, sizeof(MHOOKS_TRAMPOLINE), PAGE_EXECUTE_READWRITE, &dwOldProtectTrampolineFunction)) {
+ if (VirtualProtect(pTrampoline, sizeof(MHOOKS_TRAMPOLINE), PAGE_EXECUTE_READWRITE, &dwOldProtectTrampolineFunction)) {
ODPRINTF((L"mhooks: Mhook_SetHook: readwrite set on trampoline structure"));
// create our trampoline function
@@ -721,7 +827,7 @@ BOOL Mhook_SetHook(PVOID *ppSystemFunction, PVOID pHookFunction) {
pbCode = pTrampoline->codeJumpToHookFunction;
pbCode = EmitJump(pbCode, (PBYTE)pHookFunction);
ODPRINTF((L"mhooks: Mhook_SetHook: created reverse trampoline"));
- FlushInstructionCache(hProc, pTrampoline->codeJumpToHookFunction,
+ FlushInstructionCache(GetCurrentProcess(), pTrampoline->codeJumpToHookFunction,
pbCode - pTrampoline->codeJumpToHookFunction);
// update the API itself
@@ -740,18 +846,18 @@ BOOL Mhook_SetHook(PVOID *ppSystemFunction, PVOID pHookFunction) {
pTrampoline->pHookFunction = (PBYTE)pHookFunction;
// flush instruction cache and restore original protection
- FlushInstructionCache(hProc, pTrampoline->codeTrampoline, dwInstructionLength);
+ FlushInstructionCache(GetCurrentProcess(), pTrampoline->codeTrampoline, dwInstructionLength);
// MPC-HC HACK: otherwise we go into infinite recursion when hooking NtQueryInformationProcess() with EMET active and the hook calls the original function
*ppSystemFunction = pTrampoline->codeTrampoline;
- VirtualProtectEx(hProc, pTrampoline, sizeof(MHOOKS_TRAMPOLINE), dwOldProtectTrampolineFunction, &dwOldProtectTrampolineFunction);
+ VirtualProtect(pTrampoline, sizeof(MHOOKS_TRAMPOLINE), dwOldProtectTrampolineFunction, &dwOldProtectTrampolineFunction);
} else {
- ODPRINTF((L"mhooks: Mhook_SetHook: failed VirtualProtectEx 2: %d", gle()));
+ ODPRINTF((L"mhooks: Mhook_SetHook: failed VirtualProtect 2: %d", gle()));
}
// flush instruction cache and restore original protection
- FlushInstructionCache(hProc, pSystemFunction, dwInstructionLength);
- VirtualProtectEx(hProc, pSystemFunction, dwInstructionLength, dwOldProtectSystemFunction, &dwOldProtectSystemFunction);
+ FlushInstructionCache(GetCurrentProcess(), pSystemFunction, dwInstructionLength);
+ VirtualProtect(pSystemFunction, dwInstructionLength, dwOldProtectSystemFunction, &dwOldProtectSystemFunction);
} else {
- ODPRINTF((L"mhooks: Mhook_SetHook: failed VirtualProtectEx 1: %d", gle()));
+ ODPRINTF((L"mhooks: Mhook_SetHook: failed VirtualProtect 1: %d", gle()));
}
if (pTrampoline->pSystemFunction) {
// this is what the application will use as the entry point
@@ -785,19 +891,17 @@ BOOL Mhook_Unhook(PVOID *ppHookedFunction) {
// make sure nobody's executing code where we're about to overwrite a few bytes
SuspendOtherThreads(pTrampoline->pSystemFunction, pTrampoline->cbOverwrittenCode);
ODPRINTF((L"mhooks: Mhook_Unhook: found struct at %p", pTrampoline));
- // open ourselves so we can VirtualProtectEx
- HANDLE hProc = GetCurrentProcess();
DWORD dwOldProtectSystemFunction = 0;
// make memory writable
- if (VirtualProtectEx(hProc, pTrampoline->pSystemFunction, pTrampoline->cbOverwrittenCode, PAGE_EXECUTE_READWRITE, &dwOldProtectSystemFunction)) {
+ if (VirtualProtect(pTrampoline->pSystemFunction, pTrampoline->cbOverwrittenCode, PAGE_EXECUTE_READWRITE, &dwOldProtectSystemFunction)) {
ODPRINTF((L"mhooks: Mhook_Unhook: readwrite set on system function"));
PBYTE pbCode = (PBYTE)pTrampoline->pSystemFunction;
for (DWORD i = 0; i<pTrampoline->cbOverwrittenCode; i++) {
pbCode[i] = pTrampoline->codeUntouched[i];
}
// flush instruction cache and make memory unwritable
- FlushInstructionCache(hProc, pTrampoline->pSystemFunction, pTrampoline->cbOverwrittenCode);
- VirtualProtectEx(hProc, pTrampoline->pSystemFunction, pTrampoline->cbOverwrittenCode, dwOldProtectSystemFunction, &dwOldProtectSystemFunction);
+ FlushInstructionCache(GetCurrentProcess(), pTrampoline->pSystemFunction, pTrampoline->cbOverwrittenCode);
+ VirtualProtect(pTrampoline->pSystemFunction, pTrampoline->cbOverwrittenCode, dwOldProtectSystemFunction, &dwOldProtectSystemFunction);
// return the original function pointer
*ppHookedFunction = pTrampoline->pSystemFunction;
bRet = TRUE;
@@ -806,7 +910,7 @@ BOOL Mhook_Unhook(PVOID *ppHookedFunction) {
TrampolineFree(pTrampoline, FALSE);
ODPRINTF((L"mhooks: Mhook_Unhook: unhook successful"));
} else {
- ODPRINTF((L"mhooks: Mhook_Unhook: failed VirtualProtectEx 1: %d", gle()));
+ ODPRINTF((L"mhooks: Mhook_Unhook: failed VirtualProtect 1: %d", gle()));
}
// make the other guys runnable
ResumeOtherThreads();
diff --git a/src/thirdparty/mhook/mhook-lib/mhook.h b/src/thirdparty/mhook/mhook-lib/mhook.h
index 1c6c64a14..1d7cfff5f 100644
--- a/src/thirdparty/mhook/mhook-lib/mhook.h
+++ b/src/thirdparty/mhook/mhook-lib/mhook.h
@@ -26,6 +26,3 @@
BOOL Mhook_SetHook(PVOID *ppSystemFunction, PVOID pHookFunction);
BOOL Mhook_Unhook(PVOID *ppHookedFunction);
-
-#define MHOOKS_MAX_SUPPORTED_HOOKS 64
-
diff --git a/src/thirdparty/mhook/mhook.vcxproj b/src/thirdparty/mhook/mhook.vcxproj
index b95c41602..32c134880 100644
--- a/src/thirdparty/mhook/mhook.vcxproj
+++ b/src/thirdparty/mhook/mhook.vcxproj
@@ -59,7 +59,9 @@
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\common.props" />
</ImportGroup>
- <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Label="UserMacros">
+ <NOMINMAX>False</NOMINMAX>
+ </PropertyGroup>
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>