
Sistema de protección de máquina virtual para ELF ARM64
Sistema de Protección de Máquina Virtual para ARM64 ELF
Traduce instrucciones nativas ARM64 a bytecode de VM personalizado para protección de código a nivel de función
🇨🇳 中文文档 • Características • Arquitectura • Inicio rápido • Uso • Licencia
VMPacker es un sistema de Protección de Máquina Virtual (VMP) para binarios ARM64 (AArch64) Linux ELF. Decodifica las instrucciones nativas ARM64 de la función objetivo en una representación intermedia, las traduce a bytecode de VM personalizado e inyecta un intérprete de VM embebido en el archivo ELF. En tiempo de ejecución, las funciones protegidas son ejecutadas por el intérprete de VM en lugar de forma nativa.
Código nativo ARM64 → Decodificar → Traducir → Bytecode de VM personalizado
↓
ELF original ← Inyectar ← Stub del intérprete de VM
vmp/
├── cmd/vmpacker/ # Punto de entrada CLI
│ ├── main.go # Análisis de argumentos CLI + orquestación
│ └── vm_interp.bin # Intérprete de VM compilado (GCC, go:embed)
│
├── pkg/ # Biblioteca central Go
│ ├── arch/arm64/ # Soporte de arquitectura ARM64
│ │ ├── decoder.go # Decodificador de instrucciones basado en tablas (implementa vm.Decoder)
│ │ ├── decode_*.go # Tablas de patrones de decodificación (DP-IMM/DP-REG/Branch/LdSt)
│ │ ├── translator.go # Traductor ARM64 → bytecode de VM
│ │ ├── tr_alu.go # Traducción de instrucciones ALU
│ │ ├── tr_branch.go # Traducción de instrucciones de bifurcación
│ │ ├── tr_loadstore.go # Traducción de instrucciones de memoria
│ │ ├── tr_bitfield.go # Traducción de instrucciones de campo de bits
│ │ └── tr_special.go # Instrucciones especiales (ADRP/ADR)
│ ├── vm/ # Definiciones de ISA de VM
│ │ ├── types.go # Tipos compartidos + interfaces (Decoder/Translator/Packer)
│ │ ├── opcodes.go # Definiciones de 58+ opcodes de VM (valores mapeados aleatoriamente)
│ │ └── disasm.go # Desensamblador de bytecode de VM
│ └── binary/elf/ # Manipulación de binarios ELF
│ ├── packer.go # Inyección de VMP en ELF (secuestro PT_NOTE, generación de trampolín)
│ └── trampoline.go # Generación de código de trampolín
│
├── stub/ # Intérprete de VM en C (compilado a binario plano PIC)
│ ├── vm_interp_clean.c # Bucle principal del intérprete + puntos de entrada
│ ├── vm_types.h # Contexto de CPU de VM (vm_ctx_t)
│ ├── vm_opcodes.h # Definiciones de opcodes en C (sincronizados con opcodes.go)
│ ├── vm_decode.h # Utilidades de lectura de bytecode
│ ├── vm_token.h # Codificación/decodificación de tokens + tabla de descriptores
│ ├── vm_dispatch.h # Tabla de saltos de despacho indirecto
│ ├── vm_crc.h # Verificación de integridad CRC32
│ ├── vm_sections.h # Macros de dispersión de secciones de manejadores
│ ├── vm_interp.lds # Script de enlace
│ └── vm_handlers/ # Manejadores de instrucciones modulares
│ ├── h_alu.h # Operaciones aritméticas/lógicas
│ ├── h_mem.h # Acceso a memoria
│ ├── h_branch.h # Bifurcación/salto
│ ├── h_cmp.h # Comparación/condicional
│ ├── h_mov.h # Movimiento de datos
│ ├── h_stack.h # Pila (PUSH/POP)
│ └── h_system.h # Sistema (SVC/MRS/BLR/BR/RET)
│
├── vmp-gui/ # Interfaz gráfica Wails
│ ├── frontend/ # Vue 3 + Element Plus
│ └── backend/ # Enlaces del backend Go
│
└── build/ # Herramientas precompiladas + artefactos de prueba
El proyecto utiliza una arquitectura modular basada en interfaces, lo que facilita la extensión a nuevos ISAs y formatos binarios:
// Interfaz del decodificador de arquitectura — extensible a x86, RISC-V
type Decoder interface {
Decode(raw uint32, offset int) Instruction
InstName(op int) string
}
// Interfaz del traductor de bytecode
type Translator interface {
Translate(instructions []Instruction) (*TranslateResult, error)
}
// Interfaz del inyector de formato binario — extensible a PE, Mach-O
type Packer interface {
Process() error
}
graph LR
A[ELF de entrada] --> B[Localizar función objetivo]
B --> C[Extraer instrucciones ARM64]
C --> D[Decodificar ARM64]
D --> E[Traducir a bytecode de VM]
E --> F[Cifrar bytecode con XOR]
F --> G[Inyectar intérprete de VM]
G --> H[Generar trampolín]
H --> I[Reemplazar entrada de función]
I --> J[ELF protegido de salida]
git clone https://github.com/LeoChen-CoreMind/VMPacker.git
cd VMPacker
make all
# Proteger una función individual
./vmpacker -func check_license -v -o protected.elf original.elf
# Proteger múltiples funciones
./vmpacker -func "check_license,verify_token" -v -o protected.elf original.elf
# Especificar rango de direcciones
./vmpacker -addr "0x4006AC-0x400790:main" -v -o protected.elf original.elf
# Modo mixto
./vmpacker -addr "0x4006AC-0x400790:main" -func verify -o protected.elf original.elf
./vmpacker -info input.elf
# Compilación estándar (GCC)
aarch64-linux-gnu-gcc -Os -nostdlib -fPIC -ffreestanding \
-o stub.elf stub/vm_interp_clean.c \
-T stub/vm_interp.lds
aarch64-linux-gnu-objcopy -O binary stub.elf vm_interp.bin
go build -o vmpacker ./cmd/vmpacker/
cd vmpacker
make gui
VMPacker define una Arquitectura de Conjunto de Instrucciones (ISA) personalizada con valores de opcode mapeados aleatoriamente para aumentar la dificultad de la ingeniería inversa.
📖 Para la tabla completa de opcodes con detalles de codificación, consulte la documentación en chino.
¡Las contribuciones son bienvenidas! Por favor, siga estas pautas:
git checkout -b feature/nueva-arquitecturagit commit -m 'feat: añadir decodificador x86_64'git push origin feature/nueva-arquitecturaSeguimos Conventional Commits:
feat: Nueva funcionalidadfix: Corrección de erroresrefactor: Refactorización de códigodocs: Documentacióntest: PruebasEste proyecto está licenciado bajo la Licencia AGPL-3.0.
¿Por qué AGPL-3.0?
ESTE SOFTWARE SE PROPORCIONA "TAL CUAL", SIN GARANTÍA DE NINGÚN TIPO, EXPRESA O IMPLÍCITA, INCLUYENDO PERO NO LIMITADO A LAS GARANTÍAS DE COMERCIABILIDAD, IDONEIDAD PARA UN PROPÓSITO PARTICULAR Y NO INFRACCIÓN. EN NINGÚN CASO LOS AUTORES O TITULARES DE DERECHOS DE AUTOR SERÁN RESPONSABLES DE NINGUNA RECLAMACIÓN, DAÑO U OTRA RESPONSABILIDAD, YA SEA EN UNA ACCIÓN CONTRACTUAL, EXTRACONTRACTUAL O DE OTRO MODO, QUE SURJA DE O EN CONEXIÓN CON EL SOFTWARE O EL USO U OTRO TIPO DE ACCIONES EN EL SOFTWARE.
Este proyecto está diseñado para proporcionar protección legítima de la propiedad intelectual a desarrolladores de software, ayudando a proteger algoritmos centrales y código crítico en software comercial contra ingeniería inversa no autorizada o robo.
Aviso para el usuario:
- Debe cumplir con todas las leyes y regulaciones aplicables en su jurisdicción al usar este software
- Está estrictamente prohibido usar este software para cualquier propósito ilegal, incluyendo pero no limitado a: desarrollo de malware, evasión de auditorías de seguridad, infracción de los derechos de propiedad intelectual de otros, o comprometer la seguridad de sistemas informáticos
- El(los) autor(es) no será(n) responsable(s) por ninguna consecuencia directa o indirecta resultante del uso de este software por parte de cualquier persona
- Al descargar, usar o distribuir este software, reconoce que ha leído y aceptado los términos anteriores
LeoChen — @LeoChen-CoreMind
Copyright © 2026 LeoChen. Todos los derechos reservados.
| Capa | Técnica | Descripción |
|---|
| Protección VM | ISA personalizada | Opcodes mapeados aleatoriamente — los ingenieros inversos no pueden identificar directamente la semántica de las instrucciones |
| OpcodeCryptor | Cifrado de opcodes por instrucción | enc[pc] = op[pc] ^ (key ^ (pc * 0x9E3779B9)) |
| Inversión de bytecode | Inversión del orden de ejecución | Las instrucciones se almacenan en orden inverso; el intérprete recorre hacia atrás |
| Entrada tokenizada | Trampolín de 3 instrucciones | La función original se reemplaza con una entrada tokenizada, ocultando la ubicación real del bytecode |
| Despacho indirecto | Tabla de saltos de punteros a función | Se llena en tiempo de ejecución en la pila, rompiendo las referencias cruzadas de IDA |
![]() | ![]() | ![]() |
| Lista de funciones | Análisis y selección | Opciones de protección |
![]() | ![]() | |
| Registros en tiempo real | Protección completada |
| Opción | Valor por defecto | Descripción |
|---|
-func | — | Nombre(s) de función a proteger (separados por comas) |
-addr | — | Proteger por dirección (0xINICIO-0xFIN[:nombre]) |
-o | input.vmp | Ruta del archivo de salida |
-v | false | Salida detallada (mostrar desensamblado) |
-strip | true | Eliminar tabla de símbolos |
-debug | false | Generar archivo de mapeo de depuración ARM64 → bytecode de VM |
-token | true | Modo de entrada basado en tokens |
-info | false | Solo imprimir información del ELF |
| Categoría | Cantidad | Descripción |
|---|
| Movimiento de datos | 3 | MOV_IMM64, MOV_IMM32, MOV_REG |
| Aritmética/Lógica | 21 | ADD, SUB, MUL, XOR, AND, OR, SHL, SHR, ASR, NOT, ROR, UMULH + variantes _IMM |
| Acceso a memoria | 8 | LOAD/STORE 8/16/32/64 |
| Bifurcación/Salto | 13 | JMP, JE, JNE, JL, JGE, JGT, JLE, JB, JAE, JBE, JA, TBZ, TBNZ |
| Comparación | 6 | CMP, CMP_IMM, CCMP_REG, CCMP_IMM, CCMN_REG, CCMN_IMM |
| Pila | 2 | PUSH, POP |
| Sistema/Especial | 8 | NOP, HALT, RET, CALL_NATIVE, CALL_REG, BR_REG, SVC, MRS |
| SIMD | 2 | VLD16, VST16 |
| Total | 63 |