Исследования ядра LINUXа

       

HTE дизассемблирует "дикий" код — неправильный результат


А все потому, что начиная с этого места, ядро начинает исполнятся в 32-разрядном защищенном режиме и для правильного дизассемблирования разрядность сегмента необходимо изменить. После чего, IDA Pro заработает как ни в чем ни бывало. Сейчас мы находимся в распаковщике, подготавливающим основной ядерный код к работе. Он реализован в файлах \arch\i386\boot\compressed\head.S и misc.c. "Персонального" адреса загрузки не имеет и грузится вместе с первичным загрузчиком по адресу 1000h:0000h. Таким образом, первый байт распаковщика расположен в памяти по адресу 1000h:0000h + sizeof(ldf) == 1000h:01300h, что соответствует физическому адресу 101300h. Распаковщик настраивает сегментные регистры DS/ES/SS/GS/FS на селектор 18h, а регистр CS на селектор 10h.

За концом распаковщика идут текстовые строки "System halted", "Ok, booting the kernel", "invalid compressed format (err=1)", за ними следует длинная цепочка нулей, а потом начинается упакованный код, дизассемблировать который без предварительной распаковки невозможно. А как его распаковать? Поскольку, Линуксоиды не любят изобретать велосипед и всегда стремятся использовать готовые компоненты, ядро упаковывается в формате gzip.

Упакованный код начинается с "магической последовательности" 1F 8B 08 00, которую легко найти в любом hex-редакторе. В ядре 2.4.27 она расположена по смещению 4904h, а в ядре 2.6.7 по смещению 49D4h от начала файла. Выделим область отсюда и до конца файла, и запишем ее в файл с расширением gz (например, kernel.gz). Пропустив ее через gzip (gzip -d kernel.gz) мы получим на выходе готовый к дизассемблированию образ ядра. IDA Pro уже ждет когда он будет загружен в нее.

Основной код ядра исполняется в 32-разрядном режиме и грузится в память по адресу 10:C0100000h. В самом начале идет модуль \arch\i386\kernel\head.S, а затем init.c, подгружающий все остальные модули. Как определить какому именно модулю соответствует данная часть дизассемблерного кода?

В директории /boot лежит замечательный файл System.map-x.y.z (где x.y.z номер версии ядра), в котором перечислены адреса публичных символьные имен, они же метки (см. листинг 3):

c0108964 T system_call

c010899c T ret_from_sys_call

c01089ad t restore_all

c01089bc t signal_return

c01089d4 t v86_signal_return

c01089e4 t tracesys

c0108a07 t tracesys_exit

c0108a11 t badsys



Содержание раздела