获得进程完整路径的第二种方法
第一次发的博客是用PEB获得进程完整路径,这几天在学一种新方法。进程下有多个模块,而通过windbg调试发现第一模块即进程完整路径。直接看代码把。
#include <TlHelp32.h> #include <Psapi.h> char* GetProcessList(ULONG& BufferLength) { HANDLE SnapshotHandle = NULL; HANDLE ProcessHandle = NULL; DWORD Offset = 0; DWORD v7 = 0; PROCESSENTRY32 ProcessEntry32; //快照 char ProcessFullPath[MAX_PATH] = { 0 }; if (EnableDebugPrivilege()==FALSE) { return NULL; } ProcessEntry32.dwSize = sizeof(PROCESSENTRY32); //结构体中有dwSize的时候dwSize一般要初始化为自己结构体的大小。 SnapshotHandle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (SnapshotHandle == INVALID_HANDLE_VALUE) { return NULL; } char* BufferData = (char*)LocalAlloc(LPTR, 1024); //暂时分配一下缓冲区 --->虚拟内存 malloc if (BufferData==NULL) { CloseHandle(SnapshotHandle); return NULL; } if (Process32First(SnapshotHandle, &ProcessEntry32)) //得到第一个进程顺便判断一下系统快照是否成功 { //ProcessID ProcessImageName ProcessFullPath //C:\Windows\System32\Calc.exe do { //打开进程并返回句柄 ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, ProcessEntry32.th32ProcessID); //打开目标进程 // (ProcessEntry32.th32ProcessID !=4)) if (ProcessHandle == NULL)// 权限太高 - 降低打开 { ProcessHandle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, ProcessEntry32.th32ProcessID); //打开目标进程 if (ProcessHandle == NULL) { strcpy(ProcessFullPath, "打开进程失败"); goto Label1; } } //获得进程下的第一个模块 HMODULE ModuleHandle = NULL; DWORD ReturnLength = GetModuleFileNameEx(ProcessHandle, ModuleHandle, ProcessFullPath, sizeof(ProcessFullPath)); //进程下的第一模块就是本身的进程所在地址 if (ReturnLength == 0) { RtlZeroMemory(ProcessFullPath, MAX_PATH); QueryFullProcessImageName(ProcessHandle, 0, ProcessFullPath, &ReturnLength); // 更推荐使用这个函数 if (ReturnLength == 0) { strcpy(ProcessFullPath, "枚举信息失败"); } } //BufferData[[20][calc.exe\0][ \0][20][calc.exe\0][ \0][20][calc.exe\0][ \0] ] Label1: v7 = sizeof(DWORD) + lstrlen(ProcessEntry32.szExeFile) + lstrlen(ProcessFullPath) + 2; //ID + ImageName + 1 + FullPath + 1 // 缓冲区太小,再重新分配下 if (LocalSize(BufferData) < (Offset + v7)) BufferData = (char*)LocalReAlloc(BufferData, (Offset + v7), LMEM_ZEROINIT | LMEM_MOVEABLE); //接下来三个memcpy就是向缓冲区里存放数据 数据结构是 //进程ID+进程名+0+进程完整名+0 进程 //因为字符数据是以0 结尾的 memcpy(BufferData + Offset, &(ProcessEntry32.th32ProcessID), sizeof(DWORD)); Offset += sizeof(DWORD); memcpy(BufferData + Offset, ProcessEntry32.szExeFile, lstrlen(ProcessEntry32.szExeFile) + 1); Offset += lstrlen(ProcessEntry32.szExeFile) + 1; memcpy(BufferData + Offset, ProcessFullPath, lstrlen(ProcessFullPath) + 1); Offset += lstrlen(ProcessFullPath) + 1; if (ProcessHandle!=NULL) { CloseHandle(ProcessHandle); ProcessHandle = NULL; } } while (Process32Next(SnapshotHandle, &ProcessEntry32)); } else { CloseHandle(SnapshotHandle); LocalFree(BufferData); return NULL; } BufferLength = Offset; CloseHandle(SnapshotHandle); return BufferData; }
顺带着挖个坑,ListCtrl这个控件贼坑,咋写都不出来。。。。