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; }