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)
X
正在加载信息~
2
最新回复 (0)