From 29fc7bb33e05dc007f2af16df907eaebb7cc59d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?George=20Bi=C8=99oc?= Date: Sun, 19 Mar 2023 22:04:21 +0100 Subject: [PATCH] [NTOS:OB] Implement name information querying on ObjectBasicInformation case Currently there is no implementation support for object name information querying when someone queries information about an object with ObjectBasicInformation class case. Some device drivers may take use of such information. NameInfoSize is a size that is the sum of all name directories of an object, including path separators. TypeInfoSize is a size that is pointed by the size of a type object itself, therefore this size remains pretty much fixed depending on the kind of an object. For more information: https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/api/ntobapi/object_basic_information.htm http://undocumented.ntinternals.net/index.html?page=UserMode%2FUndocumented%20Functions%2FNT%20Objects%2FType%20independed%2FNtQueryObject.html --- ntoskrnl/ob/oblife.c | 78 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 2 deletions(-) diff --git a/ntoskrnl/ob/oblife.c b/ntoskrnl/ob/oblife.c index 9704ad8b355..a6161a4bbf7 100644 --- a/ntoskrnl/ob/oblife.c +++ b/ntoskrnl/ob/oblife.c @@ -869,6 +869,79 @@ ObpAllocateObject(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo, return STATUS_SUCCESS; } +/** + * @brief + * Queries the name info size of a given resource object. + * The function loops through all the parent directories + * of the object and computes the name size. + * + * @param[in] ObjectHeader + * A pointer to an object header, of which name and + * directory info are to be retrieved. + * + * @return + * Returns the name info size that is pointed by the + * given object by the caller of this function. If + * an object does not have a name or no directories, + * it returns 0. + */ +static +ULONG +ObpQueryNameInfoSize( + _In_ POBJECT_HEADER ObjectHeader) +{ + ULONG NameSize = 0; + POBJECT_DIRECTORY ParentDirectory; + POBJECT_HEADER_NAME_INFO NameInfo; + PAGED_CODE(); + + /* Get the name info */ + NameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader); + if (!NameInfo) + { + return 0; + } + + /* Get the parent directory from the object name too */ + ParentDirectory = NameInfo->Directory; + if (!ParentDirectory) + { + return 0; + } + + /* Take into account the name size of this object and loop for all parent directories */ + NameSize = sizeof(OBJ_NAME_PATH_SEPARATOR) + NameInfo->Name.Length; + for (;;) + { + /* Get the name info from the parent directory */ + NameInfo = OBJECT_HEADER_TO_NAME_INFO( + OBJECT_TO_OBJECT_HEADER(ParentDirectory)); + if (!NameInfo) + { + /* Stop looking if this is the last one */ + break; + } + + /* Get the parent directory */ + ParentDirectory = NameInfo->Directory; + if (!ParentDirectory) + { + /* This is the last directory, stop looking */ + break; + } + + /* + * Take into account the size of this name info, + * keep looking for other parent directories. + */ + NameSize += sizeof(OBJ_NAME_PATH_SEPARATOR) + NameInfo->Name.Length; + } + + /* Include the size of the object name information as well as the NULL terminator */ + NameSize += sizeof(OBJECT_NAME_INFORMATION) + sizeof(UNICODE_NULL); + return NameSize; +} + NTSTATUS NTAPI ObQueryTypeInfo(IN POBJECT_TYPE ObjectType, @@ -1584,8 +1657,9 @@ NtQueryObject(IN HANDLE ObjectHandle, } /* Copy name information */ - BasicInfo->NameInfoSize = 0; /* FIXME*/ - BasicInfo->TypeInfoSize = 0; /* FIXME*/ + BasicInfo->NameInfoSize = ObpQueryNameInfoSize(ObjectHeader); + BasicInfo->TypeInfoSize = sizeof(OBJECT_TYPE_INFORMATION) + ObjectType->Name.Length + + sizeof(UNICODE_NULL); /* Check if this is a symlink */ if (ObjectHeader->Type == ObpSymbolicLinkObjectType)