2 мая 2012 г.

Введение в реверс инженеринг используя IDA - Глава 1

 В основном я всегда для отладки пользовался отладчиком всех времен и народов OllyDbg. Это шикарный деббагер, который очень удобен и прост одновременно обладающий очень мощным функционалом. Но, в последнее время я все больше сталкиваюсь х64 программами, да и домашний компьютер у меня поднят на х64 операционной системе, а OllyDbg версии 1.10 не корректно работает на такой операционной системе, теряет точку входа и вообще печально все. Попытки использовать более новую версию 2.01а тоже не увенчались успехом, так как она виснет в неожиданный момент и перестает отвечать, можно конечно накатить кучу патчей от китайских друзей и более менее оживить дебагер, но все равно огромное количество багов и похоже прекращение разработки(с августа 2011 года никаких подвижек) заставило меня посмотреть в сторону Interactive Disassembler, сокращенно IDA. Это мощнейший инструмент для отладки и исследования программ который обладает кучей нужных и не очень не нужных свистелок и перделок.
 Но он тоже обладает некоторыми минусами, которые меня всегда останавливали для изучения сего мощного инструмента:
1. Мало вменяемой документации, есть конечно книги от уважаемого господина К. Касперски, но они настолько древние, что читать их смысл есть, но в текущих реалиях не шибко большой, в основном для общего развития.
2. Цена сего продукта у X-Rays - стартовая лицензия более 500 австралийских долларов и это без X-Rays Decompiler, который стоит совсем каких то неадекватных денег.
Но разочарование OllyDbg  возобладало над жабой и здравым смыслом и я решил заняться всетаки изучением IDA.


 Небольшое отступление - не нада спрашивать меня где скачать на халяву IDA бесплатно и без смс, вернее спросить можно, но я не знаю и отправлю на этот сайт .

 Первым делом я поискал информацию об мануалах и был несколько разочарован, информации достаточно мало и она устарела, есть форумы на которых народ обменивается всякими полезностями про IDA, но мне надо было пройти для начала хотя бы курс молодого самца. В этом мне помогло видео руководство от TiGa, взять его можно тут. Потратив почти целые выходные и выпив пол ящика пива я просмотрел все видеоруководства. После чего у меня появилась мысль, а почему бы не попробовать разобраться в IDA при помощи старых добрых статей от Рикардо Наваха под названием "Введение в крекинг с нуля используя OllyDbg", почитать их на русском можно например тут, может возникнуть вопрос, причем тут OllyDbg и IDA, а потому, что статьи очень подробные и я буду искать похожие элементы в IDA, что даст мне базовые понимания в работе с IDA.

 Итак я не буду описывать базовые навыки при работе с ассемблером как в статьях Рикардо Наваха, так как думаю те кто переходят к IDA уже немного понимают что такое стек, регистры, как устроена память и что такое условный и без условный переход, а займемся сразу  исследованием программ которые описаны в статьях Рикардо. Я постараюсь пройтись по всем его статьям с разбором crackme которые он упоминает.

 Первая статья в которой уже идет разбор crackme, является главой под номером 9, у меня же она будет первой главой.
Качаем необходимый фаил который будет исследоваться, например с сайта wasm.ru
Запускаем IDA и открываем в нем фаил через File->Open. После чего видим следующую картинку:

Все настройки можно оставить по умолчанию, так как они в принципе в текущий момент ничего мне особа не говорят. Жмем ОК и видим основное окно IDA:


Кружочками с циферками выделены следующие позиции:
1. Информация об базе, точке входа,  размере секции кода виртуальной и реальной и прочая полезная информация про секцию.
2. Функции которые обнаружены в программе, розовым обозначены функции которые импортируются из внешних библиотек. start - чаще всего это функция которая идет в точке входа, к стати посмотреть варианты Entery Point можно нажав хоткей CTRL+E.
3. Собственно сам ассемблерный код текущей открытой функции, если не хочется смотреть в графическом режиме то можно переключить в текстовой сплошной простыней по пробелу, обратно в графический переключается пкм на листинге Graph view.
4. Миникарта функций со всеми переходами и прочим, очень полезна для ориентации в коде.

Для того чтобы можно было запускать приложение в отладчике, необходимо выбрать сам отладчик, так как листинг кода это еще не отладка.
Нажимаем F9 или выбираем в верху опцию Debugger - появиться окно под названием Select a debugger в котором выбираем Local Win32 debugger для начала нам хватит этого дебагера, а с остальными будем разбираться позже.

Нажимаем еще раз F9 и программа запускается, не остановишись на Entery Point как в OllyDbg. Это можно исправить, если есть желание постоянно останавливаться в самом начале, идем опять же в закладку Debugger и там выбираем Debugger Options в открывшимся окне можно установить галочку на Stop on process entry point и получим реакцию такуюже как в OllyDbg, при старте отладки останавливаемся на точке входа. Но так же можно сразу установить руками брякпоинт если необходимо посмотрев в ASM листинг и остановиться там.

Теперь рассмотрим окно дебаггера:

Стрелочками показаны основные элементы интерфейса, они не шибко сильно отличаются от тогоже OllyDbg, хотя и есть некоторые дополнения, например отображение не в виде листинга, а в графическом виде, не забываем, что всегда можем переключиться в листинг из графического режима по пробелу и чаще всего также обратно. Есть панель с логом и карта графического отображения.

Что нам здесь еще понадобиться, основные инструменты показаны на следующей картинке:


Disassembly - собственно вызывает окно с дизассемблированной программой.
Hex Dump - открывает окно с дампом.
Pseudocode - эта функция пытается преобразовать ASM код в жалкое подобие C.
Exports - что программа или библиотека экспортирует.
Imports - что программа или библиотека импортирует.
Names - список APIшных имен найденых в данном экзешнике.
Functions - список функций обнаруженных в программе.
Strings - текстовые строки обнаруженные в программе.
Segments - сегменты которые обнаружены в памяти.
 Для начала хватит, так как назначение остальных функций пока не очень понятны, а текущее понадобиться для иследования первой программы crackme.

Теперь немного про дебаггер, основные клавиши остались стандартные
F9 - выполнить программу
F8 - трассировать не заходя в функцию
F7 - трассировать заходя в функции
F2 - снять/установить брякпоинт на строке где в текущий момент курсор.

Как в IDA различать где мы сейчас находимся в программе которую отлаживаем или уже шаримся по дллке импорта - можно посмотреть в текстовом виде с лево от номера позиции и увидеть описание, например вот такое:
kernel32.dll:764FD8F3 mov     edi, edi
Ну по слову kernel32. сразу становиться понятно, что сейчас мы находимся в кернеле.

Ну теперь всетаки давайте вернемся нашему многострадальному crackme.
Запустим его и попытаемся ввести какое нибуть имя и серийный номер, вывалиться мессадж бокс, который скажет "No luck there, mate!". Значит мы не угадали имя и пользователя. Давайте попробуем отловить это сообщение и посмотрим как нам заставить выдавать правильное сообщение, что имя и серийник правильные. Известно, что вывод сообщения об неудаче использует стандартную API функцию MessageBoxA, вот на нее и необходимо нам поставить брякпоинт.
Идем в View->Open SubViews->Functions или нажимам Shift+F3, а вот там видим все функции которые удалось определить IDA.
Выделяем нужную нам функцию MessageBoxA и по низпадающему меню от правой мыши ставим брякпоинт на функцию. Както так:

Ок. Поставили, продолжим выполнение программы и попробуем ввести снова неправильное имя и серийник.(к стати вернутся в окно отладки по умолчанию чаще всего можно кнопкой ESC)
Отладка остановилась на выводе сообщения о неправильном логине и пароле, отлично, смотрим какую полезную информацию мы можем выудить.
Мы находимя на входе в функцию MessageBoxA, сама функция нам не интересна, по этому жмем CTRL+F7 что означает, выполнить код до обнаружения первого ret, тоесть выхода из функции. После всех манипуляций, основное окно дизасемблированного кода выглядит вот так:

Ага! Это процедура которая передает аргументы для MessageBoxA которая выводит сообщение об неправильном серийнике и имени. Так как назначение понятно, то можно переименовать сразу функцию щелкнув ПКМ(правой кнопокй мыши) на sub_401362 и выбрав там пункт Rename или использовав горячую кнопку N. Я назову эту функцию AHTUNG! :)

Посмотрим далее, откуда растут ноги этой процедуры и что же находиться за ней. Нажмем F8 и выйдем на уровень в верх. А там сразу видно некую проверку со стрелочками, одна стрелочка на лево ведет к вредной процедуре AHTUNG, а вот вторая не очень понятно, но там видно CALL и адрес sub_40134D, очень интересно посмотреть, что же там. Варианта 2 в принципе, 1 это щелкнуть 2 раза ЛКМ(левой кнопкой мыши) на sub_40134D и попасть в эту функцию, а второй, это просто навести мышой на туже sub_40134D и подождать пол секунды,  что покажет кусок этой функции, както так:

Уже очень интересно, похоже что другой вариант проверки ведет к правильному окошку. Обзовем эту процедурку GOOD.
Снимаем старый брякпоинт на MessageBoxA, он нам не нужен уже идем в Debugger->Breakpoints->Breakpoint List и удаляем старый брякпоинт в открывшемся окне.
Теперь необходимо поставить брякпоинт на проверку jz над этими процедурками AHTUNG и GOOD либо по ПКМ и выбором соответсвующей опции или хоткеем F2. Перезапустим программу и осмотримся.
Получится у нас следующее окно:

К сожалению на статичной картинке не видно, но поверьте мне на слово, в текущий момент мигает срелочка которая ведет в сторону процедурки AHTUNG и это есть не очень хорошо. Нам было бы неплохо чтобы мигала зелененькая стрелочка в сторону процедурки которую мы обозвали GOOD. Для этого необходимо поставить флаг ZF в 1. ПКМ на флаге и выбрать опцию Increment Value или выделить флаг и нажать на кнопочку +(плюс) цифровой клавиатуре. Конечно лучше это смотреть в динамике, в статичных картинках плохо видно, но теперь замигала стрелочка в сторону GOOD процедурки в листинге это выглядит вот так:

Тут более наглядно на статике, когда ZF = 0, то переход не совершается и выглядит в виде пунктиной линии, соответсвенно мы попадаем на процедурку AHTUNG, а когда совершается - то видно жирную зеленую стрелочку и ведет он на процедурку GOOD.
Ну чтож, жмем наконец F9 и наслаждаемся результатом: Great work, mate. Now try the next CrackMe.


 Правда если закрыть программу и снова открыть в отладчике, флаг конечно пропадет, надо придумать что нибуть, чтобы пропатчить ее и больше не извращаться с флагами, самый простой вариант, это за место JZ сделать JNZ, чтобы принимался наоборот любой неправильный серийник, кроме правильного.
Hex код JZ - 74, а код JNZ - 75, значит нада поменять байт, встаем на строку которую хочем поменять, идем в Edit->Patch programm->Change Byte.
Повяиться панель с набором байтов:
74 07 E8 18 01 00 00 EB 9A E8 FC 00 00 00 EB 93
необходимо поправить первую цифру на 75, чтобы получилось
75 07 E8 18 01 00 00 EB 9A E8 FC 00 00 00 EB 93
В дизасемблированном коде можно будет увидеть изменения.
Тем самым теперь будет правильно проходить любой серийник кроме правильного, хотя я считаю что это грязным трюком, лучше или знать серийник или сделать безусловный JMP.

Сохраним результат патча, File->Produce File, вывалиться куча возможных сохранений, даже в EXE, но оно почемуто не работает, так что сохраним в банальный DIF.
Посмотрим в файлик что получилось:

CRACKME.EXE
00000843: 74 75
То что надо.


Ну вот и все на сегодня, следующая часть я думаю будет через недельку.


Комментариев нет:

Отправить комментарий