清淡小女子 发表于 2013-2-7 08:56:27

在内核驱动中,获得到当前进程的全路径。

作者:guijc
在应用层想要获得一个进程的全路径,有一个很简单的API函数,但是在内核中却没有提供这样的函数,上次看了一位前辈的帖子,根据他的思路写出了下面的代码,欢迎大家的评论


代码思路如下:
1. 利用ZwQueryInformationProcess得到当前进程的NT路径
2. 用ZwOpenFile打开NT路径,获得进程的句柄
3. 用ObReferenceObjectByHandle获得内核对象(FileObj)
4. 获得盘符(C:\),RtlVolumeDeviceToDosName(FileObj->DeviceObject, &DosName);
5. 拼接路径,RtlAppendUnicodeStringToString(&ImageName, &FileObj->FileName);

好了废话不多,直接上代码:void GetProcessImageName(PANSI_STRING ImageFileName)
{
    UNICODE_STRINGImageName = {0};
    PUNICODE_STRING Buffer = NULL;
    ULONG ReturnLength = 0;
    NTSTATUS status = 0;

    HANDLE FileHandle = NULL;
    OBJECT_ATTRIBUTES ObjectAttributes = {0};
    IO_STATUS_BLOCK IoStatusBlock = {0};
    PFILE_OBJECT FileObj = NULL;
    UNICODE_STRING DosName = {0};

    status = ZwQueryInformationProcess(
                            NtCurrentProcess(),
                            ProcessImageFileName,
                            NULL,
                            0,
                            &ReturnLength);

    if(STATUS_INFO_LENGTH_MISMATCH != status ||0 == ReturnLength){
      return;
    }

    Buffer = ExAllocatePool(NonPagedPool, ReturnLength);
    if(NULL == Buffer){
      goto Clean;
    }
   
    status = ZwQueryInformationProcess(
                            NtCurrentProcess(),
                            ProcessImageFileName,
                            Buffer,
                            ReturnLength,
                            &ReturnLength);

    if(!NT_SUCCESS(status)){
      goto Clean;
    }

    InitializeObjectAttributes( &ObjectAttributes,
                            Buffer,
                            OBJ_KERNEL_HANDLE,
                            NULL,
                            NULL );

    status = ZwOpenFile(&FileHandle, 0, &ObjectAttributes, &IoStatusBlock, 0, 0);
    if (!NT_SUCCESS (status)){
       goto Clean;
    }

    status = ObReferenceObjectByHandle(FileHandle, 0, NULL, KernelMode, &FileObj, NULL);
    if (!NT_SUCCESS (status)){
       goto Clean;
    }

    if(FileObj->DeviceObject && FileObj->FileName.Buffer){
   
      RtlVolumeDeviceToDosName(FileObj->DeviceObject, &DosName);

      ImageName.MaximumLength = DosName.Length + FileObj->FileName.Length;
      ImageName.Buffer = ExAllocatePool(NonPagedPool, ImageName.MaximumLength);      

      RtlCopyUnicodeString(&ImageName, &DosName);
      RtlAppendUnicodeStringToString(&ImageName, &FileObj->FileName);
      
      RtlUnicodeStringToAnsiString(ImageFileName ,&ImageName, TRUE);
      RtlFreeUnicodeString(&ImageName);
      RtlFreeUnicodeString(&DosName);
    }
   
Clean:

    if(Buffer){
      ExFreePool (Buffer);
    }

    if(FileHandle){
      ZwClose(FileHandle);
    }   

    if(FileObj){
      ObDereferenceObject(FileObj);
    }

}
页: [1]
查看完整版本: 在内核驱动中,获得到当前进程的全路径。