欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

使用WTSEnumerateProcesses枚举进程--Ring3枚举进程

程序员文章站 2022-06-10 14:45:53
...

接下来介绍的这种枚举当前系统进程的方法是通过wtsapi32.dll提供的API来实现。主要用到了以下两个函数:

  • WTSOpenServerA
  • WTSEnumerateProcessesA
    我们来简单介绍一下这两个函数:
/***************************************
*WTSOpenServer函数打开指定终端服务器的句柄
*pServerName:指向终端服务器的NetBIOS名称的指针。
***************************************/
HANDLE WTSOpenServer(  LPTSTR pServerName);
/***************************************
*WTSEnumerateProcesses函数检索关于指定终端
*服务器上的活动进程的信息。
*hServer:指向终端服务器的句柄。
*Reserved:保留值,必须为0
*Version:枚举请求版本,必须是1
*ppProcessInfo:该变量接收指向WTS_PROCESS_INFO
*结构数组的指针。数组中的每个结构都包含关于指定终端
*服务器上的活动进程的信息
*pCount:ppProcessInfo中返回WTS_PROCESS_INFO结构的数量
***************************************/
BOOL WTSEnumerateProcesses(  
HANDLE hServer,  
DWORD Reserved,  
DWORD Version,
PWTS_PROCESS_INFO* ppProcessInfo,
DWORD* pCount);

在使用WTSOpenServerA的时候,需要用到NetBios指定的终端服务名,如果查看的是我们本地的所有进程,那自然是要指定我们本地的服务名,但是服务名需要在哪儿去找呢?

  • 打开cmd
  • 输入nbtstat -n即可查看

使用WTSEnumerateProcesses枚举进程--Ring3枚举进程
枚举进程信息实例源码:

#pragma once
#include<iostream>
#include<Windows.h>
#include<tchar.h>

using namespace std;
typedef struct _WTS_PROCESS_INFO 
{
	DWORD SessionId;
	DWORD ProcessId;
	LPSTR pProcessName;
	PSID pUserSid;
} WTS_PROCESS_INFO, *PWTS_PROCESS_INFO;

// NetBios指定的终端服务名,如果查看本地终端所有进程信息,
// 可以通过在控制台命令行下用nbtstat -n来获取本机NetBios名.

typedef HANDLE (WINAPI* LPFN_WTSOPENSERVERA)(LPSTR pServerName);

typedef BOOL(WINAPI *LPFN_WTSENUMERATEPROCESSESA)
(
	HANDLE hServer,   // WTSOpenServer返回的句柄. 
	DWORD Reserved,   // 保留值 0.
	DWORD Version,    // 指定枚举要求的版本,必须为 1.
	PWTS_PROCESS_INFO* ppProcessInfo, // 存放我们要的进程名和进程id.
	DWORD* pCount     // 存放ppProcessInfo里WTS_PROCESS_INFO结构数量指针.
	);

#include"Test.h"
void main()
{
	setlocale(LC_ALL, "chs");//识别中文
	//加载动态库
	HMODULE WtsApi32Handle = LoadLibrary(_T("wtsapi32.dll"));
	//WtsApi32Handle = wtsapi32.dll!0x73560000 (加载符号以获取其他信息) {unused=0x00905a4d }

	LPFN_WTSOPENSERVERA WTSOpenServerA = 
		(LPFN_WTSOPENSERVERA)GetProcAddress(WtsApi32Handle, "WTSOpenServerA");
	//WTSOpenServerA = wtsapi32.dll!0x73564610 (加载符号以获取其他信息)

	LPFN_WTSENUMERATEPROCESSESA WTSEnumerateProcessesA =
		(LPFN_WTSENUMERATEPROCESSESA)GetProcAddress(WtsApi32Handle, "WTSEnumerateProcessesA");
	//WTSEnumerateProcessesA = wtsapi32.dll!0x73565840 (加载符号以获取其他信息)


	// 通过szServerName给终端服务名
	char szServerName[] = "KOOKNUT";//该名字是通过cmd得出来的本机NetBios名
	HANDLE WtsServerHandle = WTSOpenServerA(szServerName);
	//WtsServerHandle = 0x00331de8

	// 然后开始遍历终端服务器上的所有进程,这里我们是指本机的所有进程.
	PWTS_PROCESS_INFO WtsProcessInfo;//存放本地进程信息
	DWORD Count;

	if (!WTSEnumerateProcessesA(WtsServerHandle,
		0, 1, &WtsProcessInfo, &Count))
	{
		return;
	}

	for (DWORD i = 0; i < Count; i++)
	{
		printf("ProcessID: %d (%s)\n", WtsProcessInfo[i].ProcessId,
			WtsProcessInfo[i].pProcessName);
	}
	
	getchar();
}

几经风雨,阳光终会照在这片土地。

相关标签: Windows应用层开发