获取进程完整路径名附源码
文章里对于如何获取其他进程,提供了两种方法,但是都不太方便,
在我的驱动里,我是在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]