Недокументовані можливості Windows: точки зупинки для ключів реєстру

Іноді в процесі зворотної розробки якої-небудь програми (в тому числі драйвера) може знадобитися перервати її виконання в момент вчинення певної дії з певним ключем реєстру, в такій ситуації можна скористатися недокументованій функціональністю точок зупинки для ключів реєстру.

Вперше точки зупинки для ключів реєстру з'явилися в Windows XP, де була реалізована можливість виконання ядром інструкції int 3 при відкритті ключа реєстру з позначкою (випробувальні прапором)
BREAK_ON_OPEN
або при створенні підключа у складі такого ключа.


Рис. 1: Фрагмент функції CmpDoOpen

Дана функціональність з'явилася в ядрі ще до випуску будь-яких пакетів оновлення, причому встановлювати налагоджувальну («checked») версію ядра не вимагалося. Разом з тим API-функцій для встановлення прапора
BREAK_ON_OPEN
не було, а тому цей прапор можна було виставити біля ключа тільки через редагування файлу з кущем реєстру в HEX-редакторі.

Починаючи з Windows Vista, список доступних налагоджувальних прапорів був розширений, з'явилася можливість установки цих прапорів через API-функцію NtSetInformationKey, однак сама функціональність залишилася тільки в налагоджувальних версіях ядра (які можна взяти з Windows Driver Kit).

Табл. 1: Можливі значення налагоджувального прапора
Прапор Значення Примітка
BREAK_ON_OPEN 0x01 Відкриття ключа
BREAK_ON_DELETE 0x02 Видалення ключа
BREAK_ON_SECURITY_CHANGE 0x04 Зміна дескриптора безпеки
BREAK_ON_CREATE_SUBKEY 0x08 Створення підключа
BREAK_ON_DELETE_SUBKEY 0x10 Видалення підключа
BREAK_ON_SET_VALUE 0x20 Установка значення
BREAK_ON_DELETE_VALUE 0x40 Видалення значення
BREAK_ON_KEY_VIRTUALIZE 0x80 Віртуалізація ключа
Для установки налагоджувального прапора необхідно викликати функцію NtSetInformationKey, передавши їй в якості першого аргументу дескриптор ключа реєстру, для якого потрібно встановити налагоджувальний прапор. В якості другого аргументу — KeySetDebugInformation, а останні два аргументи повинні описувати буфер, який містить подвійне слово (DWORD), в якому розміщено значення налагоджувального прапора (або комбінація з двох і більше прапорів).

Для активації обговорюваних точок зупинки необхідно виставити значення змінної ядра CmpRegDebugBreakEnabled в одиницю.

Приклад

В якості прикладу спробуємо зловити момент запису значення ключ реєстру «
HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices
», де зберігаються відомості про змонтованих томах, і визначити компонент Windows, який записує туди дані. Для цього зазначимо вказаний ключ випробувальні прапором
BREAK_ON_SET_VALUE
, включимо точки зупинки, змінивши значення змінної CmpRegDebugBreakEnabled на одиницю, і отформатируем тестовий диск, який потім змонтуємо.

В результаті відбувається спрацьовування точки зупинки, видно наступний стек викликів:

# Child-SP RetAddr Call Site
00 ffffd000'79b851a0 fffff803'7ccf88fa nt!CmSetValueKey+0x158
01 ffffd000'79b852b0 fffff803'7c69eac3 nt!NtSetValueKey+0x73e
02 ffffd000'79b85470 fffff803'7c697e40 nt!KiSystemServiceCopyEnd+0x13
03 ffffd000'79b85678 fffff803'7d08f11e nt!KiServiceLinkage
04 ffffd000'79b85680 fffff801'46d6fcaa nt!RtlWriteRegistryValue+0x9e
05 ffffd000'79b856f0 fffff801'46d6b58c mountmgr+0xecaa
06 ffffd000'79b85820 fffff803'7cd9cd78 mountmgr+0xa58c
07 ffffd000'79b85850 fffff803'7cd9bdd5 nt!PnpNotifyDriverCallback+0x1b8
08 ffffd000'79b85900 fffff803'7cdd6755 nt!PnpNotifyDeviceClassChange+0x2f9
09 ffffd000'79b859d0 fffff803'7c66dcb7 nt!PnpDeviceEventWorker+0x4c1
0a ffffd000'79b85b50 fffff803'7c5e7071 nt!ExpWorkerThread+0x177
0b ffffd000'79b85be0 fffff803'7c699836 nt!PspSystemThreadStartup+0x23d
0c ffffd000'79b85c60 00000000`00000000 nt!KiStartSystemThread+0x16

По стеку викликів ясно видно, що запис ініціює компонент «mountmgr», в його коді можна виявити шуканий виклик nt!RtlWriteRegistryValue:

fffff801'46d6fca4 ff15fe44ffff call qword ptr [mountmgr+0x31a8 (fffff801'46d641a8)] // виклик nt!RtlWriteRegistryValue
fffff801'46d6fcaa 488d55b7 lea rdx,[rbp-49h]

Висновки

Описана функціональність може бути використана як для вирішення завдань, безпосередньо пов'язаних з налагодженням і драйверів ядра, так і для вирішення прихильник завдань — наприклад, пошук програм в досліджуваному образі системи, які використовують вказаний ключ реєстру.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.