Введение в реверсинг с нуля используя IDA PRO. Часть 14. (Часть 1)

NullX

Участник
Клуб
Студент
Регистрация
30.06.18
Сообщения
141
Лучшие ответы
0
Реакции
320
Баллы
12
Это курс будет смешанным, и он будет включать в себя разные темы связанные с реверсингом (мы уже говорили о статическом реверсинге, а также будем говорить об отладке, распаковке, эксплоитинге).

В этой главе мы будем распаковывать файл CRACKME.EXE упакованный последним UPX. Это не означает, что мы собираемся cделать много частей только с распаковкой, мы будем менять темы разговора, и перемешивать различные темы, для того, чтобы никто не скучал, так что у нас будут уроки по распаковке, смешанные с другими темами.

Упакованные файлы

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

Существует тысяча видов упаковщиков и большинство из них являются протекторами, которые изменяют IAT или таблицу импорта, а также изменяют ЗАГОЛОВОК, они добавляют анти-отладочный код, чтобы предотвратить распаковку и восстановление исходного файла.

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

1.png


Мы будем помещать галочку в MANUAL LOAD и снимать другую с пункта CREATE IMPORTS SEGMENT так как нам необходимо, чтобы у нас были загружены все секции программы,
и если она может влиять на галочку CREATE IMPORTS SEGMENTS, то я про это не знаю, но IDA советует снять эту галочку при работе с упакованными файлами.

2.png


Это начало или EP файла PACKED_CRACKME.EXE, мы видим, что она находится по адресу 0x409BE0, в то время как оригинальная EP находилась по адресу 0x401000, как мы видим ниже.

3.png


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

OРИГИНАЛЬНЫЙ

4.png


УПАКОВАННЫЙ

5.png


Мы видим, что секция UPX0 упаковщика заканчивается по адресу 0x409000, в то время как в исходном файле все секции расположены в памяти начиная с адреса 0x401000 и заканчиваются по адресу 0x408200.

Здесь мы начинаем говорить о виртуальной памяти, т.е. когда программа запускается, она может иметь 1 килобайт на жестком диске, а резервировать 20 килобайт или сколько она пожелает в памяти.

Это возможно видеть в IDA, например, по адресу начала секции исходного файла 0x401000 мы видим.

6.png


Вышеупомянутая секция (SECTION SIZE IN FILE) занимает 0x600 байт в файле, в то время как в памяти (VIRTUAL SIZE) она занимает 0x1000 байт.

В то время, как у упакованного файла, если мы идём по адресу 0x401000, который является началом секции UPX0, мы видим.

7.png


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

8.png


Также мы видим, что адрес 0x401000 имеет впереди префикс DWORD_, который означает, что его содержимым является данные типа DWORD.

Знак (?) означает, что место только зарезервировано, т.е. оно не имеет содержимого и DUP или умножитель, означает, что этот DWORD умножается на 0xC00 и в итоге получится 0x3000 зарезервированных байт.

9.png


Затем по адресу 0x404000 есть 0x1400 DWORD символов (?), это место тоже зарезервировано.

10.png


То есть, в памяти резервируется 0x8000 байт, чтобы загрузить туда программу.

11.png


Также мы видим, что по адресу 0x401000 есть ссылка на исполняемый код, позже мы увидим, что это он и что он делает.

12.png


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

Если мы видим ссылки по адресу начала секции 0x409000.

Мы видим, что ниже (DOWN) есть ссылка в исполняемой части, если мы щелкнем на неё.

13.png


14.png


Мы видим, что в СТАБЕ после EP загружается адрес 0x409000 (запомните СМЕЩЕНИЕ впереди).

Если мы нажмём на пробел, мы увидим там

15.png


Что код СТАБА находится в той же секции UPX1 под упакованным кодом исходной программы, в секции UPX1 у нас есть сохраненные байты исходной зашифрованной программы и код СТАБА находящийся по адресу 0x409BE0.

Нам не нужно быть гением, чтобы знать, что он будет читать байты по адресу начиная с адреса 0x409000, он применит некоторые операции над ними и сохранит их по адресу 0x401000. EDI = ESI - 0x8000.

16.png


17.png


Другими словами, видно, что он будет использовать содержимое ESI как ИСТОЧНИК откуда он будет читать данные, он будет применять к ним некоторые операции и сохранять их в содержимое EDI, для создания программы.

Ранее мы сказали, что по адресу 0x401000 есть ссылка на исполняемый код, если мы сделаем двойной щелчок по этой ссылке.

18.png


Мы видим, что есть переход в 0x401000.

19.png


JMP NEAR это прямой переход по адресу, который находится рядом с ним, т.е. он будет переходить по адресу 0x401000, очевидно, здесь, позже, выполнится весь СТАБ и создастся исходный код, он будет переходить в OEP по адресу 0x401000, что будет OEP, которая отличается от EP СТАБА тем, что находится по адресу 0x00409BE0.

Мы будем вызывать OEP или ORIGINAL ENTRY POINT в ENTRY POINT исходной программы, очевидно, так как это упакованная программа, то мы не знаем где она находится и только поскольку мы у нас есть исходная программа, мы можем знать, что OEP была по адресу 0x401000.

20.png


Очевидно, когда у нас есть упакованная программа, то мы не знаем её OEP, потому что мы не имеем исходной программы, поэтому нам нужно научиться её находить, следовательно, когда СТАБ закончит выполнять все свои трюки и закончит создавать исходный код, он будет переходить туда для выполнения программы, почти всегда первая инструкция кода, которую он выполняет в созданной секции, будет OEP.

Мы могли бы установить BP в этот JMP на OEP, чтобы увидеть есть ли там оригинальная программа, которая уже создана, давайте попробуем.

21.png


Давайте выберем отладчик LOCAL WIN32 DEBUGGER и давайте нажмём START DEBUGGER.

22.png


Здесь я останавливаюсь на переходе в OEP, мы трассируем его с помощью F8.

23.png


Мы нажимаем YES для того, чтобы отладчик интерпретировал как КОД первую секцию UPX0, которая была определена как ДАННЫЕ.

24.png


Мы видим, что отладчик уже распаковал код и теперь переходим туда, чтобы выполнить его. Код очень похож на код оригинальной программы по адресу 0x401000, хотя, мы видим, что если мы захотим перейти в графический режим, у нас ничего не получится, потому что код не определен как функция (loc_401000), но мы сделаем это автоматически.

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

25.png


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

26.png
 
Сверху