Pages Menu
Categories Menu

Опубликовано | Нет комментариев

Таблицы дескрипторов служб

Главная таблица, используемая по умолчанию, KeServiceDescriptorTable, определяет основные системные службы исполняющей системы, реализованные в файле Ntosrknl.exe. Другая таблица, KeServiceDescriptorTableShadow, включает Windows-службы USER и GDI, реализованные в той части подсистемы Windows, которая работает в режиме ядра, Win32k.sys.

На 32-разрядной версии Windows и на версии IA64, где поток Windows сразу же вызывает Windows-службу USER или службу GDI, адрес таблицы системных служб потока изменяется, чтобы указать на таблицу, которая включает Windows-службы USER и GDI.

Функция KeAddSystemServiceTable позволяет Win32k.sys добавлять таблицу системных служб.

Инструкции диспетчера системных служб для служб исполняющей системы Windows находятся в системной библиотеке Ntdll.dll. Для реализации своих документированных функций DLL-библиотеки подсистем вызывают функции в Ntdll.

Исключение составляют функции Windows USER и GDI, для которых инструкции диспетчера системных служб реализованы в User32.dll и Gdi32.dll — Ntdll.dll в данном случае не привлекается. Эти два обстоятельства показаны на рисунке.

Как показано на рисунке, Windows-функция WriteFile в Kernel32.dll импортирует и вызывает функцию WriteFileв API-MS-Win-Core-File-L1-1-0.dll, в одной из DLL-библиотек перенаправления MinWin, которая, в свою очередь, вызывает функцию WriteFile в KernelBase.dll, где находится ее фактическая реализация.

После проверки некоторых параметров, характерных для подсистемы, она затем вызывает функцию NtWriteFile в Ntdll.dll, которая, в свою очередь, выполняет соответствующую инструкцию, чтобы вызвать системное прерывание системной службы, передавая номер системной службы, представляющей NtWriteFile.

Затем диспетчер системных служб (функция KiSystemService в Ntoskrnl.exe) вызывает настоящую функцию NtWriteFile для обработки запроса ввода-вывода. Для функций Windows USER и GDI диспетчер системных служб вызывает функции в загружаемой части подсистемы Windows режима ядра, Win32k.sys.

диспетчеризация-системных-служб

Диспетчеризация системных служб.

Содержание:

Отображение номеров системных служб на функции и аргументы.

Такой же поиск можно продублировать с помощью ядра, работая с идентификатором системного вызова для определения, какая именно функция отвечает за его обработку и сколько аргументов она принимает

  • Обе таблицы, KeServiceDescriptorTableи KeServiceDescriptorTableShadow, направляют на один и тот же массив указателей (или смещений на 64-разрядной системе) для системных вызовов ядра, который называется KiServiceTable, и на один и тот же массив байтов стека, который называется KiArgumentTable. На 32-разрядной системе для получения дампа данных наряду с символьной информацией можно воспользоваться командой отладчика ядра dds.

Отладчик пытается сопоставить каждый указатель с символом. Частичный вывод имеет следующий вид:

lkd> dds KiServiceTable

820807d0 821be2e5 nt!NtAcceptConnectPort

820807d4 820659a6 nt!NtAccessCheck

820807d8 8224a953 nt!NtAccessCheckAndAuditAlarm

820807dc 820659dd nt!NtAccessCheckByType

820807e0 8224a992 nt!NtAccessCheckByTypeAndAuditAlarm

820807e4 82065a18 nt!NtAccessCheckByTypeResultList

820807e8 8224a9db nt!NtAccessCheckByTypeResultListAndAuditAlarm

820807ec 8224aa24 nt!NtAccessCheckByTypeResultListAndAuditAlarmByHandle

820807f0 822892af nt!NtAddAtom

  • Как уже ранее говорилось, 64-разрядная Windows создает таблицу системных вызовов по-другому и использует относительные указатели (или смещения) к системным вызовам, а не абсолютные адреса, используемые в 32-разрядной Windows. Базой указателя служит сама таблица KiServiceTable, поэтому выводить дамп данных в его необработанном формате придется с помощью команды dq. Пример вывода из 64-разрядной системы имеет следующий вид:

lkd> dq nt!KiServiceTable

fffff800'01a73b00 02f6f000'04106900 031a0105'fff72d00

  • Вместо вывода дампа всей таблицы вы также можете найти конкретный номер. На 32-разрядной Windows, благодаря тому, что номер каждого системного вызова является индексом в таблице, и тому, что каждый элемент занимает 4 байта, можно воспользоваться следующим вычислением: Обработчик = KiServiceTable + Номер * 4. Давайте возьмем номер 0x102, полученный во время описания кода функции-заглушки

NtReadFile в Ntdll.dll.

lkd> ln poi(KiServiceTable + 102 * 4)

(82193023) nt!NtReadFile

На 64-разрядной Windows каждое смещение может быть сопоставлено с каждой функцией с помощью команды ln, путем смещения вправо на 4 разряда (используемых согласно ранее данному описанию) и добавления оставшегося значения к базе самой таблицы KiServiceTable, как показано в следующем примере:

lkd> ln @@c++(((int*)@@(nt!KiServiceTable))[3] >> 4) + nt!KiServiceTable

(fffff800'01d9cb10) nt!NtReadFile | (fffff800'01d9d24c) nt!NtOpenFile

Exact matches:

nt!NtReadFile = <no type information>

  • Поскольку драйверы, включая руткиты режима ядра, способны на 32-разрядных версиях Windows делать вставки в эту таблицу, что операционной системой не поддерживается, команду dds можно использовать для получения дампа всей таблицы и для поиска любых значений за пределами диапазона допустимых адресов ядра (dds также даст это понять, не давая возможности просматривать символ для функции). На 64-разрядной Windows таблицы системных служб отслеживаются системой защиты от правки ядра — Kernel Patch Protection, которая при обнаружении изменений вводит систему в аварийное состояние.

Просмотр проявления активности системной службы.

Проявление активности системной службы можно отследить, наблюдая за счетчиком производительности, показывающим количество системных вызовов в секунду — "Системных вызовов/с" (System Calls/Sec) в объекте "Система" (System).

Запустите "Системный монитор" (Performance Monitor), щелкните на пункте "Системный монитор" (Performance Monitor) в разделе "Средства наблюдения" (Monitoring Tools) и щелкните на кнопке "Добавить" (Add), чтобы добавить счетчик к графику. Выберите объект "Система" (System), выберите счетчик "Системных вызовов/с" (System Calls/Sec), а затем щелкните на кнопке "Добавить" (Add) для добавления счетчика к графику.

Оставить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Лимит времени истёк. Пожалуйста, перезагрузите CAPTCHA.

↓