一、Ring3层方法总结
1)利用Createtoolhelp32Snapshot
Createtoolhelp32Snapshot会返回当前进程的进程快照句柄 通过 Process32First 和 Process32Next枚举进程

1 #include "stdafx.h" 2 #include <Windows.h> 3 #include <tlhelp32.h> 4 5 int main() 6 { 7 //创建快照句柄,CreateToolhelp32Snapshot()函数返回当前运行的进程快照句柄 8 HANDLE ToolHelpHandle = NULL; 9 10 //PROCESSENTRY32结构体记录当前进程的一些信息,其中dwSize必须指定大小,大小为当前结构体大小 11 PROCESSENTRY32 ProcessEntry32 = { 0 }; 12 ProcessEntry32.dwSize = sizeof(PROCESSENTRY32); 13 14 ToolHelpHandle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 15 if (ToolHelpHandle == INVALID_HANDLE_VALUE) 16 { 17 return FALSE; 18 } 19 20 BOOL bOk = Process32First(ToolHelpHandle, &ProcessEntry32); 21 while (bOk) 22 { 23 printf("PID: 0x%X,", ProcessEntry32.th32ProcessID); 24 printf(" Name: %S ", ProcessEntry32.szExeFile); 25 bOk = Process32Next(ToolHelpHandle, &ProcessEntry32); 26 } 27 28 CloseHandle(ToolHelpHandle); 29 ToolHelpHandle = INVALID_HANDLE_VALUE; 30 return 0; 31 }
2)通过Psapi.dll提供的API函数实现 利用EnumProcessModules

1 #include "stdafx.h" 2 #include <Windows.h> 3 #include <Psapi.h> 4 5 #define MAXPROCESSES 1024 6 7 void PrintProcessNameAndID(DWORD ProcessID); 8 int main() 9 { 10 // 定义参数,EnumProcesses有三参数,接收进程标示符的数组,数组大小,数组返回字节数(真实接收数组的大小) 11 12 DWORD Processes[MAXPROCESSES], Size, ProcessesNumber; 13 14 if (!EnumProcesses(Processes, sizeof(Processes), &Size)) 15 { 16 return 1; 17 } 18 19 20 //计算进程总数 21 22 ProcessesNumber = Size / sizeof(DWORD); 23 24 //打印各个进程 25 26 for (int i = 0; i < ProcessesNumber; i++) 27 { 28 if (Processes[i] != 0) 29 { 30 PrintProcessNameAndID(Processes[i]); 31 } 32 } 33 return 0; 34 } 35 36 void PrintProcessNameAndID(DWORD ProcessID) 37 { 38 WCHAR wzProcessName[MAX_PATH] = L"<unknown>"; 39 40 //获得进程句柄 41 HANDLE ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | 42 PROCESS_VM_READ, 43 FALSE, ProcessID); 44 45 //获得进程名称 46 if (NULL != ProcessHandle) 47 { 48 HMODULE hMod; 49 DWORD ReturnLength; 50 51 if (EnumProcessModules(ProcessHandle, &hMod, sizeof(hMod), 52 &ReturnLength)) 53 { 54 GetModuleBaseName(ProcessHandle, hMod, wzProcessName, 55 sizeof(wzProcessName) / sizeof(WCHAR)); 56 } 57 } 58 59 printf("PID: 0x%X, Name: %S ",ProcessID,wzProcessName); 60 61 //关闭进程句柄 62 CloseHandle(ProcessHandle); 63 }
3)利用ZwQuerySystemInformation

1 #include "stdafx.h" 2 #include <Windows.h> 3 #include <ntsecapi.h> 4 5 #define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) 6 #define NT_SUCCESS(x) ((x) >= 0) 7 8 // 结构体定义 9 typedef struct _SYSTEM_PROCESS_INFORMATION { 10 ULONG NextEntryOffset; 11 ULONG NumberOfThreads; 12 LARGE_INTEGER Reserved[3]; 13 LARGE_INTEGER CreateTime; 14 LARGE_INTEGER UserTime; 15 LARGE_INTEGER KernelTime; 16 UNICODE_STRING ImageName; 17 DWORD BasePriority; 18 HANDLE ProcessId; 19 HANDLE InheritedFromProcessId; 20 ULONG HandleCount; 21 ULONG Reserved2[2]; 22 ULONG PrivatePageCount; 23 DWORD VirtualMemoryCounters; 24 IO_COUNTERS IoCounters; 25 PVOID Threads[0]; 26 } SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION; 27 28 typedef enum _SYSTEM_INFORMATION_CLASS { 29 SystemBasicInformation, 30 SystemProcessorInformation, 31 SystemPerformanceInformation, 32 SystemTimeOfDayInformation, 33 SystemPathInformation, 34 SystemProcessInformation, 35 SystemCallCountInformation, 36 SystemDeviceInformation, 37 SystemProcessorPerformanceInformation, 38 SystemFlagsInformation, 39 SystemCallTimeInformation, 40 SystemModuleInformation, 41 SystemLocksInformation, 42 SystemStackTraceInformation, 43 SystemPagedPoolInformation, 44 SystemNonPagedPoolInformation, 45 SystemHandleInformation, 46 SystemObjectInformation, 47 SystemPageFileInformation, 48 SystemVdmInstemulInformation, 49 SystemVdmBopInformation, 50 SystemFileCacheInformation, 51 SystemPoolTagInformation, 52 SystemInterruptInformation, 53 SystemDpcBehaviorInformation, 54 SystemFullMemoryInformation, 55 SystemLoadGdiDriverInformation, 56 SystemUnloadGdiDriverInformation, 57 SystemTimeAdjustmentInformation, 58 SystemSummaryMemoryInformation, 59 SystemMirrorMemoryInformation, 60 SystemPerformanceTraceInformation, 61 SystemObsolete0, 62 SystemExceptionInformation, 63 SystemCrashDumpStateInformation, 64 SystemKernelDebuggerInformation, 65 SystemContextSwitchInformation, 66 SystemRegistryQuotaInformation, 67 SystemExtendServiceTableInformation, 68 SystemPrioritySeperation, 69 SystemVerifierAddDriverInformation, 70 SystemVerifierRemoveDriverInformation, 71 SystemProcessorIdleInformation, 72 SystemLegacyDriverInformation, 73 SystemCurrentTimeZoneInformation, 74 SystemLookasideInformation, 75 SystemTimeSlipNotification, 76 SystemSessionCreate, 77 SystemSessionDetach, 78 SystemSessionInformation, 79 SystemRangeStartInformation, 80 SystemVerifierInformation, 81 SystemVerifierThunkExtend, 82 SystemSessionProcessInformation, 83 SystemLoadGdiDriverInSystemSpace, 84 SystemNumaProcessorMap, 85 SystemPrefetcherInformation, 86 SystemExtendedProcessInformation, 87 SystemRecommendedSharedDataAlignment, 88 SystemComPlusPackage, 89 SystemNumaAvailableMemory, 90 SystemProcessorPowerInformation, 91 SystemEmulationBasicInformation, 92 SystemEmulationProcessorInformation, 93 SystemExtendedHandleInformation, 94 SystemLostDelayedWriteInformation, 95 SystemBigPoolInformation, 96 SystemSessionPoolTagInformation, 97 SystemSessionMappedViewInformation, 98 SystemHotpatchInformation, 99 SystemObjectSecurityMode, 100 SystemWatchdogTimerHandler, 101 SystemWatchdogTimerInformation, 102 SystemLogicalProcessorInformation, 103 SystemWow64SharedInformation, 104 SystemRegisterFirmwareTableInformationHandler, 105 SystemFirmwareTableInformation, 106 SystemModuleInformationEx, 107 SystemVerifierTriageInformation, 108 SystemSuperfetchInformation, 109 SystemMemoryListInformation, 110 SystemFileCacheInformationEx, 111 MaxSystemInfoClass 112 } SYSTEM_INFORMATION_CLASS; 113 114 //定义原型函数 115 typedef 116 NTSTATUS 117 (WINAPI *pfnZwQuerySystemInformation)( 118 IN SYSTEM_INFORMATION_CLASS SystemInformationClass, 119 IN OUT PVOID SystemInformation, 120 IN ULONG SystemInformationLength, 121 OUT PULONG ReturnLength); 122 pfnZwQuerySystemInformation ZwQuerySystemInformation = NULL; 123 UINT32 PrintProcessesIDAndName(); 124 int main() 125 { 126 // 从Ntdll.dll中获得导出函数 127 HMODULE NtdllHmodule = GetModuleHandle(L"ntdll.dll"); 128 ZwQuerySystemInformation = (pfnZwQuerySystemInformation)GetProcAddress(NtdllHmodule, "ZwQuerySystemInformation"); 129 130 if (ZwQuerySystemInformation == NULL) 131 { 132 printf("Can't Get Address of ZwQuerySystemInformation!"); 133 return 0; 134 } 135 PrintProcessesIDAndName(); 136 137 return 0; 138 } 139 140 //打印进程ID和名称 141 UINT32 PrintProcessesIDAndName() 142 { 143 UINT32 BufferLength = 0x1000; 144 void* BufferData = NULL; 145 146 NTSTATUS Status = STATUS_INFO_LENGTH_MISMATCH; 147 HANDLE HeapHandle = GetProcessHeap(); //获得当前进程默认堆 148 149 UINT32 ProcessID = 0; 150 151 BOOL bOk = FALSE; 152 while (!bOk) 153 { 154 BufferData = HeapAlloc(HeapHandle, HEAP_ZERO_MEMORY, BufferLength); 155 if (BufferData == NULL) 156 { 157 return 0; 158 } 159 160 Status = ZwQuerySystemInformation(SystemProcessInformation, BufferData, BufferLength, (PULONG)&BufferLength); 161 if (Status == STATUS_INFO_LENGTH_MISMATCH) 162 { 163 //内存不足,将内存扩大二倍重新申请 164 HeapFree(HeapHandle, NULL, BufferData); 165 BufferLength *= 2; 166 } 167 else if (!NT_SUCCESS(Status)) 168 { 169 //不让看 170 HeapFree(HeapHandle, NULL, BufferData); 171 return 0; 172 } 173 else 174 { 175 176 PSYSTEM_PROCESS_INFORMATION SystemProcess = (PSYSTEM_PROCESS_INFORMATION)BufferData; 177 while (SystemProcess) 178 { 179 //定义变量ProcessName接收Name 180 char ProcessName[MAX_PATH]; 181 memset(ProcessName, 0, sizeof(ProcessName)); 182 WideCharToMultiByte(0, 0, SystemProcess->ImageName.Buffer, SystemProcess->ImageName.Length, ProcessName, MAX_PATH, NULL, NULL); 183 ProcessID = (UINT32)(SystemProcess->ProcessId); 184 printf("PID: %X, Name: %s ",ProcessID, ProcessName); 185 186 if (!SystemProcess->NextEntryOffset) 187 { 188 break; 189 } 190 SystemProcess = (PSYSTEM_PROCESS_INFORMATION)((unsigned char*)SystemProcess + SystemProcess->NextEntryOffset); 191 } 192 193 if (BufferData) 194 { 195 HeapFree(HeapHandle, NULL, BufferData); 196 } 197 198 bOk = TRUE; 199 } 200 } 201 202 return ProcessID; 203 }
4)利用WTSEnumerateProcesses

1 #include "stdafx.h" 2 #include <Windows.h> 3 #include <WtsApi32.h> 4 #pragma comment(lib,"WtsApi32.lib") 5 int main() 6 { 7 //用nbtsat -n获得本机NetBios名 8 WCHAR wzServerName[] = L"JARVIS"; //NetBios名 9 10 //开启远程终端服务 11 HANDLE WtsServerHandle = WTSOpenServer(wzServerName); 12 13 PWTS_PROCESS_INFO WtsProcessInfo; 14 DWORD Count; 15 16 //枚举进程 17 if (!WTSEnumerateProcesses(WtsServerHandle, 18 0, 19 1, 20 &WtsProcessInfo, 21 &Count)) 22 { 23 printf("Enum rocesses Error: %d ", GetLastError()); 24 return 0; 25 } 26 27 for (int i = 0; i < Count; i++) 28 { 29 printf("PID: %d Name: %S ", WtsProcessInfo[i].ProcessId, WtsProcessInfo[i].pProcessName); 30 } 31 //关闭服务 32 WTSCloseServer(WtsServerHandle); 33 return 0; 34 }
二、Ring0层方法总结
1)利用PsLookupProcessByProcessId

1 BOOLEAN GetProcessImageNameByProcessID(ULONG32 ulProcessID,char* szProcessImageName,ULONG32* ulProcessImageNameLength) 2 { 3 4 NTSTATUS Status; 5 PEPROCESS EProcess = NULL; 6 Status = PsLookupProcessByProcessId((HANDLE)ulProcessID,&EProcess); 7 8 if (!NT_SUCCESS(Status)) 9 { 10 return FALSE; 11 } 12 13 14 if (EProcess==NULL) 15 { 16 return FALSE; 17 } 18 19 ObDereferenceObject(EProcess); 20 21 22 23 24 if (strlen(PsGetProcessImageFileName(EProcess))>MAX) 25 { 26 *ulProcessImageNameLength = MAX-1; 27 } 28 29 else 30 { 31 *ulProcessImageNameLength = strlen(PsGetProcessImageFileName(EProcess)); 32 } 33 34 35 memcpy(szProcessImageName,PsGetProcessImageFileName(EProcess),*ulProcessImageNameLength); 36 37 38 return TRUE; 39 40 41 42 43 }