-
Автор темы
- #1
Цель данного анализа - предоставить образовательные ресурсы о борьбе с вредоносным ПО. Все действия выполняются на ваш страх и риск.
Тестируемая версия - 6.9.0.0. Под прицелом самое интересное, остальное легко снимается.
1. Native EXE File
Протектор предлагает возможность обернуть файл в нативный стаб. Архитектура - x86. К сожалению малдева, легко снимается. Использует COM.
Первым делом стаб проверяет, идет ли профилирование процесса. Также он ищет DLL, относящиеся к JIT`у, и если находит, то закрывает хендл CreateToolhelp32Snapshot`a и выходит:

Затем стаб читает ресурс "__" и расшифровывает его:

Расшифровка идет в 2 или 3 функции, внутри которых идут еще функции и так далее. Например, decrypt1:

Затем начинается работа с CLR:

Заметили memcpy_0? Это наш ключ к победе.
Я составил паттерн вызова -
8B 44 24 48 55 57 50 E8 ?? ?? ?? ??
.Паттерн самой функции -
55 8B EC 57 56 8B 75 0C 8B 4D 10 8B 7D 08 8B C1 8B D1 03 C6 3B FE
.Время контрить
Вам понадобится плагин xSelectBlock. Перейдя в дамп, тыкайте ПКМ по 4D, затем xSelectBlock -> Select block. Смотрите на скрине.

Далее сохраняем в файл:

Работа с нативом закончена. Наш дамп оказался дотнетовской DLL. Кидаем в dnSpy. Оказывается, это еще один стаб. Все на скрине:

Это единственный класс. Как мы заметили, никакого шифрования. Это значит, что оригинальный файл лежит в ресурсах в чистом виде. Сохраняем, проверяем:


Итак, мы извлекли файл из стаба.
2. Виртуализация
Ассоциируется с истериками, мозгоеблей. Но тут у нас си-решеточка, все решаемо :)
Прежде всего: вот так выглядит метод decryptByte(я не уверен, правильно ли назвал, но выглядит правдоподобно):

Магия виртуализации начинается с вызова виртуализированного метода, где 0 - индекс, array - аргументы:

Прежде всего проверяется инициализация. Если false, то вызывается метод readBytecodeResourceAndDoStuff:

Затем начинается чтение байткода согласно индексу. Подготавливаются некоторые данные, включая токен метода, количество виртуальных инструкций. Парсятся параметры:

Проверяется валиднось опкода, подготавливаются некоторые данные и добавляется опкод + операнд в список инструкций:

Во время отладки я заглянул в этот список и увидел некоторые сходства с оригинальным набором инструкций:

Вот оригинал:

После еще некоторой подготовки начинается выполнение. Я заметил класс, в котором есть метод, выполняющий наш байткод:

Сам метод:

Метод resolveHandlerAndExecute содержит огромную конструкцию switch, которая ищет хандлер согласно номеру опкода:

Проблема реверса этой ВМ в количестве опкодов. Вот конец switch`a:

Отлаживая, я рассмотрел носколько хандлеров. Вот, например, хандлек call`a:

Самое сочное:

Напоследок, вот так выглядит (часть?) стека:

На этом с виртуализацией все. У меня мало времени, а еще я умудрился сломать файл из-за некорректного ремапа ^^.
В теории можно хукнуть с помощью Harmony и логгировать все, и этого будет достаточно. Еще в dnSpy можно настроить бряки(условия, кол-во хитов, фильтр и логгирование при хите). Брякаем VmStack.Push() и Invoke(), и пишем аргументы в консоль.
Особо усидчивые могут реверснуть каждый хандлер и сделать девиртуализатор. Я не уверен, уникальна ли ВМ в каждом билде. Девиртуализация займет много времени, и могут возникнуть сложности(например, опкоды уникальны, и придется искать хандлеры по паттернам), но оно того стоит, и это намного легче любого натива.