- PVSM.RU - https://www.pvsm.ru -

M-o-Vfuscator2, безумный компилятор

M-o-Vfuscator2, безумный компилятор - 1

Однажды один умный чувак (Кристофер Домас) читал статью другого умного чувака (Стивена Долана) про удивительную особенность архитектуры x86. Стивен ругал её за избыточность и утверждал, что набор инструкций можно сократить до одной лишь mov, потому что она Тюринг-полная. Если бы Стивен не был таким умным, в его словах можно было бы усомниться, но у Кристофера загорелись глаза: проработав двадцать лет с x86, он не слышал ни о чём подобном, и ему страшно захотелось написать компилятор, который бы переводил весь код в наборы одних лишь mov-инструкций. Так родились M/o/Vfuscator [1] и M/o/Vfuscator2 [2], наглядно иллюстрирующие ненормальное программирование.

Идея

Небольшое отступление про инструкцию mov: это самая простая инструкция в ассемблере, перемещающая значение из памяти в регистры или из регистров в память. Как может штука, перекладывающая байты из одного места в другое, оказаться Тьюринг-полной? Ну, если вам правда интересно, почитайте оригинальную статью [3] Стивена с доказательством. Если не очень, перейдём сразу к выводу:

Удаление из будущих итераций архитектуры x86 всех инструкций, кроме mov, может обеспечить множество плюсов: формат инструкций будет значительно упрощен, дорогой блок декодирования станет намного дешевле в выполнении, а кремний, используемый в настоящее время для сложных функциональных блоков, можно было бы использовать для еще большего увеличения кэша. Как только кто-нибудь реализует компилятор.

Собственно, на последних словах Кристофер и загорается этой идеей и попутно соображает, что через подобную компиляцию можно нехило так обфусцировать код — сам чёрт ногу сломит в этих бесконечных mov'ax! Для сравнения, обычный, «читаемый» ассемблер:

M-o-Vfuscator2, безумный компилятор - 2

и та же самая программа на мувах:

M-o-Vfuscator2, безумный компилятор - 3

Представьте, какое немыслимое количество операций нужно совершить чтобы отреверсить такой код? Крис сам занимается реверс-инжинирингом, он понимает что это полное безумие — и поэтому кайфует ещё больше от своего проекта. В первую очередь, он выписывает основные принципы Стивена, на которых будет держаться компилятор:

mov может сравнивать значения
Допустим, вы хотите сравнить x и y, для этого вам понадобится следующий код:

  mov [x], 0
  mov [y], 1
  mov R, [x]

Если x == y, то в третьей строчке, где считывается значение по адресу x, окажется не ноль, а перезаписавшая его единица.
Если x != y, то считается ноль, так как единица лежит по другому адресу.

Код выполняется без ветвлений
Согласно идее Стивена, правильно написанный блок кода может либо что-то делать, либо не делать, в зависимости (только!) от исходного состояния системы. То есть ветвление отсутствует как класс, если абсолютно все инструкции исполняются последовательно.

M-o-Vfuscator2, безумный компилятор - 4

Ограничения
Для выполнения требуется одна инструкция jmp start (в конце списка mov'ов) для перевода программы в начало; для остановки нужен заведомо нерабочий адрес памяти.

Дальше Крис добавляет свои требования:

  • Использовать примитивные операции машины Тьюринга как основу для высокоуровневой логики
  • Работать надо с реальными данными, не с абстрактными символами (эксперимент Стивена всё-таки академичен, далёк от реального мира)
  • Должны быть реализованы основные операции: условные ветвления, арифметика, логика, циклы и так далее

Подробно о реализации некоторых вещей можно послушать в его докладе по ссылке [4] (таймкод 9:06), а мы сразу перепрыгнем к состоянию «оно реализовано и работает», чтобы не пересказывать оригинал.

Реализация

Первая версия компилятора была написана для брейнфака, для ощущения максимального абсурда и тщетности жизни реверсера, но, конечно, она осталась ужасно далека от реальных примеров и задач. Поэтому Крис спустя пару лет ВНЕЗАПНО выпустил M/o/Vfuscator2, рабочий mov-компилятор для С. Впечатляющий апгрейд, не правда ли?

M-o-Vfuscator2, безумный компилятор - 5

M-o-Vfuscator2, безумный компилятор - 6

Заявлена относительно легкая адаптация компилятора под другие платформы и языки, но всё же создавался он именно для x86, и с ним связан ворох особенностей и ограничений:

  • Для дробных чисел используется самописный эмулятор плавающей точки, из-за размера поставляется в трёх версиях: softfloat32.o для float, softfloat64.o для float и double, и softfloatfull для полной поддержки стандарта IEEE
  • Так как арифметика строится на таблицах поиска, таблицы символов могут занимать огромное количество места, и их, возможно, придётся обрезать флагом -s
  • Компилятор работает строго на C89 из-за использования LCC в качестве фронтенда. Нельзя использовать bool, for (int ...), и другие фишки C99
  • Код с нестрогой типизацией или небезопасными конвертациями, скорее всего, не скомпилируется — тоже из-за LCC
  • Функция, использующая внешние библиотеки, без прототипа лишает компилятор информации о необходимости и моменте подключения этих библиотек, что почти гарантированно повесит приложение
  • Вызовы внешних функций (printf и т.д.) через указатели функций еще не реализованы
  • Для подключения библиотек, скомпилированных не на mov, могут потребоваться другие инструкции. Полностью избавиться от них можно, перекомпилировав в mov все ресурсы

Заключение

Несмотря на всю крутизну проекта и Кристофера, нужно понимать, что такая обфускация скорее игрушка, чем реальный рабочий инструмент. И всё же, учитывая возможность прикрутить другие фронтенды и архитектуры открывает для M/o/Vfuscator больше возможностей, чем мог бы получить другой безумный ассемблерный проект.

Информацию по установке и использованию можно найти на гитхабе [2].


На правах рекламы

Эпично! Недорогие серверы [5] на базе новейших процессоров AMD EPYC для размещения проектов любой сложности, от корпоративных сетей и игровых проектов до лендингов и VPN.

Присоединяйтесь к нашему чату в Telegram [6].

M-o-Vfuscator2, безумный компилятор - 7 [5]

Автор: Mikhail

Источник [7]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/nenormal-noe-programmirovanie/364455

Ссылки в тексте:

[1] M/o/Vfuscator: https://github.com/Battelle/movfuscator/blob/master/poc

[2] M/o/Vfuscator2: https://github.com/Battelle/movfuscator

[3] оригинальную статью: https://web.archive.org/web/20190331191157/https://www.cl.cam.ac.uk/~sd601/papers/mov.pdf

[4] ссылке: https://youtu.be/R7EEoWg6Ekk?t=546

[5] Недорогие серверы: https://vdsina.ru/cloud-servers?partner=habr385

[6] нашему чату в Telegram: https://t.me/vdsina

[7] Источник: https://habr.com/ru/post/558458/?utm_source=habrahabr&utm_medium=rss&utm_campaign=558458