Погружение в технику и философию 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 выглядит так: |