• Ring 3层枚举进程的四种方法


    1.CreateToolhelp32Snapshot()。这一种是比较常见的,利用进程快照进行枚举进程,主要利用CreateToolhelp32Snapshot()、Process32First()和 Process32Next()三个函数。下面直接上代码:

    // CreateToolhelp32Snapshot.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include <Windows.h>
    #include <tlhelp32.h>
    
    int main()
    {
    	//创建快照句柄,CreateToolhelp32Snapshot()函数返回当前运行的进程快照句柄
    	HANDLE ToolHelpHandle = NULL;
    
    	//PROCESSENTRY32结构体记录当前进程的一些信息,其中dwSize必须指定大小,大小为当前结构体大小
    	PROCESSENTRY32 ProcessEntry32 = { 0 };
    	ProcessEntry32.dwSize = sizeof(PROCESSENTRY32);
    	
    	ToolHelpHandle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    	if (ToolHelpHandle == INVALID_HANDLE_VALUE)
    	{
    		return FALSE;
    	}
    	
    	BOOL bOk = Process32First(ToolHelpHandle, &ProcessEntry32);
    	while (bOk)
    	{
    		printf("PID:	0x%X,", ProcessEntry32.th32ProcessID);
    		printf("	Name:	%S
    ", ProcessEntry32.szExeFile);
    		bOk = Process32Next(ToolHelpHandle, &ProcessEntry32);
    	}
    
    	CloseHandle(ToolHelpHandle);
    	ToolHelpHandle = INVALID_HANDLE_VALUE;
        return 0;
    }

    2.EnumProcesses()。利用Psapi下EnumProcesses()函数进行枚举进程,该方法有可能得不到某些进程的名称,下面是代码:

    #include "stdafx.h"
    #include <Windows.h>
    #include <Psapi.h>
    
    #define MAXPROCESSES 1024
    
    void PrintProcessNameAndID(DWORD ProcessID);
    int main()
    {
    	// 定义参数,EnumProcesses有三参数,接收进程标示符的数组,数组大小,数组返回字节数(真实接收数组的大小)
    
    	DWORD Processes[MAXPROCESSES], Size, ProcessesNumber;
    
    	if (!EnumProcesses(Processes, sizeof(Processes), &Size))
    	{
    		return 1;
    	}
    
    
    	//计算进程总数
    
    	ProcessesNumber = Size / sizeof(DWORD);
    
    	//打印各个进程
    
    	for (int i = 0; i < ProcessesNumber; i++)
    	{
    		if (Processes[i] != 0)
    		{
    			PrintProcessNameAndID(Processes[i]);
    		}
    	}
        return 0;
    }
    
    void PrintProcessNameAndID(DWORD ProcessID)
    {
    	WCHAR wzProcessName[MAX_PATH] = L"<unknown>";
    
    	//获得进程句柄
    	HANDLE ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION |
    		PROCESS_VM_READ,
    		FALSE, ProcessID);
    
    	//获得进程名称
    	if (NULL != ProcessHandle)
    	{
    		HMODULE hMod;
    		DWORD ReturnLength;
    
    		if (EnumProcessModules(ProcessHandle, &hMod, sizeof(hMod),
    			&ReturnLength))
    		{
    			GetModuleBaseName(ProcessHandle, hMod, wzProcessName,
    				sizeof(wzProcessName) / sizeof(WCHAR));
    		}
    	}
    
    	printf("PID:	0x%X,	Name:	%S
    ",ProcessID,wzProcessName);
    
    	//关闭进程句柄
    	CloseHandle(ProcessHandle);
    }

    3.WTSEnumerateProcesses()。这个方法就比较少用了,利用Windows终端相关服务进行枚举进程,主要有三个函数,WTSOpenServer()、WTSEnumerateProcesses()、WTSCloseServer()。该例子需要先在CMD中用nbtsat -n获得本机NetBios名,然后开启终端服务,具体还是看代码:

    // WTSEnumerateProcesses.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include <Windows.h>
    #include <WtsApi32.h>
    #pragma comment(lib,"WtsApi32.lib")
    int main()
    {
    	//用nbtsat -n获得本机NetBios名
    	WCHAR wzServerName[] = L"JARVIS";  //NetBios名
    
    	//开启远程终端服务
    	HANDLE WtsServerHandle = WTSOpenServer(wzServerName);
    
    	PWTS_PROCESS_INFO WtsProcessInfo;
    	DWORD Count;
    
    	//枚举进程
    	if (!WTSEnumerateProcesses(WtsServerHandle,
    		0,
    		1,
    		&WtsProcessInfo,
    		&Count))
    	{
    		printf("Enum rocesses Error: %d
    ", GetLastError());
    		return 0;
    	}
    
    	for (int i = 0; i < Count; i++)
    	{
    		printf("PID:	%d	Name:	%S
    ", WtsProcessInfo[i].ProcessId, WtsProcessInfo[i].pProcessName);
    	}
    	//关闭服务
    	WTSCloseServer(WtsServerHandle);
        return 0;
    }

    4.ZwQuerySystemInformation()。利用ntdll.dll中的导出函数进行枚举进程,对了,顺便说一下,dll导出函数的zw函数和nt函数其实是直线同一个函数地址,相互之间没有区别,也可以用NtQuerySystemInformation()函数。下面上代码:

    // ZwQuerySystemInformation.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include <Windows.h>
    #include <ntsecapi.h> 
    
    #define STATUS_INFO_LENGTH_MISMATCH    ((NTSTATUS)0xC0000004L)
    #define NT_SUCCESS(x) ((x) >= 0)
    
    // 结构体定义  
    typedef struct _SYSTEM_PROCESS_INFORMATION {
    	ULONG                   NextEntryOffset;
    	ULONG                   NumberOfThreads;
    	LARGE_INTEGER           Reserved[3];
    	LARGE_INTEGER           CreateTime;
    	LARGE_INTEGER           UserTime;
    	LARGE_INTEGER           KernelTime;
    	UNICODE_STRING          ImageName;
    	DWORD					BasePriority;
    	HANDLE                  ProcessId;
    	HANDLE                  InheritedFromProcessId;
    	ULONG                   HandleCount;
    	ULONG                   Reserved2[2];
    	ULONG                   PrivatePageCount;
    	DWORD					VirtualMemoryCounters;
    	IO_COUNTERS             IoCounters;
    	PVOID					Threads[0];
    } SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;
    
    typedef enum _SYSTEM_INFORMATION_CLASS {
    	SystemBasicInformation,
    	SystemProcessorInformation,
    	SystemPerformanceInformation,
    	SystemTimeOfDayInformation,
    	SystemPathInformation,
    	SystemProcessInformation,
    	SystemCallCountInformation,
    	SystemDeviceInformation,
    	SystemProcessorPerformanceInformation,
    	SystemFlagsInformation,
    	SystemCallTimeInformation,
    	SystemModuleInformation,
    	SystemLocksInformation,
    	SystemStackTraceInformation,
    	SystemPagedPoolInformation,
    	SystemNonPagedPoolInformation,
    	SystemHandleInformation,
    	SystemObjectInformation,
    	SystemPageFileInformation,
    	SystemVdmInstemulInformation,
    	SystemVdmBopInformation,
    	SystemFileCacheInformation,
    	SystemPoolTagInformation,
    	SystemInterruptInformation,
    	SystemDpcBehaviorInformation,
    	SystemFullMemoryInformation,
    	SystemLoadGdiDriverInformation,
    	SystemUnloadGdiDriverInformation,
    	SystemTimeAdjustmentInformation,
    	SystemSummaryMemoryInformation,
    	SystemMirrorMemoryInformation,
    	SystemPerformanceTraceInformation,
    	SystemObsolete0,
    	SystemExceptionInformation,
    	SystemCrashDumpStateInformation,
    	SystemKernelDebuggerInformation,
    	SystemContextSwitchInformation,
    	SystemRegistryQuotaInformation,
    	SystemExtendServiceTableInformation,
    	SystemPrioritySeperation,
    	SystemVerifierAddDriverInformation,
    	SystemVerifierRemoveDriverInformation,
    	SystemProcessorIdleInformation,
    	SystemLegacyDriverInformation,
    	SystemCurrentTimeZoneInformation,
    	SystemLookasideInformation,
    	SystemTimeSlipNotification,
    	SystemSessionCreate,
    	SystemSessionDetach,
    	SystemSessionInformation,
    	SystemRangeStartInformation,
    	SystemVerifierInformation,
    	SystemVerifierThunkExtend,
    	SystemSessionProcessInformation,
    	SystemLoadGdiDriverInSystemSpace,
    	SystemNumaProcessorMap,
    	SystemPrefetcherInformation,
    	SystemExtendedProcessInformation,
    	SystemRecommendedSharedDataAlignment,
    	SystemComPlusPackage,
    	SystemNumaAvailableMemory,
    	SystemProcessorPowerInformation,
    	SystemEmulationBasicInformation,
    	SystemEmulationProcessorInformation,
    	SystemExtendedHandleInformation,
    	SystemLostDelayedWriteInformation,
    	SystemBigPoolInformation,
    	SystemSessionPoolTagInformation,
    	SystemSessionMappedViewInformation,
    	SystemHotpatchInformation,
    	SystemObjectSecurityMode,
    	SystemWatchdogTimerHandler,
    	SystemWatchdogTimerInformation,
    	SystemLogicalProcessorInformation,
    	SystemWow64SharedInformation,
    	SystemRegisterFirmwareTableInformationHandler,
    	SystemFirmwareTableInformation,
    	SystemModuleInformationEx,
    	SystemVerifierTriageInformation,
    	SystemSuperfetchInformation,
    	SystemMemoryListInformation,
    	SystemFileCacheInformationEx,
    	MaxSystemInfoClass
    } SYSTEM_INFORMATION_CLASS;
    
    //定义原型函数 
    typedef
    NTSTATUS
    (WINAPI *pfnZwQuerySystemInformation)(
    	IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
    	IN OUT PVOID SystemInformation,
    	IN ULONG SystemInformationLength,
    	OUT PULONG ReturnLength);
    pfnZwQuerySystemInformation ZwQuerySystemInformation = NULL;
    UINT32 PrintProcessesIDAndName();
    int main()
    {
    	// 从Ntdll.dll中获得导出函数  
    	HMODULE NtdllHmodule = GetModuleHandle(L"ntdll.dll");
    	ZwQuerySystemInformation = (pfnZwQuerySystemInformation)GetProcAddress(NtdllHmodule, "ZwQuerySystemInformation");
    	
    	if (ZwQuerySystemInformation == NULL)
    	{
    		printf("Can't Get Address of ZwQuerySystemInformation!");
    		return 0;
    	}
    	PrintProcessesIDAndName();
    	
        return 0;
    }
    
    //打印进程ID和名称
    UINT32 PrintProcessesIDAndName()
    {
    	UINT32 BufferLength = 0x1000;
    	void*  BufferData = NULL;
    
    	NTSTATUS Status = STATUS_INFO_LENGTH_MISMATCH;
    	HANDLE   HeapHandle = GetProcessHeap();      //获得当前进程默认堆
    
    	UINT32 ProcessID = 0;
    
    	BOOL   bOk = FALSE;
    	while (!bOk)
    	{
    		BufferData = HeapAlloc(HeapHandle, HEAP_ZERO_MEMORY, BufferLength);
    		if (BufferData == NULL)
    		{
    			return 0;
    		}
    
    		Status = ZwQuerySystemInformation(SystemProcessInformation, BufferData, BufferLength, (PULONG)&BufferLength);
    		if (Status == STATUS_INFO_LENGTH_MISMATCH)
    		{
    			//内存不足,将内存扩大二倍重新申请
    			HeapFree(HeapHandle, NULL, BufferData);
    			BufferLength *= 2;
    		}
    		else if (!NT_SUCCESS(Status))
    		{
    			//不让看
    			HeapFree(HeapHandle, NULL, BufferData);
    			return 0;
    		}
    		else
    		{
    
    			PSYSTEM_PROCESS_INFORMATION SystemProcess = (PSYSTEM_PROCESS_INFORMATION)BufferData;
    			while (SystemProcess)
    			{
    				//定义变量ProcessName接收Name
    				char ProcessName[MAX_PATH];
    				memset(ProcessName, 0, sizeof(ProcessName));
    				WideCharToMultiByte(0, 0, SystemProcess->ImageName.Buffer, SystemProcess->ImageName.Length, ProcessName, MAX_PATH, NULL, NULL);
    				ProcessID = (UINT32)(SystemProcess->ProcessId);
    				printf("PID:	%X,	Name:	%s
    ",ProcessID, ProcessName);
    
    				if (!SystemProcess->NextEntryOffset)
    				{
    					break;
    				}
    				SystemProcess = (PSYSTEM_PROCESS_INFORMATION)((unsigned char*)SystemProcess + SystemProcess->NextEntryOffset);
    			}
    
    			if (BufferData)
    			{
    				HeapFree(HeapHandle, NULL, BufferData);
    			}
    
    			bOk = TRUE;
    		}
    	}
    
    	return ProcessID;
    }


  • 相关阅读:
    应用层协议及ip地址划分
    请求与响应编码及jsp基本原理
    springboot注解
    springboot 快速入门
    Http协议简单解析及web请求过程
    Tomcat原理详解及请求过程
    mysql数据库乱码的问题解决
    AOP的实现原理
    Springl利用Aspectj的扩展实现Aop
    JDK动态代理实现原理
  • 原文地址:https://www.cnblogs.com/Toring/p/6628276.html
Copyright © 2020-2023  润新知