From 49e652b7b790de896e63b4de07822376f4d627f0 Mon Sep 17 00:00:00 2001 From: Ratin Gao Date: Sun, 27 Apr 2025 02:17:34 +0800 Subject: [PATCH] [NTOS:PS] Implement `ProcessImageFileNameWin32` information class --- ntoskrnl/include/internal/ps_i.h | 6 +-- ntoskrnl/ps/query.c | 70 ++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 3 deletions(-) diff --git a/ntoskrnl/include/internal/ps_i.h b/ntoskrnl/include/internal/ps_i.h index 04d564bd36a..7f15a8afb63 100644 --- a/ntoskrnl/include/internal/ps_i.h +++ b/ntoskrnl/include/internal/ps_i.h @@ -341,9 +341,9 @@ static const INFORMATION_CLASS_INFO PsProcessInfoClass[] = /* ProcessImageFileNameWin32 */ IQS_SAME ( - CHAR, - CHAR, - ICIF_NONE + UNICODE_STRING, + ULONG, + ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE ), /* ProcessImageFileMapping */ diff --git a/ntoskrnl/ps/query.c b/ntoskrnl/ps/query.c index 72fa309d0c8..6e34c0f8085 100644 --- a/ntoskrnl/ps/query.c +++ b/ntoskrnl/ps/query.c @@ -748,6 +748,76 @@ NtQueryInformationProcess( break; } +#if (NTDDI_VERSION >= NTDDI_VISTA) || (DLL_EXPORT_VERSION >= _WIN32_WINNT_VISTA) + case ProcessImageFileNameWin32: + { + PFILE_OBJECT FileObject; + POBJECT_NAME_INFORMATION ObjectNameInformation; + + /* Reference the process */ + Status = ObReferenceObjectByHandle(ProcessHandle, + PROCESS_QUERY_INFORMATION, // FIXME: Use PROCESS_QUERY_LIMITED_INFORMATION if implemented + PsProcessType, + PreviousMode, + (PVOID*)&Process, + NULL); + if (!NT_SUCCESS(Status)) + { + break; + } + + /* Get the image path */ + Status = PsReferenceProcessFilePointer(Process, &FileObject); + ObDereferenceObject(Process); + if (!NT_SUCCESS(Status)) + { + break; + } + Status = IoQueryFileDosDeviceName(FileObject, &ObjectNameInformation); + ObDereferenceObject(FileObject); + if (!NT_SUCCESS(Status)) + { + break; + } + + /* Determine return length and output */ + Length = sizeof(UNICODE_STRING) + ObjectNameInformation->Name.MaximumLength; + if (Length <= ProcessInformationLength) + { + _SEH2_TRY + { + PUNICODE_STRING ImageName = (PUNICODE_STRING)ProcessInformation; + ImageName->Length = ObjectNameInformation->Name.Length; + ImageName->MaximumLength = ObjectNameInformation->Name.MaximumLength; + if (ObjectNameInformation->Name.MaximumLength) + { + ImageName->Buffer = (PWSTR)(ImageName + 1); + RtlCopyMemory(ImageName->Buffer, + ObjectNameInformation->Name.Buffer, + ObjectNameInformation->Name.MaximumLength); + } + else + { + ASSERT(ImageName->Length == 0); + ImageName->Buffer = NULL; + } + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + } + else + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + ExFreePool(ObjectNameInformation); + + break; + } +#endif /* (NTDDI_VERSION >= NTDDI_VISTA) || (DLL_EXPORT_VERSION >= _WIN32_WINNT_VISTA) */ + case ProcessDebugFlags: if (ProcessInformationLength != sizeof(ULONG))