windows遍历进程与杀死进程

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);
        }
    }

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);
            }
        }
    }






你可能感兴趣的:(windows)