准备写一个进程管理的功能模块,今天下午先写了扫描获取本机各个进程路径,获取各个进程映像名称,进程完整路径。

  要获取进程信息,第一步想到的就是提权,提权代码用过多次了,今天也小结了一下(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,获取系统内所有进程快照时是;

  函数调用:

  

	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\0][ \0][20][calc.exe\0][ \0][20][calc.exe\0][ \0] ]
Label1:
ZeroMemory(&v1, sizeof(v1)); v1.ProcessID = ProcessEntry32.th32ProcessID;
v1.ParentProcessID = ProcessEntry32.th32ParentProcessID;
//v1.ParentProcessID = GetParentProcessID(v1.ProcessID);
memcpy(v1.ImageNameData, ProcessEntry32.szExeFile, lstrlen(ProcessEntry32.szExeFile) + 1);
memcpy(v1.ProcessFullPathData, ProcessFullPathData, lstrlen(ProcessFullPathData) + 1); ProcessInfo.push_back(v1);
if (ProcessHandle != NULL)
{
CloseHandle(ProcessHandle);
ProcessHandle = NULL;
} } while (Process32Next(SnapshotHandle, &ProcessEntry32));

  

0x03  进程完整路径

    获得进程完整路径的3个WINDOWS API:

    GetModuleFileNameEx

    GetProcessImageFileName

    QueryFullProcessImageName

  

  第一个函数:想获得进程可执行文件的路径最常用的方法是通过GetModuleFileNameEx函数获得可执行文件的模块路径这个函数从Windows NT 4.0开始到现在的Vista系统都能使用,向后兼容性比较好。

  第二个函数:GetProcessImageFileName函数,这个函数在Windows XP及其以后的系统中都能使用,使用此函数返回的路径不是通常的系统盘符,如"C:\...",而是驱动层的表示方式"\Device\HarddiskVolume1\...",所以使用起来不是很方便。

  第三个函数:Windows Vista新增的函数QueryFullProcessImageName。

  函数原型:

  

DWORD GetModuleFileNameEx(
HANDLEhProcess,
HMODULE hModule,
LPTSTR lpFilename,
DWORD nSize)

   hProcess是目标进程的句柄、

  hModule是目标模块的句柄(当此参数为NULL时函数返回的是进程可执行文件的路径)、

  lpFilename是存放路径的字符串缓冲区、

  nSize表示缓冲区的大小。函数调用失败将返回0。需要注意的是进程的句柄须有PROCESS_QUERY_INFORMATION和PROCESS_VM_READ权限。

DWORD
GetProcessImageFileName(
HANDLE hProcess,
LPTSTR lpImageFileName,
DWORD nSize)

   hProcess是目标进程的句柄、

  lpImageFileName是存放路径的字符串缓冲区、

  nSize表示缓冲区的大小。函数失败将返回0。需要注意的是进程句柄需要有PROCESS_QUERY_INFORMATION的权限。

BOOL QueryFullProcessImageName(
HANDLEhProcess,
DWORD dwFlags,
LPTSTR lpExeName,
PDWORD lpdwSize)

  hProcess是目标进程的句柄、

  dwFlags一般设为0(表示返回的路径是Win32的路径格式,如"C:\...",如将其设为PROCESS_NAME_NATIVE将返回"\Device\HarddiskVolume1\..."这样的格式路径)、

  lpExeName是存放路径的字符串缓冲区、

  lpdwSize表示缓冲区的大小。

  函数失败将返回FALSE。需要注意的是调用此函数的句柄须有PROCESS_QUERY_INFORMATION或这是PROCESS_QUERY_LIMITED_INFORMATION的权限,并且只能在Vista或更高版本的系统中使用。

  调用GetModuleFileNameEx和GetProcessImageFileName需要包含Psapi.h头文件

  

DWORD ReturnLength = GetModuleFileNameEx(ProcessHandle, ModuleHandle,
ProcessFullPathData,
sizeof(ProcessFullPathData)); if (ReturnLength == 0)
{
RtlZeroMemory(ProcessFullPathData, MAX_PATH); QueryFullProcessImageName(ProcessHandle, 0, ProcessFullPathData, &ReturnLength); // 更推荐使用这个函数

  

获取进程ID,父进程ID,进程完整路径的更多相关文章

  1. vue_elementUI_ tree树形控件 获取选中的父节点ID

    el-tree 的 this.$refs.tree.getCheckedKeys() 只可以获取选中的id 无法获取选中的父节点ID想要获取选中父节点的id;需要如下操作1. 找到工程下的node_m ...

  2. Windows获取进程完整路径

    #include <stdio.h> #include <locale.h> #include <windows.h> #include <tlhelp32. ...

  3. Linux下查找进程id并强制停止进程的脚本

    Linux下的tomcat的停止脚本shutdown.sh经常失败,造成tomcat进程没关闭.所以只能手动查找进程id,然后用kill命令来强制停止.每次都要这样查一下,然后再杀进程.感觉有点麻烦, ...

  4. 进程控制之更改用户ID和组ID

    在UNIX系统中,特权(例如能改变当前日期的表示法以及访问控制(例如,能否读.写一特定文件))是基于用户ID和组ID的.当程序需要增加特权,或需要访问当前并不允许访问的资源时,我们需要更换自己的用户I ...

  5. ORA-03113: 通信通道的文件结尾 进程 ID: 764 会话 ID: 125 序列号: 5

    昨天因为导入很久数据,最后一看是因为数据文件不够,后来就关机了.现在,开启数据库,总是报“ORA-03113: 通信通道的文件结尾” SQL> conn /as sysdba; 已连接到空闲例程 ...

  6. id为194024的进程当前未运行

    .NET MVC 编译运行时 提示  >> id为194024的进程当前未运行 << 清理解决方案,重新运行

  7. Linux进程的实际用户ID和有效用户ID

    转自:https://blog.csdn.net/hulifangjiayou/article/details/47400943 在Linux中,每个文件都有其所属的用户和用户组,默认情况下是文件的创 ...

  8. C++获取当前所有进程的完整路径

    实现代码 #include <stdio.h> #include <windows.h> #include <tlhelp32.h> #include <st ...

  9. 进程ID[PID(Process ID)]与端口号[(Port ID)]的联系

    1.首先声明一点:PID不是端口(port id),而是Process ID进程号的意思. 2.那么,什么是进程号? 采集网友的意见就是: 进程号,是系统分配给么一个进程的唯一标识符.PID就是各进程 ...

随机推荐

  1. JAVA多线程之CountDownLatch与join的区别

    首先,我们来看一个应用场景1: 假设一条流水线上有三个工作者:worker0,worker1,worker2.有一个任务的完成需要他们三者协作完成,worker2可以开始这个任务的前提是worker0 ...

  2. K-wolf Number (数位DP)

    题意:求区间内有多少个数满足条件:任意相邻的k个数位都不相等. 思路:老套路 #include<bits/stdc++.h> using namespace std; typedef lo ...

  3. Linux基础命令---lpc打印机控制

    lpc lpc指令用来控制打印机,它提供了一个命令行,用户可以输出命令来控制打印机.如果命令行上没有指定命令,lpc将从标准输入中显示提示符并接受命令. 此命令的适用范围:RedHat.RHEL.Ub ...

  4. 数据挖掘算法——Close算法

    说明奥:菜鸟的自我学习,可能有错. Close算法原理: 一个频繁闭合项目集的所有闭合子集一定是频繁的,一个非频繁闭合项目集的所有闭合超集一定是非频繁的. close算法是对Apriori算法的改进 ...

  5. 新手如何学习python(python学习路线图)

    现在互联网巨头,都已经转投到人工智能领域,而人工智能最好的编程语言就是python,未来前景显而易见.这是小编给大家整理的python学习路线图,按照此教程一步步的学习来,肯定会对python有更深刻 ...

  6. Oracle 12c 的RMAN备份

    备份 rman只备份cdb 只备份CDB数据库需要具有SYSDBA或SYSBACKUP权限用户连接到CDB的root环境下,执行backupdatabase root命令即可完成对CDB的备份,方法如 ...

  7. python__面向对象,继承,命名空间

    http://www.cnblogs.com/Eva-J/articles/7293890.html 阅读目录 楔子 面向过程vs面向对象 初识面向对象 类的相关知识 对象的相关知识 对象之间的交互 ...

  8. 拦截导弹nlogn解法

    题目 题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国 ...

  9. Git Github的区别 & Pycharm使用GitHub

    首先:git和github功能很强大,随着使用深入,我将随时填充,更新这篇文章,记录随时遇到的新的问题和感悟. 第一次知道github是看廖雪峰的课程,所谓版本管理,之前在辉煌科技用的是SVN,了解一 ...

  10. 《Visual C# 从入门到精通》第三章使用判断语句——读书笔记

    第3章 使用判断语句 3.1 使用布尔操作符 布尔操作符是求值为true或false的操作符. C#提供了几个非常有用的布尔操作符,其中最简单的是NOT(求反)操作符,它用感叹号(!)表示.!操作符求 ...