Об`єкти типу
Заголовки об`єктів містять дані, загальні для всіх об`єктів, які можуть набувати різних значень для кожного екземпляра об`єкта. Наприклад, у кожного об`єкта є унікальне ім`я і може бути унікальний дескриптор безпеки.
Але об`єкти також містять деякі дані, які залишаються постійними для всіх об`єктів конкретного типу. Наприклад, при відкритті дескриптора об`єкта певного типу можна вибрати права доступу з набору, властивого цьому типу об`єктів. Виконуюча система надає для об`єктів типу потік крім всіх інших доступ до завершення і припинення, а для об`єктів типу файл доступ для читання, записи, додавання і видалення.
Ще одним прикладом атрибута, властивого певному типу об`єктів, є синхронізація, яка незабаром буде розглянута.
Для економії пам`яті диспетчер об`єктів зберігає ці статичні атрибути, властиві об`єктам певного типу, одного разу при створенні нового об`єкта типу. Для запису цих даних він використовує свій власний об`єкт, так званий об`єкт типу. Як показано на малюнку, якщо встановлено прапор налагодження для відстеження об`єктів (що розглядається далі в розділі «Глобальні прапори Windows»), об`єкт типу також пов`язує разом всі об`єкти одного і того ж типу (в даному випадку типу процес), дозволяючи диспетчеру об`єктів знаходити ці об`єкти і вести їх підрахунок, якщо це необхідно. Ця функція використовує можливість раніше розглянутого підзаголовка з інформацією про творця.
З призначеного для користувача режиму працювати з об`єктами типу не можна, оскільки диспетчер об`єктів не надає для них ніяких служб. Проте деякі, які визначаються ними атрибути, видимі за допомогою деяких власних служб операційної системи і процедур Windows API. Інформація, що зберігається в ініціалізатор типу, описана в таблиці.
Поля ініціалізаторів типу
Атрибут | призначення |
---|---|
Type name (Ім`я типу) | Ім`я об`єктів даного типу ( «процес», «подія», «порт» і т. Д.) |
Pool type (Тип пулу) | Показує, чи може об`єктів даного типу виділятися вивантажувати або невивантажуваного пам`ять |
Default quota charges (Квота за замовчуванням) | Значення пулів вивантажується і невивантажуваного пам`яті, складові за замовчуванням квоту процесу. |
Valid access mask (Діюча маска доступу) | Види доступу, які потік може запросити при відкритті дескриптора об`єкта даного типу ( «читання», «запис», «завершення», «припинення» і т. Д.) |
Generic access rights mapping (Відображення загальних прав доступу) | Відображення чотирьох загальних прав доступу (для читання, записи, виконання і всіх прав) на права доступу, властиві конкретному типу |
Flags (Прапори) | Вказують на те, що об`єкти не повинні мати імен (наприклад, у випадку з об`єктами типу «процес»), що в їхніх іменах враховується регістр символів, що вони вимагають наявність дескриптора безпеки, що вони підтримують зворотні виклики, фільтровані об`єктами, і повинна Чи підтримуватися база даних дескрипторів (підзаголовок інформації про дескрипторах) і (або) взаємозалежність списку типів (підзаголовок інформації про творця). Прапор use default object також визначає поведінку показаного далі в цій таблиці поля default object |
Object type code (Код об`єкта типу) | Використовується для опису того, що з себе представляє тип об`єкта (на відміну від порівняння з відомим значенням імені). Для файлових об`єктів значення цього поля встановлюється в 1, для об`єктів синхронізації - в 2 і для об`єктів потоків - в 4. Це поле також використовується ALPC для зберігання інформації про атрибут дескриптора, пов`язаної з повідомленням |
Invalid attributes (Неприпустимі атрибути) | Задає прапори атрибутів об`єкта, неприпустимі для цього типу об`єкта |
Default object (Об`єкт за замовчуванням) | Визначає внутрішнє подія диспетчера об`єктів, яке повинно використовуватися при очікуванні даного об`єкта, якщо цього вимагає творець об`єкта типу. Слід врахувати, що такі об`єкти, як File і ALPC-порт, вже містять свій вбудований диспетчер об`єктів-в такому випадку це поле є зміщенням в тілі об`єкта. Наприклад, подія всередині структури FILE_OBJECT вбудовано в поле під назвою Event |
Methods (Методи) | Одна або кілька процедур, що викликаються диспетчером об`єктів автоматично в певні моменти життя об`єкта |
Перегляд заголовків об`єктів і об`єктів типу.
Структуру даних об`єкта типу «процес» можна побачити в отладчике ядра, попередньо идентифицировав цей об`єкт за допомогою команди! Process:
lkd>! process 0 0
**** NT ACTIVE PROCESS DUMP ****
PROCESS fffffa800279cae0
SessionId: none Cid: 0004 Peb: 00000000 ParentCid 0000
DirBase: 00187000 ObjectTable: fffff8a000001920 HandleCount: 541.
Image: System
Виконайте команду! Object з адресою об`єкта «процес» як аргумент:
lkd>! object fffffa800279cae0
Object: fffffa800279cae0 Type: (fffffa8002755b60) Process
ObjectHeader: fffffa800279cab0 (new version)
HandleCount: 3 PointerCount: 172 3172
Врахуйте, що на 32-розрядної версії Windows заголовок об`єкта починається з 0x18 (24 в десятковому форматі) байт, що передують тілу об`єкта, а на 64-розрядної версії Windows він починається з 0x30 (48 в десятковому форматі) байт, що передують тілу, тобто з розміру самого заголовка об`єкта. Переглянути заголовок об`єкта можна за допомогою наступної команди:
lkd> dt nt! _OBJECT_HEADER fffffa800279cab0
+0x000 PointerCount: 172
+0x008 HandleCount: 33
+0x008 NextToFree: 0x000000000x00000000`00000003
+0x010 Lock: _EX_PUSH_LOCK
+0x018 TypeIndex: 0x7 ``
+0x019 TraceFlags: 0 ``
+0x01a InfoMask: 0 ``
+0x01b Flags: 0x2 ``
+0x020 ObjectCreateInfo: 0xfffff800`01c53a80 _OBJECT_CREATE_INFORMATION
+0x020 QuotaBlockCharged: 0xfffff800`01c53a80
+0x028 SecurityDescriptor: 0xfffff8a0`00004b29
+0x030 Body: _QUAD
Тепер подивимося на структуру даних об`єкта типу, отримавши його адресу з таблиці ObTypeIndexTable, вказаний у записі, пов`язаної з полем TypeIndex структури даних заголовка об`єкта:
lkd> ?? ((Nt! _OBJECT_TYPE **) @@ (nt! ObTypeIndexTable)) [((nt! _OBJECT_
HEADER *) 0xfffffa800279cab0) -> TypeIndex]
struct _OBJECT_TYPE * 0xfffffa80`02755b60
+0x000 TypeList: _LIST_ENTRY [0xfffffa80`02755b60 - 0xfffffa80`02755b60
]
+0x010 Name: _UNICODE_STRING "Process"
+0x020 DefaultObject: (null)
+0x028 Index: 0x70x7 ``
+0x02c TotalNumberOfObjects: 0x380x38
+0x030 TotalNumberOfHandles: 0x1320x132
+0x034 HighWaterNumberOfObjects: 0x3d
+0x038 HighWaterNumberOfHandles: 0x13c
+0x040 TypeInfo: _OBJECT_TYPE_INITIALIZER
+0x0b0 TypeLock: _EX_PUSH_LOCK
+0x0b8 Key: 0x636f7250
+0x0c0 CallbackList: _LIST_ENTRY [0xfffffa80`02755c20 - 0xfffffa80`02755c20]
У виведеної інформації показано, що структура об`єкта типу включає ім`я об`єкта типу, в ній відстежується загальна кількість активних об`єктів цього типу і пікову кількість дескрипторів і об`єктів даного типу. В поле CallbackList також відстежується фільтрація зворотних викликів диспетчера об`єктів, пов`язана з цим об`єктом типу.
В поле TypeInfo зберігається покажчик на структуру даних, в якій зберігаються загальні для всіх об`єктів цього типу атрибути, а також покажчики на методи об`єкта типу:
Відео: Величезний об`єкт типу - ШАТЛ, на місяці
lkd> ?? ((Nt! _OBJECT_TYPE *) 0xfffffa8002755b60) -> TypeInfo *) 0xfffffa8002755b60) -> TypeInfo
+0x000 Length: 0x70
+0x002 ObjectTypeFlags: 0x4a `J`
+0x002 CaseInsensitive: 0y0
+0x002 UnnamedObjectsOnly: 0y1
Відео: виріб в садок "Об`єкт типу Яйце"
+0x002 UseDefaultObject: 0y0
+0x002 SecurityRequired: 0y1
+0x002 MaintainHandleCount: 0y0
+0x002 MaintainTypeList: 0y0
+0x002 SupportsObjectCallbacks: 0y1
+0x004 ObjectTypeCode: 0
+0x008 InvalidAttributes: 0xb0
+0x00c GenericMapping: _GENERIC_MAPPING
+0x01c ValidAccessMask: 0x1fffff
+0x020 RetainAccess: 0x101000
+0x024 PoolType: 0 (NonPagedPool)
+0x028 DefaultPagedPoolCharge: 0x1000
+0x02c DefaultNonPagedPoolCharge: 0x528
+0x030 DumpProcedure: (null)
Відео: Створення точкового об`єкта типу "векторний знак"
+0x038 OpenProcedure: 0xfffff800`01d98d58 long nt! PspProcessOpen + 0
+0x040 CloseProcedure: 0xfffff800`01d833c4 void nt! PspProcessClose + 0
+0x048 DeleteProcedure: 0xfffff800`01d83090 void nt! PspProcessDelete + 0
+0x050 ParseProcedure: (null)
+0x058 SecurityProcedure: 0xfffff800`01d8bb50 long nt! SeDefaultObjectMethod + 0
+0x060 QueryNameProcedure: (null)
+0x068 OkayToCloseProcedure: (null)
Синхронізація, що є одним з атрибутів, видимих додатками Windows, відноситься до здатності потоків синхронізувати їх виконання шляхом очікування переходу об`єкта з одного стану в інший. Потік може синхронізуватися з об`єктами виконуваного завдання, процесу, потоку, файлу, семафора, мьютекса і таймера. Всі інші об`єкти виконуючої системи синхронізацію не підтримують. Здатність об`єкта підтримувати синхронізацію заснована на трьох можливостях:
- Об`єкт виконує системи є оболонкою для об`єкта-диспетчера і містить заголовок диспетчера.
- Творець об`єкта типу вимагає об`єкт за умовчанням, і диспетчер об`єктів надає такий об`єкт.
- Об`єкт виконує системи має вбудований диспетчер об`єктів, такий як подія, де-небудь всередині тіла об`єкта, і власник об`єкта надає зміщення на нього диспетчеру об`єктів при реєстрації об`єкта типу.