windows下遍历进程有多种方式:
进程快照:CreateToolhelp32Snapshot;
进程状态API:PSAPI;
在psapi中主要使用到的方法有:
EnumProcesses——枚举进程;
EnumProcessModules——枚举进程内模块;
GetModuleFileNameEx——获取模块名;
通过这3个方法就可以遍历进程以及进程内各个模块;
其中基本数据结构QString、QList是基于Qt的,如果用的不是Qt库,换成C++对应STL标准库List、String的即可;
//Win32Api: void AdjustPrivilege() { HANDLE hToken; if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) { TOKEN_PRIVILEGES tp; tp.PrivilegeCount = 1; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid)) { AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL); } CloseHandle(hToken); } } //根据进程所在的路径查询进程,并返回进程的ID列表 QList<DWORD> CheckProcess(const QString &processPath) { AdjustPrivilege(); QList<DWORD> pIDList; DWORD dwProcessId[1024]; DWORD bytesRet; if (EnumProcesses(dwProcessId, sizeof(dwProcessId), &bytesRet)) { HANDLE hProcess = NULL; HMODULE hModus[1024]; DWORD bytesModuRet; TCHAR szModuleName[MAX_PATH]; QStringList tempPathList = processPath.toLower() .split(QRegExp("[/\\\\]"), QString::SkipEmptyParts); QString processPathWinStd;//转成windows标准的路径 int listLength = tempPathList.length(); for (int idx = 0; idx < listLength; ++idx) { if (idx != 0) processPathWinStd.push_back("\\"); processPathWinStd.push_back(tempPathList[idx]); } int ProcessNum = (bytesRet/sizeof(DWORD)); for (int i = 0, j = 0; i < ProcessNum; ++i) { hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, dwProcessId[i]); if (hProcess) { //Do not call CloseHandle on any of the handles returned by this function. //The information comes from a snapshot, so there are no resources to be freed. if (EnumProcessModules(hProcess, hModus, sizeof(hModus), &bytesModuRet)) { int ModuleNum = (bytesRet/sizeof(DWORD)); for (j = 0; j < ModuleNum; ++j) { if (GetModuleFileNameEx(hProcess, hModus[j], szModuleName, sizeof(szModuleName)) && processPathWinStd == QString::fromWCharArray(szModuleName, _tcslen(szModuleName)).toLower()) { pIDList.push_back(dwProcessId[i]); } } } CloseHandle(hProcess); } } } return pIDList; }注意其中的EnumProcessModules中的hModus句柄不能使用CloseHandle(因为这些句柄来自一个快照snapshot,不是实际的资源):
Do not call CloseHandle on any of the handles returned by this function.
The information comes from a snapshot, so there are no resources to be freed.
windows下杀死进程也有两种方式:
TerminateProcess——系统API;
NtTerminateProcess——ntdll.dll中未公开导出方法;
TerminateProcess实际上也是调用NtTerminateProcess实现具体功能的;
正常情况下,调用这两个任何一个都可以终结或者杀死一个进程(夸用户杀进程需要先提权,提权见“windows提权方法”),但是在有些情况下有些应用程序为了防止自己被杀,会hook系统的TerminateProcess方法,导致TerminateProcess失效;所以用NtTerminateProcess可以使杀死进程的成功率更高一些;
void Terminate(const QString &processPath) { AdjustPrivilege(); //================TerminateProcess================//遍历进程列表与进程模块,匹配路径后强杀 DWORD dwProcessId[1024]; DWORD bytesRet; if (EnumProcesses(dwProcessId, sizeof(dwProcessId), &bytesRet)) { HANDLE hProcess = NULL; HMODULE hModus[1024]; DWORD bytesModuRet; TCHAR szModuleName[MAX_PATH]; QStringList tempPathList = processPath.toLower() .split(QRegExp("[/\\\\]"), QString::SkipEmptyParts); QString processPathWinStd;//转成windows标准的路径 int listLength = tempPathList.length(); for (int idx = 0; idx < listLength; ++idx) { if (idx != 0) processPathWinStd.push_back("\\"); processPathWinStd.push_back(tempPathList[idx]); } int ProcessNum = (bytesRet/sizeof(DWORD)); for (int i = 0, j = 0; i < ProcessNum; ++i) { hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, dwProcessId[i]); if (hProcess) { //Do not call CloseHandle on any of the handles returned by this function. //The information comes from a snapshot, so there are no resources to be freed. if (EnumProcessModules(hProcess, hModus, sizeof(hModus), &bytesModuRet)) { int ModuleNum = (bytesRet/sizeof(DWORD)); for (j = 0; j < ModuleNum; ++j) { if (GetModuleFileNameEx(hProcess, hModus[j], szModuleName, sizeof(szModuleName)) && processPathWinStd == QString::fromWCharArray(szModuleName, _tcslen(szModuleName)).toLower()) { TerminateProcess(hProcess, 4); } } } CloseHandle(hProcess); } } } } void Terminate(const DWORD &pID) { AdjustPrivilege(); //================TerminateProcess================//根据进程ID强杀 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pID); if (hProcess) { TerminateProcess(hProcess, 4); CloseHandle(hProcess); } }
const unsigned long SE_DEBUG_PRIVILEGE = 0x14; typedef int (__stdcall *fRtlAdjustPrivilege)(ULONG, BOOLEAN, BOOLEAN, PBOOLEAN); typedef DWORD (__stdcall *fNtTerminateProcess)(HANDLE, UINT); HMODULE hNtDll = NULL; fRtlAdjustPrivilege funcAdjustPrivilege = NULL; fNtTerminateProcess funcTerminateProcess = NULL; //================ //NtDll方式: //================ bool NtInit() { hNtDll = LoadLibrary(_T("ntdll.dll")); if (!hNtDll) return false; funcAdjustPrivilege = (fRtlAdjustPrivilege)GetProcAddress(hNtDll, "RtlAdjustPrivilege"); funcTerminateProcess = (fNtTerminateProcess)GetProcAddress(hNtDll, "NtTerminateProcess"); return true; } void NtFree() { if (hNtDll) FreeLibrary(hNtDll); } void NtAdjustPrivilege() { if (funcAdjustPrivilege) { BOOLEAN oldStatus; funcAdjustPrivilege(SE_DEBUG_PRIVILEGE, true, false, &oldStatus); } } void NtTerminate(const QString &processPath) { NtAdjustPrivilege(); //================TerminateProcess================//遍历进程列表与进程模块,匹配路径后强杀 if (funcTerminateProcess) { DWORD dwProcessId[1024]; DWORD bytesRet; if (EnumProcesses(dwProcessId, sizeof(dwProcessId), &bytesRet)) { HANDLE hProcess = NULL; HMODULE hModus[1024]; DWORD bytesModuRet; TCHAR szModuleName[MAX_PATH]; QStringList tempPathList = processPath.toLower() .split(QRegExp("[/\\\\]"), QString::SkipEmptyParts); QString processPathWinStd;//转成windows标准的路径 int listLength = tempPathList.length(); for (int idx = 0; idx < listLength; ++idx) { if (idx != 0) processPathWinStd.push_back("\\"); processPathWinStd.push_back(tempPathList[idx]); } int ProcessNum = (bytesRet/sizeof(DWORD)); for (int i = 0, j = 0; i < ProcessNum; ++i) { hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, dwProcessId[i]); if (hProcess) { //Do not call CloseHandle on any of the handles returned by this function. //The information comes from a snapshot, so there are no resources to be freed. if (EnumProcessModules(hProcess, hModus, sizeof(hModus), &bytesModuRet)) { int ModuleNum = (bytesRet/sizeof(DWORD)); for (j = 0; j < ModuleNum; ++j) { if (GetModuleFileNameEx(hProcess, hModus[j], szModuleName, sizeof(szModuleName)) && processPathWinStd == QString::fromWCharArray(szModuleName, _tcslen(szModuleName)).toLower()) { funcTerminateProcess(hProcess, 4); } } } CloseHandle(hProcess); } } } } } void NtTerminate(const DWORD &pID) { NtAdjustPrivilege(); //================TerminateProcess================//根据进程ID强杀 if (funcTerminateProcess) { HANDLE hProcess = NULL; hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pID); if (hProcess) { funcTerminateProcess(hProcess, 4); CloseHandle(hProcess); } } }