准备写一个进程管理的功能模块,今天下午先写了扫描获取本机各个进程路径,获取各个进程映像名称,进程完整路径。
要获取进程信息,第一步想到的就是提权,提权代码用过多次了,今天也小结了一下(http://www.cnblogs.com/lsh123/p/8280575.html),不再复述。
0x01 自定义结构体
struct _PROCESS_INFORMATION_ { ULONG ProcessID; ULONG ParentProcessID; char ImageNameData[MAX_PATH]; char ProcessFullPathData[MAX_PATH]; };
首先定义好自己需要的各个成员变量为一个结构体,包括进程ID,父进程ID,映像名称,进程完整路径四个成员变量。
0x02 进程ID,父进程ID,进程名 ProcessEntry32结构体
要列出所有进程,需要调用CreateToolHelp32Snapshot函数先得到系统进程快照的句柄,函数包含在<tlhelp32.h>头中。函数的具体参数如下:
HANDLE_WINAPI CreateToolHelp32Snapshot( DWORD dwFlags, DWORD th32ProcessID );
参数含义:
dwFlags:指定了获取系统进程快照的类型,获取进程相关信息应该填入参数 TH32CS_SNAPPROCESS 表示在快照中包含系统中所有的进程
th32ProcessID:指向要获取进程快照的ID,获取系统内所有进程快照时是0;
函数调用:
HANDLE SnapshotHandle = NULL; PROCESSENTRY32 ProcessEntry32; ProcessEntry32.dwSize = sizeof(PROCESSENTRY32); SnapshotHandle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
如果函数调用成功返回快照句柄,否则返回INVALID_HANDLE_VALUE。在得到系统进程快照句柄之后,需要调用Process32First函数查找系统进程快照中的第一个进程。函数参数如下:
BOOL Process32First( HANDLE hSnapshot, LPROCESSENTRY32 lppe );
再调用Process32Next函数列出系统中下一个进程,利用do while循环遍历出所有进程,Process32Next参数如下:
BOOL Process32Next( HANDLE hSnapshot, LPROCESSENTRY32 lppe );
两个函数的参数是一样的,其中hSnapshot是由CreateToolHelp32Snapshot函数返回的系统进程快照的句柄;而lppe是指向PROCESSENTRY32的结构体指针,进程的详细信息保存在结构体中。PROCESSENTRY32结构体定义:
typedef struct tagPROCESSENTRY32 { DWORD dwSize;//结构大小 DWORD cntUsage;//此进程的引用计数 DWORD th32ProcessID;//进程ID DWORD th32DefaultHeapID;//进程默认堆ID DWORD th32ModuleID;//进程模块ID DWORD cntThreads;//此进程开启的线程计数 DWORD th32ParentProcessID;//父进程ID LONG pcPriClassBase;//线程优先权 DWORD dwFlags;//保留 char szExeFile[MAX_PATH];//进程名 } PROCESSENTRY32;
可以看到PROCESSENTRY32结构体中我所需要的三个成员,进程ID,父进程ID,进程名。
当上述两个函数列举到进程时返回TRUE,否则返回FALSE。当列举到一个进程时lppe参数就会返回进程的详细信息,所以用户就可以读取这些进程的信息,然后输出。
列举完后,需要调用CloseHandle函数关闭系统进程句柄。
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(ProcessFullPathData, "打开进程失败"); goto Label1; } } //获得进程下的第一个模块 HMODULE ModuleHandle = NULL; DWORD ReturnLength = GetModuleFileNameEx(ProcessHandle, ModuleHandle, ProcessFullPathData, sizeof(ProcessFullPathData)); if (ReturnLength == 0) { RtlZeroMemory(ProcessFullPathData, MAX_PATH); QueryFullProcessImageName(ProcessHandle, 0, ProcessFullPathData, &ReturnLength); // 更推荐使用这个函数 if (ReturnLength == 0) { strcpy(ProcessFullPathData, "枚举信息失败"); } } //BufferData[[20][calc.exe