Наномиты и техника «Debug Blocker» в приложениях Linux
Автор: Apriorit.inc
Перевод: K.St0rke
Введение
Продолжая исследование антиотладки, в этой статье мы исследуем один из современных методов борьбы с отладкой и дампингом, который основан на наномитах.
Этот приём впервые был введён в протекторе Armadillo для защиты приложений ОС Windows. В этой статье мы рассмотрим возможно применение этой техники в решении задач под ОС Linux.
Протектор Armadillo
Armadillo (также известен как SoftwarePassport) является коммерческим протектором с богатой историей развития. Первый выпуск состоялся 15 января 1999 года. Разработчиком протектора являлась фирма Silicon Realms, в качестве ведущего разработчика выступал Чарльз Нельсон.
Один из методов, используемых Armadillo являются наномиты.
Механизм работы наномитов в Armadillo
«Debug Blocker»
Armadillo использует защиту родительским процессом. В ОС Windows, процесс может отлаживаться только одним отладчиком пользовательского уровня. Это использовано в Armadillo. Сначла создаётся процесс, который в свою очередь порождает дочерний процесс и начинает его отлаживать. В результате, отлаживать можно только процесс-отладчик. Эта техника полчила назание «Debug Blocker».
«Armadillo Nanomites»
Программист, использующий Armadillo на стадии написания кода отмечает участки кода в исходном коде программы. Компилятор оставляет эти маркеры нетронутыми после компиляции. Это позволяет протектору найти код требующий защиты. После нахождения кода он вырезает его и программы и упаковывает. При распаковке программы, вырезанные участки кода записываются в выделенную память и на них осуществляются прыжки, это называется «jmp-вермишель».
Затем обрабатываются условные и безусловные переходы в защищаемой области. Вместо переходов (Jxx) устанавливаются отладочные прерывания INT3 (0xCC), также они могут устанавливаться произвольно, являясь мусорными прерываниями. Для обработки прерывания создаётся таблица, содержащая флаги, размер и смещение прыжка.
При исполнении кода постоянно возникают отладочные исключения и управление передаётся процессу-отладчику, он в свою очередь проверяет исключение по таблице, и если оно ложно продолжает исполнение со следующего адреса, если оно не ложно, то проверяются флаги, пр и которых должен быть совершён прыжок, для определения адреса прыжка берётся значение размера участка кода + смещение.
Этот метод — самое мощное оружие этого протектора, поскольку нет 100% надёжного средства борьбы с наномитами.
Борьба с наномитами
Существует три основных способа борьбы с наномитами. Первый из них - повторное навешивание отладочного процесса, либо включение VEH с последующим включением в код отладчика таблиц наномитов. По сути отладчик защиты заменяется отладчиком крэкера. Исследовать такую программу - не самое приятное занятие, отсутствие переходов и мусорные байты ломают работу почти всех анализаторов. Второй способ - запуск программы под анпакером или встроенным в распакованную программу отладчиком. Во время работы программы следует постараться воспользоваться как можно большим числом возможностей программы, попробовать разные комбинации возможных настроек. Так постепенно можно собрать информацию о "настоящих" наномитах и восстановить их. Поскольку все наномиты таким способом вряд ли можно восстановить, способ кобминируют с первым. Третий способ самый сложный в реализации - анализатор. Анализатор должен "выполнить" код и пройтись по всем его ветвлениям, а напарываясь на наномиты восстанавливать их по таблице. Сложность здесь возникает в обработке switch-таблиц, табличных вызовов (вызовы методов классов и конструкторов высокоуровневых языков выглядят на низком уровне, например
call ds:[edx+410h]), а также API функций с параметрами-CALLBACK'ами.
Трудности реверсинга приложений, защищённых наномитами
1. Debug blocker требует специального подхода. Мы не можем присоединиться с отладчиком к процессу, который уже отлаживается в третьем кольце. Единственная опция - нулевое кольцо, и это не очень удобно. Отсоединение родительского процесса возможно только после восстановления всей таблицы наномитов. Результат попытки присоединения отладчика к процессу, защищенному наномитами:
2. Из-за отсутствия переходов в коде, приложение выглядит как сплошной кусок кода в дизассемблерах (например, IDA Pro), и это затрудняет любой анализ. Код выглядить следующим образом:
Недостатки использования наномитов
1. Главный недостаток - производительность. Каждый раз, когда выполнение сталкивается с наномитом, контекст переключается, управление передаётся родительскому процессу. Эта процедура очень медлительна, поэтому лучше использовать наномиты в не критических по скорости участках кода.
2. Этот механизм может конфликтовать с другими антиотладочными методами.
Исправления make-файлов защищенного проекта требуются для реализации этого механизма, и это не всегда удобно.
Описание проекта в Linux
Проект проектирован под 32-разрядные приложения Linux. Но принципы могут легко быть реализованы для других операционных систем, таким образом, запланировано и дальнейшее развитие.
Во-первых, мы будем смотреть на создание пользовательского отладчика для Linux. После этого мы будем двигаться к реализации наномитов. Binutils и Perl используются для компиляции проекта.
Мы применим комбинацию двух методов: Наномиты и Debug Blocker.
Основная идея
Библиотека Linux Code Protection включает 2 основных компонента:Есть также набор скриптов для добавления наномитов к приложению и для создания таблицы наномитов.
- Nanomites: статическая библиотека, которая содержит отладчик, обрабатывает логику.
- Debugger Nanomites: исполняемый файл отладчика, собран с библиотекой Nanomites.
Пошаговое создание защищённого приложения
Приложение с ключом –S для создания ассемблерного листинга создано;
Ассемблерный листинг проанализирован Perl скриптом. Все переходы и вызовы (например, jmp, jz, jne, call, и т.д.) обработаны и заменены instructionOffsetLabel (N): int 3;
После этого пользовательское приложение, которое состоит из измененных ассемблерных вставок, собрано. С помощью сценария Perl проанализировано собранное приложение, и таблица наномитов создана.
Описание библиотеки отладчика
Наш отладчик основывается на ptrace (трассировка процесса), который существует в некоторых подобных Unix системах (включая Linux, FreeBSD, Mac OS X). Он позволяет отлаживать выбранный процесс. Можно сказать, что ptrace обеспечивает полный контроль над процессом: мы можем изменить поток выполнения приложения, дисплей и изменить значения в состояниях реестра или памяти. Нужно упомянуть, что нам не предоставляется никаких дополнительных прав: возможные действия ограничены полномочиями запущенного процесса. Кроме того, когда программа с setuid трассируется, бит привелегий не работает, поскольку права не передаются.
После того, как демо приложение обработано скриптами, это весьма зависимо, и если это запущено без отладчика, «отказ сегментации» появляется сразу. Отладчик запускает демонстрационное приложение с этого времени. С этой целью дочерний процесс создается в отладчике, и затем родительский процесс присоединяется к нему. Все события отладки от дочернего процесса обработаны в цикле. Это включает все события перехода; родительский процесс анализирует nanomite таблицу и таблицу флагов, чтобы выполнить корректное действие.
Преимущество решения по сравнению с Armadillo
В Armadillo изменен бинарный код. Поэтому когда 2/5-байтовый прыжок заменён более короткой 1-байтовой инструкцией INT 3 (0xCC), остается свободное место. Соответственно, мы можем и должны записать исходную команду перехода вместо INT 3, чтобы восстановить наномит.
В нашем решении мы изменяем код на уровне исходного кода. Поэтому размер наномита будет равен 1 байту. Соответственно, восстановить наномит, просто переписав его на исходный прыжок не возможно. И мы не можем расширить размер, выделенный под наномит, поскольку все относительные переходы были бы повреждены. Но есть способ восстановить наш наномит, например ниже.
Восстановление наномитов в Linux
Хакер может создать дополнительный раздел в исполняемом файле, затем найти наномит и получить его команду перехода и соответственно адрес перехода.
Тогда восстановление произойдёт следующим образом:
Такое решение сложно в реализации. Во-первых, для автоматизации требуется механизм дизассемблера, во-вторых, перемещенные инструкции могут содержать команды перехода с относительными переходами, которые потребуют исправлений.
Оффициальный сайт проекта - apriorit.com







Reply With Quote
Thanks
