Skip to content

TUGOhost/LLVMmovfuscator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LLVMmovfuscator

LLVMmovfuscator is an LLVM-based ARM mov-style / data-transfer-style obfuscation prototype. The current mainline target is AArch64MovLite on Apple Silicon: user-level i32 arithmetic and comparisons are expanded in LLVM IR, control flow is lowered to block-id dispatch, and an isolated experimental LLVM target emits AArch64 assembly that is linked into a native executable.

In the ARM context, "mov" does not mean the literal x86 mov instruction. It means the restricted ARM-Lite model: user semantics are pushed toward MOV/LDR/STR-style data transfer and runtime helpers. libc calls, function ABI, stack frames, call/return, symbol materialization, and runtime dispatch stubs are allowed to use native AArch64 instructions in the current v1 scaffold.

Chinese version: README.zh-cn.md

Repository Layout

Path Description
src/ LLVM-based ARM mov-style implementation: target-prep pass (pass/) plus runtime stubs (runtime/). See src/README.md.
patches/ Small LLVM-side patches kept in Git instead of committing a full LLVM source tree.
llvm-project-21.1.8/ Local LLVM 21.1.8 source tree. It is not committed to Git and is used to build the pass, Clang, opt, and llc.
docs/DESIGN.md LLVM implementation design and phase plan. Recommended first read.
docs/AARCH64_MOVLITE_V1_IMPLEMENTATION.md AArch64MovLite v1 implementation summary, tradeoffs, verification commands, and current boundaries.
movfuscator/ Local clone of the original M/o/Vfuscator. It is not committed to Git and is used as reference material and validation case source.
tests/ Unicorn example tests, the movfuscator validation runner, and AArch64MovLite basic C dual-execution comparison.

Goals

  • v1 feature scope: Cover a basic ANSI C subset on -O0 LLVM IR, including 32-bit signed/unsigned integer arithmetic, comparisons, if/for/while, break/continue, switch, normal functions, recursion, local/global variables, arrays, pointer dereference, malloc/free, and libc boundaries such as printf/puts/putchar/getchar.
  • v1 implementation path: The aarch64-movlite-prepare pass expands user arithmetic/comparison semantics directly and lowers branches to ARM-Lite dispatch. llc -march=aarch64movlite emits .s, and the system clang/assembler links an arm64 Mach-O executable. The AArch64MovLite runner checks that the final binary does not contain __mov_* helper symbols.
  • Multi-architecture direction: The current hard acceptance target is Apple Silicon macOS arm64. ARM32 remains design-compatible. The x86 M/o/Vfuscator subtree remains a reference implementation and validation case source.

Quick Start

This repository does not commit the large llvm-project-21.1.8/ or movfuscator/ directories. Prepare them locally:

# After placing the LLVM 21.1.8 source tree at llvm-project-21.1.8/,
# apply the AArch64MovLite target registration patch.
git apply --unidiff-zero patches/llvm-21.1.8-aarch64movlite-target.patch

# To run movfuscator validation cases, clone the original repository locally.
git clone https://github.com/xoreaxeaxeax/movfuscator movfuscator
  • Use the original compiler (LCC + mov backend)

    cd movfuscator && ./build.sh && sudo ./install.sh
    movcc example.c -o example
  • Build LLVM-mov with the local LLVM tree

    # 1. Build LLVM once. This registers the aarch64movlite target.
    cmake -S llvm-project-21.1.8/llvm -B build-llvm -G Ninja -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS=clang
    ninja -C build-llvm clang opt llc
    
    # 2. Build the pass and runtime.
    cmake -S src -B build -G Ninja -DLLVM_DIR=$PWD/build-llvm/lib/cmake/llvm
    ninja -C build

    Verify target registration:

    build-llvm/bin/llc --version | grep aarch64movlite
  • AArch64MovLite compilation pipeline

    build-llvm/bin/clang -O0 -S -emit-llvm -target arm64-apple-macosx case.c -o case.ll
    build-llvm/bin/opt -load-pass-plugin build/pass/MovOnlyPass.so \
      -passes=aarch64-movlite-prepare case.ll -S -o case_movlite.ll
    build-llvm/bin/llc -march=aarch64movlite -mtriple=aarch64movlite-apple-macosx \
      case_movlite.ll -o case_movlite.s
    clang -target arm64-apple-macosx case_movlite.s build/runtime/libmov_runtime_stubs.a -o case_movlite
  • Execution comparison

    LLVM_BIN=$PWD/build-llvm/bin python3 tests/run_basic_c_tests.py -o artifacts/basic_c
    MOVFUSCATOR=$PWD/movfuscator TARGET=arm64-apple-macosx LLVM_BIN=$PWD/build-llvm/bin \
      python3 tests/run_movfuscator_tests.py

    The runner builds both the reference and MovLite paths, runs them with the same stdin/argv, and strictly compares stdout plus process exit code.

    ARM64 validates hello, prime, arithmetic, crc32, and hanoi by default. crc32 is currently recorded as an expected failure because v1 does not support ordered pointer comparisons.

  • Design and implementation notes Read docs/DESIGN.md for the design and phase plan. Read docs/AARCH64_MOVLITE_V1_IMPLEMENTATION.md for the v1 implementation summary. Source code lives under src/.

References

About

movfuscator base on LLVM

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors