Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lab7.doc
Скачиваний:
4
Добавлен:
12.11.2019
Размер:
286.72 Кб
Скачать

3. Защита объектов ядра

Объекты ядра можно защитить дескриптором защиты (security descriptor), который описывает, кто создал объект и кто имеет права на доступ к нему. Дескрипторы защиты обычно используют при написании серверных приложений; создавая клиентское приложение, можно игнорировать это свойство объектов ядра.

Замечание: В Windows 98 дескрипторы защиты отсутствуют, так как она не предназначена для выполнения серверных приложений. Тем не менее, при разработке приложений необходимо знать о тонкостях, связанных с защитой, и реализовать соответствующие механизмы, чтобы приложение корректно работало и в Windows 2000.

Почти все функции, создающие объекты ядра, принимают указатель на структуру SECURITY_ATTRIBUTES как аргумент, например:

HANDLE CreateFileMapping(

   HANDLE hFile,

   PSECURITY_ATTRIBUTES psa, 

   DWORD flProtect,

   DWORD dwMaximumSizeHigh, 

   DWORD dwMaximumSizeLow,    PCTSTR pszName);

Большинство приложений вместо этого аргумента передает NULL и создает объект с защитой по умолчанию. Такая защита подразумевает, что создатель объекта и любой член группы администраторов получают к нему полный доступ, а все прочие к объекту не допускаются. Однако можно создать и инициализировать структуру SECURITY_ATTRIBUTES, а затем передать ее адрес. Она выглядит так:

typedef struct _SECURITY_ATTRIBUTES {

   DWORD nLength;

   LPVOID lpSecurityDescriptor;

   BOOL bInheritHandle;

} SECURITY_ATTRIBUTES; 

Хотя структура называется SECURITY__ATTRIBUTES, лишь один ее элемент имеет отношение к защите — lpSecuntyDescnptor. Если надо ограничить доступ к созданному объекту ядра, создайте дескриптор защиты и инициализируйте структуру SECURITY_ATTRIBUTES следующим образом:

SECURITY_ATTRIBUTES sa;

sa.nLength = sizeof(sa); // используется для выяснения версий sa.lpSecuntyDescriptor = pSD, // адрес инициализированной SD sa.bInheritHandle = FALSE; /* используется при наследовании объектов ядра дочерними процессами TRUE – объект ядра наследуется, FALSE – не наследуется*/

HANDLE hFileMapping = CreateFileMapping(INVALID_HANDLE_VALUE, &sa, PAGE_READWRITE, 0, 1024, "MyFileMapping");

Желая получить доступ к существующему объекту ядра (вместо того чтобы создавать новый), необходимо указать, какие операции будут проводить над объектом. Например, если надо было бы считывать данные из существующей проекции файла, то необходимо осуществить вызов функции OpenFileMapping таким образом:

HANDLE hFileMapping = OpenFileMapping(FILE_MAP_READ, FALSE, "MyFileMapping");

Приложение передавая FILE_MAPREAD первым параметром в функцию OpenFileMapping, сообщает, что, как только мне предоставят доступ к проекции файла, оно будет считывать из нее данные. Функция OpenFileMapping, прежде чем вернуть действительный описатель, проверяет тип защиты объекта. Если пользователя, как зарегистрировавшегося в системе, допускают к существующему объекту ядра «проекция файла», OpenFileMapping возвращает действительный описатель. Но если пользователю отказывают в доступе, OpenFileMapping возвращает NULL, а вызов GetLastError дает код ошибки 5 (или ERROR_ACCESS_DENIED). В основной массе приложений защиту не используют.

Замечание: Хотя в большинстве приложений нет нужды беспокоиться о защите, многие функции Windows требуют, чтобы им передавалась информация о нужном уровне защиты. Некоторые приложения, написанные для Windows 98, в Windows 2000 толком не работают из-за того, что при их реализации не было уделено должного внимания защите. Представьте, что при запуске приложение считывает данные из какого-то раздела реестра. Чтобы делать это корректно, оно должно вызывать функцию RegOpenKeyEx, передавая значение KEY_QUERY_VALUE, которое разрешает операцию чтения в указанном разделе. Однако многие приложения для Windows 98 создавались без учета специфики Windows 2000. Поскольку Windows 98 не защищает свой реестр, разработчики часто вызывали RegQpenKeyEx со значением KEY_ALL_ACCESS. Так проще и не надо ломать голову над том, какой уровень доступа требуется на самом деле. Но проблема в том, что раздел реестра может быть доступен для чтения и блокирован для записи. В Windows 2000 вызов RegOpenKeyEx со значением KEY_ALL_ACCESS заканчивается неудачно, и без соответствующего контроля ошибок приложение может повести себя совершенно непредсказуемо. Если бы разработчик хоть немного подумал о защите и поменял значение KEY_ALL_ACCESS на KEY_QUERY_VALUE, его продукт мог бы работать в обеих операционных системах. Пренебрежение флагами, определяющими уровень доступа, — одна из самых крупных ошибок, совершаемых разработчиками. Правильное их использование позволило бы легко перенести многие приложения Windows 98 в Windows 2000.

Кроме объектов ядра программа может использовать объекты других типов — меню, окна, курсоры мыши, кисти и шрифты. Они относятся к объектам User или GDI Новичок в программировании для Windows может запутаться, пытаясь отличить объекты User или GDI от объектов ядра. Выяснить, не принадлежит ли объект ядру, проще всего так проанализировать функцию, создающую объект. Практически у всех функций, создающих объекты ядра, есть параметр, позволяющий указать атрибуты защиты, — как у CreateFileMapping.

В то же время у функций, создающих объекты User или GDI, нет параметра типа PSECURITY_ATTRIBUTES, и пример тому — функция CreateIcon.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]