获取流程说明

时间:2017-11-18 07:02:50

标签: c++ c windows process

如您所知,流程名称与其说明之间存在一些差异,例如dwm.exe流程的说明为Desktop Window Manager

我可以使用以下代码检查进程的名称:

#include <windows.h>
#include <TlHelp32.h>
#include <Winternl.h>

typedef NTSTATUS (NTAPI *NTQUERYINFORMATIONPROCESS)(
    IN HANDLE ProcessHandle,
    IN PROCESSINFOCLASS ProcessInformationClass,
    OUT PVOID ProcessInformation,
    IN ULONG ProcessInformationLength,
    OUT PULONG ReturnLength OPTIONAL
    );

int main()
{
    PEB Peb = {0};
    DWORD dwSize = 0;
    DWORD dwPID = 0;
    HANDLE hProcess = NULL;
    HANDLE hProcessSnap = NULL;
    WCHAR PsPath[MAX_PATH] = {0};
    WCHAR wszProcName[20] = L"dwm.exe"; //Desktop Window Manager
    PROCESSENTRY32 PsEntry32 = {0}; 
    PROCESS_BASIC_INFORMATION PsBasicInfo = {0};    
    RTL_USER_PROCESS_PARAMETERS RtlUserPsParams = {0};
    NTQUERYINFORMATIONPROCESS NtFunction = NULL;


    if((hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) != INVALID_HANDLE_VALUE)
    {
        PsEntry32.dwSize = sizeof(PROCESSENTRY32);

        if(!Process32First(hProcessSnap, &PsEntry32))
        {
            CloseHandle(hProcessSnap);
            return FALSE;
        }

        do
        {
            if(lstrcmpiW(PsEntry32.szExeFile, wszProcName) == 0)
            {
                hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, PsEntry32.th32ProcessID);

                if(hProcess != INVALID_HANDLE_VALUE)
                {
                    NtFunction = (NTQUERYINFORMATIONPROCESS)GetProcAddress(LoadLibraryW(L"ntdll.dll"), "NtQueryInformationProcess");

                    if(NtFunction)
                    {
                        if(NtFunction(hProcess, ProcessBasicInformation, &PsBasicInfo, sizeof(PROCESS_BASIC_INFORMATION), &dwSize) == ERROR_SUCCESS)
                        {
                            ReadProcessMemory(hProcess, PsBasicInfo.PebBaseAddress, &Peb, sizeof(PEB), (SIZE_T*)&dwSize);
                            ReadProcessMemory(hProcess, Peb.ProcessParameters, &RtlUserPsParams, sizeof(RTL_USER_PROCESS_PARAMETERS), (SIZE_T*)&dwSize);
                            ReadProcessMemory(hProcess, RtlUserPsParams.ImagePathName.Buffer, PsPath, RtlUserPsParams.ImagePathName.Length, (SIZE_T*)&dwSize);
                            dwPID = PsEntry32.th32ProcessID;
                        }
                    }
                    CloseHandle(hProcess);
                }                           
            }
        }while(Process32Next(hProcessSnap, &PsEntry32));

        CloseHandle(hProcessSnap);
    }

    return 0;
}

现在我想查看流程描述

是否可以逐个获取所有流程描述并进行检查?

1 个答案:

答案 0 :(得分:0)

在我之后,我使用ToolHelp32Snapshot()而不是您的PEB方法来获取模块路径:

GetFileVersionInfoSizeA()获取版本结构的大小

GetFileVersionInfoA()将数据从该结构中提取到本地char数组中。

VerQueryValue()和“ \ VarFileInfo \ Translation”以获取语言代码页

然后,我循环浏览不同的语言代码页,以创建下一个查询所需的子块字符串。

然后,我将VerQueryValue()与正确的语言代码页一起插入子块中,并将结果存储到另一个char数组中。

然后我们将该字符串打印到控制台。

#include <iostream>
#include <string>
#include <Windows.h>
#include <TlHelp32.h>
#include <strsafe.h>

#pragma comment(lib,"Version.lib")

std::string GetModulePath(std::string moduleName, DWORD procId)
{
    std::string path;
    HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, procId);
    if (hSnap != INVALID_HANDLE_VALUE)
    {
        MODULEENTRY32 modEntry{};
        modEntry.dwSize = sizeof(modEntry);
        if (Module32First(hSnap, &modEntry))
        {
            do
            {
                if (!_stricmp(modEntry.szModule, moduleName.c_str()))
                {
                    path = modEntry.szExePath;
                    break;
                }
            } while (Module32Next(hSnap, &modEntry));
        }
    }
    CloseHandle(hSnap);
    return path;
}

std::string GetFilePath(std::string procName)
{
    std::string path;
    HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnap != INVALID_HANDLE_VALUE)
    {
        PROCESSENTRY32 procEntry;
        procEntry.dwSize = sizeof(procEntry);

        if (Process32First(hSnap, &procEntry))
        {
            do
            {
                if (!_stricmp(procEntry.szExeFile, procName.c_str()))
                {
                    path = GetModulePath(procName, procEntry.th32ProcessID);
                    break;
                }
            } while (Process32Next(hSnap, &procEntry));

        }
    }
    CloseHandle(hSnap);
    return path;
}

struct LANGANDCODEPAGE {
    WORD wLanguage;
    WORD wCodePage;
};

int main()
{
    std::string path = GetFilePath("notepad++.exe");

    DWORD verSize = GetFileVersionInfoSizeA(path.c_str(), 0);

    char* data = new char[verSize]{ 0 };

    GetFileVersionInfoA(path.c_str(), 0, verSize, data);

    UINT length;
    LANGANDCODEPAGE* lpTranslate;

    VerQueryValue(data, "\\VarFileInfo\\Translation", (LPVOID*)&lpTranslate, &length);

    char SubBlock[50]{ 0 };

    for (unsigned int i = 0; i < (length / sizeof(struct LANGANDCODEPAGE)); i++)
    {
        HRESULT result = StringCchPrintf(SubBlock, 50,
            TEXT("\\StringFileInfo\\%04x%04x\\FileDescription"),
            lpTranslate[i].wLanguage,
            lpTranslate[i].wCodePage);

        char* description = new char[0x100]{ 0 };

        UINT length2;
        VerQueryValue(data, SubBlock, (LPVOID*)&description, &length2);

        std::cout << description << "\n";
    }

    getchar();
    return 0;
}

必须以管理员身份运行,并且只能在x86上进行测试。