0

MSDN says that OpenProcess() must return either a valid handle, or NULL on error.

However, I met a rare situation on Win7 x64 (and also on Win 8.1 x86, Win XP x64, Win Vista x64) where OpenProcess() returned -1 for the current process, i.e. the pseudo handle, while I enumerated processes. It occurs very rarely from time to time (when I run my test suite on different platforms). And I can't reproduce it on Win 10.

Then CloseHandle() fails on this handle with ERROR_INVALID_HANDLE error. But on the other hand MSDN says that

The pseudo handle need not be closed when it is no longer needed. Calling the CloseHandle function with a pseudo handle has no effect.

Why does this happen? Is it correct behavior for OpenProcess()?

Below is an example of my code:

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: I found why my tests never fail on Win 10 platform - CloseHandle(HANDLE(-1)) always returns TRUE on Win 10, while on Win 7 it returns FALSE with 0x6 error. But I still have no explanation about OpenProcess() behaviour.

SOLUTION: As Ben Voigt said (see the accepted answer) there was a hook in the test environment, which was not cleared after the previous test suite run. After days of debugging the hook was found and localized, the test suite was fixed to clean the hooks up. Now OpenProcess call works correctly.

4

1 回答 1

2

最可能的解释是写得不好的OpenProcess钩子,例如反恶意软件和恶意软件都使用这样的钩子。

这个钩子的编写者没有OpenProcess仔细阅读文档,当真正的WindowsOpenProcess成功但钩子想要阻止你的访问时,它正在做

return INVALID_HANDLE_VALUE;

CreateFile(这也可能是编写钩子时出现的复制/粘贴错误)

由于此类钩子主要用于 rootkit 中——“邪恶”和“好”(但无论如何都是邪恶的)变种,您可能无法从系统内部确认钩子。另一方面,内核调试器连接应该表明,在真正的 Windows OpenProcess 执行期间,返回地址是挂钩代码,而不是内核转换存根。

于 2018-03-24T17:53:26.467 回答