
Système de protection par machine virtuelle ARM64 ELF
Système de Protection par Machine Virtuelle pour ELF ARM64
Traduit les instructions natives ARM64 en bytecode VM personnalisé pour une protection au niveau des fonctions
🇨🇳 中文文档 • Fonctionnalités • Architecture • Démarrage rapide • Utilisation • Licence
VMPacker est un système de Protection par Machine Virtuelle (VMP) pour les binaires ELF Linux ARM64 (AArch64). Il décode les instructions natives ARM64 de la fonction cible en une représentation intermédiaire, les traduit en bytecode VM personnalisé et injecte un interpréteur VM embarqué dans le fichier ELF. À l'exécution, les fonctions protégées sont exécutées par l'interpréteur VM au lieu de nativement.
Code natif ARM64 → Décodage → Traduction → Bytecode VM personnalisé
↓
ELF original ← Injection ← Stub de l'interpréteur VM
| Couche | Technique | Description |
|---|---|---|
| Protection VM | ISA personnalisé | Opcodes mappés aléatoirement — les rétro-ingénieurs ne peuvent pas identifier directement la sémantique des instructions |
| OpcodeCryptor | Chiffrement par instruction | enc[pc] = op[pc] ^ (key ^ (pc * 0x9E3779B9)) |
| Inversion du bytecode | Inversion de l'ordre d'exécution | Instructions stockées dans l'ordre inverse ; l'interpréteur parcourt en arrière |
| Entrée tokenisée | Trampoline à 3 instructions | La fonction originale est remplacée par une entrée tokenisée, masquant l'emplacement réel du bytecode |
| Distribution indirecte | Table de pointeurs de fonction | Remplie à l'exécution sur la pile, brisant les références croisées IDA |
![]() |
![]() |
![]() |
| Liste des fonctions | Analyse et sélection | Options de protection |
![]() |
![]() |
|
| Logs en temps réel | Protection terminée |
vmp/
├── cmd/vmpacker/ # Point d'entrée CLI
│ ├── main.go # Analyse des arguments CLI + orchestration
│ └── vm_interp.bin # Interpréteur VM compilé (GCC, go:embed)
│
├── pkg/ # Bibliothèque principale Go
│ ├── arch/arm64/ # Support de l'architecture ARM64
│ │ ├── decoder.go # Décodeur d'instructions piloté par tables (implémente vm.Decoder)
│ │ ├── decode_*.go # Tables de motifs de décodage (DP-IMM/DP-REG/Branch/LdSt)
│ │ ├── translator.go # Traducteur ARM64 → bytecode VM
│ │ ├── tr_alu.go # Traduction des instructions ALU
│ │ ├── tr_branch.go # Traduction des instructions de branchement
│ │ ├── tr_loadstore.go # Traduction des instructions mémoire
│ │ ├── tr_bitfield.go # Traduction des instructions de champ de bits
│ │ └── tr_special.go # Instructions spéciales (ADRP/ADR)
│ ├── vm/ # Définitions de l'ISA VM
│ │ ├── types.go # Types partagés + interfaces (Decoder/Translator/Packer)
│ │ ├── opcodes.go # 58+ définitions d'opcodes VM (valeurs mappées aléatoirement)
│ │ └── disasm.go # Désassembleur de bytecode VM
│ └── binary/elf/ # Manipulation des binaires ELF
│ ├── packer.go # Injection VMP ELF (détournement PT_NOTE, génération de trampoline)
│ └── trampoline.go # Génération de code de trampoline
│
├── stub/ # Interpréteur VM en C (compilé en binaire plat PIC)
│ ├── vm_interp_clean.c # Boucle principale de l'interpréteur + points d'entrée
│ ├── vm_types.h # Contexte CPU VM (vm_ctx_t)
│ ├── vm_opcodes.h # Définitions d'opcodes côté C (synchronisées avec opcodes.go)
│ ├── vm_decode.h # Utilitaires de lecture du bytecode
│ ├── vm_token.h # Encodage/décodage des jetons + table de descripteurs
│ ├── vm_dispatch.h # Table de distribution indirecte
│ ├── vm_crc.h # Vérification d'intégrité CRC32
│ ├── vm_sections.h # Macros de dispersion des sections de gestionnaires
│ ├── vm_interp.lds # Script de l'éditeur de liens
│ └── vm_handlers/ # Gestionnaires d'instructions modulaires
│ ├── h_alu.h # Opérations arithmétiques/logiques
│ ├── h_mem.h # Accès mémoire
│ ├── h_branch.h # Branchement/saut
│ ├── h_cmp.h # Comparaison/conditionnel
│ ├── h_mov.h # Mouvement de données
│ ├── h_stack.h # Pile (PUSH/POP)
│ └── h_system.h # Système (SVC/MRS/BLR/BR/RET)
│
├── vmp-gui/ # Interface graphique Wails
│ ├── frontend/ # Vue 3 + Element Plus
│ └── backend/ # Liaisons Go backend
│
└── build/ # Outils pré-compilés + artefacts de test
Le projet utilise une architecture modulaire pilotée par interfaces, ce qui facilite l'extension à de nouveaux ISA et formats binaires :