Windows7/10下32位/64位应用程序枚举所有进程文件路径及描述信息

xingyun86 2022-8-19 532

Windows7/10下32位/64位应用程序枚举所有进程文件路径及描述信息

今天有个兄弟找我说需要32位应用程序获取系统所有32位和64位进程信息及进程路径文件描述,故研究了了一番,做个记录,希望以后兄弟可以简单直接用。

#include <vector>
#include <Windows.h>
#include <TlHelp32.h>
#pragma comment(lib, "Version.lib")

BOOL EnableDebugPrivilege()
{
	HANDLE hToken;
	LUID Luid;
	TOKEN_PRIVILEGES tp;
	if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))return FALSE;
	if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &Luid))
	{
		CloseHandle(hToken);
		return FALSE;
	}
	tp.PrivilegeCount = 1;
	tp.Privileges[0].Luid = Luid;
	tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
	if (!AdjustTokenPrivileges(hToken, false, &tp, sizeof(tp), NULL, NULL))
	{
		CloseHandle(hToken);
		return FALSE;
	}
	CloseHandle(hToken);
	return TRUE;
}
std::string EP_WToA(const std::wstring& ws)
{
	if (ws.empty() == true)
	{
		return ("");
	}
	std::string as(::WideCharToMultiByte(CP_ACP, 0, ws.data(), -1, NULL, 0, NULL, NULL), 0x00);
	::WideCharToMultiByte(CP_ACP, 0, ws.data(), -1, as.data(), as.size(), NULL, NULL);
	return as;
}
std::string EnumProcInfo()
{
	std::string strRet = "";
	BOOL bResult = FALSE;
	HANDLE hProcessSnap = NULL;
	PROCESSENTRY32W pe32 = { 0 };
	std::vector<std::vector<std::string>> vvProcInfo = {};
	EnableDebugPrivilege();
	hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (hProcessSnap == INVALID_HANDLE_VALUE) {
		return strRet;
	}
	pe32.dwSize = sizeof(pe32);
	bResult = ::Process32FirstW(hProcessSnap, &pe32);
	while (bResult == TRUE)
	{
		std::wstring wstrExeName = L"";
		std::vector<std::string> vProcInfo(7, "无数据");
		vProcInfo[0] = EP_WToA(pe32.szExeFile);
		vProcInfo[1] = std::to_string(pe32.th32ProcessID);
		HANDLE hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID);
		if (hProcess != NULL)
		{
			DWORD dwSize = MAX_PATH;
			WCHAR wExeName[MAX_PATH] = { 0 };
			bResult = ::QueryFullProcessImageNameW(hProcess, 0, wExeName, &dwSize);
			if (bResult == TRUE)
			{
				wstrExeName = wExeName;
			}
			::CloseHandle(hProcess);
		}
		if (wstrExeName.empty() == false)
		{
			vProcInfo[4] = EP_WToA(wstrExeName);
			{
				DWORD dwFileInfoSize = ::GetFileVersionInfoSizeW(wstrExeName.c_str(), NULL);
				if (dwFileInfoSize > 0)
				{
					std::vector<char> vFileVerInfo(dwFileInfoSize, 0x00);
					bResult = ::GetFileVersionInfoW(wstrExeName.c_str(), 0, dwFileInfoSize, vFileVerInfo.data());
					if (bResult == TRUE)
					{
						typedef struct EP_LANGANDCODEPAGE {
							WORD wLanguage;
							WORD wCodePage;
						} EP_LANGANDCODEPAGE;
						UINT uLen = 0;
						LPWSTR lpBuffer = NULL;
						bResult = ::VerQueryValueW(vFileVerInfo.data(), L"\\VarFileInfo\\Translation", (LPVOID*)&lpBuffer, &uLen);
						EP_LANGANDCODEPAGE* pEPLang = (EP_LANGANDCODEPAGE*)lpBuffer;
						for (int i = 0; i < (uLen / sizeof(EP_LANGANDCODEPAGE)); i++)
						{
							WCHAR wPrefix[32] = { 0 };
							_snwprintf(wPrefix, sizeof(wPrefix) / sizeof(*wPrefix), (L"\\StringFileInfo\\%04x%04x\\"), pEPLang[i].wLanguage, pEPLang[i].wCodePage);
							UINT uSubLen = 0;
							LPWSTR lpSubCompanyName = NULL;
							LPWSTR lpSubFileDescription = NULL;
							LPWSTR lpSubProductName = NULL;
							LPWSTR lpSubLegalCopyright = NULL;
							bResult = ::VerQueryValueW(vFileVerInfo.data(), (wPrefix + std::wstring(L"CompanyName")).c_str(), (LPVOID*)&lpSubCompanyName, &uSubLen);
							if (bResult == TRUE)vProcInfo[2] = EP_WToA(lpSubCompanyName);
							bResult = ::VerQueryValueW(vFileVerInfo.data(), (wPrefix + std::wstring(L"FileDescription")).c_str(), (LPVOID*)&lpSubFileDescription, &uSubLen);
							if (bResult == TRUE)vProcInfo[3] = EP_WToA(lpSubFileDescription);
							bResult = ::VerQueryValueW(vFileVerInfo.data(), (wPrefix + std::wstring(L"LegalCopyright")).c_str(), (LPVOID*)&lpSubLegalCopyright, &uSubLen);
							if (bResult == TRUE)vProcInfo[5] = EP_WToA(lpSubLegalCopyright);
							bResult = ::VerQueryValueW(vFileVerInfo.data(), (wPrefix + std::wstring(L"ProductName")).c_str(), (LPVOID*)&lpSubProductName, &uSubLen);
							if (bResult == TRUE)vProcInfo[6] = EP_WToA(lpSubProductName);
							break;
						}
					}
				}
			}
		}
		vvProcInfo.emplace_back(vProcInfo);
		bResult = ::Process32NextW(hProcessSnap, &pe32);
	}
	::CloseHandle(hProcessSnap);
	for (auto& it : vvProcInfo)
	{
		std::string strTmp = "";
		if (strRet.empty() == false)strRet.append("$&#*");
		for (auto& iit : it)
		{
			if (strTmp.empty() == false)strTmp.append("*%*&*");
			strTmp.append(iit.c_str());
		}
		strRet.append(strTmp);
	}
	return strRet;
}

附加方法:

//将Nt文件路径转为Dos文件路径
std::wstring NTFilePath2DosFilePath(std::wstring& name)
{
	WCHAR wzDriveStr[MAX_PATH] = { 0 };
	WCHAR wzDeviceStr[MAX_PATH] = { 0 };
	WCHAR wzDrive[3] = { 0 };
	int cchDevName = 0;
	if (GetLogicalDriveStringsW(sizeof(wzDriveStr)/sizeof(*wzDriveStr), wzDriveStr) == 0)
	{
		return L"";
	}
	for (int i = 0; wzDriveStr[i]; i += 4)
	{
		wmemcpy(wzDrive, wzDriveStr + i, 2);
		if (!QueryDosDeviceW(wzDrive, wzDeviceStr, sizeof(wzDeviceStr)/sizeof(*wzDeviceStr)))
		{
			return L"";
		}
		cchDevName = lstrlenW(wzDeviceStr);
		if (_wcsnicmp(wzDeviceStr, name.c_str(), cchDevName) == 0) //比较前缀
		{
			return (wzDrive + name.substr(cchDevName));;
		}
	}
	return L"";
}
std::wstring GetProcessPath(int PID)
{
	auto hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, PID);
	if (!hProcess)
		return L"";
	WCHAR* FileNativePath = new WCHAR[MAX_PATH + 1];
	if (!GetProcessImageFileNameW(hProcess, FileNativePath, MAX_PATH + 1))
		return L"";
	std::wstring FilePath = NTFilePath2DosFilePath(FileNativePath);
	delete[] FileNativePath;
	return FilePath;
}
std::string EnumProcInfoEx()
{
	EnableDebugPrivilege();
	BOOL bResult = FALSE;
	HANDLE hProcessSnap = NULL;
	PROCESSENTRY32W pe32 = { 0 };
	std::vector<std::vector<std::string>> vvProcInfo = {};
	hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (hProcessSnap == INVALID_HANDLE_VALUE) {
		return "";
	}
	pe32.dwSize = sizeof(pe32);
	bResult = ::Process32FirstW(hProcessSnap, &pe32);
	while (bResult == TRUE)
	{
		std::wstring wstrExeName = L"";
		std::vector<std::string> vProcInfo(7, "无数据");
		vProcInfo[0] = EP_WToA(pe32.szExeFile);
		vProcInfo[1] = std::to_string(pe32.th32ProcessID);
		wstrExeName = GetProcessPath(pe32.th32ProcessID);
		if (wstrExeName.empty() == true)
		{
			HANDLE hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pe32.th32ProcessID);
			printf("0x%x\n", GetLastError());
			if (hProcess != NULL)
			{
				DWORD dwSize = MAX_PATH;
				WCHAR wExeName[MAX_PATH] = { 0 };
				bResult = ::QueryFullProcessImageNameW(hProcess, 0, wExeName, &dwSize);
				if (bResult == TRUE)
				{
					wstrExeName = wExeName;
				}
				//GetModuleFileNameExW(processHaldle,nullptr, szProcessName, MAX_PATH); //win7下出错
				::CloseHandle(hProcess);
			}
		}
		if (wstrExeName.empty() == false)
		{
			vProcInfo[4] = EP_WToA(wstrExeName);
			{
				DWORD dwFileInfoSize = ::GetFileVersionInfoSizeW(wstrExeName.c_str(), NULL);
				if (dwFileInfoSize > 0)
				{
					// GetFileVersionInfoW
					std::vector<char> vFileVerInfo(dwFileInfoSize, 0x00);
					bResult = ::GetFileVersionInfoW(wstrExeName.c_str(), 0, dwFileInfoSize, vFileVerInfo.data());
					if (bResult == TRUE)
					{
						{
							UINT uLen = 0;
							VS_FIXEDFILEINFO* lpBuffer = NULL;
							LPCWSTR lpRootVersion = L"\\";
							bResult = ::VerQueryValueW(vFileVerInfo.data(), lpRootVersion, (LPVOID*)&lpBuffer, &uLen);
							if (bResult == FALSE)
							{
								fwprintf(stderr, L"Error code: %u(%d)\n", GetLastError(), __LINE__);
							}
						}
						// VerQueryValueW
						{
							typedef struct EP_LANGANDCODEPAGE {
								WORD wLanguage;
								WORD wCodePage;
							} EP_LANGANDCODEPAGE;
							UINT uLen = 0;
							LPWSTR lpBuffer = NULL;
							bResult = ::VerQueryValueW(vFileVerInfo.data(), L"\\VarFileInfo\\Translation", (LPVOID*)&lpBuffer, &uLen);
							if (bResult == FALSE)
							{
								fwprintf(stderr, L"Error code: %u(%d)\n", GetLastError(), __LINE__);
							}
							EP_LANGANDCODEPAGE* pEPLang = (EP_LANGANDCODEPAGE*)lpBuffer;
							for (int i = 0; i < (uLen / sizeof(EP_LANGANDCODEPAGE)); i++)
							{
								WCHAR wPrefix[32] = { 0 };
								_snwprintf(wPrefix, sizeof(wPrefix) / sizeof(*wPrefix), (L"\\StringFileInfo\\%04x%04x\\"), pEPLang[i].wLanguage, pEPLang[i].wCodePage);
								UINT uSubLen = 0;
								LPWSTR lpSubCompanyName = NULL;
								LPWSTR lpSubFileDescription = NULL;
								LPWSTR lpSubProductName = NULL;
								LPWSTR lpSubLegalCopyright = NULL;
								bResult = ::VerQueryValueW(vFileVerInfo.data(), (wPrefix + std::wstring(L"CompanyName")).c_str(), (LPVOID*)&lpSubCompanyName, &uSubLen);
								if (bResult == FALSE)
								{
									fwprintf(stderr, L"Error code: %u(%d)\n", GetLastError(), __LINE__);
								}
								else
								{
									vProcInfo[2] = EP_WToA(lpSubCompanyName);
								}
								bResult = ::VerQueryValueW(vFileVerInfo.data(), (wPrefix + std::wstring(L"FileDescription")).c_str(), (LPVOID*)&lpSubFileDescription, &uSubLen);
								if (bResult == FALSE)
								{
									fwprintf(stderr, L"Error code: %u(%d)\n", GetLastError(), __LINE__);
								}
								else
								{
									vProcInfo[3] = EP_WToA(lpSubFileDescription);
								}
								bResult = ::VerQueryValueW(vFileVerInfo.data(), (wPrefix + std::wstring(L"LegalCopyright")).c_str(), (LPVOID*)&lpSubLegalCopyright, &uSubLen);
								if (bResult == FALSE)
								{
									fwprintf(stderr, L"Error code: %u(%d)\n", GetLastError(), __LINE__);
								}
								else
								{
									vProcInfo[5] = EP_WToA(lpSubLegalCopyright);
								}
								bResult = ::VerQueryValueW(vFileVerInfo.data(), (wPrefix + std::wstring(L"ProductName")).c_str(), (LPVOID*)&lpSubProductName, &uSubLen);
								if (bResult == FALSE)
								{
									fwprintf(stderr, L"Error code: %u(%d)\n", GetLastError(), __LINE__);
								}
								else
								{
									vProcInfo[6] = EP_WToA(lpSubProductName);
								}
								break;
							}
						}
					}
					else
					{
						fwprintf(stderr, L"Error code: %u(%d)\n", GetLastError(), __LINE__);
					}
				}
				else
				{
					fwprintf(stderr, L"\nError code: %u(%d)\n", GetLastError(), __LINE__);
				}
			}
		}
		static FILE* pFile = fopen("test.log", "w");
		printf("ExeName=%s, PID=%s, CompanyName=%s,FileDescription=%s,Path=%s,ProductName=%s,LegalCopyright=%s\n",
			vProcInfo[0].c_str(), vProcInfo[1].c_str(), vProcInfo[2].c_str(), vProcInfo[3].c_str(), vProcInfo[4].c_str(), vProcInfo[5].c_str(), vProcInfo[6].c_str());
		fprintf(pFile, "ExeName=%s, PID=%s, CompanyName=%s,FileDescription=%s,Path=%s,ProductName=%s,LegalCopyright=%s\n",
			vProcInfo[0].c_str(), vProcInfo[1].c_str(), vProcInfo[2].c_str(), vProcInfo[3].c_str(), vProcInfo[4].c_str(), vProcInfo[5].c_str(), vProcInfo[6].c_str());
		fflush(pFile);
		vvProcInfo.emplace_back(vProcInfo);
		bResult = ::Process32NextW(hProcessSnap, &pe32);
	}
	::CloseHandle(hProcessSnap);
	return "";
}

扩展方法:WMI需检测组件是否注册(某些安全软件安装或者Win10的COM组件服务会出错)

#define _WIN32_DCOM
#include <comdef.h>
#include <Wbemidl.h>
#pragma comment(lib, "wbemuuid.lib")
int get_process_path(std::wstring& path, unsigned long dwProcessId)
{
    HRESULT hres;
    // Step 1: --------------------------------------------------
    // Initialize COM. ------------------------------------------
    hres = CoInitializeEx(0, COINIT_MULTITHREADED);
    if (FAILED(hres))
    {
        printf("Failed to initialize COM library. Error code = 0x%0X", hres);
        return 1;                  // Program has failed.
    }
    // Step 2: --------------------------------------------------
    // Set general COM security levels --------------------------
    hres = CoInitializeSecurity(
        NULL,
        -1,                          // COM authentication
        NULL,                        // Authentication services
        NULL,                        // Reserved
        RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication 
        RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation  
        NULL,                        // Authentication info
        EOAC_NONE,                   // Additional capabilities 
        NULL                         // Reserved
    );
    if (FAILED(hres))
    {
        printf("Failed to initialize security. Error code = 0x%X\n", hres);
        CoUninitialize();
        return 1;                    // Program has failed.
    }
    // Step 3: ---------------------------------------------------
    // Obtain the initial locator to WMI -------------------------
    IWbemLocator* pLoc = NULL;
    hres = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLoc);
    if (FAILED(hres))
    {
        printf("Failed to create IWbemLocator object. Err code = 0x%X\n", hres);
        CoUninitialize();
        return 1;                 // Program has failed.
    }
    // Step 4: -----------------------------------------------------
    // Connect to WMI through the IWbemLocator::ConnectServer method
    IWbemServices* pSvc = NULL;
    // Connect to the root\cimv2 namespace with
    // the current user and obtain pointer pSvc
    // to make IWbemServices calls.
    hres = pLoc->ConnectServer(
        _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace
        NULL,                    // User name. NULL = current user
        NULL,                    // User password. NULL = current
        0,                       // Locale. NULL indicates current
        NULL,                    // Security flags.
        0,                       // Authority (for example, Kerberos)
        0,                       // Context object 
        &pSvc                    // pointer to IWbemServices proxy
    );
    if (FAILED(hres))
    {
        printf("Could not connect. Error code = 0x%X\n", hres);
        pLoc->Release();
        CoUninitialize();
        return 1;                // Program has failed.
    }
    printf("Connected to ROOT\\CIMV2 WMI namespace\n");
    // Step 5: --------------------------------------------------
    // Set security levels on the proxy -------------------------
    hres = CoSetProxyBlanket(
        pSvc,                        // Indicates the proxy to set
        RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx
        RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx
        NULL,                        // Server principal name 
        RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx 
        RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
        NULL,                        // client identity
        EOAC_NONE                    // proxy capabilities 
    );
    if (FAILED(hres))
    {
        printf("Could not set proxy blanket. Error code = 0x%X\n", hres);
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return 1;               // Program has failed.
    }
    // Step 6: --------------------------------------------------
    // Use the IWbemServices pointer to make requests of WMI ----
    // For example, get the name of the operating system
    IEnumWbemClassObject* pEnumerator = NULL;
    std::wstring wWQL = L"Select ExecutablePath From Win32_Process Where ProcessId = " + std::to_wstring(dwProcessId);
    hres = pSvc->ExecQuery(
        bstr_t("WQL"),
        //bstr_t("SELECT * FROM Win32_OperatingSystem"),
        (BSTR)wWQL.c_str(),//bstr_t(wWQL.c_str()),
        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
        NULL,
        &pEnumerator);
    if (FAILED(hres))
    {
        printf("Query for operating system name failed. Error code = 0x%X\n", hres);
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return 1;               // Program has failed.
    }
    // Step 7: -------------------------------------------------
    // Get the data from the query in step 6 -------------------
    IWbemClassObject* pclsObj = NULL;
    ULONG uReturn = 0;
    while (pEnumerator)
    {
        HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
        if (0 == uReturn)
        {
            break;
        }
        VARIANT vtProp;
        VariantInit(&vtProp);
        // Get the value of the Name property
        //hr = pclsObj->Get(L"Name", 0, &vtProp, 0, 0);
        //printf(" OS Name : %ws\n", vtProp.bstrVal);
        hr = pclsObj->Get(L"ExecutablePath", 0, &vtProp, 0, 0);
        printf(" ExecutablePath : %ws\n", vtProp.bstrVal);
        VariantClear(&vtProp);
        pclsObj->Release();
    }
    // Cleanup
    // ========
    pSvc->Release();
    pLoc->Release();
    pEnumerator->Release();
    CoUninitialize();
    return 0;   // Program successfully completed.
}

扩展:

#include <Windows.h>
#include <winternl.h>
std::wstring GetProcessCmdLine(DWORD PID)
{
	typedef NTSTATUS(CALLBACK* PFN_NTQUERYINFORMATIONPROCESS)(HANDLE ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength OPTIONAL);
	PFN_NTQUERYINFORMATIONPROCESS fnNtQueryInformationProcess = (PFN_NTQUERYINFORMATIONPROCESS)GetProcAddress(::GetModuleHandleW((L"NTDLL.DLL")), "NtQueryInformationProcess");
	HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, PID);
	if (hProcess == NULL) return (L"");
	int iReturn = 1;
	DWORD dwSize;
	SIZE_T size;
	// 0. 获取进程环境块的地址
	PROCESS_BASIC_INFORMATION pbi;
	iReturn = fnNtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), &dwSize);
	if (iReturn < 0) return (L"");
	// 1. 获取进程环境块
	PEB peb;
	size = dwSize;
	if (ReadProcessMemory(hProcess, pbi.PebBaseAddress, &peb, sizeof(peb), &size) == 0)
		return (L"");
	// 2. 获取PEB块的地址(PEB包含执行命令行地址的指针)
	RTL_USER_PROCESS_PARAMETERS rupp;
	if (ReadProcessMemory(hProcess, (LPVOID)peb.ProcessParameters, &rupp, sizeof(rupp), &size) == 0)
		return (L"");
	// 3. 获取命令行
	std::vector<WCHAR> vwCmdLine(rupp.CommandLine.Length, L'\0');
	if (ReadProcessMemory(hProcess, (LPVOID)rupp.CommandLine.Buffer, vwCmdLine.data(), vwCmdLine.size(), &size) == 0)
		return (L"");
	CloseHandle(hProcess);
	return vwCmdLine.data();
}


×
打赏作者
最新回复 (0)
只看楼主
全部楼主
返回