123456811 发表于 2024-3-11 13:34:13

32位内核-通过进程ID获得进程的对应路径

////////////////////////////////////////////////
//函数功能:通过进程ID获得进程的对应路径
//参    数:输入:dwProcessId,进程ID
//          输出:ProcessImagePath,进程所在路径,
//          这个变量必须先分配好空间
//返 回 值:NTSTATUS
////////////////////////////////////////////////
NTSTATUS
GetProcessImagePath(
    INULONG   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;
    //Wdm中定义的全局变量 PsProcessType
    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;

}


---------------------------------------------

方法2不蓝屏:方法1 会 蓝屏的。。


/*nt_ddk.h*/
/*获取应用程序路径*/

bool GetIamgeName(PANSI_STRING pImageName)
{
KIRQL      CurIRQL ;
NTSTATUS   status;
ULONG      returnedLength;
ULONG      bufferLength;
PVOID      buffer;
PUNICODE_STRING imageName;
BOOLEAN      bRet = FALSE ;

CurIRQL = KeGetCurrentIrql() ;      //返回当前中断请求级别
DbgPrint ("Current IRQL is %d\r\n", CurIRQL) ;
if (PASSIVE_LEVEL != CurIRQL)
{   
return FALSE ;
}

if ( ! MmIsAddressValid (pImageName))
{//判断地址是否有效。
return FALSE ;
}

pImageName->Length = 0 ;
pImageName->MaximumLength = 0 ;
pImageName->Buffer = NULL ;

if (NULL == ZwQueryInformationProcess) {
//取得ZwQueryInformationProcess地址
UNICODE_STRING routineName;
RtlInitUnicodeString(&routineName, L"ZwQueryInformationProcess");
ZwQueryInformationProcess =
(QUERY_INFO_PROCESS) MmGetSystemRoutineAddress(&routineName);

if (NULL == ZwQueryInformationProcess) {
DbgPrint("Cannot resolve ZwQueryInformationProcess\n");
return FALSE ;
}
}

// 判断ZwQueryInformationProcess是否正常返回
status = ZwQueryInformationProcess( NtCurrentProcess(),
ProcessImageFileName,
NULL, // buffer
0, // buffer size
&returnedLength);

if (STATUS_INFO_LENGTH_MISMATCH != status) {
return FALSE;
}

bufferLength = returnedLength - sizeof(UNICODE_STRING);
buffer = ExAllocatePoolWithTag(PagedPool, returnedLength, 'ipgD');

status = ZwQueryInformationProcess( NtCurrentProcess(), //取得进程句柄
ProcessImageFileName,
buffer,      //取得当前进程路径地址
returnedLength,
&returnedLength);

if (NT_SUCCESS(status)) {
imageName = (PUNICODE_STRING)buffer;
if (STATUS_SUCCESS != RtlUnicodeStringToAnsiString (pImageName, imageName, TRUE))
{
bRet = false;
KdPrint (("Current ProcessImageFileName: Unknow\r\n"));
}
else
{
bRet = true;
KdPrint (("Current ProcessImageFileName: \"%s\"\r\n", pImageName->Buffer));
DeviceToDos(pImageName);//将驱动盘符转换为DOS盘符

}
}
ExFreePool(buffer);
return bRet;
}

页: [1]
查看完整版本: 32位内核-通过进程ID获得进程的对应路径