Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Фантазия разработчиков, желающих защитить свою программу, порой не знает границ. Частенько им мало одного навешенного на софтину протектора, и они, как монашка из известного анекдота, натягивают их несколько штук последовательно. Порой тем же самым грешат и сами разработчики средств защиты. Случай подобного симбиоза IL-обфускатора с VMProtect мы и рассмотрим в сегодняшней статье.
.NET-обфускатор DNGuard HVM существует довольно долгое время, за которое он успел обзавестись изрядным количеством фич (антиотладка и антидамп, тотальное шифрование всей информации в модуле и весьма успешное противодействие статическому и динамическому анализу). Несмотря на широкую известность и неплохую изученность (в свое время CodeCracker запилил множество распаковщиков под разные версии DNGuard и сопутствующих фреймворков), последние несколько лет средства анализа и распаковки для актуальных версий этого обфускатора напрочь отсутствуют. Вплоть до того, что популярные инструменты (и даже Detect It Easy) до сих пор не научились их даже детектировать. Поэтому, надеюсь, сегодняшняя статья поможет читателю разобраться, как распознать эту заразу и бороться с ней подручными средствами.
warning
Статья имеет ознакомительный характер и предназначена для специалистов по безопасности, проводящих тестирование в рамках контракта. Автор и редакция не несут ответственности за любой вред, причиненный с применением изложенной информации. Распространение вредоносных программ, нарушение работы систем и нарушение тайны переписки преследуются по закону.
Итак, предположим, что в твои загребущие руки попала сборка, защищенная DNGuard. Есть два варианта. Первый: нам повезло, и это одна из старых изученных версий, тогда все ясно и можно смело пользоваться одним из дамперов DNGuard_HVM_Unpacker от CodeCracker. Возможно, я когда‑нибудь и расскажу об особенностях и даже принципах работы этих утилит. Однако DNGuard совершенствуется стремительно, а проект, судя по всему, давно заброшен: последняя версия поддерживаемого фреймворка была 4.2, а физическая привязка к конкретным файлам библиотек настолько сильна, что делает использование данных наработок малополезным в деобфускации новых версий.
Поэтому сразу переходим к более грустному варианту. Как я уже писал выше, хоть актуальные версии и не детектятся, однако сильно и не скрываются. В рабочем каталоге программы сразу бросается в глаза библиотека runtime.dll
(или со схожим названием), с навешенным на ней VMProtect на минималках.
Внутри библиотеки обнаруживаются две экспортируемые функции: VMRuntime
и GetUserString
(или ResolveString
).
Еще одна характерная черта — VMProtect’овская секция hvm0
, из‑за которой этот обфускатор, насколько я понимаю, и получил такое название.
Впрочем, наличие этой библиотеки в каталоге в явном виде вовсе необязательно, самые последние версии научились держать ее в зашифрованном виде в теле основной программы, рожая ее при загрузке в системные временные каталоги типа Temp
или ProgramData
. Cама программа, защищенная этим обфускатором, тоже выглядит достаточно характерным образом при загрузке в отладчик вроде dnSpy.
Как видно, для стартап‑кода программы характерно наличие класса с методами CheckRuntime
, CheckString
, GetUserString
и так далее и импортом упомянутых выше функций из библиотеки Runtime.dll
. Так же как и во всех серьезных обфускаторах, о которых я писал в предыдущих статьях, названия остальных классов, методов, строк и ресурсов жестко пошифрованы, а тела методов пусты или содержат вызов исключения «Error, DNGuard Runtime library not loaded!» (причем даже эта строка может быть зашифрована).
Собственно, если попробовать запустить такое приложение из отладчика, максимум, что мы сможем увидеть, — это инициализация стартап‑кода DNGuard до нативного вызова VMRuntime, после чего тот перехватывает на себя JIT-компилятор и мы прощаемся с отладчиком, словив подобное исключение.
Попытка приаттачиться к запущенному процессу тоже не дает полезного результата, так же как и дамп его всеми известными дамперами. Поэтому закрываем dnSpy и начинаем вспоминать матчасть, в том числе информацию, изложенную в моей статье «Реверсинг .NET. Как искать JIT-компилятор в приложениях».
Для тех, кто не читал статью, напомню ее суть в двух словах. Как известно, любая .NET-сборка устроена следующим образом: кросс‑платформенный IL-код хранится в специальных метаданных, из которых подгружается по мере исполнения каждого метода и компилируется в нативный код специальной функцией. Указатель на нее возвращает функция GetGit
библиотеки clrjit.dll
, однако фреймворк любезно предоставляет пользователю самому устанавливать адрес на компилятор, чем беззастенчиво пользуются создатели всевозможных обфускаторов, подменяя ее своими процедурами расшифровки IL-кода.
Источник: xakep.ru