遍历进程树终止进程

#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;

};
View Code
#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;
    //}

}
View Code
#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;
    
};
View Code
#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;
}
View Code
if (!m_processName.IsEmpty())
    {
        CProcess cproc;
        cproc.InitProcessList();

        cproc.TerminateProcessByName(m_processName);
    }
View Code

通过遍历进程树,在map中标记父进程,重新排序进程父子关系,根据名字查杀进程会遍历到根节点。

posted @ 2019-07-25 17:12  _**  阅读(295)  评论(0编辑  收藏  举报