说明:用PSAPI.DLL里函数写的,此代码无PSAPI.H头文件,无PSAPI.LIB链接库文件。
功能:列举当前系统下所有进程,包括PID,进程名,进程完整路径。
环境:Win2000+sp4+VC6.0
另外:本人水平有限,错误在所难免,望高手批评。
#include<stdio.h> #include<windows.h> #define MAX_ID 1024 //最大进程ID //枚举进程 typedef BOOL (_stdcall *ENUMPROCESS)( DWORD *pProcessIds, //指向进程ID数组链 DWORD cb, //ID数组的大小,用字节计数 DWORD *pBytesReturned //返回的字节 ); //枚举进程模块 typedef BOOL (_stdcall *ENUMPROCESSMODULES)( HANDLE hProcess, //进程句柄 HMODULE *lphModule, //指向模块句柄数组链 DWORD cb, //模块句柄数组大小,字节计数 LPDWORD lpcbNeeded //存储所有模块句柄所需的字节数 ); //获得进程模块名 typedef DWORD (_stdcall *GETMODULEFILENAMEEX)( HANDLE hProcess, //进程句柄 HMODULE hModule, //进程句柄 LPTSTR lpFilename, //存放模块全路径名 DWORD nSize //lpFilename缓冲区大小,字符计算 ); //获得进程名 typedef DWORD (_stdcall *GETMODULEBASENAME)( HANDLE hProcess, //进程句柄 HMODULE hModule, //模块句柄 LPTSTR lpBaseName,//存放进程名 DWORD nSize //lpBaseName缓冲区大小 ); BOOL EnablePrivilege(HANDLE hToken,LPCSTR szPrivName); BOOL EnumAllProcess(); int main(int argc,char *argv[]) { EnumAllProcess(); return 1; } BOOL EnumAllProcess() { ENUMPROCESS pEnumProcess; ENUMPROCESSMODULES pEnumProcessModules; GETMODULEFILENAMEEX pGetModuleFileNameEx; GETMODULEBASENAME pGetModuleBaseName; HANDLE hToken;//访问令牌句柄 DWORD dwPID[MAX_ID];//接授进程ID的数组 DWORD cbReturn;//返回的字节数 DWORD dwPCount;//进程数 DWORD i; char szFileName[MAX_PATH];//文件名 char szPathName[MAX_PATH];//路径名 char Id[]="ID",Pid[]="PID",Exe[]="ProcessName",Path[]="Path"; HANDLE hProcess; //进程句柄 HMODULE hModule; //模块句柄 HINSTANCE hPsDll;//实例句柄 hPsDll=LoadLibrary("PSAPI.DLL");//获得DLL的实例 if(hPsDll==NULL) { FreeLibrary(hPsDll); printf("Load Library Failed.../nErrorCode:%d/n",GetLastError()); } //获得函数的地址 pEnumProcess=(ENUMPROCESS)GetProcAddress(hPsDll,"EnumProcesses"); pEnumProcessModules=(ENUMPROCESSMODULES)GetProcAddress(hPsDll,"EnumProcessModules"); pGetModuleFileNameEx=(GETMODULEFILENAMEEX)GetProcAddress(hPsDll,"GetModuleFileNameExA"); pGetModuleBaseName=(GETMODULEBASENAME)GetProcAddress(hPsDll,"GetModuleBaseNameA"); if(!(pEnumProcess && pEnumProcessModules && pGetModuleFileNameEx &&pGetModuleBaseName)) { FreeLibrary(hPsDll); printf("Get Processs Address Failed.../nErrorCode:%d/n",GetLastError()); } printf("%-4s %-8s %-8s/n",Id,Pid,Exe); printf("==========================================/n"); //打开当前进程访问令牌 if(OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken)) { if(EnablePrivilege(hToken,SE_DEBUG_NAME)) { pEnumProcess(dwPID,sizeof(dwPID),&cbReturn);//枚举进程 dwPCount=cbReturn/sizeof(DWORD);//计算线程总数 for(i=0;i<dwPCount;i++) { //打开进程 hProcess=OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,//访问权限 false,//是否允许得到的进程句柄被后创建的子进程继承 dwPID[i]);//进程ID if(hProcess) { //枚举进程模块 pEnumProcessModules(hProcess,&hModule,sizeof(hModule),&cbReturn); //保存文件名 pGetModuleBaseName(hProcess,hModule,szFileName,sizeof(szFileName)); printf("%-4d %-8u %-8s/n",i,dwPID[i],szFileName); //获得进程模块文件名(包含路径) pGetModuleFileNameEx(hProcess,hModule,szPathName,sizeof(szPathName)); printf("Path:%s/n/n",szPathName); } } } } printf("Process Total:%d/n",dwPCount); //关闭句柄和实例 CloseHandle(hProcess); CloseHandle(hModule); FreeLibrary(hPsDll); return 1; } //提权函数 BOOL EnablePrivilege(HANDLE hToken,LPCSTR szPrivName) { TOKEN_PRIVILEGES tkp;//访问令牌权限结构变量 LUID luid;//本地唯一标识符结构变量 //查询SE_DEBUG_NAME权限所对应的luid值 if(!LookupPrivilegeValue(NULL,szPrivName,&luid)) { printf("Lookup Privilege Value Failed.../nErrorCode:%d/n",GetLastError()); return 0; } //填充Token_Privileges结构 tkp.PrivilegeCount=1; tkp.Privileges[0].Luid=luid; tkp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED; //提升权限 if(!AdjustTokenPrivileges(hToken,FALSE,&tkp,sizeof(tkp),NULL,NULL)) { printf("Adjust Token Privileges Failed.../nErrorCode:%d/n",GetLastError()); return 0; } return(GetLastError()==ERROR_SUCCESS); }
-------------------------------------------------------------------------------------
请教个问题楼主:
我在Windows2000P + sp4 + VC6.0下调试的时候有2个进程如下:
Path:/??/C:/WINNT/system32/csrss.exe
4 192 winlogon.exe
Path:/??/C:/WINNT/system32/winlogon.exe
为什么路径前面有2个“?”号呢?
还有个进程为:
2 140 smss.exe
Path:/SystemRoot/System32/smss.exe
它的路径为什么是/SystemRoot?虽然systemroot和C:/winnt/差不多。
其他进程基本都正常... ...
-----------------------------------------------------------------------------------
/??/C:是符号连接 这是为了让应用程序操作设备而导出的
在存储Windows对象的Hash Table中 它看上去是这样的
DosDevices --> Global --> 符号连接 比如 C:是符号连接
但"连接"的设备就是/Device/HarddiskVolume1 系统第一个分区
至于SystemRoot 表示系统根目录 也是一个符号连接 形如
/Device/Harddisk0/Partition1/WINNT或WINDOWS 如果是2000
系统 就是WINNT 如果是XP/2003 就是Windows
而Partition1也是一个符号连接 它"连接"到/Device/HarddiskVolume1
拼接起来就是/Device/HarddiskVolume1/WINDOWS或WINNT
其实就是C:/WINDOWS或WINNT了