分享

UNDOCUMENTED WINDOWS 2000 SECRETS Ch7 读书笔记

 昵称12942125 2013-07-01
_OBJECT_HEADER和可选头
#define OB_FLAG_CREATE_INFO 0x01 //
#define OB_FLAG_KERNEL_MODE 0x02 // created by kernel
#define OB_FLAG_CREATOR_INFO 0x04 // has OBJECT_CREATOR_INFO
#define OB_FLAG_EXCLUSIVE 0x08 // OBJ_EXCLUSIVE
#define OB_FLAG_PERMANENT 0x10 // OBJ_PERMANENT
#define OB_FLAG_SECURITY 0x20 // has security descriptor
#define OB_FLAG_SINGLE_PROCESS 0x40 // no HandleDBList

typedef struct _OBJECT_HEADER
{
/*000*/ DWORD PointerCount; // number of references
/*004*/ DWORD HandleCount; // number of open handles,在XPSP2上+004处是共用体(NextToFree       : Ptr32 Void)
/*008*/ POBJECT_TYPE ObjectType; //后面会详细讲解
/*00C*/ BYTE NameOffset; // (PBYTE)&_OBJECT_HEADER -  NameOffset 指向_OBJECT_NAME头,我怀疑OB_FLAG_CREATE_INFO决定此头是否存在
/*00D*/ BYTE HandleDBOffset; // (PBYTE)&_OBJECT_HEADER -  HandleDBOffset指向_OBJECT_HANDLE_DB头,
/*00E*/ BYTE QuotaChargesOffset; //(PBYTE)&_OBJECT_HEADER -  指向_OBJECT_QUOTA_CHARGES头
/*00F*/ BYTE ObjectFlags; // OB_FLAG_*, 注意OBJECT_CREATOR_INFO紧挨着OBJECT_HEADER
/*010*/ union
{ // OB_FLAG_CREATE_INFO ? ObjectCreateInfo : QuotaBlock
/*010*/ PQUOTA_BLOCK QuotaBlock;
/*010*/ POBJECT_CREATE_INFO ObjectCreateInfo;
/*014*/ };
/*014*/ PSECURITY_DESCRIPTOR SecurityDescriptor;
/*018*/ }
OBJECT_HEADER,
* POBJECT_HEADER,
**PPOBJECT_HEADER;

_OBJECT_NAME

typedef struct _OBJECT_NAME
{
/*000*/ POBJECT_DIRECTORY Directory;
/*004*/ UNICODE_STRING Name;
/*00C*/ DWORD Reserved;
/*010*/ }
OBJECT_NAME,
* POBJECT_NAME,
**PPOBJECT_NAME;
这里的OBJECT_DIRECTORY与文件系统的目录是相似的,但不是同一个东西,之后会讲到。

_OBJECT_HANDLE_DB

typedef struct _OBJECT_HANDLE_DB
{
/*000*/ union
{
/*000*/ struct _EPROCESS *Process;
/*000*/ struct _OBJECT_HANDLE_DB_LIST *HandleDBList;
/*004*/ };
/*004*/ DWORD HandleCount;
/*008*/ }
OBJECT_HANDLE_DB,
* POBJECT_HANDLE_DB,
**PPOBJECT_HANDLE_DB;

typedef struct _OBJECT_HANDLE_DB_LIST
{
/*000*/ DWORD Count;
/*004*/ OBJECT_HANDLE_DB Entries [];
/*???*/ }
OBJECT_HANDLE_DB_LIST,
* POBJECT_HANDLE_DB_LIST,
**PPOBJECT_HANDLE_DB_LIST;

_OBJECT_QUOTA_CHARGES

typedef struct _OBJECT_QUOTA_CHARGES
{
/*000*/ DWORD PagedPoolCharge;
/*004*/ DWORD NonPagedPoolCharge;
/*008*/ DWORD SecurityCharge;
/*00C*/ DWORD Reserved;
/*010*/ }
OBJECT_QUOTA_CHARGES,
* POBJECT_QUOTA_CHARGES,
**PPOBJECT_QUOTA_CHARGES;
应该是指该对象被配给了多少资源,至于它实际使用多少,后面会讲解。

_OBJECT_CREATOR_INFO

typedef struct _OBJECT_CREATOR_INFO
{
/*000*/ LIST_ENTRY ObjectList; // OBJECT_CREATOR_INFO
/*008*/ HANDLE UniqueProcessId;
/*00C*/ WORD Reserved1;
/*00E*/ WORD Reserved2;
/*010*/ }
OBJECT_CREATOR_INFO,
* POBJECT_CREATOR_INFO,
**PPOBJECT_CREATOR_INFO;

_QUOTA_BLOCK

typedef struct _QUOTA_BLOCK
{
/*000*/ DWORD Flags;
/*004*/ DWORD ChargeCount;
/*008*/ DWORD PeakPoolUsage [2]; // NonPagedPool, PagedPool
/*010*/ DWORD PoolUsage [2]; // NonPagedPool, PagedPool
/*018*/ DWORD PoolQuota [2]; // NonPagedPool, PagedPool
/*020*/ }
QUOTA_BLOCK,
* PQUOTA_BLOCK,
**PPQUOTA_BLOCK;
_OBJECT_DIRECTORY
#define OBJECT_HASH_TABLE_SIZE 37
typedef struct _OBJECT_DIRECTORY
{
/*000*/ POBJECT_DIRECTORY_ENTRY HashTable [OBJECT_HASH_TABLE_SIZE];
/*094*/ POBJECT_DIRECTORY_ENTRY CurrentEntry;
/*098*/ BOOLEAN CurrentEntryValid;
/*099*/ BYTE Reserved1;
/*09A*/ WORD Reserved2;
/*09C*/ DWORD Reserved3;
/*0A0*/ }
OBJECT_DIRECTORY,
* POBJECT_DIRECTORY,
**PPOBJECT_DIRECTORY;

typedef struct _OBJECT_DIRECTORY_ENTRY
{
/*000*/ struct _OBJECT_DIRECTORY_ENTRY *NextEntry;
/*004*/ POBJECT Object;
/*008*/ }
OBJECT_DIRECTORY_ENTRY,
* POBJECT_DIRECTORY_ENTRY,
**PPOBJECT_DIRECTORY_ENTRY;

可见对象目录是一个树形结构(根节点应该是'/'),不过每个目录节点最多只能有OBJECT_HASH_TABLE_SIZE个入口
对象类型

对象类型本身也是一种对象:_OBJECT_TYPE,不过这种对象在系统中最多存在一个实例。
typedef struct _OBJECT_TYPE
{
/*000*/ ERESOURCE Lock;
/*038*/ LIST_ENTRY ObjectListHead; // OBJECT_CREATOR_INFO
/*040*/ UNICODE_STRING ObjectTypeName; // see above
/*048*/ union
{
/*048*/ PVOID DefaultObject; // ObpDefaultObject
/*048*/ DWORD Code; // File: 5C, WaitablePort: A0
};
/*04C*/ DWORD ObjectTypeIndex; // OB_TYPE_INDEX_*
/*050*/ DWORD ObjectCount;
/*054*/ DWORD HandleCount;//类型对象也可以被打开
/*058*/ DWORD PeakObjectCount;
/*05C*/ DWORD PeakHandleCount;
/*060*/ OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
/*0AC*/ DWORD ObjectTypeTag; // OB_TYPE_TAG_*,是ObjectTypeName的一个简写
/*0B0*/ }

对象句柄
typedef struct _HANDLE_TABLE
{
/*000*/ DWORD Reserved;
/*004*/ DWORD HandleCount;
/*008*/ PHANDLE_LAYER1 Layer1;
/*00C*/ struct _EPROCESS *Process; // passed to PsChargePoolQuota ()
/*010*/ HANDLE UniqueProcessId;
/*014*/ DWORD NextEntry;
/*018*/ DWORD TotalEntries;
/*01C*/ ERESOURCE HandleTableLock;
/*054*/ LIST_ENTRY HandleTableList;
/*05C*/ KEVENT Event;
/*06C*/ }
HANDLE_TABLE,
* PHANDLE_TABLE,
**PPHANDLE_TABLE;

typedef struct _HANDLE_LAYER1
{
/*000*/ PHANDLE_LAYER2 Layer2 [HANDLE_LAYER_SIZE]; // bits 18 to 25 of HANDLE
/*400*/ }
HANDLE_LAYER1,
* PHANDLE_LAYER1,
**PPHANDLE_LAYER1;

typedef struct _HANDLE_LAYER2
{
/*000*/ PHANDLE_LAYER3 Layer3 [HANDLE_LAYER_SIZE]; // bits 10 to 17 of HANDLE
/*400*/ }
HANDLE_LAYER2,
* PHANDLE_LAYER2,
**PPHANDLE_LAYER2;

typedef struct _HANDLE_LAYER3
{
/*000*/ HANDLE_ENTRY Entries [HANDLE_LAYER_SIZE]; // bits 2 to 9 of HANDLE,
/*800*/ }
HANDLE_LAYER3,
* PHANDLE_LAYER3,
**PPHANDLE_LAYER3;

系统用HANDLE_TABLE->HandleTableList将句柄表链接起来,属于同一个进程的表的UniqueProcessId相同。每个进程可以有多个句柄表,但通常一个表就足够用了,一个句柄表用一个内存页就可容纳(SIZOF(_HANDLE_LAYER3)+SIZEOF(_HANDLE_LAYER2)+SIZEOF(_HANDLE_LAYER1)=4K);
句柄的高位BITS和0,1位无效。
OBJECT_BODY
我们通常说的对象实际指的是OBJECT_BODY,有Dispatcher object(派遣对象),IO对象和杂项对象。

Dispatcher object

Dispatcher objects(派遣对象) reside on the lowest system level and share a common data structure called DISPATCHER_HEADER at the
beginning of their object bodies. This header contains an object type ID and the length of the object body in 32-bit DWORD units. The names of
all dispatcher object structures start with a K for “kernel.”(不是所有以K开头的对象都是派遣对象)

The presence of a DISPATCHER_HEADER makes an object “waitable.” This means
that the object can be passed to the synchronization functions
KeWaitForSingleObject()。这个结构在2000和XPSP2中的定义是一样的:
nt!_DISPATCHER_HEADER
   +0x000 Type             : UChar
   +0x001 Absolute         : UChar
   +0x002 Size             : UChar
   +0x003 Inserted         : UChar
   +0x004 SignalState      : Int4B
   +0x008 WaitListHead     : _LIST_ENTRY

以下是派遣对象的类型和相关结构:
0 DISP_TYPE_NOTIFICATION_EVENT KEVENT ntddk.h
1 DISP_TYPE_SYNCHRONIZATION_EVENT KEVENT ntddk.h
2 DISP_TYPE_MUTANT KMUTANT, KMUTEX ntddk.h
3 DISP_TYPE_PROCESS KPROCESS w2k_def.h
4 DISP_TYPE_QUEUE KQUEUE w2k_def.h
...
I/O Object
以下是I/O对象的类型和相关结构:
...
4 IO_TYPE_DRIVER DRIVER_OBJECT ntddk.h
5 IO_TYPE_FILE FILE_OBJECT ntddk.h
6 IO_TYPE_IRP IRP ntddk.h
...




    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多