通过ZwQuerySystemInformation获取EPROCESS
google一下,发现很多都是直接通过ZwQuerySystemInformation通过11号获取进程结构SYSTEM_PROCESS_INFORMATION,对于详细的进程信息表达不够。所以想要通过这个来查看详细的 EPROCESS 结构。方法可以通过 PsLookupProcessByProcessId 这个函数来获取。函数原型在下面给出。
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; KPRIORITY BasePriority; HANDLE ProcessId; HANDLE InheritedFromProcessId; ULONG HandleCount; ULONG Reserved2[2]; ULONG PrivatePageCount; VM_COUNTERS VirtualMemoryCounters; IO_COUNTERS IoCounters; SYSTEM_THREAD Threads[0]; } SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;
而_SYSTEM_PROCESS_INFORMATION结构在WRK下面的结构明显比上面的多。看来微软的动作还挺大的。
typedef struct _SYSTEM_PROCESS_INFORMATION { ULONG NextEntryOffset; ULONG NumberOfThreads; LARGE_INTEGER SpareLi1; LARGE_INTEGER SpareLi2; LARGE_INTEGER SpareLi3; LARGE_INTEGER CreateTime; LARGE_INTEGER UserTime; LARGE_INTEGER KernelTime; UNICODE_STRING ImageName; KPRIORITY BasePriority; HANDLE UniqueProcessId; HANDLE InheritedFromUniqueProcessId; ULONG HandleCount; ULONG SessionId; ULONG_PTR PageDirectoryBase; SIZE_T PeakVirtualSize; SIZE_T VirtualSize; ULONG PageFaultCount; SIZE_T PeakWorkingSetSize; SIZE_T WorkingSetSize; SIZE_T QuotaPeakPagedPoolUsage; SIZE_T QuotaPagedPoolUsage; SIZE_T QuotaPeakNonPagedPoolUsage; SIZE_T QuotaNonPagedPoolUsage; SIZE_T PagefileUsage; SIZE_T PeakPagefileUsage; SIZE_T PrivatePageCount; LARGE_INTEGER ReadOperationCount; LARGE_INTEGER WriteOperationCount; LARGE_INTEGER OtherOperationCount; LARGE_INTEGER ReadTransferCount; LARGE_INTEGER WriteTransferCount; LARGE_INTEGER OtherTransferCount; } SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;
ReactOS下的PsLookupProcessByProcessId:
NTSTATUS NTAPI PsLookupProcessByProcessId(IN HANDLE ProcessId, OUT PEPROCESS *Process) { PHANDLE_TABLE_ENTRY CidEntry; PEPROCESS FoundProcess; NTSTATUS Status = STATUS_INVALID_PARAMETER; PAGED_CODE(); PSTRACE(PS_PROCESS_DEBUG, "ProcessId: %p\n", ProcessId); KeEnterCriticalRegion(); /* Get the CID Handle Entry */ CidEntry = ExMapHandleToPointer(PspCidTable, ProcessId); if (CidEntry) { /* Get the Process */ FoundProcess = CidEntry->Object; /* Make sure it's really a process */ if (FoundProcess->Pcb.Header.Type == ProcessObject) { /* Safe Reference and return it */ if (ObReferenceObjectSafe(FoundProcess)) { *Process = FoundProcess; Status = STATUS_SUCCESS; } } /* Unlock the Entry */ ExUnlockHandleTableEntry(PspCidTable, CidEntry); } /* Return to caller */ KeLeaveCriticalRegion(); return Status; }
WRK下的PsLookupProcessByProcessId:
NTSTATUS PsLookupProcessByProcessId( __in HANDLE ProcessId, __deref_out PEPROCESS *Process ) /*++ Routine Description: This function accepts the process id of a process and returns a referenced pointer to the process. Arguments: ProcessId - Specifies the Process ID of the process. Process - Returns a referenced pointer to the process specified by the process id. Return Value: STATUS_SUCCESS - A process was located based on the contents of the process id. STATUS_INVALID_PARAMETER - The process was not found. --*/ { PHANDLE_TABLE_ENTRY CidEntry; PEPROCESS lProcess; PETHREAD CurrentThread; NTSTATUS Status; PAGED_CODE(); Status = STATUS_INVALID_PARAMETER; CurrentThread = PsGetCurrentThread (); KeEnterCriticalRegionThread (&CurrentThread->Tcb); CidEntry = ExMapHandleToPointer(PspCidTable, ProcessId); if (CidEntry != NULL) { lProcess = (PEPROCESS)CidEntry->Object; if (lProcess->Pcb.Header.Type == ProcessObject && lProcess->GrantedAccess != 0) { if (ObReferenceObjectSafe(lProcess)) { *Process = lProcess; Status = STATUS_SUCCESS; } } ExUnlockHandleTableEntry(PspCidTable, CidEntry); } KeLeaveCriticalRegionThread (&CurrentThread->Tcb); return Status; }
通过ZwQuerySystemInformation获取EPROCESS的代码块:
status = ZwQuerySystemInformation(SystemProcessesAndThreadsInformation,NULL,0,&BufferSize); if (!BufferSize) { KdPrint(("ZwQuerySystemInformation error!\n")); return status; } Buffer = ExAllocatePoolWithTag(NonPagedPool,BufferSize,'myta'); if (!Buffer) { KdPrint(("ExAllocatePoolWithTag error!\n")); return STATUS_UNSUCCESSFUL; } status = ZwQuerySystemInformation(SystemProcessesAndThreadsInformation,Buffer,BufferSize,0); if (!NT_SUCCESS(status)) { KdPrint(("ZwQuerySystemInformation error!\n")); ExFreePool(Buffer); return status; } pProcessInfo = (PSYSTEM_PROCESS_INFORMATION)Buffer; status = PsLookupProcessByProcessId(pProcessInfo->ProcessId,&eProcess); if (!NT_SUCCESS(status)) { KdPrint(("PsLookupProcessByProcessId error! %x\n",status)); ExFreePool(Buffer); return status; }
上述代码不出意外的话能够得到EPROCESS结构。