EAC под скальпелем: девиртуализация Linux-модуля Easy Anti-Cheat
Инженер Hex-Rays разобрал VM-защиту Linux-сборки EAC и восстановил из байткода компилируемый C. Восстановленный код проверяется регрессионными тестами против исполнения оригинальной виртуальной машины.
Объект исследования —
plx.elf, x86-64 ELF со смешанным исполнением: часть кода нативная, часть упакована в собственную VM. Репозиторий содержит полный пайплайн и все артефакты, а не просто дамп.
Инвентаризация VMКаталогизировано 360 хендлеров и 2107 entry-стабов. Хендлеры классифицируются и символически лифтятся на базе Capstone. Затем каждый стаб трассируется в конкретном и символическом режимах, а трассы группируются в функции. Итог: 107 восстановленных функций.
Границы вызововОтдельная задача — найти места, где VM-код передаёт управление нативному. Восстановлено 243 inline-модели, 249 внешних нативных целей и 31 API-импорт. Сгенерированный C собирается в
libeac_devirt.so и
.dylib.
Сшивка с оригиналомСгенерированный код ребейзится на
0x1000000 и дописывается в исходный ELF. Применено 730 релокаций, пропатчено 1411 переходов, импорты привязаны к оригинальному PLT. В IDA 9.5 открываешь
plx_devirt_paths.i64 и переходишь между
devirt_sub_* и оригинальными
sub_* по xref.
Что нашлось внутри•
sub_44D10 оказалась RC4 key scheduling. Старая трасса специализировала цикл инициализации на первой итерации и «протекала» конкретным регистровым sentinel. Новая модель совпадает с VM на 13 длинах ключа.
• Чтение
FS:[0x28] (stack canary) опущено до нативных FS/GS-загрузок.
• Деление через
__divti3 заменено на
divl/
idivl/
idivq с сохранением поведения #DE.
• Расшифровано 189 строковых адресов в
.rodata, из них 167 уникальных текстов.
ВерификацияГлавная ценность проекта — дисциплина проверок. Набор из 21 регрессионного теста включает 128 сравнений continuation-ов на
-O0 и
-O2 с эмуляцией оригинальной VM в Unicorn. На 64 комбинациях входов сверяются 15 GPR, флаги CF/PF/ZF/SF/OF и 512 байт гостевого стека. Бюджет восстановления поднят с 200 до 1024 хендлеров, а вложенные символические ветки возвращаются в CFG-worklist. Все артефакты привязаны к SHA-256.
ОграниченияОстаётся внешняя зависимость
vm_read_xmm: 40 мест сохранения XMM6–XMM15 в четырёх функциях. В выводе Hex-Rays ещё есть дефекты реконструкции циклов. Найдено 10 пропущенных VM-входов. Эквивалентность всей программы автор прямо называет непроверенной.
Любопытная деталь: лифтинг, трассировку и аудит автор выполнял с помощью LLM через Hex-Rays IDA Assist. Репозиторий опубликован "исключительно" для изучения VM-защит.
Repo: github.com/19h/eac-linux-devirt @poxek | @poxek_ai |
MAX