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:
NTSTATUSNTAPIPsLookupProcessByProcessId(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:
NTSTATUSPsLookupProcessByProcessId( __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結構。
如有錯漏,望請指出。