我尽可能地减少了代码,以保持斯考斯代码所做的工作:
CreateProcess启动windows记事本TerminateProcess在我们从CreateProcess得到的手柄上。TerminateProcess是异步的OpenProcess在调试时,您可以很容易地(在OpenProcess之前)检查给定的Pid在任务管理器或processExplorer中都找不到。但是其他的windows API函数似乎没有接受这个Pid。
#include "stdafx.h"
#include <windows.h>
#include "Psapi.h"
#include <TlHelp32.h>
#include <iostream>
#include <cassert>
typedef unsigned long PID;
typedef const std::string& P_PATH;
// Launch an executable given by a path and set a few infomatives stuffs passed as ref parameters
bool launch_process(P_PATH path, STARTUPINFO& info, PROCESS_INFORMATION& processInfo, HANDLE& hProcess, PID& pid)
{
setlocale(LC_ALL, "en_US.utf8");
std::wstring widestr = std::wstring(path.begin(), path.end());
const wchar_t* widecstr = widestr.c_str();
LPTSTR szCmdline = _tcsdup(widecstr);
if (CreateProcess(szCmdline, NULL, NULL, NULL, false, NULL, NULL, NULL, &info, &processInfo))
{
hProcess = processInfo.hProcess;
pid = processInfo.dwProcessId;
return true;
}
return false;
}
int main(int argc, char* argv[])
{
// Setup
// -----
bool OK = false;
STARTUPINFO info = { sizeof(info) };
PROCESS_INFORMATION processInfo;
HANDLE hProcess;
PID pid = 0;
// launch notepad
// --------------
OK = launch_process("C:\\WINDOWS\\System32\\notepad.exe", info, processInfo, hProcess, pid);
assert(OK);
// wait a bit
// ----------
system("PAUSE");
SetLastError(0);
// get Handle on notepad
// ---------------------
hProcess = OpenProcess(PROCESS_TERMINATE | SYNCHRONIZE, false, static_cast<DWORD>(pid));
std::cout << "Error: " << GetLastError() << std::endl;
// Kill notepad
// ------------
UINT exitCode = 0;
DWORD dwWaitResult = 0;
SetLastError(0);
OK = TerminateProcess(hProcess, exitCode);
std::cout << "Error: " << GetLastError() << std::endl;
// ensure everything went well ( we need to wait because TerminateProcess is asynchronous )
if (!OK || (dwWaitResult != WaitForSingleObject(hProcess, INFINITE)))
return -1;
// Cleanup
CloseHandle(hProcess);
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
hProcess = nullptr;
processInfo.hProcess = nullptr;
// Ya know what let's reopen the pid I just killed
// ( you can see that notepad was started then killed, you can check the pid does not exist in either the task manager or processExplorer )
SetLastError(0);
hProcess = OpenProcess(PROCESS_TERMINATE | SYNCHRONIZE, false, static_cast<DWORD>(pid));
std::cout << "Error: " << GetLastError() << std::endl;
// Yeah I can speak to the deads!
if (hProcess != nullptr)
{
LPWSTR szProcessName = L"";
GetModuleFileNameEx(hProcess, NULL, szProcessName, sizeof szProcessName);
char c_szText[MAX_PATH];
wcstombs(c_szText, szProcessName, wcslen(szProcessName) + 1);
// But the deads have no names
std::cout << "Error: " << GetLastError() << std::endl;
std::cout << "Zombie Name: " << c_szText << std::endl;
}
return 0;
}发布于 2016-02-09 16:58:12
ps -Af f,它确实显示僵尸)。OpenProcess可以访问它,因为process对象还没有被销毁,也就是说它处于僵尸状态。这将是因为另一个进程有一个打开的句柄。例如,- an antivirus, which may call OpenProcess to get information to assess if the application is malicious, or
- Process Monitor, which gets all sorts of information, probably some of which it calls OpenProcess to get, or
- the DWM, which I imagine, but do not know, calls OpenProcess to get information on whether the application supports e.g. high DPI mode and so forth, or
- any number of other applications may have called OpenProcess previously and have a still open handle.
道德:
GetExitCodeProcess读取他们的退出代码,或者对进程的状态有任何其他兴趣,那么所有进程都将处于僵尸状态。通常情况下,一旦退出代码被读取,对进程的兴趣就会减弱,句柄被关闭,最后进程将被销毁。https://stackoverflow.com/questions/35296996
复制相似问题