Google found that many of them directly obtained the process structure system_process_information through zwquerysysteminformation on the 11th, which is insufficient to express detailed process information. So I want to use this to view the detailed eprocess structure. The method can be obtained through the function pslookupprocessbyprocessid. The function prototype is given below.
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;
The _ system_process_information structure is much more structured under wrk than above. It seems that Microsoft's actions are quite big.
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;
Pslookupprocessbyprocessid in reactos:
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;}
Pslookupprocpolicyprocessid in wrk:
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;}
Use zwquerysysteminformation to obtain the eprocess code block:
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;}
The above code can get the eprocess structure without exception.
If any, please point out.