OpenProcess 调用 returns 伪句柄
OpenProcess call returns pseudo handle
MSDN 说 OpenProcess()
必须 return 一个有效的句柄,或者错误时为 NULL。
但是,我在 Win7 x64(以及 Win 8.1 x86、Win XP x64、Win Vista x64)上遇到了一种罕见的情况,其中 OpenProcess()
returned -1 用于当前进程,即伪句柄,而我枚举了进程。它很少偶尔发生(当我 运行 我在不同平台上的测试套件时)。而且我无法在 Win 10 上重现它。
然后 CloseHandle()
在此句柄上失败并出现 ERROR_INVALID_HANDLE
错误。但另一方面,MSDN 说
The pseudo handle need not be closed when it is no longer needed.
Calling the CloseHandle function with a pseudo handle has no effect.
为什么会这样? OpenProcess()
的行为是否正确?
下面是我的代码示例:
HANDLE snap = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 prEntry = {};
prEntry.dwSize = sizeof (PROCESSENTRY32);
if (Process32First (snap, &prEntry))
{
do
{
if (prEntry.th32ProcessID)
{
HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, prEntry.th32ProcessID);
// <<<< from time to time h is (-1) here when meets the current process
if (h)
{
wchar_t imageFilename[MAX_PATH + 1] = {};
if (GetProcessImageFileName(hProc, imageFilename, MAX_PATH))
{
// do something
}
if (!CloseHandle(h))
{
// CLoseHandle returns FALSE on pseudo handle (at least on Win 7)
DWORD err = ::GetLastError();
// err == 0x6, i.e. ERROR_INVALID_HANDLE, for the pseudo handle
// << create a memory dump here for further analysis
}
}
}
}
while (Process32Next (snap, &prEntry));
}
UPD:我发现为什么我的测试在 Win 10 平台上永远不会失败 - CloseHandle(HANDLE(-1))
在 Win 10 上总是 returns TRUE
,而在 Win 7 上它 return s FALSE
出现 0x6 错误。但我仍然无法解释 OpenProcess()
行为。
解决方案:正如 Ben Voigt 所说(参见接受的答案),测试环境中有一个挂钩,在之前的测试套件 运行 之后没有被清除。经过几天的调试,找到并本地化了挂钩,修复了测试套件以清理挂钩。现在 OpenProcess 调用可以正常工作。
最可能的解释是 OpenProcess
钩子写得不好,例如反恶意软件和恶意软件都使用这种钩子。
这个钩子的作者没有仔细阅读 OpenProcess
文档,当真正的 Windows OpenProcess
成功但钩子想要阻止你的访问时,它正在做
return INVALID_HANDLE_VALUE;
(这可能是一个 copy/paste 错误,因为还写了一个 CreateFile
钩子)
由于此类挂钩主要用于 rootkit——"evil" 和 "good" (but accidentally evil anyway) 变种,您可能无法从系统内部确认挂钩。另一方面,内核调试器连接应该表明在真正的 Windows OpenProcess 执行期间,return 地址指向挂钩代码,而不是内核转换存根。
MSDN 说 OpenProcess()
必须 return 一个有效的句柄,或者错误时为 NULL。
但是,我在 Win7 x64(以及 Win 8.1 x86、Win XP x64、Win Vista x64)上遇到了一种罕见的情况,其中 OpenProcess()
returned -1 用于当前进程,即伪句柄,而我枚举了进程。它很少偶尔发生(当我 运行 我在不同平台上的测试套件时)。而且我无法在 Win 10 上重现它。
然后 CloseHandle()
在此句柄上失败并出现 ERROR_INVALID_HANDLE
错误。但另一方面,MSDN 说
The pseudo handle need not be closed when it is no longer needed. Calling the CloseHandle function with a pseudo handle has no effect.
为什么会这样? OpenProcess()
的行为是否正确?
下面是我的代码示例:
HANDLE snap = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 prEntry = {};
prEntry.dwSize = sizeof (PROCESSENTRY32);
if (Process32First (snap, &prEntry))
{
do
{
if (prEntry.th32ProcessID)
{
HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, prEntry.th32ProcessID);
// <<<< from time to time h is (-1) here when meets the current process
if (h)
{
wchar_t imageFilename[MAX_PATH + 1] = {};
if (GetProcessImageFileName(hProc, imageFilename, MAX_PATH))
{
// do something
}
if (!CloseHandle(h))
{
// CLoseHandle returns FALSE on pseudo handle (at least on Win 7)
DWORD err = ::GetLastError();
// err == 0x6, i.e. ERROR_INVALID_HANDLE, for the pseudo handle
// << create a memory dump here for further analysis
}
}
}
}
while (Process32Next (snap, &prEntry));
}
UPD:我发现为什么我的测试在 Win 10 平台上永远不会失败 - CloseHandle(HANDLE(-1))
在 Win 10 上总是 returns TRUE
,而在 Win 7 上它 return s FALSE
出现 0x6 错误。但我仍然无法解释 OpenProcess()
行为。
解决方案:正如 Ben Voigt 所说(参见接受的答案),测试环境中有一个挂钩,在之前的测试套件 运行 之后没有被清除。经过几天的调试,找到并本地化了挂钩,修复了测试套件以清理挂钩。现在 OpenProcess 调用可以正常工作。
最可能的解释是 OpenProcess
钩子写得不好,例如反恶意软件和恶意软件都使用这种钩子。
这个钩子的作者没有仔细阅读 OpenProcess
文档,当真正的 Windows OpenProcess
成功但钩子想要阻止你的访问时,它正在做
return INVALID_HANDLE_VALUE;
(这可能是一个 copy/paste 错误,因为还写了一个 CreateFile
钩子)
由于此类挂钩主要用于 rootkit——"evil" 和 "good" (but accidentally evil anyway) 变种,您可能无法从系统内部确认挂钩。另一方面,内核调试器连接应该表明在真正的 Windows OpenProcess 执行期间,return 地址指向挂钩代码,而不是内核转换存根。