Русский
Русский
English
Статистика
Реклама

Исполняемый обвес. Часть 2

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

Описание работы VMProtect

Рассматриваемая защита имеет ряд функций, которые здорово портят жизнь реверс-инженеру. Например:

  1. Создание полиморфных обработчиков для одной и той же программы;

  2. Однонаправленное кодирование команд процессора;

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

Дизассемблированный граф выглядит так:

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

Чтобы проанализировать приложение, нужно понимать, как строится код VMP и как он обрабатывает различные команды. Приведем в качестве шаблона следующий псевдокод.

pusha ; сохранить все регистрыpush 0 ; установка начального значенияmov esi, [esp+x+var] ; esi = указатель на VM байт код, адрес может меняться за счет x и varmov ebp, esp ; так как VMProtect использует стековую виртуальную машину, то ebp = VM "stack" указательsub esp, 0C0hmov edi, esp ; edi = область памяти, где находятся регистры общего назначенияСместить обработчик:add esi, [ebp+0]Выбрать следующую команду:mov al, [esi]; читаем байт байткода в EIP виртуальной машиныmovzx eax, alsub esi, -1; смещаем значение EIP виртуальной машиныjmp ds:VMHandlers[eax*4] ; выполняем обработчик команды

Теперь тоже самое, но на графе:

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

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

Отладка VM

Для отладки будем использовать x64dbg, на сегодняшний день это самый активно развивающийся отладчик для ОС Windows (помимо WinDBG). Вообще можно пользоваться любым отладчиком, лишь бы вы могли удобно видеть регистры и память, с которой работает приложение. Загрузим приложение в отладчик и встанем на первую команду протектора:

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

На рисунке пунктирной красной рамкой выделен main loop. Это основной цикл, который работает с байткодом, расположенным по адресу из регистра ESI. EIP для виртуальной машины является AX регистр. В него помещаются идентификаторы обработчиков. В итоге, чтобы получить развернутый листинг приложения, нам нужно собрать номера вызываемых обработчиков. Сделать это можно либо используя приложение, которое будет самостоятельно парсить сегмент упакованного исполняемого файла, либо нужно установить условный breakpoint, который будет регистрировать заданные данные. Будем использовать второй метод и запишем в лог отладчика все номера вызванных хэндлеров.

Для начала определим точку, где индекс хэндлера можно получить уже после вычислений:

Теперь откроем меню "breakpoints" и установим вот такие значения:

Настройка достаточно проста, поле "Log Text" используется для занесения данных в лог отладчика. Формат строки, которая заполняется из регистров или локальных переменных отладчика выглядит так: {формат данных:объект откуда взять данные}. В нашем случае мы просматриваем регистр eax и локальную переменную $breakpointcounter.

Поле Command Text позволяет выполнять операции автоматически по достижению адреса точки останова. В нашем случае мы ничего не делаем, поэтому команда просто продолжает выполнение приложения.

Посмотрим на результат:

Итак, у нас есть индексы обработчиков и их количество 669. Согласитесь, разбирать такое количество обработчиков достаточно трудоемкий процесс, однако уникальных индексов может быть гораздо меньше. Попробуем это выяснить. Для фильтрации будем использовать notepad++ и его функцию замены текста:

Для замены использовалась следующая регулярка: ^(.*?)$\s+?^(?=.*^\1$) Итого у нас 53 уникальных индекса для хэндлеров. Уже лучше, перейдем к следующему этапу.

Сбор команд алгоритма

К сожалению, на этом этапе придется попрощаться на время с отладчиком и заняться программированием. Основная наша задача будет получение общего листинга всех обработчиков приложения, которые вызываются последовательно из main loop. Зачем это нужно? Чтобы собрать алгоритм воедино и попробовать его оптимизировать для разбора.

Скрипт, который нам поможет собрать обработчики в единую последовательность команд:

import pefile# загружаем файлpe = pefile.PE(filePath)# помещаем в памятьimage = pe.get_memory_mapped_image()# смещение до таблицы хэндлеровbaseOffset = 0xB400# Всего 255 хэндлеров в исполняемом файлаhandlers = []for i in range(255):    offset+=4    handlers.append(image[offset])# собираем байткод хэндлеровfor h in handlers:    md = Cs(CS_ARCH_X86, CS_MODE_32)    for i in md.disasm(h, 0x1000):        print("0x%x:\t%s\t%s" %(i.address, i.mnemonic, i.op_str))

Фрагмент получаемого листинга:

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


Автор статьи Александр Колесников.

Статья приурочена к курсу "Reverse-Engineering. Basic".

Приглашаем также посетить открытый вебинар на тему Эксплуатация уязвимостей в драйвере. Часть 2: разберём уязвимость переполнения пула памяти и уязвимость типа type confusion; напишем эксплойт.

Источник: habr.com
К списку статей
Опубликовано: 16.03.2021 20:17:50
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Блог компании otus

Реверс-инжиниринг

Reverse-engineering

Vmprotect

Защита кода

Эксплойт

Эксплуатация уязвимостей

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru