win 7 object header

Windows 7 Object Headers


This document describes the changes to the object header structure that have been made in Windows 7 and the areas of functionality these changes affect. It starts with a brief description of the layout of objects and the related data structures, the difference between the legacy and the new object header structures, followed by a detailed description of the reason for the changes and the areas of functionality that are affected by these changes. This document refers to all versions of Windows before Windows 7 as "older" versions as Windows. All debugger examples used in the document are on Windows Vista SP1 or Windows 7 kernel running on the X86 platform.

A structure becomes an object when the object manager, a component in the Windows kernel, puts headers before the start of the object, to provide a range of services including object naming, object reference counting, checking for security, using information stored in these headers. The following figure shows the layout of objects and the associated headers:

 

FIG#1
Figure 1 : Object Layout

 

As shown in the above figure, objects are allocated from either the paged or non-paged pool. The allocation always starts with a pool header, a structure of type nt!_POOL_HEADER. The pool header is then followed by optional object headers, which could be of four different types - details of which are described later.The optional object headers are followed by a mandatory object header which is a structure of type nt!_OBJECT_HEADER and finally the object itself. This could be any of the 37 different object types supported as of Windows Vista. Examples of objects inlcude events (nt!_KEVENT), semaphores (nt!_KSEMAPHORE), file objects (nt!_FILE_OBJECT), device objects (nt!_DEVICE_OBJECT). The last few bytes of the object header, the field OBJECT_HEADER->Body, overlap with the actual object body. The OBJECT_HEADER->Type->TypeInfo.PoolType field determines which pool a particular type of objects would be allocated from this can be either PagedPool or NonPagedPool.

OBJECT_HEADER Structure

Running the "!object" command in the kernel debugger displays the following output on older version of Windows:

053c: Object: 87d67f80  GrantedAccess: 00000001 Entry: 8fe02a78
Object: 87d67f80  Type: (87515590) File
    ObjectHeader: 87d67f68 (old version)
        HandleCount: 1  PointerCount: 1

On Windows 7 and later version of Windows the "!object" command displays a slightly different output:

0328: Object: 84e8ee10  GrantedAccess: 00100001 Entry: 9b710650
Object: 84e8ee10  Type: (848cc3c0) File
    ObjectHeader: 84e8edf8 (new version)
        HandleCount: 1  PointerCount: 1

Examining the OBJECT_HEADER structure on the respective versions of Windows shows the reason for the debugger displaying "old version" and "new version". Following debugger output shows the OBJECT_HEADER on older versions of Windows. The fields below that are highlighted are ones that have been removed from the OBJECT_HEADER structure in Windows 7:

kd> dt nt!_OBJECT_HEADER
   +0x000 PointerCount     : Int4B
   +0x004 HandleCount      : Int4B
   +0x004 NextToFree       : Ptr32 Void
   +0x008 Type             : Ptr32 _OBJECT_TYPE
   +0x00c NameInfoOffset   : UChar
   +0x00d HandleInfoOffset : UChar
   +0x00e QuotaInfoOffset  : UChar
   +0x00f Flags            : UChar
   +0x010 ObjectCreateInfo : Ptr32 _OBJECT_CREATE_INFORMATION
   +0x010 QuotaBlockCharged : Ptr32 Void
   +0x014 SecurityDescriptor : Ptr32 Void
   +0x018 Body             : _QUAD

The highlighted fields below are new to the OBJECT_HEADER structure in Windows 7:

kd>  dt nt!_OBJECT_HEADER
   +0x000 PointerCount     : Int4B
   +0x004 HandleCount      : Int4B
   +0x004 NextToFree       : Ptr32 Void
   +0x008 Lock             : _EX_PUSH_LOCK
   +0x00c TypeIndex        : UChar
   +0x00d TraceFlags       : UChar
   +0x00e InfoMask         : UChar
   +0x00f Flags            : UChar
   +0x010 ObjectCreateInfo : Ptr32 _OBJECT_CREATE_INFORMATION
   +0x010 QuotaBlockCharged : Ptr32 Void
   +0x014 SecurityDescriptor : Ptr32 Void
   +0x018 Body             : _QUAD

Per Object Lock

In Windows 7, the new "Lock" field in the OBJECT_HEADER is used to reduce the locking granularity for objects. On older version of Windows, the object manager attempted to acquire an object type specific lock (OBJECT_TYPE->TypeLock) before performing an operation on an object. This implied that no other object of that type in the entire system could be manipulated for the duration the object type lock was held. With Windows 7, due to the availability of the per-object lock (OBJET_HEADER->Lock), manipulating one object does not prevent any other object from being manipulated simultaneously, including objects of the same type. The rest of the changes that have been made to the OBJECT_HEADER structure were required to make room for this "Lock" field without increasing the size of the structure.

Object Type Structure

In older versions of Windows, the OBJECT_HEADER->Type field contained a pointer to the OBJECT_TYPE data structure, which consumed 32/64 bits depending on the platform. In Windows 7, this field has been converted to a CHAR (8-bit) value stored at OBJECT_HEADER->TypeIndex. Instead of pointing directly to the OBJECT_TYPE data structure, the object header now contains an index into a new global data structure nt!ObTypeIndexTable, which is an array of pointers to the different OBJECT_TYPE structures, one of each supported object type. The following command shows the OBJECT_TYPE structure that a object header would point to if the OBJECT_HEADER->TypeIndex is set to 5 :

kd> dt nt!_OBJECT_TYPE poi(nt!ObTypeIndexTable + ( 5 * @$ptrsize ))
   +0x000 TypeList         : _LIST_ENTRY [ 0x84833960 - 0x84833960 ]
   +0x008 Name             : _UNICODE_STRING "Token"
   +0x010 DefaultObject    : 0x82745ba0 Void
   +0x014 Index            : 0x5 ''
   +0x018 TotalNumberOfObjects : 0x2f3
   +0x01c TotalNumberOfHandles : 0xec
   +0x020 HighWaterNumberOfObjects : 0x2ff
   +0x024 HighWaterNumberOfHandles : 0xff
   +0x028 TypeInfo         : _OBJECT_TYPE_INITIALIZER
   +0x078 TypeLock         : _EX_PUSH_LOCK
   +0x07c Key              : 0x656b6f54
   +0x080 CallbackList     : _LIST_ENTRY [ 0x848339e0 - 0x848339e0 ]

Object Tracing

Object tracing is a new feature added to windows Vista to collect stack traces during object referencing and dereferencing operations. This helps in debugging reference counting problems. The documentation of the "!objtrace" command, in the debugger help, describes how to enable various object reference tracing options and view them, in the debugger.

In older versions of Windows, the lower 2 bits (i.e. bits 0 and 1) of the OBJECT_HEADER->QuotaInfoOffset field were used to determine if object reference tracing was enabled on the object. Since the OBJECT_HEADER->QuotaInfoOffset is not longer available in Windows 7, as discussed later, the new field OBJECT_HEADER->TraceFlag was added to store the object tracing related flags.

Object Reference Tagging APIs

In Windows 7, the object reference tracing functionality has been enhanced to allow drivers to pass in their own custom tags, to the object referencing and dereferencing APIs. The new "WithTag" versions of all the object reference and dereference APIs have been added as shown below:

  • ObReferenceObjectByHandleWithTag()
  • ObReferenceObjectByPointerWithTag()
  • ObReferenceObjectWithTag()
  • ObDereferenceObjectWithTag()
  • ObDereferenceObjectDeferDeleteWithTag()

Developers can call these APIs instead of the old ones and pass in a 4 character tag that would be stored along with the stack trace when the operation is performed on the object.

 

Optional Object Headers

In older versions of Windows, the OBJECT_HEADER structure fields NameInfoOffset, HandleInfoOffset and QuotaInfoOffset were used to describe the presence and location of the optional object headers OBJECT_HEADER_NAME_INFO, OBJECT_HEADER_HANDLE_INFO and OBJECT_HEADER_QUOTA_INFO respectively. These xxxInfoOffset fields contain a number (between 0 and 265) that determines the offset of the corresponding OBJECT_HEADER_xxx_INFO structure from the start of the OBJECT_HEADER structure. If any of these fields are zero the object manager assumes that the corresponding header does not exist. There is another optional header, i.e. OBJECT_HEADER_CREATOR_INFO, whose presence is controlled by a bit in the OBJECT_HEADER->Flag field instead of the xxxInfoOffset fields. The following figure shows the layout of the optional object headers and their offsets:

 

FIG#2
Figure 2 : Optional Object Headers in older Windows Versions

 

Since all of the above optional headers OBJECT_HEADER_NAME_INFO, OBJECT_HEADER_HANDLE_INFO, OBJECT_HEADER_QUOTA_INFO and OBJECT_HEADER_CREATOR_INFO are fixed in size and they are always stored in a specific order, there is little need to store offsets to these structures. The object manager simply needs to know which ones are present and it can use this information to compute their respective offsets from the start of the OBJECT_HEADER.

So in Windows 7, the 3 xxInfoOffsets fields have been replaced with a single field OBJECT_HEADER->InfoMask, which contains one bit for each optional object header and indicates its presence. In addition to this a new optional header OBJECT_HEADER_PROCESS_INFO has been introduced in Windows 7. The following table shows the bits in the OBJECT_HEADER->InfoMask, the structures they represent, and the size of these structures that are used to compute the offsets:

BitTypeSize (on X86)
0x01nt!_OBJECT_HEADER_CREATOR_INFO0x10
0x02nt!_OBJECT_HEADER_NAME_INFO0x10
0x04nt!_OBJECT_HEADER_HANDLE_INFO0x08
0x08nt!_OBJECT_HEADER_QUOTA_INFO0x10
0x10nt!_OBJECT_HEADER_PROCESS_INFO0x08

 

The order in which the optional object headers are stored in Windows 7 is shown in the following figure:

FIG#3
Figure 3 : Order of Optional Object Headers in Windows 7

 

Depending on the number and position of the bits set in OBJECT_HEADER->InfoMask a number is calculated which serves as an index into the ObpInfoMaskToOffset[] array. The elements of this array contain the offset of the desired optional header taking into consideration presence of the other optional headers. This array is large enough to accommodate the offsets for all the 25possibilites based on the bits in OBJECT_HEADER->InfoMask.

The pseudo code for retrieving the offset of the desired optional object header for a particular object is Offset = ObpInfoMaskToOffset[OBJECT_HEADER->InfoMask & (DesiredHeaderBit | (DesiredHeaderBit-1))].

For example, if a certain object has the creator, handle and process info header structures, its OBJECT_HEADER->InfoMask value would be 0x15. If the object manager desires to compute the offset to the handle info header structure for this object, the DesiredHeaderBit would be 0x04. Based on the above pseudo code, the computed offset to the handle info header structure would be 0x18 as shown by the following command:

kd> ?? ((unsigned char *)@@masm(nt!ObpInfoMaskToOffset))[0x15 & (0x04 | (0x04-1))]
unsigned char 0x18 ''

When changing the object header in Windows 7 Microsoft ensured that they maintained backward compatibility to the extent that the OBJECT_HEADER size did not change and the OBJECT_HEADER still contained all the information that the previous versions of the structure did. The document covered the areas of functionality that were affected by the changes to the object header and described the new functionality that was brought about by the changes in the header.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当将Microsoft Speech Object Library发布到Windows 7服务器时,可能会遇到以下几种报错情况: 1. 缺少依赖项:确保Windows 7服务器上安装了Microsoft Speech Object Library的所有依赖项。这些依赖项可能包括.NET Framework、Visual Studio运行时组件等。可以通过在服务器上运行Windows更新程序来确保系统及其组件是最新的。 2. 版本不兼容:请确保使用的Microsoft Speech Object Library版本与Windows 7服务器的操作系统版本兼容。某些较新的版本可能不支持旧的操作系统。可以尝试使用较旧版本的Speech Object Library或升级服务器的操作系统。 3. 权限问题:检查发布目录的文件和文件夹权限是否允许对其进行写入和执行操作。对于Microsoft Speech Object Library的正常运行,确保运行该库的应用程序具有足够的权限以访问和操作相关资源。 4. 配置问题:检查服务器的配置是否符合Microsoft Speech Object Library的要求。例如,确保服务器的语言设置与Speech Object Library所需的语言设置匹配。 5. 损坏的安装文件:如果之前尝试过将Speech Object Library发布到服务器,可能存在安装文件损坏的情况。请尝试重新下载和安装Speech Object Library。 总之,解决该问题的关键是在确保服务器环境满足Speech Object Library要求的前提下,仔细检查和排除可能导致报错的各种问题。根据实际错误信息和报错内容,进一步分析和调试问题可能有助于找到更精准的解决方案。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值