遍历系统进程经常使用的有三种方式windows
<Tlhelp32.h>
,先使用CreateToolhelp32Snapshot
建立系统快照,即拷贝一份系统全部进程的信息到指定的结构体PROCESSENTRY32
中,而后使用Process32First
和Process32Next
得到每个进程的详细信息。须要注意的是编译成32位程序只能获取32位进程的详细信息,编译成64位则能获取全部进程的详细信息<psapi.h>
,先使用EnumProcesses
获取系统全部的进程PID,而后用EnumProcessModules
遍历每一个进程中的模块,最后用GetModuleFileNameEx
获取模块的完整路径或者用GetModuleBaseName
获取模块的名称。也须要注意程序编译的位数与进程的位数NtQuerySystemInformation
,因为是未公开函数因此须要自定义函数原型。留个坑之后填完整思路
(1).使用CreateToolhelp32Snapshot
以及传参TH32CS_SNAPPROCESS
建立系统进程快照
(2).使用Process32First
获取第一个进程的信息存入到PROCESSENTRY32
结构体中
(3).再用Process32Next
遍历全部进程
(4).最后用CloseHandle
关闭句柄api
注意事项
程序很简单,须要注意的是编码问题,包括控制台输出的编码以及程序自己的编码,windows.h
头文件也定义许多保证编码兼容性的变量,好比TEXT()
_T
TCHAR
LPTSTR...
函数
-fexec-charset=gbk
wchar_t *ws = L"你好"; wprintf(L"%s\n",ws)
TCHAR
遇到宽字符就是Unicode
编码,不然就是char
类型,TEXT()
_T()
_tprintf
等函数同理<locale.h>
和<tchar.h>
,可能须要添加代码setlocale(LC_ALL,"chs");
完整Demoui
#include <stdio.h> #include <stdlib.h> #include <windows.h> #include <Tlhelp32.h> int main(int argc, char *argv[]) { PROCESSENTRY32 pe32; pe32.dwSize = sizeof(pe32); HANDLE hSnapshot_proc = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hSnapshot_proc != INVALID_HANDLE_VALUE) { BOOL check = Process32First(hSnapshot_proc, &pe32); while (check) { printf("进程PID = %d 进程名 = %s\n", pe32.th32ProcessID, pe32.szExeFile); check = Process32Next(hSnapshot_proc, &pe32); } } CloseHandle(hSnapshot_proc); system("pause"); return 0; }
编译命令gcc -fexec-charset=gbk proc1.c -o proc1
编码
运行截图spa
完整思路
(1).使用EnumProcesses
获取全部进程PID
(2).获取当前进程的Debug
权限
(3).使用OpenProcess
打开进程,依次获取全部进程的进程句柄
(4).根据进程句柄以及EnumProcessModules
遍历进程的全部模块
(5).使用GetModuleFileNameEx
获取进程的完整路径
(6).使用CloseHandle
关闭句柄以及取消Debug
权限code
注意事项
使用EnumProcesses
须要注意四个坑,先说明一下我是用的MinGW
编译器,用 VScode 写完代码本身调 gcc 编译!orm
<psapi.h>
必定要在<windows.h>
以后-lpsapi
必定要在文件名proc3.c
以后OpenProcess
前必定要获取Debug
权限完整Demotoken
#include <windows.h> #include <stdio.h> #include <stdlib.h> #include <psapi.h> BOOL SetProcessPrivilege(char *lpName, BOOL opt); int main(int argc, char *argv[]) { DWORD Proc_pid[1024], Retn_bytes, Proc_count, Retn_bytes2; unsigned int i; HMODULE hMod[1024]; HANDLE hProcess; char szModName[MAX_PATH]; if (EnumProcesses(Proc_pid, sizeof(Proc_pid), &Retn_bytes)) { Proc_count = Retn_bytes / sizeof(DWORD); SetProcessPrivilege("SeDebugPrivilege", 1); for (i = 0; i < Proc_count; i++) { hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, Proc_pid[i]); if (hProcess != NULL) { EnumProcessModules(hProcess, hMod, sizeof(hMod), &Retn_bytes2); GetModuleFileNameEx(hProcess, hMod[0], szModName, sizeof(szModName)); printf("PID=%d Path=%s\n", Proc_pid[i], szModName); } CloseHandle(hProcess); } SetProcessPrivilege("SeDebugPrivilege", 0); } system("pause"); return 0; } BOOL SetProcessPrivilege(char *lpName, BOOL opt) { HANDLE tokenhandle; TOKEN_PRIVILEGES NewState; if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &tokenhandle)) { LookupPrivilegeValue(NULL, lpName, &NewState.Privileges[0].Luid); NewState.PrivilegeCount = 1; NewState.Privileges[0].Attributes = opt != 0 ? 2 : 0; AdjustTokenPrivileges(tokenhandle, FALSE, &NewState, sizeof(NewState), NULL, NULL); CloseHandle(tokenhandle); return 1; } else { return 0; } }
编译命令gcc proc3.c -lpsapi -o proc3
接口
运行截图