Как получить доступ к реестру через функции ntdll
Для операций с реестром используются документированные в MSDN функции, названия которых оканчиваются на -Key, например для чтения из реестра используется NtQueryValueKey.
На уровне Native API реестр выглядит немного не так, как в Win32. Вместо нескольких корневых псевдоключей HKEY_XXX используется единственный ключ «\REGISTRY» с двумя подключами «\USER» и «\MACHINE». Эти два ключа соответствуют HKEY_USERS и HKEY_LOCAL_MACHINE. Эквивалента ключу HKEY_CURRENT_USER нет, ветки разных пользователей следует искать в “\USER”. Ключу HKEY_CLASSES_ROOT соответствуют разные ветви реестра, располагающиеся как в ветке “\USER”, так и в “\MACHINE”. Еще одно отличие от WinAPI в том, что работая с реестром, мы оперируем обычным типом HANDLE, а не специальным типом HKEY.
Дэниэл Мэдден еще в 2006 году написал программу с открытым исходным кодом под названием NtRegEdit — аналог стандартного редактора реестра (regedit.exe). NtRegEdit использует для доступа к реестру только функции Native API, поэтому код из программы можно перенести в своё собственное native-приложение.
В библиотеке ZenWinX также присутствует код, использующий функции реестра. Например, функция winx_register_boot_exec_command умеет, как видно из названия, прописывать команду, выполняющуюся при запуске, то есть выполнять запись в ключ реестра BootExecute.
Библиотека ntreg корейского программиста rodream содержит набор функций для работы с реестром, достаточно просто подключить к своему проекту файлы ntreg.c и ntreg.h и программа может читать и писать в реестр. В этой библиотеке отсутствует функция вывода списка ключей и значений из заданной ветки реестра, но к счастью, её несложно написать самостоятельно.
Чтобы узнать, какие подключи есть у какого-либо ключа, используется функция NtEnumerateKey.
NTSYSCALLAPI NTSTATUS NTAPI NtEnumerateKey( IN HANDLE KeyHandle, IN ULONG Index, IN KEY_INFORMATION_CLASS KeyInformationClass, OUT PVOID KeyInformation, IN ULONG Length, OUT PULONG ResultLength );Имена подключей будут браться из указателя на структуру KEY_NODE_INFORMATION. В параметр KeyInformationClass записываем константу KeyNodeInformation, в параметр KeyInformation помещаем указатель на структуру. Код для получения всех подключей в итоге будет выглядеть следующим образом:
ULONG ResultLength, i = 0; char buf[BUFFER_SIZE]; PKEY_NODE_INFORMATION pki = (PKEY_NODE_INFORMATION)buf; while (STATUS_SUCCESS == NtEnumerateKey(hKey, i++, KeyNodeInformation, pki, BUFFER_SIZE, &ResultLength)) { ; }Внутри этого цикла очередное имя подключа доступно как строка WCHAR pki->Name, её можно выводить на экран или сохранять в какой-нибудь внутренний список. Похожим образом можно получить список всех значений, содержащихся в ключе реестра, только используется другая функция NtEnumerateValueKey с константой KeyValueBasicInformation, а результат оказывается в структуре KEY_VALUE_BASIC_INFORMATION.
pbi = (PKEY_VALUE_BASIC_INFORMATION)buf; while (STATUS_SUCCESS == NtEnumerateValueKey(hKey, i++, KeyValueBasicInformation, pbi, BUFFER_SIZE, &ResultLength)) { ; }Имя находится в строке pbi->Name, а тип значения (REG_SZ, REG_DWORD или другой) определяется в pbi->Type.
Автор: амдф
Дата: 15.04.2011
Избранное
Остальное
Лента atom