雨过天晴 发表于 2013-4-12 09:42:56

驱动中获取进程完整路径名

作者:未知
文章里对于如何获取其他进程,提供了两种方法,但是都不太方便,在我的驱动里,我是在PsSetCreateProcessNotifyRoutine的回调函数里获取进程路径,能得到的进程信息是PID,于是动手改了下上面的代码,如下:

C++代码NTSTATUS   
    GetProcessImagePath(   
      INDWORD   dwProcessId,   
      OUT PUNICODE_STRING ProcessImagePath   
    )   
{   
    NTSTATUS Status;   
    HANDLE hProcess;   
    PEPROCESS pEprocess;   
    ULONG returnedLength;   
    ULONG bufferLength;   
    PVOID buffer;   
    PUNICODE_STRING imageName;   
      
    PAGED_CODE(); // this eliminates the possibility of the IDLE Thread/Process   
   
    if (NULL == ZwQueryInformationProcess) {   
   
      UNICODE_STRING routineName;   
   
      RtlInitUnicodeString(&routineName, L"ZwQueryInformationProcess");   
   
      ZwQueryInformationProcess =   
               (QUERY_INFO_PROCESS) MmGetSystemRoutineAddress(&routineName);   
   
      if (NULL == ZwQueryInformationProcess) {   
            DbgPrint("Cannot resolve ZwQueryInformationProcess\n");   
      }   
    }   
      
    Status = PsLookupProcessByProcessId((HANDLE)dwProcessId, &pEprocess);   
    if (!NT_SUCCESS(Status))
      return Status;
      
    Status = ObOpenObjectByPointer(pEprocess,          // Object   
                                 OBJ_KERNEL_HANDLE,// HandleAttributes   
                                 NULL,               // PassedAccessState OPTIONAL   
                                 GENERIC_READ,       // DesiredAccess   
                                 *PsProcessType,   // ObjectType   
                                 KernelMode,         // AccessMode   
                                 &hProcess);   
    if (!NT_SUCCESS(Status))
      return Status;
      
      
    //   
    // Step one - get the size we need   
    //   
    Status = ZwQueryInformationProcess( hProcess,   
                                        ProcessImageFileName,   
                                        NULL, // buffer   
                                        0, // buffer size   
                                        &returnedLength);   
      
   
    if (STATUS_INFO_LENGTH_MISMATCH != Status) {   
   
      return Status;   
   
    }   
   
    //   
    // Is the passed-in buffer going to be big enough for us?   
    // This function returns a single contguous buffer model...   
    //   
    bufferLength = returnedLength - sizeof(UNICODE_STRING);   
      
    if (ProcessImagePath->MaximumLength < bufferLength) {   
   
      ProcessImagePath->Length = (USHORT) bufferLength;   
   
      return STATUS_BUFFER_OVERFLOW;   
         
    }   
   
    //   
    // If we get here, the buffer IS going to be big enough for us, so   
    // let's allocate some storage.   
    //   
    buffer = ExAllocatePoolWithTag(PagedPool, returnedLength, 'ipgD');   
   
    if (NULL == buffer) {   
   
      return STATUS_INSUFFICIENT_RESOURCES;   
         
    }   
   
    //   
    // Now lets go get the data   
    //   
    Status = ZwQueryInformationProcess( hProcess,   
                                        ProcessImageFileName,   
                                        buffer,   
                                        returnedLength,   
                                        &returnedLength);   
   
    if (NT_SUCCESS(Status)) {   
      //   
      // Ah, we got what we needed   
      //   
      imageName = (PUNICODE_STRING) buffer;   
   
      RtlCopyUnicodeString(ProcessImagePath, imageName);   
         
    }   
      
    ZwClose(hProcess);   
   
    //   
    // free our buffer   
    //   
    ExFreePool(buffer);   
   
    //   
    // And tell the caller what happened.   
    //      
    return Status;   
      
}   

typedef NTSTATUS (*QUERY_INFO_PROCESS) (
    __in HANDLE ProcessHandle,
    __in PROCESSINFOCLASS ProcessInformationClass,
    __out_bcount(ProcessInformationLength) PVOID ProcessInformation,
    __in ULONG ProcessInformationLength,
    __out_opt PULONG ReturnLength
    );
QUERY_INFO_PROCESS ZwQueryInformationProcess;
NTSTATUS GetProcessImageName(PUNICODE_STRING ProcessImageName)
{
    NTSTATUS status;
    ULONG returnedLength;
    ULONG bufferLength;
    PVOID buffer;
    PUNICODE_STRING imageName;
   
    PAGED_CODE(); // this eliminates the possibility of the IDLE Thread/Process
    if (NULL == ZwQueryInformationProcess) {
      UNICODE_STRING routineName;
      RtlInitUnicodeString(&routineName, L"ZwQueryInformationProcess");
      ZwQueryInformationProcess =
               (QUERY_INFO_PROCESS) MmGetSystemRoutineAddress(&routineName);
      if (NULL == ZwQueryInformationProcess) {
            DbgPrint("Cannot resolve ZwQueryInformationProcess\n");
      }
    }
    //
    // Step one - get the size we need
    //
    status = ZwQueryInformationProcess( NtCurrentProcess(),
                                        ProcessImageFileName,
                                        NULL, // buffer
                                        0, // buffer size
                                        &returnedLength);
    if (STATUS_INFO_LENGTH_MISMATCH != status) {
      return status;
    }
    //
    // Is the passed-in buffer going to be big enough for us?
    // This function returns a single contguous buffer model...
    //
    bufferLength = returnedLength - sizeof(UNICODE_STRING);
   
    if (ProcessImageName->MaximumLength < bufferLength) {
      ProcessImageName->Length = (USHORT) bufferLength;
      return STATUS_BUFFER_OVERFLOW;
      
    }
    //
    // If we get here, the buffer IS going to be big enough for us, so
    // let's allocate some storage.
    //
    buffer = ExAllocatePoolWithTag(PagedPool, returnedLength, 'ipgD');
    if (NULL == buffer) {
      return STATUS_INSUFFICIENT_RESOURCES;
      
    }
    //
    // Now lets go get the data
    //
    status = ZwQueryInformationProcess( NtCurrentProcess(),
                                        ProcessImageFileName,
                                        buffer,
                                        returnedLength,
                                        &returnedLength);
    if (NT_SUCCESS(status)) {
      //
      // Ah, we got what we needed
      //
      imageName = (PUNICODE_STRING) buffer;
      RtlCopyUnicodeString(ProcessImageName, imageName);
      
    }
    //
    // free our buffer
    //
    ExFreePool(buffer);
    //
    // And tell the caller what happened.
    //   
    return status;
   
}
页: [1]
查看完整版本: 驱动中获取进程完整路径名