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 CheckProcess(const QString &processPath)
{
AdjustPrivilege();
QList 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);
}
}
}