这一节,我们将学会如何获取本地进程信息与模块信息
注:转载请注明来源 enjoy5512的博客 http://blog.csdn.net/enjoy5512
测试环境 :
windows xp sp3 + vc6.0
实现思路:
1) 通过自己编写的EnableDebugPriv()函数获取调试权限
2) 通过CreateToolhelp32Snapshot()函数获取进程快照
3) 通过Process32First()函数获取第一个进程信息
3.1) 通过CreateToolhelp32Snapshot()获取进程模块信息
3.2) 通过Module32First()获取第一个模块信息
3.3) 通过Module32Next()循环获取其他模块信息
4) 通过Process32Next()循环遍历其他进程信息
代码:
/////////////////////////////////////////////////////////////////////////////
// 文件名 : test.c
// 工程 : test
// 作者 : enjoy5512 修改者 : enjoy5512 最后优化注释者 : enjoy5512
// 个人技术博客 : blog.csdn.net/enjoy5512
// 个人GitHub : github.com/whu-enjoy
// csdn code : code.csdn.net/enjoy5512
// 描述 : 获取本地系统进程列表
// 编译环境 : Windows XP SP3 + vc6.0
// 主要函数 :
// 版本 : 最终确定版 完成日期 : 2016年6月2日 20:00:02
// 修改 :
/////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <windows.h>
#include"tlhelp32.h"
//函数说明开始
//==================================================================================
// 功能 : 获取进程的调试权限
// 参数 : const char *name
// (入口) name : 指向权限名称,我们这里用到SE_DEBUG_NAME
// #define SE_BACKUP_NAME TEXT("SeBackupPrivilege")
// #define SE_RESTORE_NAME TEXT("SeRestorePrivilege")
// #define SE_SHUTDOWN_NAME TEXT("SeShutdownPrivilege")
// #define SE_DEBUG_NAME TEXT("SeDebugPrivilege")
// 返回 : -1表示获取权限失败, 0表示获取权限成功
// 主要思路 : 先打开进程令牌环,然后获得本地进程name所代表的权限类型的局部唯一ID
// 最后调整进程权限
// 调用举例 : EnableDebugPriv(SE_DEBUG_NAME)
// 日期 : 2016年6月1日 19:08:22(注释日期)
//==================================================================================
//函数说明结束
int EnableDebugPriv(const char *name)
{
HANDLE hToken; //进程令牌句柄
TOKEN_PRIVILEGES tp; //TOKEN_PRIVILEGES结构体,其中包含一个【类型+操作】的权限数组
LUID luid; //上述结构体中的类型值
//打开进程令牌环
//GetCurrentProcess()获取当前进程的伪句柄,只会指向当前进程或者线程句柄,随时变化
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &hToken))
{
fprintf(stderr,"OpenProcessToken error\n");
return -1;
}
//获得本地进程name所代表的权限类型的局部唯一ID
if (!LookupPrivilegeValue(NULL, name, &luid))
{
fprintf(stderr,"LookupPrivilegeValue error\n");
}
tp.PrivilegeCount = 1; //权限数组中只有一个“元素”
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; //权限操作
tp.Privileges[0].Luid = luid; //权限类型
//调整进程权限
if (!AdjustTokenPrivileges(hToken, 0, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL))
{
fprintf(stderr,"AdjustTokenPrivileges error!\n");
return -1;
}
return 0;
}
int main()
{
HANDLE hProcess; //进程句柄
HANDLE hModule; //模块句柄
BOOL bProcess = FALSE; //获取进程信息的函数返回值
BOOL bModule = FALSE; //获取模块信息的函数返回值
PROCESSENTRY32 pe32; //保存进程信息
MODULEENTRY32 me32; //保存模块信息
int i = 0;
int j = 0;
//获取进程调试权限,如果失败,则提示获取权限失败,失败的话,有的进程信息就会获取不到
if (EnableDebugPriv(SE_DEBUG_NAME))
{
fprintf(stderr,"Add Privilege error\n");
}
hProcess = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);//获取进程快照
if (hProcess == INVALID_HANDLE_VALUE)
{
printf("获取进程快照失败\n");
exit(1);
}
bProcess = Process32First(hProcess, &pe32); //获取第一个进程信息
while (bProcess) //循环获取其余进程信息
{
printf("%d :\t Father's PID(%d)\tPID(%d)\t%s\n", i, pe32.th32ParentProcessID, pe32.th32ProcessID, pe32.szExeFile);
i++;
j = 0;
if (0 != pe32.th32ParentProcessID) //获取进程PID不为0的模块信息
{
hModule = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,pe32.th32ProcessID); //获取模块快照
if (hModule != INVALID_HANDLE_VALUE)
{
bModule = Module32First(hModule,&me32); //获取第一个模块信息,即进程相应可执行文件的信息
while(bModule)
{
printf("模块:\n%d\t%s\n", j, me32.szExePath);
j++;
bModule = Module32Next(hModule, &me32); //获取其他模块信息
}
CloseHandle(hModule);
}
}
bProcess = Process32Next(hProcess,&pe32); //继续获取其他进程信息
printf("\n\n");
getchar();
}
CloseHandle(hProcess);
return 0;
}