我有一个最特殊的错误。。。我正在挂接HeapAlloc
以记录所有调用并获取调用API的DLL的名称。该代码适用于Windows7,但不适用于Windows10。我用迷你钩钩住。所有使用Visual Studio 2019 v142编译的内容。
// BasicTest.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include <windows.h>
#include <iostream>
#include <intrin.h>
#include <psapi.h>
#include "minihook.h"
#pragma intrinsic(_ReturnAddress)
#pragma comment(lib, "libMinHook.x64.lib") //v142
LPVOID(WINAPI* OldHeapAlloc)(HANDLE, DWORD, SIZE_T);
template <typename T>
inline MH_STATUS MH_CreateHookApiEx(
LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, T** ppOriginal)
{
return MH_CreateHookApi(
pszModule, pszProcName, pDetour, reinterpret_cast<LPVOID*>(ppOriginal));
}
BOOL intercept = FALSE;
int iMbox = 0;
int iTotal = 0;
LPVOID HookedHeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes) {
iTotal++;
LPVOID ptr = OldHeapAlloc(hHeap, dwFlags, dwBytes);
if (intercept) {
return ptr;
}
intercept = TRUE;
iMbox++;
HMODULE hModule;
char lpBaseName[32];
if (GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)_ReturnAddress(), &hModule) != 0) {
if (GetModuleBaseNameA(GetCurrentProcess(), hModule, lpBaseName, sizeof(lpBaseName)) != 0) {
printf("Reserved %d at %08x from %sn", dwBytes, ptr, lpBaseName);
}
}
intercept = FALSE;
return ptr;
}
int main()
{
if (MH_Initialize() != MH_OK)
{
return 1;
}
if (MH_CreateHookApiEx(
L"ntdll.dll", "RtlAllocateHeap", &HookedHeapAlloc, &OldHeapAlloc) != MH_OK)
{
return 1;
}
if (MH_EnableHook(MH_ALL_HOOKS) != MH_OK)
{
return 1;
}
MessageBoxA(NULL, "This is a test", "Test", MB_OK);
MH_DisableHook(MH_ALL_HOOKS);
printf("RtlAllocateHeap calls for MessageBoxA = %dn", iMbox);
printf("RtlAllocateHeap total calls = %dn", iTotal);
return 0;
}
CCD_ 2是为了防止CCD_。因为类似GetModule*
的函数调用HeapAlloc
。需要注意的是,如果您自己调用HeapAlloc
,即使是重复调用(HeapAlloc
->HeapAlloc
->HeapAlloc
(,代码也能正常工作。您可以调用HeapAlloc
5000次,并在HookedHeapAlloc
中放入深度为5的递归(拦截可以防止任何崩溃(。
但当使用MessageBoxA
时,程序会挂在Windows 10上(在20H2和21H1中测试(。
Windows 7上的输出类似于
[.......]
Reserved 24 at 004528f0 from KERNELBASE.dll
Reserved 40 at 0046afb0 from KERNELBASE.dll
Reserved 520 at 02aae4f0 from uxtheme.dll
Reserved 512 at 0046dd90 from IMM32.DLL
Reserved 48 at 00468960 from ntdll.dll
Reserved 48 at 004689a0 from ntdll.dll
Reserved 512 at 004612a0 from USER32.dll
Reserved 48 at 004689e0 from ntdll.dll
Reserved 48 at 00468a20 from ntdll.dll
Reserved 48 at 00468a60 from ntdll.dll
RtlAllocateHeap calls for MessageBoxA = 828
RtlAllocateHeap total calls = 1657
在Windows10上,程序在几次输出后挂起。在调试器内部时,它挂起在ZwWaitForAlertByThreadId
。
感谢您的帮助:(
所以,回答我自己的问题。我发现了问题。GetModuleHandleExA
递增模块的引用计数。事实证明,如果引用计数增加得太多,就会出现死锁。我不知道为什么。。。添加标志GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT
修复了该问题。