Pull to refresh

Comments 14

Статья хорошая, но мне кажется, что демо версия вмпротектора ничего толком не защищает. Попробуйте взять полную 2.12.3, её несложно найти в сети.
Спасибо. Что касается VMProtect'a, то для тестов я брал именно 2.12.3, а вот Safengine бралась демо и там явно урезана обфускация
Понятно. Правда мне кажется, что если внутри черного ящика будет шифрование (и константа(ключ) не будет зашита, а будет генериться как нибудь кодом, например)
а внутри другого — расшифровывание, то фиг вы чего стрейсите. Тут можно идти ва-банк и менять константы в криптоалгоритмах и вообще творить что душе угодно, на выходе все равно будет белиберда.
Понимаете, тут проблема в том, что мы любые вычисления можем отслеживать по обращениям к памяти. Стек, глобальная память, кучи, всё это нам извесно. Ведь если вы будете расшифровывать что-то или генерировать, то как не крути для хранения данных и промежуточных вычислений будет использоватся память. Другое дело если это реализовать на регистровой арифметике, с минимальными обращениями к памяти, такой код очень хорошо будет разбавлен мусором и его ревер будет возможен только деобфускацией. Но компиляторы генерируют код шаблонно, так что такое разве что на ассемблере можно сделать
UFO landed and left these words here
А вы посмотрите на пример из 0x03, в том эксперементе над кодом была произведена мутация + виртуализация, но трасса обращений к памяти была точно такой же как на не обфусцированном коде. Если мы зашифруем данные, то компилятор всё равно сгенерирует код, который будет скидывать результат в память после выполнения каждого выражения. Мы ведь не можем хранить все необходимые данные только в регистрах. Хотя в случаях когда промежуточные вычисления долго не скидываются в память, восстановить такой код достаточно сложно, но это не в стиле компиляторов.
UFO landed and left these words here
Что касается общей сложности, тут не поспоришь, но никто не говорит что это нужно в ручную анализировать, я лишь показал базовые возможности трассировки.

То есть в памяти в расшифрованном виде вообще ничего нет, любое обращение к данным приводит к расшифровке.

Почему вы так решили? Разве расшифрованные данные и вычесления хранятся в регистровой памяти? Нет, они скорее всего будут находится в промежуточном буфере, который можно предугадать(стек) и трассировать.

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

Необязательно трассировать только входные параметры, мы можем трассировать стек (локальные буферы), кучу, глобальную память модуля. Т.е. можно предпологать, что в нашем распоряжении может быть доступ к любым данным используемым в закрытом алгоритме и все обращения к ним трассируются.
5 п. Сейчас популярно передавать обфусцированный код оптимизирующему компилятору и на выходе получить вполне читабельный код.
Вот схема работы на LLVM:
1) Чтение обфусцированного кода.
2) Трансляция в LLVM bitcode.
3) Построение CFG.
4) Оптимизация.
5) Генерация оптимизированного кода.

Есть несколько попыток реализации:
а) Fracture
b) Dagger
c) Opticode online
Спасибо, в принципе я этот процесс так и представлял
Спасибо за статью, познавательно. Если есть желание посмотреть на работу полноценной купленной Safengine могу запаковать Вам крякми на Ваш выбор.
Интересная статья. С Themida подобных исследований не проводили? Столкнулся с тем, что разработчики Themida «проверенным» пользователям могут давать кастомные версии своего продукта.
Нет с темидой я не тестировал, но думаю темида будет страдать от тех же проблем
UFO landed and left these words here
Only those users with full accounts are able to leave comments. Log in, please.