Сегодня мы поговорим о том, что многие называют "помойной ямой" Windows, а именно о реестре. Многие уже научились работать с содержимым реестра: менять параметры системы, извлекать полезную информацию и т.д. - но не все знают, что же представляет из себя реестр Windows "изнутри".
В системе Win95/98 (о ней сегодня пойдет речь) реестр хранится в двух файлах SYSTEM.DAT и USER.DAT. Как их найти. В корневом каталоге загрузочного диска имеется файл установок командного процессора MSDOS.SYS, в разделе [Paths] которого следует отыскать переменную WinDir. Ее значение - каталог с установленной Win95/98, в нем и находятся интересующие нас файлы. Надо заметить, что они имеют атрибут Hidden (скрытый) и Read only (только для чтения).
Что же представляет из себя файл реестра? Это файл данных древовидной структуры, состоящий из трех основных частей: заголовка, индекса, и данных, которые могут располагаться в одном или нескольких блоках.
Заголовок - запись размером 20h (32) байта имеет следующий вид:
00h: 4 байта - "CREG" сигнатура заголовка реестра
08h: двойное слово - адрес первого блока данных
10h: слово - количество блоков данных
Индекс - список ссылок на элементы реестра (на его ветви), имеет свой подзаголовок размером в 10h байт:
00h: 4 байта - "RGKN" сигнатура индекса реестра
04h: двойное слово - размер индекса
08h: слово - относительное смещение адреса в файле
(обычно равно 20h - размер заголовка реестра)
0Ch: двойное слово - количество записей в индексе
Далее идут записи индекса следующей структуры:
00h: двойное слово
04h: двойное слово - контрольная сумма ключа
(сумма всех букв имени ключа в верхнем регистре)
08h: двойное слово
0Ch: двойное слово - указатель на предка
10h: двойное слово - указатель на потомка
14h: двойное слово - указатель на следующий ключ этого уровня
18h: слово - номер блока данных, в котором находится ключ
1Ah: слово - номер (не порядковый!) ключа в блоке данных
Таким образом, мы видим, что в индекс представляет собой каркас дерева, которое может состоять из (0FFFFFFFFh-10h)/1Ch=9249248h (153391688) элементов (где 0FFFFFFFFh - максимальный размер индекса, 10h - подзаголовок индекса, 1Ch размер записи в индексе), с условием того, что индекс в файле может быть только один (?).
Все данные (имена ключей, их параметры и значения параметров) находятся в блоках данных. Исходя из размера отведенного под количество этих блоков в заголовке файла реестра, видно, что их может быть не более 64k (65536). Хотя, как дальше будет видно, под размер самого блока данных отведено двойное слово, мне лично не довелось встречать блоки больше 0F000h байт. Если принять этот факт за правило, то не трудно вычислить максимальный размер файла реестра ~7,75Gb. Если же использовать возможности по "раздутию" файла на полную катушку, то размер одного файла может достичь совершенно немыслимых размеров ~256Tb.
Итак, блоки данных. Каждый блок данных имеет свой подзаголовок:
00h: 4 байта - "RGDB" сигнатура блока данных
04h: двойное слово - размер блока данных
08h: двойное слово - размер свободного раздела в блоке
0Ch: слово - (8)
0Eh: слово - номер блока данных
10h: двойное слово - указатель на свободный раздел
14h: слово - количество разделов в блоке (включая свободный раздел)
16h: слово - свободный номер для создания элемента
18h: 8 байт - выравнивание
Для каждого нового элемента создается свой раздел, начиная с начала свободного раздела. При удалении раздела данные в блоке сдвигаются, заполняя собой освободившееся место и увеличивая, тем самым, свободный раздел. При уменьшении размера информации внутри раздела, место не освобождается, а только меняется реальный размер записи (см. далее).
Записи в блоке данных имеют следующую структуру:
00h: двойное слово - размер записи
04h: слово - номер записи в блоке
06h: слово - номер блока данных
08h: двойное слово - реальный размер записи
0Ah: слово - размер имени ключа (n)
0Ch: слово - количество параметров
0Eh: n байт - имя ключа
0Eh+n: - информация о параметрах:
00h: двойное слово - тип параметра
04h: двойное слово (?)
08h: слово - размер имени параметра (n)
0Ah: слово - размер значения параметра (m)
0Ch: n байт - имя параметра
0Ch+n: m байт - значение параметра
Информация о параметрах записывается один за другим, без какого-либо разделения. Если у параметра отсутствует имя (размер равен нулю), то он считается параметром "по умолчанию" для этого ключа.
Программа редактирования реестра RegEdit предоставляет возможность создания параметров лишь трех типов (1, 3, 4), хотя Windows позволяет хранить до 65536 типов параметров.
Здесь можно ознакомиться с программой, написанной в ходе проведенного исследования. С ее помощью можно просматривать файлы реестра без использования средств, предоставляемых Windows (например, можно посмотреть ранее сохраненный реестр и т.п.)
ПРИЛОЖЕНИЕ 1
Типы параметров зарезервированные в MSDE
0 - REG_NONE
Неопределенный тип
1 - REG_SZ
Строка, заканчивающаяся нулем
2 - REG_EXPAND_SZ
Строка, заканчивающаяся нулем
(со ссылками на переменные окружения)
3 - REG_BINARY
Двоичный тип
4 - REG_DWORD или REG_DWORD_LITTLE_ENDIAN
Двойное слово
5 - REG_DWORD_BIG_ENDIAN
Двойное слово
6 - REG_LINK
Символическая связь
(Symbolic Link)
7 - REG_MULTI_SZ
Многостроковый параметр
(строки разделены конечными нулями)
8 - REG_RESOURCE_LIST
Представление ресурса в виде карты ресурса
(Resource list in the resource map)
9 - REG_FULL_RESOURCE_DESCRIPTOR
Представление ресурса в виде аппаратного описания
(Resource list in the hardware description)
10 - REG_RESOURCE_REQUIREMENTS_LIST
ПРИЛОЖЕНИЕ 2
Схематичное представление структуры файла реестра