Загрузчик и первые функции. IDA Pro «с нуля» ч.9

Обсудить статью на форуме


Очень удобно, когда все крэкерские инструменты, книги и статьи в одном месте. Используйте сборник 2020 года от EXELAB - вот тут.
Мы разбираемся понемногу как нужно работать с ЗАГРУЗЧИКОМ, мы оставили некоторые вещи на потом, чтобы наблюдать за ними позже в ОТЛАДЧИКЕ, например, как меняются флаги в зависимости от используемых инструкций.

Мы будем практиковаться на очень простых примерах, в нашем случае это очень простые крэкми, которые скомпилированы в VISUAL STUDIO 2015 для нашей практики. Очевидно, для того, чтобы крэкми заработал, у Вас должны быть установлены последние версия библиотек VISUAL STUDIO 2015 C++.

https://www.microsoft.com/es-ar/download/details.aspx?id=48145

Пакеты Visual C++ Redistributable устанавливают компоненты среды выполнения, которые необходимы для запуска приложений написанных на языке C++ и скомпилированные в Visual Studio 2015.

Выберите нужный для своей операционной системы пакет, согласно вашему языку, загрузите и установите библиотеки.

Присоединенный файл - это исполняемый файл, который называется HOLA_REVERSER.EXE и который запускается под WINDOWS 7.

IDA Pro взлом и реверсинг программ

При вводе номера крэкми будет говорить, насколько я хороший или плохой реверсер.

IDA Pro взлом и реверсинг программ

Мы видим, что это очень простой крэкми, если я открою его в IDA и только в ЗАГРУЗЧИКЕ без отладчика, увидим следующее.

В моём случае (не в Вашем) функция MAIN появляется среди других функций, поэтому я могу найти её с помощью комбинации CTRL + F здесь на этой вкладке или там, где у меня открыта вкладка с функциями, но это происходит, потому что я скомпилировал программу с помощью VISUAL STUDIO и создал PDB файл с символами, который обнаруживает IDA и загружает оттуда имена функций и имена переменных, мы видим, что в моём листинге равно как и в моём исходном коде, появляется функция MAIN, а ниже функция PRINTF, мы будем смотреть, что будет происходить в Вашем случае.

IDA Pro взлом и реверсинг программ

В Вашем случае, IDA не скажет, что это за функция, потому что у IDA'Ы нет символов.

Вероятно, это потому, что никто не распространяет программу с символами.

IDA Pro взлом и реверсинг программ

Обычно у нас будут символы для системных модулей, за исключением очень редких случаев, в этом случае этот косяк с программой под моей ответственностью, поэтому у меня есть символы, но мы будем анализировать крэкми без символов как любую обычную программу.

Мы видим, что здесь у нас нет символов.

IDA Pro взлом и реверсинг программ

Мы имеем очень мало информации, но хорошо то, что мы можем видеть строки.

IDA Pro взлом и реверсинг программ

У нас есть строки в поле зрения, те, что использует крэкми, чтобы сказать нам, что мы ошибаемся при вводе недопустимого серийного номера.

Мы можем сделать двойной щелчок на строке “Pone un numerito\n”.

IDA Pro взлом и реверсинг программ

Здесь мы видим, что 0x402108 это адрес строки, а рядом с адресом мы видим ТЭГ, который помещен рядом и всегда начинается с буквы “a” если это строка ASCII, а оставшиеся символы принадлежат к той же строки, поэтому её очень легко распознать, в нашем случае тэг называется aPoneUnNumerito, а затем идут символы DB, потому что строка - это последовательность байт.

Строку можно рассыпать на байты с помощью клавиши D, теперь мы видим те же самые символы только по вертикали и по одному.

IDA Pro взлом и реверсинг программ

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

IDA Pro взлом и реверсинг программ

Поместив курсор мыши на ссылку в виде маленькой стрелки, мы видим откуда вызывается эта строка, но будет лучше, если мы нажмем клавишу X, чтобы увидеть список ссылок и перейдём туда.

IDA Pro взлом и реверсинг программ

Хорошо, мы находимся в главной функции, здесь она не называется главной, хотя имя буфера, который является общим помечен как BUF.

IDA Pro взлом и реверсинг программ

Предполагается, что мы не знаем исходный код программы, но я Вам его покажу.

IDA Pro взлом и реверсинг программ

Я понимаю, что переменные, которые Вы создаете, становятся оптимизированными, например такие как COOKIE и MAX, которые заменены константами и остаётся только мой буфер, который в моём коде составлял 120 байт в десятичной системе.

Буфер - это пространство памяти зарезервированное, чтобы хранить данные, в нашем случае резервируется 120 байтов.

Как мы можем узнать в IDA размер буфера в стеке, если у нас нет исходного кода?

IDA Pro взлом и реверсинг программ

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

IDA Pro взлом и реверсинг программ

Здесь мы видим буфер BUF, но он определен как последовательность байт DB (IDA если нет символов не может обнаружить буфер). Чтобы собрать его в массив символов или пустой массив, щелкните правой кнопкой мыши на слове BUF и выберите параметр ARRAY.

-= Примечание от Яши — Можно также нажать символ * на цифровой клавиатуре=-

IDA Pro взлом и реверсинг программ

Здесь мы видим, что до следующей переменной или того, что находится ниже в стеке, IDA обнаружила 120 десятичных DB, а элемент массива равен длине каждого поля, так как размер поля равен 1 байту, то это массив символов или байтов и его сумма рассчитывается так 120*1 байт или просто 120 байт.

Если согласимся с этим, то получится так.

IDA Pro взлом и реверсинг программ

Я вижу, что буфер состоит из 120 байт, что соответствует моему исходному коду, хотя компилятор может сделать его больше, пока он минимум равен 120 байт, то всё хорошо, в этом случае они равны. DUP - означает дубликат (на самом деле он должен быть умножен) 120 раз на символ “?”, потому что значение ещё не определено и это соответствует пустому статическому буферу.

IDA Pro взлом и реверсинг программ

Я буду прояснять представление статического стека позже, но ниже BUF есть переменная DWORD (DW) называемая VAR_4

S
и R - это сохраненный EBP родительской функции, которая вызвала эту функцию и АДРЕС ВОЗВРАТА, как мы видели при входе в первую функцию - сначала кладутся аргументы с помощью PUSH, а затем делается CALL, чтобы войти в функцию, которая сохранит АДРЕС ВОЗВРАТА в стек, и локальные переменные будут выше S.

ПЕРЕМЕННЫЕ


S (Сохраненный EBP - как правило, происходит от PUSH EBP, которая является первой инструкцией функции)
R (Адрес возврата)
АРГУМЕНТЫ

Поскольку аргументы помещаются в стек перед CALL, который помещает адрес возврата в стек, они будут ниже него, затем будет идти адрес возврата, а выше него СОХРАНЕННЙ EBP порожденный инструкцией PUSH EBP, которая как правило первая инструкция в функции, а затем выше идет пространство локальных переменных, мы увидим их более подробно позже.

Если я нажму X, чтобы увидеть откуда вызывается эта функция, то увижу:

IDA Pro взлом и реверсинг программ

IDA Pro взлом и реверсинг программ

И я иду туда и вижу, что у нас есть инструкции PUSH, которые передают аргументы функции, имя которой я видел, когда работал с СИМВОЛАМИ, а сейчас её здесь нет, 3 аргумента ниже пропущены, ниже есть изображение с символами.

IDA Pro взлом и реверсинг программ

IDA обнаружила, что никогда не используются такие аргументы как ARGC, ARGV и ENVP, они присутствуют по умолчанию в функции MAIN, но так как там не было никаких ссылок на них или их использование в функции, IDA избавилась от них.

IDA Pro взлом и реверсинг программ

Кроме того, в моём коде даже не передаются переменные как аргументы к функции MAIN, так что все хорошо - функция без аргументов.

Когда мы хотим увидеть из какого место получается доступ к переменной, мы отмечаем её и нажимаем X.

IDA Pro взлом и реверсинг программ

Мы видим, что VAR_4 используется в двух местах, для тех кто не знает, это переменная COOKIE, которую я не программировал, это защита от переполнения стека, программа сохраняет их в начале при запуске функции, проверяет их на целостность при выходе из функции, теперь мы можем переименовать их в COOKIE_DE_SEGURIDAD или CANARY.

IDA Pro взлом и реверсинг программ

Мы видим, что когда функция хочет напечатать строки она вызывает CALL в которой в конечном итоге будет вызвана функция PRINTF для печати строк.

IDA Pro взлом и реверсинг программ

Мы видим, что в версии с символами IDA обнаружила её непосредственно как функцию PRINTF.

IDA Pro взлом и реверсинг программ

Но только если мы посмотрим внутрь CALL то узнаем, что аргументы, это строки, которые печатаются в консоли и мы делаем вывод, что это функция PRINTF.

IDA Pro взлом и реверсинг программ

Мы видим, что внутри эта функция заканчивается вызовом VFPRINTF, так что, это то, что нам нужно переименовать.

IDA Pro взлом и реверсинг программ

У нас остаётся только буфер из 120 байт, давайте посмотрим, что будет с ним происходить.

Мы видим, что буфер идет как аргумент к функции GETS_S - эта функция, которая получает то, что мы вводим в консоли.

IDA Pro взлом и реверсинг программ

Мы видим, что есть два аргумента - указатель на буфер и его максимальный размер, в который позволено нам печатать, давайте посмотрим, что будет в нашем случае.

IDA Pro взлом и реверсинг программ

Ранее мы сказали, что LEA вычисляет адрес переменной, в этом случае LEA является указателем на буфер BUF, который передаётся с помощью инструкции PUSH EAX, а затем идёт PUSH 0x14, который указывает максимальное количество символов, которое можно ввести в консоли.

IDA Pro взлом и реверсинг программ

В моём исходном, мы видим тот же самый вызов GET_S с двумя аргументами - БУФЕР и его максимальное значение, который я обозвал как переменную MAX из 20 элементов, но компилятор, чтобы сохранить пространство поместил именно 20 в десятичной или 0x14 в HEX в этот аргумент, так как не нужно использовать больше.

Следовательно, не выполняя этот вызов, я знаю, что в буфере у меня есть символы, которые я набираю в консоли.

Позже, тот же указатель на буфер помещается как аргумент к функции ATOI.

IDA Pro взлом и реверсинг программ

Она делает то же самое.

IDA Pro взлом и реверсинг программ

Эта функция конвертирует строку в целое число и если она не может это сделать, потому что происходит переполнение (выход за максимально возможное значение), нам будет показываться ошибка и вернётся ноль, тоже самое происходит и с отрицательным числом, но идея состоит в том, что всё что я буду вводить будет конвертироваться в число, если я введу значение 41424344 оно будет конвертироваться в десятичное значение 41424344, а так как в ассемблере мы работаем с HEX значениями, оно будет возвращено в HEX через регистр EAX.

Каждая функция возвращает генерируемое значение INT, она интерпретирует входные символы как число. Функция возвращает значение 0 для ATOI и _WTOI, если ввод не может быть преобразован в значение этого типа.

IDA Pro взлом и реверсинг программ

Мы видим, что значение возращенное из EAX переносится в ESI и после печати первоначальной строки, которая была введена, сравнивает ESI с числом 0x124578.

Так что, то, что набрано интерпретируется как строка в десятичном формате, которая возвращается в HEX виде и это число сравнивается с этой константой, передавая десятичное значение этой константы.

IDA Pro взлом и реверсинг программ

Мы видим, что если сравнение не равно (JNZ) оно переносит меня к BAD REVERSER, а если равно, то переносит к GOOD REVERSER, давайте попробуем в консоли PYTHON увидеть десятичное значение числа 0x124578.

IDA Pro взлом и реверсинг программ

Мы вводим это значение в наш CRACKME.

IDA Pro взлом и реверсинг программ

IDA Pro взлом и реверсинг программ

Хорошо, это простой пример статического реверсинга, далее также продолжим работу с ЗАГРУЗЧИКОМ

До встрече в 10-той части.

Рикардо Нарваха.

Обсуждение статьи: Загрузчик и первые функции. IDA Pro «с нуля» ч.9 >>>


При перепечатке ссылка на https://exelab.ru обязательна.



Видеокурс ВЗЛОМ