遍历进程树终止进程
#pragma once #include <afxtempl.h> class tagProcess: public CObject { public: tagProcess() { strProcessName = ""; pid = ppid = 0; arySubPid.RemoveAll(); } tagProcess(const tagProcess& c) { strProcessName = c.strProcessName; ppid = c.ppid; pid = c.pid; arySubPid.RemoveAll(); int x = c.arySubPid.GetSize(); for (int i = 0; i < c.arySubPid.GetSize(); i++) { DWORD dwx = c.arySubPid.GetAt(i); arySubPid.Add(dwx); } } tagProcess& tagProcess::operator=(const tagProcess& tagP) { if (this == & tagP) { return *this; } strProcessName = tagP.strProcessName; ppid = tagP.ppid; pid = tagP.pid; arySubPid.RemoveAll(); for (int i = 0; i < tagP.arySubPid.GetSize(); i++) { arySubPid.Add(tagP.arySubPid.GetAt(i)); } return *this; } ~tagProcess() { release(); } //查找 //添加 void Add(DWORD dwpid) { arySubPid.Add(dwpid); } //删除 void release() { if (arySubPid.GetSize()!= 0) { arySubPid.RemoveAll(); } strProcessName = ""; pid = ppid = 0; } tagProcess LookUp(CMap<DWORD,DWORD,tagProcess,tagProcess>& procMap, DWORD pid) { tagProcess tagP; procMap.Lookup(pid, tagP); return tagP; } CString strProcessName; DWORD pid; DWORD ppid; CArray <DWORD,DWORD> arySubPid; }; class CMyProcessList { public: CMyProcessList(void); ~CMyProcessList(void); void Add(DWORD, tagProcess&); void Print(); void RemoveALl(); void Sort(); bool SetPpid(DWORD dwpid, DWORD ppid); BOOL CMyProcessList::LookUp(CString& name, tagProcess& tagP); CMap<DWORD,DWORD,tagProcess,tagProcess>& GetProcMap(); private: CMap<DWORD,DWORD,tagProcess,tagProcess> m_procMap; };
#include "StdAfx.h" #include "MyProcessList.h" CMyProcessList::CMyProcessList(void) { } CMyProcessList::~CMyProcessList(void) { RemoveALl(); } void CMyProcessList::Add(DWORD dwpid , tagProcess& tagProc) { //加入前先查看下 m_procMap.SetAt(dwpid, tagProc); } void CMyProcessList::Print() { DWORD dwPid; tagProcess tagProc; CString str, str2; POSITION pos = m_procMap.GetStartPosition(); while(pos) { m_procMap.GetNextAssoc(pos, dwPid, tagProc); str.Format("procName:%s,pid:%u,subPid:", tagProc.strProcessName, dwPid); if (tagProc.arySubPid.GetSize()!= 0) { //str += ", "; for (int i = 0; i < tagProc.arySubPid.GetSize(); i++) { DWORD dw = tagProc.arySubPid.GetAt(i); str2.Format(",%d", dw); str += str2; } } OutputDebugString(str); } } void CMyProcessList::RemoveALl() { DWORD dwPid; tagProcess tagProc; if (m_procMap.GetSize() != 0) { POSITION pos = m_procMap.GetStartPosition(); while(pos) { m_procMap.GetNextAssoc(pos, dwPid, tagProc); tagProc.release(); m_procMap.SetAt(dwPid, tagProc); } m_procMap.RemoveAll(); } } void CMyProcessList::Sort() { DWORD dwPid; tagProcess tagProc; CMap<DWORD,DWORD,tagProcess,tagProcess> m_tmpMap; if (m_procMap.GetSize() == 0) { return; } //copy to tmpMap POSITION pos = m_procMap.GetStartPosition(); while(pos) { m_procMap.GetNextAssoc(pos, dwPid, tagProc); m_tmpMap.SetAt(dwPid, tagProc); } //traversal dwPid = 0; tagProc.release(); POSITION posTmp = m_tmpMap.GetStartPosition(); while(posTmp) { m_tmpMap.GetNextAssoc(posTmp, dwPid, tagProc); //add pid to ppid SetPpid(tagProc.ppid, dwPid); } } bool CMyProcessList::SetPpid(DWORD dwpid, DWORD subpid) { tagProcess tagP; if (dwpid == subpid) // 0 = 0 { return false; } m_procMap.Lookup(dwpid, tagP); tagP.Add(subpid); m_procMap.SetAt(dwpid, tagP); return true; } BOOL CMyProcessList::LookUp(CString& name, tagProcess& tagP) { DWORD dwPid; BOOL ret = FALSE; if (m_procMap.GetSize() != 0) { POSITION pos = m_procMap.GetStartPosition(); while(pos) { m_procMap.GetNextAssoc(pos, dwPid, tagP); if (tagP.strProcessName.CompareNoCase(name) == 0) //同名返回 { ret = TRUE; break; } } } tagProcess tagResult = tagP; tagProcess tagPP;// = tagP; m_procMap.Lookup(tagP.ppid, tagPP); do { if (tagPP.strProcessName.CompareNoCase(name) == 0) { tagResult = tagPP; } } while (m_procMap.Lookup(tagPP.ppid, tagPP) && tagPP.pid != 0); tagP = tagResult; return ret; } CMap<DWORD,DWORD,tagProcess,tagProcess>& CMyProcessList::GetProcMap() { //if (m_procMap.GetSize() != 0) //{ return m_procMap; //} }
#pragma once #include "MyProcessList.h " #define NTSTATUS LONG #define ProcessBasicInformation 0 typedef UINT PROCESSINFOCLASS; typedef NTSYSAPI NTSTATUS (NTAPI *Func_NtQueryInformationProcess)( IN HANDLE ProcessHandle, IN PROCESSINFOCLASS InformationClass, OUT PVOID ProcessInformation, IN ULONG ProcessInformationLength, OUT PULONG ReturnLength OPTIONAL ); typedef DWORD (WINAPI *Func_NtSuspendProcess)(HANDLE ProcessHandle); typedef struct { DWORD ExitStatus; DWORD PebBaseAddress; DWORD AffinityMask; DWORD BasePriority; ULONG UniqueProcessId; ULONG InheritedFromUniqueProcessId; }PROCESS_BASIC_INFORMATION; class CProcess { public: CProcess(void); ~CProcess(void); BOOL InitProcessList(void); BOOL EnablePrivilege(); void PrintProcessNameAndID(DWORD processID); BOOL TerminateProcessByName(CString& name); BOOL MyTerminateProcess(DWORD& pid); BOOL terminate(tagProcess tagp); private: Func_NtQueryInformationProcess NtQueryInformationProcess; Func_NtSuspendProcess NtSuspendProcess; CMyProcessList m_cMyProc; };
#include "StdAfx.h" #include "Process.h" #include <psapi.h> #pragma comment(lib,"Psapi.lib") CProcess::CProcess(void) { NtQueryInformationProcess = (Func_NtQueryInformationProcess)GetProcAddress(GetModuleHandle("NTDLL"), "NtQueryInformationProcess"); NtSuspendProcess = (Func_NtSuspendProcess)GetProcAddress(GetModuleHandle("NTDLL"), "ZwSuspendProcess"); } CProcess::~CProcess(void) { } BOOL CProcess::EnablePrivilege() { HANDLE hToken = INVALID_HANDLE_VALUE; LUID sedebugnameValue; TOKEN_PRIVILEGES tkp; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { return FALSE; } if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue)) { CloseHandle(hToken); return FALSE; } tkp.PrivilegeCount = 1; tkp.Privileges[0].Luid = sedebugnameValue; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL)) { CloseHandle(hToken); return FALSE; } if (hToken != INVALID_HANDLE_VALUE) { CloseHandle(hToken); hToken = INVALID_HANDLE_VALUE; } return TRUE; } void CProcess::PrintProcessNameAndID( DWORD processID ) { CString str; HMODULE hMod; DWORD cbNeeded; HANDLE hProcess = INVALID_HANDLE_VALUE; PROCESS_BASIC_INFORMATION pbi = {0}; char szProcessName[MAX_PATH] = "<unknown>"; TCHAR szImageFileName[MAX_PATH] = {0}; OSVERSIONINFOEX osver = { 0 }; tagProcess tagpro;// = {0}; osver.dwOSVersionInfoSize = sizeof(osver); GetVersionEx((OSVERSIONINFO*)&osver); EnablePrivilege(); hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID ); if (processID == 0) { //System Idle Process //null //没有父进程 strcpy_s(szProcessName, MAX_PATH, "System Idle Process"); NtQueryInformationProcess(hProcess, ProcessBasicInformation, (PVOID)&pbi, sizeof(PROCESS_BASIC_INFORMATION), NULL); } else if (processID == 4) { //System //C:\Windows\system32\ntoskrnl.exe //父进程为0 strcpy_s(szProcessName, MAX_PATH, "System"); NtQueryInformationProcess(hProcess, ProcessBasicInformation, (PVOID)&pbi, sizeof(PROCESS_BASIC_INFORMATION), NULL); } else { if (INVALID_HANDLE_VALUE != hProcess ) { if (osver.dwMajorVersion < 5) //2000 { EnumProcessModules( hProcess, &hMod, sizeof(hMod), &cbNeeded); GetModuleFileNameEx(hProcess, hMod, szProcessName, sizeof(szProcessName)); } else if (osver.dwMajorVersion == 5) //xp or 2003 { GetProcessImageFileName(hProcess, szProcessName, sizeof(szProcessName)); } else if (osver.dwMajorVersion >= 6) // >win7 { DWORD dwPathNameSize = sizeof(szProcessName); QueryFullProcessImageName(hProcess, 0, szProcessName, &dwPathNameSize); } NtQueryInformationProcess(hProcess, ProcessBasicInformation, (PVOID)&pbi, sizeof(PROCESS_BASIC_INFORMATION), NULL); } } if (hProcess != INVALID_HANDLE_VALUE) { CloseHandle(hProcess); hProcess = INVALID_HANDLE_VALUE; } tagpro.pid = processID; tagpro.ppid = pbi.InheritedFromUniqueProcessId; CString strName = szProcessName; strName = strName.Right(strName.GetLength() - strName.ReverseFind('\\') - 1); tagpro.strProcessName = strName; m_cMyProc.Add(processID, tagpro); str.Format(_T("%s pid:%u, ppid:%u\n"), szProcessName, processID, pbi.InheritedFromUniqueProcessId); // Print the process name and identifier. //OutputDebugString(str); } BOOL CProcess::InitProcessList(void) { DWORD aProcesses[1024], cbNeeded, cProcesses; unsigned int i; if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) ) return FALSE; cProcesses = cbNeeded / sizeof(DWORD); for ( i = 0; i < cProcesses; i++ ) { PrintProcessNameAndID(aProcesses[i]); } //排列父子关系 m_cMyProc.Sort(); m_cMyProc.Print(); //m_cMyProc.RemoveALl(); //m_cMyProc.Print(); return FALSE; } BOOL CProcess::TerminateProcessByName(CString& name) { int nCount = 0; if (name.IsEmpty()) { return FALSE; } tagProcess tagp; if (!m_cMyProc.LookUp(name, tagp)) { return FALSE; } return terminate(tagp); } BOOL CProcess::terminate(tagProcess tagp) { if(tagp.arySubPid.GetSize() > 0) { HANDLE hProcess = OpenProcess(PROCESS_SUSPEND_RESUME | SYNCHRONIZE, FALSE, tagp.pid); NtSuspendProcess(hProcess); for (int i = 0; i < tagp.arySubPid.GetSize(); i++) { DWORD dwpid = tagp.arySubPid.GetAt(i); terminate(tagp.LookUp(m_cMyProc.GetProcMap(), dwpid)); } } return MyTerminateProcess(tagp.pid); } BOOL CProcess::MyTerminateProcess(DWORD& pid) { HANDLE hProcess = OpenProcess(PROCESS_SUSPEND_RESUME | PROCESS_TERMINATE|SYNCHRONIZE, FALSE, pid); if(hProcess == NULL) return FALSE; BOOL ret = TerminateProcess(hProcess, 0); if(ret) { WaitForSingleObject(hProcess, 3000); } CloseHandle(hProcess); return ret; }
if (!m_processName.IsEmpty()) { CProcess cproc; cproc.InitProcessList(); cproc.TerminateProcessByName(m_processName); }
通过遍历进程树,在map中标记父进程,重新排序进程父子关系,根据名字查杀进程会遍历到根节点。