Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #93, СЕНТЯБРЬ 2006 г.

Погружение в технику и философию gdb

Крис Касперски

Хакер, номер #093, стр. 093-122-3


Выход — циклим elf в точке входа, запускаем и подключаемся к процессу командой "attach" (или "gdb -pid идентификатор"), а после попадания в отладчик восстанавливаем оригинальные байты и приступаем к трассировке в обычном режиме. Покажем, как это осуществить на практике.

Загружаем tiny-crackme в любой hex-редактор (например, в hte или hiew), переходим в точку входа (в hiew'е это осуществляется нажатием <ENTER> (для перехода в hex-режим), <F8> [header], <F5> [entry]). Запоминаем (записываем на бумажку) содержимое двух байт под курсором (в нашем случае они равны B3h 2Ah) и заменяем их на EBh FEh, что соответствует инструкции "jumps $".

Сохраняем изменения, запускам файл, определяем его pid, подключаем к процессу отладчик. На этот раз gdb хоть и ругается на неверный формат, но все-таки подключается к процессу, предоставляя нам полную свободу действий. Но прежде, чем начать трассировку, необходимо расциклить файл, вернув пару байт из точки входа на место.

Модификация памяти (регистров и переменных) осуществляется командой "set". Для примера запускаем зацикленный tiny-crackme:

# ./tiny-crackme

Переходим на соседнюю консоль и выполняем команду для определения уникального идентификатора процесса:

# ps -a | grep tiny-crackme

PID TTY TIME CMD

13414 pts/7 00:00:03 tiny-crackme

Отладчик ругается на неверный формат файла, но все-таки позволяет присоединиться к требуемому процессу:

# gdb -q

(gdb) attach 13414

Attaching to process 13414

"/home/kpnc/gdb/tiny-crackme": not in executable format:

File format not recognized

Теперь нам под силу восстановить оригинальные байты командой "set":

(gdb) set *(unsigned char*)$pc = 0xB3

(gdb) set *(unsigned char*)($pc+1) = 0x2A

Здесь "$pc" (с учетом регистра!) – условное обозначение регистра-счетчика команд (program count), а "*(unsigned char*)" – явное преобразование типа, без которого gdb ни за что не сможет определить размер записываемой ячейки. Довольно длинная конструкция, и у нас возникает естественное желание ее сократить.

Отладчик помнит историю команд, и чтобы не вводить уже введенную команду, достаточно нажать "стрелку вверх" и отредактировать строку. В нашем случае — заменить "$pc = 0xB3" на "($pc+1) = 0x2A". Уже короче! Но все равно длинно. Примечание: по умолчанию gdb не сохраняет историю команд, и она действительна только в пределах одного сеанса, чтобы задействовать автоматическое сохранение, следует набрать "set history save on" и при необходимости занести эту последовательность в ~/.gdbinit.

И вот тут мы подходим к одному из главных преимуществ gdb над soft-ice. Отладчик gdb неограниченно расширяем и поддерживает продвинутый интерпретатор, позволяющий, среди прочего, объявлять свои переменные, начинающиеся со знака "$", с которыми можно делать, что угодно.

Улучшенный вариант восстановления ячеек памяти с использованием переменной $i выглядит так:

Назад на стр. 093-122-2  Содержание  Вперед на стр. 093-122-4