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:\t0x%X,", ProcessEntry32.th32ProcessID);
printf("\tName:\t%S\r\n", 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:\t0x%X,\tName:\t%S\r\n",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\r\n", GetLastError());
return 0;
}
for (int i = 0; i < Count; i++)
{
printf("PID:\t%d\tName:\t%S\r\n", 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:\t%X,\tName:\t%s\r\n",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;
}