
ARM64 ELF Система защиты виртуальной машины
Система защиты ARM64 ELF на основе виртуальной машины
Преобразует нативные инструкции ARM64 в пользовательский байт-код ВМ для защиты кода на уровне функций
🇨🇳 中文文档 • Возможности • Архитектура • Быстрый старт • Использование • Лицензия
VMPacker — это система защиты с помощью виртуальной машины (VMP) для ARM64 (AArch64) Linux ELF-бинарных файлов. Она декодирует нативные инструкции ARM64 целевой функции в промежуточное представление, преобразует их в пользовательский байт-код ВМ и внедряет встроенный интерпретатор ВМ в ELF-файл. Во время выполнения защищённые функции исполняются интерпретатором ВМ вместо нативного выполнения.
ARM64 Native Code → Decode → Translate → Custom VM Bytecode
↓
Original ELF ← Inject ← VM Interpreter Stub
| Уровень | Техника | Описание |
|---|---|---|
| Защита ВМ | Пользовательская ISA | Случайное отображение опкодов — обратные инженеры не могут напрямую определить семантику инструкций |
| OpcodeCryptor | Шифрование опкода для каждой инструкции | enc[pc] = op[pc] ^ (key ^ (pc * 0x9E3779B9)) |
| Реверсирование байт-кода | Обратный порядок выполнения | Инструкции хранятся в обратном порядке; интерпретатор обходит их в обратную сторону |
| Токеновый вход | Трамплин из 3 инструкций | Исходная функция заменяется токенизированным входом, скрывающим фактическое местоположение байт-кода |
| Косвенная диспетчеризация | Таблица переходов по указателям на функции | Заполняется во время выполнения в стеке, нарушая перекрёстные ссылки IDA |
![]() |
![]() |
![]() |
| Список функций | Анализ и выбор | Параметры защиты |
![]() |
![]() |
|
| Логи в реальном времени | Защита завершена |
vmp/
├── cmd/vmpacker/ # Точка входа CLI
│ ├── main.go # Разбор аргументов CLI + оркестровка
│ └── vm_interp.bin # Скомпилированный интерпретатор ВМ (GCC, go:embed)
│
├── pkg/ # Основная библиотека Go
│ ├── arch/arm64/ # Поддержка архитектуры ARM64
│ │ ├── decoder.go # Таблично-управляемый декодер инструкций (реализует vm.Decoder)
│ │ ├── decode_*.go # Таблицы шаблонов декодирования (DP-IMM/DP-REG/Branch/LdSt)
│ │ ├── translator.go # Транслятор ARM64 → байт-код ВМ
│ │ ├── tr_alu.go # Трансляция ALU-инструкций
│ │ ├── tr_branch.go # Трансляция инструкций ветвления
│ │ ├── tr_loadstore.go # Трансляция инструкций работы с памятью
│ │ ├── tr_bitfield.go # Трансляция инструкций битовых полей
│ │ └── tr_special.go # Специальные инструкции (ADRP/ADR)
│ ├── vm/ # Определения ISA ВМ
│ │ ├── types.go # Общие типы + интерфейсы (Decoder/Translator/Packer)
│ │ ├── opcodes.go # 58+ определений опкодов ВМ (случайно отображаемые значения)
│ │ └── disasm.go # Дизассемблер байт-кода ВМ
│ └── binary/elf/ # Манипуляции с ELF-бинарными файлами
│ ├── packer.go # Внедрение VMP в ELF (перехват PT_NOTE, генерация трамплина)
│ └── trampoline.go # Генерация кода трамплина
│
├── stub/ # Интерпретатор ВМ на C (скомпилирован в PIC плоский бинарник)
│ ├── vm_interp_clean.c # Основной цикл интерпретатора + точки входа
│ ├── vm_types.h # Контекст ЦП ВМ (vm_ctx_t)
│ ├── vm_opcodes.h # Определения опкодов на C (синхронизированы с opcodes.go)
│ ├── vm_decode.h # Утилиты чтения байт-кода
│ ├── vm_token.h # Кодирование/декодирование токена + таблица дескрипторов
│ ├── vm_dispatch.h # Таблица косвенной диспетчеризации
│ ├── vm_crc.h # Проверка целостности CRC32
│ ├── vm_sections.h # Макросы разброса секций обработчиков
│ ├── vm_interp.lds # Скрипт компоновщика
│ └── vm_handlers/ # Модульные обработчики инструкций
│ ├── h_alu.h # Арифметические/логические операции
│ ├── h_mem.h # Доступ к памяти
│ ├── h_branch.h # Ветвления/переходы
│ ├── h_cmp.h # Сравнения/условные операции
│ ├── h_mov.h # Перемещение данных
│ ├── h_stack.h # Стек (PUSH/POP)
│ └── h_system.h # Системные операции (SVC/MRS/BLR/BR/RET)
│
├── vmp-gui/ # Фронтенд GUI Wails
│ ├── frontend/ # Vue 3 + Element Plus
│ └── backend/ # Привязки бэкенда на Go
│
└── build/ # Предварительно скомпилированные инструменты + тестовые артефакты
Проект использует интерфейсно-ориентированную модульную архитектуру, что упрощает расширение на новые ISA и бинарные форматы:
// Интерфейс архитектурного декодера — расширяемый для x86, RISC-V
type Decoder interface {
Decode(raw uint32, offset int) Instruction
InstName(op int) string
}
// Интерфейс транслятора байт-кода
type Translator interface {
Translate(instructions []Instruction) (*TranslateResult, error)
}