diff options
author | Alex Marsev <alex.marsev@gmail.com> | 2014-03-30 18:50:13 +0400 |
---|---|---|
committer | Alex Marsev <alex.marsev@gmail.com> | 2014-03-30 21:49:50 +0400 |
commit | 4524c7ddbbd06ae471dbb3221e9a40d067ad2840 (patch) | |
tree | 5666ee1a3703e2df10305e5bef96dc18cafaeac7 /src/thirdparty/mhook | |
parent | 513b017859353d613cb4bae7b30fbc030d49f766 (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.cpp | 310 | ||||
-rw-r--r-- | src/thirdparty/mhook/mhook-lib/mhook.h | 3 | ||||
-rw-r--r-- | src/thirdparty/mhook/mhook.vcxproj | 4 |
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> |