
ARM64 ELF Virtual-Machine-Schutzsystem
ARM64 ELF Virtuelles-Maschinen-Schutzsystem
Übersetzt native ARM64-Anweisungen in benutzerdefinierten VM-Bytecode für funktionsweisen Code-Schutz
🇨🇳 中文文档 • Funktionen • Architektur • Schnellstart • Verwendung • Lizenz
VMPacker ist ein Virtual Machine Protection (VMP)-System für ARM64 (AArch64) Linux ELF-Binärdateien. Es dekodiert die nativen ARM64-Anweisungen der Zielfunktion in eine Zwischendarstellung, übersetzt sie in benutzerdefinierten VM-Bytecode und injiziert einen eingebetteten VM-Interpreter in die ELF-Datei. Zur Laufzeit werden geschützte Funktionen vom VM-Interpreter anstatt nativ ausgeführt.
ARM64 nativer Code → Dekodieren → Übersetzen → Benutzerdefinierter VM-Bytecode
↓
Original-ELF ← Injizieren ← VM-Interpreter-Stub
| Schicht | Technik | Beschreibung |
|---|---|---|
| VM-Schutz | Benutzerdefinierte ISA | Zufällig zugeordnete Opcodes – Reverse Engineers können die Anweisungssemantik nicht direkt identifizieren |
| OpcodeCryptor | Per-Anweisung Opcode-Verschlüsselung | enc[pc] = op[pc] ^ (key ^ (pc * 0x9E3779B9)) |
| Bytecode-Umkehrung | Umkehrung der Ausführungsreihenfolge | Anweisungen in umgekehrter Reihenfolge gespeichert; Interpreter durchläuft rückwärts |
| Token-Eintritt | 3-Anweisungs-Trampolin | Ursprüngliche Funktion durch tokenisierten Eintritt ersetzt, versteckt die tatsächliche Bytecode-Position |
| Indirekter Dispatch | Funktionszeiger-Sprungtabelle | Wird zur Laufzeit auf dem Stack gefüllt, unterbricht IDA-Kreuzverweise |
![]() |
![]() |
![]() |
| Funktionsliste | Analyse & Auswahl | Schutzoptionen |
![]() |
![]() |
|
| Echtzeitprotokolle | Schutz abgeschlossen |
vmp/
├── cmd/vmpacker/ # CLI-Einstiegspunkt
│ ├── main.go # CLI-Argument-Parsing + Orchestrierung
│ └── vm_interp.bin # Kompilierter VM-Interpreter (GCC, go:embed)
│
├── pkg/ # Go-Kernbibliothek
│ ├── arch/arm64/ # ARM64-Architekturunterstützung
│ │ ├── decoder.go # Tabellengesteuerter Befehlsdekoder (implementiert vm.Decoder)
│ │ ├── decode_*.go # Dekodierungsmustertabellen (DP-IMM/DP-REG/Branch/LdSt)
│ │ ├── translator.go # ARM64 → VM-Bytecode-Übersetzer
│ │ ├── tr_alu.go # ALU-Befehlsübersetzung
│ │ ├── tr_branch.go # Verzweigungsbefehlsübersetzung
│ │ ├── tr_loadstore.go # Speicherbefehlsübersetzung
│ │ ├── tr_bitfield.go # Bitfeld-Befehlsübersetzung
│ │ └── tr_special.go # Spezielle Befehle (ADRP/ADR)
│ ├── vm/ # VM-ISA-Definitionen
│ │ ├── types.go # Gemeinsame Typen + Schnittstellen (Decoder/Translator/Packer)
│ │ ├── opcodes.go # 58+ VM-Opcode-Definitionen (zufällig zugeordnete Werte)
│ │ └── disasm.go # VM-Bytecode-Disassembler
│ └── binary/elf/ # ELF-Binärdatei-Manipulation
│ ├── packer.go # ELF-VMP-Injektion (PT_NOTE-Hijack, Trampolin-Generierung)
│ └── trampoline.go # Trampolin-Code-Generierung
│
├── stub/ # C-VM-Interpreter (kompiliert als PIC Flat Binary)
│ ├── vm_interp_clean.c # Interpreter-Hauptschleife + Einstiegspunkte
│ ├── vm_types.h # VM-CPU-Kontext (vm_ctx_t)
│ ├── vm_opcodes.h # C-seitige Opcode-Definitionen (synchron mit opcodes.go)
│ ├── vm_decode.h # Bytecode-Lese-Dienstprogramme
│ ├── vm_token.h # Token-Codieren/Decodieren + Deskriptortabelle
│ ├── vm_dispatch.h # Indirekte Dispatch-Sprungtabelle
│ ├── vm_crc.h # CRC32-Integritätsprüfung
│ ├── vm_sections.h # Handler-Abschnitts-Streuungs-Makros
│ ├── vm_interp.lds # Linker-Skript
│ └── vm_handlers/ # Modulare Anweisungs-Handler
│ ├── h_alu.h # Arithmetik/Logik-Operationen
│ ├── h_mem.h # Speicherzugriff
│ ├── h_branch.h # Verzweigung/Sprung
│ ├── h_cmp.h # Vergleich/Bedingung
│ ├── h_mov.h # Datenbewegung
│ ├── h_stack.h # Stack (PUSH/POP)
│ └── h_system.h # System (SVC/MRS/BLR/BR/RET)
│
├── vmp-gui/ # Wails-GUI-Frontend
│ ├── frontend/ # Vue 3 + Element Plus
│ └── backend/ # Go-Backend-Bindungen
│
└── build/ # Vorkompilierte Tools + Test-Artefakte
Das Projekt verwendet eine schnittstellengesteuerte modulare Architektur, was eine einfache Erweiterung auf neue ISAs und Binärformate ermöglicht:
// Architecture decoder interface — extensible to x86, RISC-V
type Decoder interface {
Decode(raw uint32, offset int) Instruction
InstName(op int) string
}
// Bytecode translator interface
type Translator interface {
Translate(instructions []Instruction) (*TranslateResult, error)
}
// Binary format injector interface — extensible to PE, Mach-O
type Packer interface {
Process() error
}