windows遍歷程序與殺死程序
阿新 • • 發佈:2019-01-03
windows下遍歷程序有多種方式:
程序快照:CreateToolhelp32Snapshot;
程序狀態API:PSAPI;
在psapi中主要使用到的方法有:
EnumProcesses——列舉程序;
EnumProcessModules——列舉程序內模組;
GetModuleFileNameEx——獲取模組名;
通過這3個方法就可以遍歷程序以及程序內各個模組;
其中基本資料結構QString、QList是基於Qt的,如果用的不是Qt庫,換成C++對應STL標準庫List、String的即可;
注意其中的EnumProcessModules中的hModus控制代碼不能使用CloseHandle(因為這些控制代碼來自一個快照snapshot,不是實際的資源)://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; }
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); } }
ntdll.dll匯出方式:
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);
}
}
}