Объекты ядра используются системой и нашими приложениями для управления множеством разных ресурсов: процессами, потоками, файлами и т.д.
Что такое объект ядра. Объекты ядра используются системой и нашими приложениями для управления множеством разных ресурсов: процессами, потоками, файлами и т.д.
Система позволяет создавать и оперировать с несколькими типами таких объектов, в том числе: маркерами доступа (access token objects), файлами (file objects), проекциями файлов (file-mapping objects), портами завершения ввода вывода (I/O completion port objects), заданиями (jobs), почтовыми ящиками (mailslot objects), мьютексами (mutex objects), каналами (pipe objects), процессами (thread objects) и ожидаемыми таймерами (waitable timer objects).
Эти объекты создаются Windows-функциями. Например, CreateFileMapping заставляет систему сформировать объект «проекция файла».
Каждый объект ядра – на самом деле просто блок памяти, выделенный ядром и доступный только ему.
Блок представляет собой структуру данных, в элементах которой содержится информация об объекте. Некоторые элементы (дескриптор защиты, счетчик числа пользователей и др.) присутствуют во всех объектах, но большая их часть специфична для объектов конкретного типа. Например, у объекта «процесс» есть идентификатор, базовый приоритет и код завершения, а у объекта «файл» - смещение в байтах, режим разделения и режим открытия.
Приложение не может напрямую обращаться к объектам ядра читать и изменять их содержимое.
Для взаимодействия с объектами ядра у Windows предусмотрен набор функций, обрабатывающих структуры объектов ядра по строго определенным правилам. Когда мы создаем объект ядра, функция возвращает описатель идентифицирующий созданный объект (HANDLE). Все операции с текущим объектом ядра возможны только при указании этого описателя управляющей функции.
Для большей защиты, описатели уникальны только внутри конкретного процесса.
Поэтому, передавая по межпроцессорной связи описатель объекта другому процессу, используя описатель в другом процессе мы получим ошибку. Это ограничение можно обойти – но об этом позже. Учет пользователей объектов ядра.
Объекты ядра принадлежат ядру, а не процессу. Это говорит о том, что завершая работу с процессом, мы не обязательно разрушаем объект ядра. В большинстве случаев объект разрушается, но если созданный вами объект ядра используется другим процессом, ядро запретит разрушение объекта до тех пор, пока от него не откажется последний пользователь.
В каждом объекте, как уже говорилось, есть счетчик пользователей объектом. В момент создания, счетчику присваивается значение 1. Соответственно, при обращении к нему другого процесса, счетчик увеличивается на 1. Когда пользовательский процесс завершается, счетчик уменьшается. Система удаляет объект ядра, когда счетчик обнуляется.
Защита объектов ядра
Почти во всех функциях, создающих объекты, есть параметр SECURITY_ATTRIBUTES.
Он необходим для защиты объектов ядра от несанкционированного доступа. Чаще всего, это свойство используют в серверных приложениях, в клиентских приложениях этот объект можно игнорировать. Если вы пишите для win98 то там такое свойство отсутствует, но для корректной работы таких приложений в Win2000 и выше, стоит помнить о работе с соответствующими механизмами.
При передаче в таком атрибуте NULL большинство объектов будут созданы со стандартными свойствами защиты, когда к объекту допускаются: создатель и администраторская группа. Остальные игнорируются.
Защита объектов ядра. Продолжая тему защиты объектов ядра приведу описание SECURITY_ATTRIBUTES.
typedef struct _SECURITY_ATTRIBUTES {
DWORD nLength; LPVOID lpSecurityDescriptor; BOOL bInheritTable; } SECURITY_ATTRIBUTES; Конкретно в этой структуре за защиту отвечает lpSecurityDescriptor. bInheritTable не относится к защите самого объекта, а nLength содержит длину sizeof(SECURITY_ATTRIBUTES), которую необходимо записать в элемент при инициализации…
Я сам редко использовал дополнительные свойства защиты объекта ядра. Обычно всегда хватает защиты по умолчанию, выставляемой системой при передаче NULL в этот параметр.
При передаче NULL системные параметры защиты разрешают доступ к объекту только членам группы администраторов.
Остальные к нему не допускаются. Это утверждает Рихтер. Честно скажу, я никогда не видел, что бы нельзя было добраться до собственного потока программе которая запущена обычным пользователем.
Резюмируя, каждый процесс создающий объект ядра имеет над ним безраздельную власть и разрешает по умолчанию доступ программам с администраторским уровнем доступа. Все это справедливо в WinNT/2000/XP – говоря о линейке 9х это все получается ерундой, так как есть вполне легальный доступ к любым ресурсам в обход запретов ОС.
Упомяну о том, что для отличия объекта ядра, от других объектов, создаваемых функциями Create…(), обратите внимание на наличие параметра защиты в вызове функции. В создании объектов ядра этот параметр всегда присутствует. Таблица описателей ядра.
Полностью описание таблицы объектов ядра можно найти у “Рихтера”, и так как он говорит, что описания полного содержания таблицы нет, стоит в это поверить.
Создание и уничтожение объектов ядра.
Для создания объекта ядра разных типов используются функции типа
Create…(); Возвращаемое значение имеет тип HANDLE.
Типовая процедура создания выглядит так:
HANDLE hObj = Create…()
If (hObj == INVALID_HANDLE_VALUE)
{ //ошибка } // действия
Уничтожение объекта
CloseHandle(hObj); Либо
HANDLE hObj = Create…() If (hObj ==NULL)
{ //ошибка } Подробности смотрите в описании самой функции создания объекта конкретного типа.
Сам описатель (HANDLE) при успешном создании либо является индексом в таблице объектов конкретного процесса, вызывающего его создание, либо, смещением от начала такой таблицы, в байтах. Последнее, по утверждению Рихтера, касается Windwos2000.
Закрытие объекта ядра достаточно условно, такая функция, как я уже говорил, уменьшает счетчик пользователей у такого объекта, после чего уничтожает сам объект уже система, в случае если пользователей объекта больше не осталось.
Сама функция удаляет из таблицы описателей, принадлежащей вашему процессу, соответствующую запись, описатель становится недействительным для текущего процесса. Если вы забыли вызвать функцию CloseHandle или в результате ее вызова произошла ошибка, тогда происходит потеря объекта и потеря памяти (memory leak).
Однако в Windows при уничтожении процесса, уничтожаются и все привязанные к нему ресурсы. Опасность в многократной потере таких ресурсов, например при многократном создании и удалении виртуальной памяти. Создание и не уничтожение потоков и т.д. В этом случае потери памяти будут накапливаться в процессе. Гром
Этот адрес e-mail защищен от спам-ботов. Чтобы увидеть его, у Вас должен быть включен Java-Script
|