June 29, 2023

введение в Reverse Engineering

всем привет! это статья нацелена на новичков. которые хотят научиться анализировать приложения / малвари. и так начнем!

что же такое реверс ижиниринг ?

Реверс инжиниринг это - процесс анализа и понимания работы приложения. выполняя обратные действия, тоесть, программист упаковывает приложение(компилирует) а реверс инженер делает обратные действия. распаковку приложения с целью понять как оно работает!

что же должен знать реверс инженер для того что бы выполнять действия?

  1. знать язык ассемблер ( в зависимости от архитектуры системы)
  2. знать язык С++ или С (для того что бы переводить из языка асемблера в C подобный код)
  3. знать архитектуру системы под которую выполняются действия (Windows - PE, linux - ELF)

так же мы рассмотрим 2 вида анализа приложений.

  1. Статический анализ
  2. динамический анализ

что такое статический анализ?
статический анализ - это процесс анализа скомпилированного кода или исполняемого файла. без выполнения
статический анализ включает в себя:
Дизассемблирование:
преобразование машинного кода в читаемый для человека вид, позволяющий изучить инструкции и структуру программы.

что такое динамический анализ?
динамический анализ - это процесс анализа скомпилированного кода или исполняемого файла. путем выполнения программы

сейчас мы рассмотрим базовые инструкции асемблера!
1. MOV - копирует данные с одного места в другое, например, из памяти в регистр или между регистрами
2. ADD/SUB - выполняет сложение и вычитание чисел. ADD используется для сложения, а SUB для вычитания
3. INC/DEC - увеличивают или уменьшают значение переменной или регистра на 1 (пример I++, i--)
4. CMP - сравнивает два значения и устанавливает флаги состояния в соответствии с результатом сравнения
5. CALL/RET - вызывает функцию и возвращает управление обратно в основной код
6. PUSH / POP - перемещает значение на вершину стека или извлекает значение из вершины стека
7. AND/OR/XOR - выполняют логические действия И, ИЛИ, ИЛИ НЕ

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

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

EAX/EBP/ESP - используется для хранения результата вычислений или возвращаемого значения из функций (EBP/ESP) в большинство случаев используются для управления стеком и доступа к параметрам функции, а так же для хранения любых данных.
ESP - указывает на вершину стека и используется для добавления и извлечения данных из стека
EIP - указывает на следующую инструкцию, которая должна быть выполнена
CS/DS/ES/SS - используются для адресации и доступа к различным сегментам памяти
VIP - используется для управления виртуальным адресом следующей инструкции, которая должна быть выполнена.
Сейчас мы поговорим о флагах

флаги - используются для управления и контроля выполнения программы. Они представляют собой битовые флаги, которые устанавливаются и сбрасываются процессором в зависимости от результата выполнения инструкций.
CF - флаг переноса, устанавливается если при выполнении арифметической операции произошло переполнение
ZF - флаг нуля, устанавливается если результат операции равен нулю
OF - флаг переполнения, устанавливается если при выполнении операции с данными со знаком произошло переполнение
SF - флаг знака, устанавливается если результат операции имеет отрицательный знак
PF - флаг четности, устанавливается если результат операции имеет четное количество единичных битов
DF - флаг направления, определяет направление операций строковых инструкций (вперед или назад)

когда мы все это изучили можно приступать к статическому анализу!
для этого нам понадобиться IDA PRO (Interactive DisAssembler)
допустим что мы имеем какой-то семпл приложения и мы сейчас хотим провести анализ, закидываем наш семпл в иду

ничего не меняем а просто нажимаем ОК. ида сама все правильно определила

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

мы нашли нашу точку входа, тут идет вызов __Security_coockie и совершается прыжок в обработку __inittern, переходим по нашему прыжку и листаем вверх.

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

найти там месседжбокс

два раза тыкнув по нему перейти в блок где видим такую картину

что бы посмотреть где оно используется нажмите на название и нажмите букву X(Ч русскую)

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

вот так выглядит пролог

вот так эпилог
так же мы можем посмотреть строки нажав сочетание клавиш Shift + F12

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

сейчас мы перейдем в динамический анализ!

для этого нам понадобиться x32dbg, перекидываем наш ехешник в поле

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

нажимаем эти 2 кнопки, выполнить до возврата и выполнить до пользовательского кода

вот мы нашли наш блок тыкаем два раза на инструкцию и нас перекидывает

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