通过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结构。

posted @ 2014-08-12 23:32  Max Woods  阅读(776)  评论(0编辑  收藏  举报