
ARM64 ELF 가상 머신 보호 시스템
ARM64 ELF 가상 머신 보호 시스템
ARM64 네이티브 명령어를 사용자 정의 VM 바이트코드로 변환하여 함수 수준의 코드 보호를 제공합니다.
🇨🇳 中文文档 • 기능 • 아키텍처 • 빠른 시작 • 사용법 • 라이선스
VMPacker는 ARM64 (AArch64) Linux ELF 바이너리를 위한 가상 머신 보호 (VMP) 시스템입니다. 대상 함수의 네이티브 ARM64 명령어를 중간 표현으로 디코딩하고, 이를 사용자 정의 VM 바이트코드로 변환한 후, ELF 파일에 임베디드 VM 인터프리터를 주입합니다. 런타임 시 보호된 함수는 네이티브로 실행되지 않고 VM 인터프리터에 의해 실행됩니다.
ARM64 Native Code → Decode → Translate → Custom VM Bytecode
↓
Original ELF ← Inject ← VM Interpreter Stub
vmp/
├── cmd/vmpacker/ # CLI 진입점
│ ├── main.go # CLI 인수 파싱 + 조정
│ └── vm_interp.bin # 컴파일된 VM 인터프리터 (GCC, go:embed)
│
├── pkg/ # Go 핵심 라이브러리
│ ├── arch/arm64/ # ARM64 아키텍처 지원
│ │ ├── decoder.go # 테이블 기반 명령어 디코더 (vm.Decoder 구현)
│ │ ├── decode_*.go # 디코드 패턴 테이블 (DP-IMM/DP-REG/Branch/LdSt)
│ │ ├── translator.go # ARM64 → VM 바이트코드 변환기
│ │ ├── tr_alu.go # ALU 명령어 변환
│ │ ├── tr_branch.go # 분기 명령어 변환
│ │ ├── tr_loadstore.go # 메모리 명령어 변환
│ │ ├── tr_bitfield.go # 비트필드 명령어 변환
│ │ └── tr_special.go # 특수 명령어 (ADRP/ADR)
│ ├── vm/ # VM ISA 정의
│ │ ├── types.go # 공유 타입 + 인터페이스 (Decoder/Translator/Packer)
│ │ ├── opcodes.go # 58+ VM opcode 정의 (무작위 매핑된 값)
│ │ └── disasm.go # VM 바이트코드 디스어셈블러
│ └── binary/elf/ # ELF 바이너리 조작
│ ├── packer.go # ELF VMP 주입 (PT_NOTE 하이재킹, 트램펄린 생성)
│ └── trampoline.go # 트램펄린 코드 생성
│
├── stub/ # C VM 인터프리터 (PIC 플랫 바이너리로 컴파일)
│ ├── vm_interp_clean.c # 인터프리터 메인 루프 + 진입점
│ ├── vm_types.h # VM CPU 컨텍스트 (vm_ctx_t)
│ ├── vm_opcodes.h # C 측 opcode 정의 (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/ # Wails GUI 프론트엔드
│ ├── 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)
}
// 바이너리 형식 주입기 인터페이스 — PE, Mach-O로 확장 가능
type Packer interface {
Process() error
}
graph LR
A[입력 ELF] --> B[대상 함수 찾기]
B --> C[ARM64 명령어 추출]
C --> D[ARM64 디코딩]
D --> E[VM 바이트코드로 변환]
E --> F[XOR 바이트코드 암호화]
F --> G[VM 인터프리터 주입]
G --> H[트램펄린 생성]
H --> I[함수 진입점 교체]
I --> J[보호된 ELF 출력]
git clone https://github.com/LeoChen-CoreMind/VMPacker.git
cd VMPacker
make all
# 단일 함수 보호
./vmpacker -func check_license -v -o protected.elf original.elf
# 여러 함수 보호
./vmpacker -func "check_license,verify_token" -v -o protected.elf original.elf
# 주소 범위 지정
./vmpacker -addr "0x4006AC-0x400790:main" -v -o protected.elf original.elf
# 혼합 모드
./vmpacker -addr "0x4006AC-0x400790:main" -func verify -o protected.elf original.elf
./vmpacker -info input.elf
# 표준 빌드 (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는 무작위로 매핑된 opcode 값을 가진 사용자 정의 명령어 집합 아키텍처(ISA)를 정의하여 리버스 엔지니어링 난이도를 높입니다.
📖 전체 opcode 테이블과 인코딩 상세 내용은 중국어 문서를 참조하세요.
기여를 환영합니다! 다음 지침을 따라주세요:
git checkout -b feature/new-archgit commit -m 'feat: add x86_64 decoder'git push origin feature/new-archConventional Commits를 따릅니다:
feat: 새로운 기능fix: 버그 수정refactor: 코드 리팩토링docs: 문서test: 테스트이 프로젝트는 AGPL-3.0 라이선스 하에 배포됩니다.
왜 AGPL-3.0인가:
이 소프트웨어는 "있는 그대로" 제공되며, 상품성, 특정 목적에의 적합성 및 비침해에 대한 보증을 포함하되 이에 국한되지 않는 모든 명시적 또는 묵시적 보증 없이 제공됩니다. 어떤 경우에도 저자 또는 저작권 보유자는 계약, 불법행위 또는 기타 행위에 기반한 청구, 손해 또는 기타 책임에 대해 책임을 지지 않습니다.
이 프로젝트는 소프트웨어 개발자에게 합법적인 지적 재산권 보호를 제공하여 상용 소프트웨어의 핵심 알고리즘과 중요 코드를 승인되지 않은 리버스 엔지니어링 또는 도용으로부터 보호하도록 설계되었습니다.
사용자 주의사항:
- 이 소프트웨어를 사용할 때 관할 구역의 모든 관련 법률 및 규정을 준수해야 합니다.
- 이 소프트웨어를 불법 목적으로 사용하는 것을 엄격히 금지합니다. 여기에는 악성 코드 개발, 보안 감사 우회, 타인의 지적 재산권 침해 또는 컴퓨터 시스템 보안 손상이 포함되나 이에 국한되지 않습니다.
- 저자는 누구든지 이 소프트웨어를 사용하여 발생하는 직접적 또는 간접적 결과에 대해 책임을 지지 않습니다.
- 이 소프트웨어를 다운로드, 사용 또는 배포함으로써 위 내용을 읽고 동의한 것으로 간주됩니다.
LeoChen — @LeoChen-CoreMind
Copyright © 2026 LeoChen. All rights reserved.
| 계층 | 기술 | 설명 |
|---|
| VM 보호 | 사용자 정의 ISA | 무작위로 매핑된 opcode — 리버스 엔지니어가 명령어 의미를 직접 식별할 수 없음 |
| OpcodeCryptor | 명령어별 opcode 암호화 | enc[pc] = op[pc] ^ (key ^ (pc * 0x9E3779B9)) |
| 바이트코드 역순 | 실행 순서 역전 | 명령어가 역순으로 저장됨; 인터프리터가 역방향으로 탐색 |
| 토큰 진입 | 3-명령어 트램펄린 | 원본 함수가 토큰화된 진입점으로 대체되어 실제 바이트코드 위치 숨김 |
| 간접 디스패치 | 함수 포인터 점프 테이블 | 런타임 시 스택에 채워져 IDA 크로스 레퍼런스 차단 |
![]() | ![]() | ![]() |
| 함수 목록 | 분석 및 선택 | 보호 옵션 |
![]() | ![]() | |
| 실시간 로그 | 보호 완료 |
| 옵션 | 기본값 | 설명 |
|---|
-func | — | 보호할 함수 이름 (쉼표로 구분) |
-addr | — | 주소로 보호 (0xSTART-0xEND[:name]) |
-o | input.vmp | 출력 파일 경로 |
-v | false | 상세 출력 (디스어셈블리 표시) |
-strip | true | 심볼 테이블 제거 |
-debug | false | ARM64 → VM 바이트코드 디버그 매핑 파일 생성 |
-token | true | 토큰 기반 진입 모드 |
-info | false | ELF 정보만 출력 |
| 범주 | 개수 | 설명 |
|---|
| 데이터 이동 | 3 | MOV_IMM64, MOV_IMM32, MOV_REG |
| 산술/논리 | 21 | ADD, SUB, MUL, XOR, AND, OR, SHL, SHR, ASR, NOT, ROR, UMULH + _IMM 변형 |
| 메모리 접근 | 8 | LOAD/STORE 8/16/32/64 |
| 분기/점프 | 13 | JMP, JE, JNE, JL, JGE, JGT, JLE, JB, JAE, JBE, JA, TBZ, TBNZ |
| 비교 | 6 | CMP, CMP_IMM, CCMP_REG, CCMP_IMM, CCMN_REG, CCMN_IMM |
| 스택 | 2 | PUSH, POP |
| 시스템/특수 | 8 | NOP, HALT, RET, CALL_NATIVE, CALL_REG, BR_REG, SVC, MRS |
| SIMD | 2 | VLD16, VST16 |
| 합계 | 63 |