• 【API】遍历进程的几种方式


    1、说明

    枚举进程的常见几种方法
    方法1:CreateToolhelp32Snapshot()、Process32First()和Process32Next()
    方法2:EnumProcesses()、EnumProcessModules()、GetModuleBaseName()
    方法3:Native Api的ZwQuerySystemInformation
    方法4:wtsapi32.dll的WTSOpenServer()、WTSEnumerateProcess()

    CreateToolhelp32Snapshot()、Process32First()和Process32Next()

    #include "stdafx.h"
    #include <Windows.h>
    #include <stdio.h>
    #include <TlHelp32.h>
    
    int main()
    {
    	PROCESSENTRY32 pe32;
    
    	pe32.dwSize = sizeof(PROCESSENTRY32);
    	HANDLE hProcessSanp = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    	if (hProcessSanp == INVALID_HANDLE_VALUE)
    	{
    		printf("Error Get the Process SnapShot
    ");
    		return -1;
    	}
    	BOOL bMore = Process32First(hProcessSanp, &pe32);
    	while (bMore)
    	{
    		printf("Process Name: %s		Process ID: %d
    ", pe32.szExeFile, pe32.th32ProcessID);
    		bMore = Process32Next(hProcessSanp, &pe32);
    	}
    	CloseHandle(hProcessSanp);
    	getchar();
    	return 0;
    }
    
    

    EnumProcesses()、EnumProcessModules()、GetModuleBaseName()

    #include "stdafx.h"
    #include <windows.h>
    #include "psapi.h"
    #pragma   comment   (lib, "psapi.lib ")
    
    
    void MyEnumProcess()
    {
    	// Get the list of process identifiers.
    	DWORD aProcesses[1024], cbNeeded, cProcesses;
    	unsigned int i;
    
    	if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded))       //枚举进程
    		return;
    	cProcesses = cbNeeded / sizeof(DWORD);             //计算进程个数
    	for (i = 0; i < cProcesses; i++)
    		if (aProcesses[i] != 0)
    		{
    
    			TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");
    			HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, aProcesses[i]);     //获得进程句柄
    
    			if (NULL != hProcess)
    			{
    				HMODULE hMod;
    				DWORD cbNeeded;
    
    				if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded))        //枚举进程模块信息
    				{
    					GetModuleBaseName(hProcess, hMod, szProcessName, sizeof(szProcessName) / sizeof(TCHAR));       //取得主模块全名,每个进程第一模块则为进程主模块
    				}
    			}
    			_tprintf(TEXT("%s  (PID: %u)
    "), szProcessName, aProcesses[i]);     //输出进程名及PID
    			CloseHandle(hProcess);
    		}
    }
    
    
    void main()
    {
    	MyEnumProcess();
    	system("pause");
    }
    

    Native Api的ZwQuerySystemInformation

    #include <ntddk.h>
    
    #define SystemProcessesAndThreadsInformation 5
    
    typedef struct _SYSTEM_PROCESSES
    {
    	ULONG NextEntryDelta;
    	ULONG ThreadCount;
    	ULONG Reserved[6];
    	LARGE_INTEGER CreateTime;
    	LARGE_INTEGER UserTime;
    	LARGE_INTEGER KernelTime;
    	UNICODE_STRING ProcessName;
    	KPRIORITY BasePriority;
    	ULONG ProcessId;
    	ULONG InheritedFromProcessId;
    	ULONG HandleCount;
    	ULONG Reserved2[2];
    	VM_COUNTERS VmCounters;
    	IO_COUNTERS IoCounters;
    } _SYSTEM_PROCESSES, *PSYSTEM_PROCESSES;
    
    NTSTATUS EnumSystemProcess( );
    
    
    NTSYSAPI
    NTSTATUS
    NTAPI ZwQuerySystemInformation(
    IN ULONG SystemInformationClass,
    IN OUT PVOID SystemInformation,
    IN ULONG SystemInformationLength,
    OUT PULONG ReturnLength
    );
    
    NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath);
    
    NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
    {
    	UNREFERENCED_PARAMETER(DriverObject);
    	UNREFERENCED_PARAMETER(RegistryPath);
    	NTSTATUS status = STATUS_SUCCESS;
    	status  = EnumSystemProcess( );
    	return status;
    }
    
    NTSTATUS EnumSystemProcess( )
    {
    	NTSTATUS status = STATUS_UNSUCCESSFUL;
    	*pRet = FALSE;
    
    	PSYSTEM_PROCESSES pProcessInfo = NULL;
    	PSYSTEM_PROCESSES pTemp = NULL;//这个留作以后释放指针的时候用。
    	ULONG ulNeededSize;
    	ULONG ulNextOffset;
    
    	if (NULL == pProcess)
    	{
    		return status;
    	}
            //第一次使用肯定是缓冲区不够,不过本人在极少数的情况下第二次也会出现不够,所以用while循环
    	status = ZwQuerySystemInformation(SystemProcessesAndThreadsInformation , pProcessInfo, 0, &ulNeededSize);
    	while (STATUS_INFO_LENGTH_MISMATCH == status)
    	{
    		pProcessInfo = ExAllocatePoolWithTag(NonPagedPool, ulNeededSize, ‘1aes‘);
    		pTemp = pProcessInfo;
    		if (NULL == pProcessInfo)
    		{
    			KdPrint(("[allocatePoolWithTag] failed"));
    			return status;
    		}
    		status = ZwQuerySystemInformation(SystemProcessesAndThreadsInformation , pProcessInfo, ulNeededSize, &ulNeededSize);
    	}
    	if (NT_SUCCESS(status))
    	{
    		KdPrint(("[ZwQuerySystemInformation]success bufferSize:%x", ulNeededSize));
    	}
            else
            {
                   KdPrint(("[error]:++++%d", status));
                   return status;
            }
    
    	do
    	{
    		KdPrint(("[imageName Buffer]:%08x", pProcessInfo->ProcessName.Buffer));
    		
    		if (MmIsAddressValid(pProcessInfo->ProcessName.Buffer) && NULL != pProcessInfo)
    		{
    			KdPrint(("[ProcessID]:%d , [imageName]:%ws", pProcessInfo->ProcessId, pProcessInfo->ProcessName.Buffer));
    		}
    		
    		ulNextOffset = pProcessInfo->NextEntryDelta;
    		pProcessInfo = (PSYSTEM_PROCESSES)((PUCHAR)pProcessInfo + pProcessInfo->NextEntryDelta);
    
    	} while (ulNextOffset != 0);
    
    	ExFreePoolWithTag(pTemp, ‘1aes‘);
    
    	return status;
    }
    

    wtsapi32.dll的WTSOpenServer()、WTSEnumerateProcess()

    // WTSOpenServer.cpp: 定义控制台应用程序的入口点。
    //
    #include "stdafx.h"
    #include <windows.h>
    #include <stdio.h>
    #include <Wtsapi32.h>
    
    #pragma  comment (lib,"Wtsapi32.lib")
    
    
    int main()
    {
    	//WCHAR* szServerName = L"";   //win10 不需要
    	WCHAR * szServerName = NULL;
    	HANDLE WtsServerHandle = WTSOpenServer(szServerName);
    
    	// 然后开始遍历终端服务器上的所有进程,这里我们是指本机的所有进程.
    
    	PWTS_PROCESS_INFO pWtspi;
    	DWORD dwCount;
    
    	if (!WTSEnumerateProcesses(WtsServerHandle, 0, 1, &pWtspi, &dwCount))
    	{
    		int a = GetLastError();
    		return 0;
    	}
    
    
    	for (DWORD i = 0; i < dwCount; i++)
    	{
    		printf("ProcessID: %d (%ls)
    ", pWtspi[i].ProcessId,
    			pWtspi[i].pProcessName);
    	}
    
    	getchar();
    }
    
    

    2、参考

    利用服务枚举进程
    https://www.cnblogs.com/kekoukele987/p/7503004.html
    ZwQuerySystemInformation function
    https://docs.microsoft.com/en-us/windows/desktop/SysInfo/zwquerysysteminformation

  • 相关阅读:
    沟通是项目管理知识体系中的九大知识领域之一
    项目管理的三要素时间、成本、质量
    项目管理提升效率的几大关键点
    收到FRDMKL02Z
    【转】arm 开发工具比较(ADS vs RealviewMDK vs RVDS)
    你不能自己把自己放弃写在毕业季
    【转】为什么你应该(从现在开始就)写博客
    Vivado 2014.4 FFT IP 使用及仿真
    项目需求的一些事
    娇荣电子工作室成立了
  • 原文地址:https://www.cnblogs.com/17bdw/p/9770602.html
Copyright © 2020-2023  润新知