6.2. Дизассемблирование программ с помощью интерактивного дизассемблера Ida Pro
Интерактивный дизассемблер IDA PRO, как и всякий дизассемблер предназначен для дизассемблирования кода программы в мнемонические инструкции на языке ассемблера. Рабочее окно IDA представлено на рис. 6.2.
Большим удобством Ida Pro является то, что он «сворачивает» стандартные библиотечные функции, что во многом упрощает навигацию по файлу, позволяя втиснуть больше информации в тесное пространство экрана. «Развернуть» функцию можно, подведя к ней курсор и нажав “+”, или для сворачивания “-”.
Кроме этого, IDA способна находить перекрестные ссылки, вызываемые из кода. На основе сигнатурного анализа, IDA умеет распознавать различные библиотечные операторы., например, “ostream::operator<<”.
Дизассемблер IDA изначально проектировался как интерактивная среда, предназначенная для совместной работы с человеком. Преимуществом интерактивных дизассемблеров является то, что дизассемблеры, пытающиеся выполнить весь процесс автоматически, легко сбить каким-либо хитрым приемом. Человека же сбить не так легко.
Рис. 6.2. Рабочий интерфейс дизассемблера Ida Pro
В IDA реализован удобный С-подобный внутренний язык написания скриптов, позволяющий реализовать многие полезные действия (например, осуществить дешифровку зашифрованного участка кода).
Ida Pro поддерживает инструкции для различного вида процессоров. Среди них – все версии процессоров INTEL, Motorola, Z80.
Пример использования дизассемблера IDA Pro приведен ниже.
Пусть у нас имеется следующий COM файл размером 292 байт. Код данного файла представлен на рис. 6.3.
Рис. 6.3. Код исследуемого файла
З агрузим данный файл в дизассемблер IDA, после чего получим следующую распечатку (рис 6.4).
В идим, что дизассемблирование произведено не совсем до конца. IDA дизассемблировала только первые две команды. Дело в том, что для того, чтобы правильно распознать остальную часть кода, потребовался бы нетривиальный интеллектуальный алгоритм. За неимением последнего, IDA прекратился процесс, ожидая дальнейших команд от пользователя. Многие дизассемблеры пытаются дизассемблировать дальше, и, как правило, неверно. Попытаемся указать для IDA, что делать дальше.
Если приглядеться к первым двум командам, то можно увидеть, что инструкция JMP в строке 103h вызывает переход по адресу 106h. Для того, чтобы объяснить это IDA, необходимо добавить новую перекрестную ссылку. Это можно сделать так.
В меню “View” выбрать пункт “Cross references” и нажать INSERT.
В Рис. 6.4. Текст файла после первоначального дизассемблирования
В поле “To” указать адрес, куда происходит прыжок (в нашем случае seg000:0106).
Этого же самого эффекта можно добиться более быстрым путем – подвести указатель к адресу 106h и нажать клавишу “C”. Тем самым мы укажем, что с данного адреса идет участок кода. Однако недостаток этого варианта состоит в том, что непонятно, с какого места этот участок кода будет получать управление.
Комментарии в дизассемблированном коде имеют очень большое значение, особенно в больших проектах. Например, в нашем случае, в строке 103h можно поставить комментарий, говорящий о том, что при выполнении инструкции JMP SI, значение регистра SI=106h. Для осуществления этого, подведем курсор к строке 103h, нажмем клавишу “:” и введем текст комментария “SI=106h”.
С адреса 106h идет следующий участок кода.
loc_0_106: |
|
|
| mov si, 114h | Загрузка в si смещения 114h |
| lodsw | Загрузка в AX слова, на которое указывает регистр si |
| xchg ax,cx | Обмен значений регистров ax и cx |
| push si | Заносим si в стек |
loc_0_10C: |
|
|
| xor byte ptr [si], 66h | Расшифровываем байт, находящийся по адресу, на который указывает si |
| inc si | Увеличиваем si на 1 |
| loop loc_0_10C | Замыкаем цикл |
| jmp si | Переходим на адрес, находящийся в регистре si |
Анализируя данный участок, видим, что данный участок осуществляет расшифровку некоторого фрагмента программы, находящегося с адреса 116h, при этом длина фрагмента хранится по адресу 114h и занимает 1 слово. Подведем курсор к адресу 114h и будем нажимать клавишу “D”, пока тип хранимых данных не изменится на «Слово» - «dw». Видим, что длина зашифрованного фрагмента равна 100h байт.
Если проанализировать команду jmp si, находящуюся по адресу 112h и выполняемую после расшифровки, то можно увидеть, что управление передается на команду, находящуюся за зашифрованным фрагментом. Адрес этой команды равен 116h+100h=216h.
Подведя курсор к адресу 216h и нажав клавишу “C”, мы получим следующий код, который выполняется после расшифровки.
call $+3; | Заносим в стек регистр IP |
pop cx; | Извлекаем из стека регистр IP |
pop si; | Извлекаем из стека начало расшифрованных данных |
sub cx, si; | Вычисляем длину расшифрованного участка (+3 байта) |
mov di, 100h; |
|
push di; | Заносим в стек адрес 100h, на который будем передавать управление |
repe movsb; | Переносим расшифрованный участок кода на адрес 100h |
retn; | Передаем управление на адрес 100h |
Общий смысл данной последовательности команд – перемещение расшифрованного фрагмента памяти по адресу 100h и передача на него управление.
Попытаемся узнать, что представляет собой зашифрованный участок кода. Для этого напишем скрипт на внутреннем языке IDA, который выполняет расшифровку.
Следует отметить, что для доступа к произвольной ячейке памяти в IDA необходимо знать сегмент, в котором она расположена, и ее смещение. Seg000 в действительности не нулевой сегмент, а символическое имя. Для того, чтобы узнать базовый адрес, соответствующий данному сегменту, необходимо воспользоваться меню View/Segments. Вызвав его, видим, что ему соответствует адрес 1000h (рис. 6.5).
Рис. 6.5. Просмотр базового адреса сегмента
Для написания скрипта, осуществляющего расшифровку программы, вызовем консоль Shift+F2. В нем вводим следующий текст (рис. 6.6).
auto a;
auto temp;
for (a=0x116;a<0x116+0x100;a++)
{
temp=Byte(MK_FP(0x1000,a));
temp=temp ^ 0x66h;
PatchByte(MK_FP(0x1000,a),temp);
}
Рис. 6.6. Ввод скрипта, осуществляющего расшифровку программы
После расшифровки, перейдем на адрес 122h, укажем на то, что с этого адреса начинается текстовая строка (клавиша “A”), после чего расшифрованный фрагмент примет следующий вид:
seg000:0116 | mov ah,9; |
|
seg000:0119 | or al,1; |
|
seg000:011B | int 21h; | Печать строки DOS |
seg000:011D | xor ax,ax; | Обнуление регистра ax |
seg000:011F | int 16h | Задержка вплоть до нажатия произвольного символа клавиатуры |
seg000:0121 | Retn |
|
seg000:0122 | db ‘Hello, IDA PRO! $’ |
|
Видим, что IDA PRO обладает многими полезными функциями, позволяющими значительно облегчить дизассемблирование программ. IDA PRO является очень мощным средством как для разработчиков ПО, так и для взломщиков.
- Модульная архитектура технических средств защиты по от несанкционированного использования
- Функционирование подсистем и модулей системы защиты по от несанкционированного использования
- Электронные ключи hasp
- Глава 1. Методы и средства обратного проектирования.
- 1.1. Понятие обратного проектирования
- 1.2. Основные приемы, используемые злоумышленником при отладке и дизассемблировании программного обеспечения
- 1.2.1. Специфика атак на модули проверки корректности ключевой информации
- 1.2.2. Специфика атак на модули проверки истечения временного срока работы программы или ограничения по количеству ее запусков
- 1.2.3. Отлов злоумышленником вызова WinApi функций при взломе по
- 1.3. Мониторинг событий
- Глава 2. Методы противодействия обратному проектированию
- 2.1. Методы противодействия отладчикам
- 2.1.1. Защита от отладчиков реального режима
- 2.1.2. Защита от отладчиков защищенного режима
- 2.1.3. Методы, основанные на невозможности полного эмулирования отладчиком среды загрузки программы
- 2.2. Методы противодействия дизассемблированию программного обеспечения
- 2.3. Защита, основанная на человеческом факторе злоумышленника
- Глава 3. Общие методы защиты программ от отладки и дизассемблирования
- 3.1. Использование недокументированных команд и недокументированных возможностей процессора
- 3.2. Шифрование кода программы
- Глава 4. Эмуляторы процессоров. Использование эмуляторов для взлома и защиты программного обеспечения.
- Глава 5. Защита исходных текстов программного обеспечения
- Глава 6. Идентификация и аутентификация субъектов
- 6.1. Идентификация и аутентификация пользователей с использованием технических устройств
- 6.2. Идентификация и аутентификация с использованием индивидуальных биометрических характеристик пользователя
- 7. Защита от разрушающих программных воздействий
- 7.1. Понятие разрушающего программного воздействия
- 7.2 Модели взаимодействия прикладной программы и рпв
- 7.3 Компьютерные вирусы как класс рпв
- 7.4. Защита от рпв. Изолированная программная среда
- Глава 8. Руководящие документы России
- Приложение
- 6.1. Отладка программ в отладчике SoftIce
- 6.2. Дизассемблирование программ с помощью интерактивного дизассемблера Ida Pro
- 6.3. Редактор кода hiew
- Лабораторные работы