Skip to main content

Metamorphic binary mutation engine with structural validation

Project description

r2morph

r2morph

Metamorphic mutation engine with structured validation and reporting

PyPI Version Python Versions License CI Status Coverage

GitHub Stars GitHub Issues Buy Me a Coffee


Overview

r2morph is a metamorphic mutation engine that applies tracked binary transformations with validation, rollback, and machine-readable reports. It uses radare2 for analysis and supports 18 mutation passes across 4 architectures.

Key Features

Feature Description
18 Mutation Passes From stable NOP/substitute/register to experimental CFF, virtualization, and self-modifying code
4 Architectures x86_64, x86, ARM64, ARM32
3 Binary Formats ELF (stable), PE and Mach-O (experimental, via LIEF)
4 Validation Modes Structural, runtime, symbolic (angr), CFG integrity
Session Management Checkpoint/rollback system preserving binary state across mutation passes
SARIF 2.1.0 Reports OASIS SARIF with MITRE ATT&CK taxonomy, fingerprints, code flows
JSON Reports Documented schema, metadata, timing, gate evaluation
Detection Suite Packer signatures, entropy analysis, pattern matching, similarity hashing
Devirtualization VM handler analysis, MBA simplification (Z3-based)

Installation

Prerequisites

  • Python 3.10+
  • radare2 installed

Install radare2

git clone https://github.com/radareorg/radare2
cd radare2
sys/install.sh

Install r2morph

pip install r2morph                  # Basic
pip install "r2morph[enhanced]"      # + angr, lief, z3
pip install "r2morph[all]"           # + frida, hypothesis

Development Install

git clone https://github.com/seifreed/r2morph.git
cd r2morph
pip install -e ".[dev]"

Support Matrix

Formats

Format Status Section Creation Notes
ELF Stable Via LIEF Full section handling, relocations, code caves
PE Experimental Via LIEF Section creation, checksum fixing
Mach-O Experimental Via LIEF Load command parsing, Fat binary support

Architectures

Architecture NOP Substitute Register Expand Block Dead Code
x86_64 Yes Yes Yes Yes Yes Yes
x86 Yes Yes Yes Yes Yes Yes
ARM64 Yes Yes Yes Yes Yes Yes
ARM32 Yes Yes Yes Yes Yes Yes

Instruction Equivalence Rules

  • x86/x86_64: 100+ rules in x86_rules.yaml - bidirectional groups covering zero registers, self-moves, flag-preserving patterns, XOR/SUB equivalence
  • ARM32: 10+ groups in arm_rules.yaml - zero, increment, decrement, self-move, shift, negate, double, compare for r0-r11
  • ARM64: Register classes defined in arm64_rules.yaml

Mutation Passes

Stable (tested, production-ready)

Pass CLI Flag Description
NOP Insertion -m nop Inserts benign NOP equivalents at safe locations
Instruction Substitution -m substitute Replaces instructions with semantically equivalent alternatives
Register Substitution -m register Substitutes registers via liveness analysis

Experimental (working, limited testing)

Pass CLI Flag Description
Instruction Expansion -m expand Expands single instructions into longer equivalent sequences
Block Reordering -m block Reorders basic blocks with jump patching
Dead Code Injection -m dead-code Injects semantically neutral code in padding regions
Control Flow Flattening -m cff Inserts opaque predicates and jump obfuscation
Opaque Predicates -m opaque Writes opaque predicate instructions into basic blocks
Code Virtualization -m code-virtualization Translates instructions to VM bytecode with dispatcher
Anti-Disassembly -m anti-disassembly Injects anti-disassembly snippets
Data Flow Mutation -m data-flow Data flow analysis-driven safe substitutions
Short Jump Patching -m short-jump Patches short jumps to equivalent sequences
Constant Unfolding -m constant-unfolding Unfolds constant expressions into multi-instruction equivalents
Code Mobility -m code-mobility Relocates blocks to code caves with trampolines
Function Outlining -m function-outlining Distributes function chunks across code caves
API Hashing -m api-hashing Hash trampolines obscuring PLT references
Import Obfuscation -m import-obfuscation Jump stub indirection for import calls
Self-Modifying Code -m self-modifying XOR-encrypts function bodies with runtime decryptor

Validation

Mode Flag Status Description
Structural --validation-mode structural Stable Binary format integrity checks (always runs)
Runtime --validation-mode runtime Stable Compares original vs mutated execution (exit code, stdout, stderr, files)
Symbolic --validation-mode symbolic Experimental Bounded symbolic step via angr (ELF x86_64, advisory)
CFG Integrity Automatic Experimental Reachability and edge preservation checks

Quick Start

# Mutate with stable passes
r2morph mutate input.elf -o output.elf -m nop -m substitute -m register

# SARIF report for CI/CD
r2morph mutate input.elf -o output.elf --format sarif --report mutations.sarif

# Reproducible run
r2morph mutate input.elf -o output.elf --seed 1337

# Runtime validation
r2morph validate original.elf mutated.elf --corpus dataset/runtime_corpus.json

# CI gate: fail if severity below threshold
r2morph mutate input.elf -o output.elf --report report.json --min-severity bounded-only

# Display and filter reports
r2morph report report.json --only-pass nop --summary-only
r2morph report report.json --format sarif -o report.sarif

CLI Reference

Commands

Command Description
r2morph mutate Apply mutations, validate, export binary + report
r2morph validate Compare original vs mutated binary behavior
r2morph report Display, filter, or convert a saved report
r2morph analyze Analyze binary structure and functions
r2morph functions List functions in a binary
r2morph version Show version

Report Filters

Filter Purpose
--format <json|sarif> Output format (JSON default, SARIF 2.1.0)
--only-pass <name> Restrict to one mutation pass
--only-mismatches Show only symbolic observable mismatches
--only-failed-gates Show only failed severity gates
--only-degraded Show only degraded validation modes
--summary-only Print textual triage summary only
--output <file> Export filtered JSON
--require-results Exit 1 when filtered view is empty
--min-severity <sev> Require minimum severity in view

SARIF 2.1.0 Integration

Reports in SARIF format include:

  • MITRE ATT&CK taxonomy - T1027 (Obfuscated Files), T1027.001 (Binary Padding), T1027.002 (Software Packing)
  • Partial fingerprints (SHA256) for deduplication across CI runs
  • Code flows showing mutation chains per function
  • Related locations linking mutations to validation failures
  • Disassembly snippets in the rendered field alongside hex bytes
  • Fix suggestions with byte-level replacements

Compatible with GitHub Code Scanning, Azure DevOps, SonarQube, and any SARIF 2.1.0 consumer.


Python API

from r2morph import MorphEngine
from r2morph.mutations import NopInsertionPass, InstructionSubstitutionPass, RegisterSubstitutionPass

with MorphEngine() as engine:
    engine.load_binary("input.elf").analyze()

    engine.add_mutation(NopInsertionPass())
    engine.add_mutation(InstructionSubstitutionPass())
    engine.add_mutation(RegisterSubstitutionPass())

    result = engine.run(validation_mode="structural", report_path="report.json")
    engine.save("output.elf")

print(f"Applied {result['total_mutations']} mutations")

Detection & Analysis

Module Capability
Obfuscation Detector Commercial packer signatures (VMProtect, Themida, UPX, etc.), confidence scoring
Entropy Analyzer Section entropy analysis for packing/encryption detection
Pattern Matcher Anti-debug, anti-VM, string encryption, import hiding detection
Similarity Hasher Fuzzy hashing for binary comparison (ssdeep-style)
Control Flow Detector CFF, opaque predicates, VM dispatch, MBA expression detection
Packer Signatures 50+ categorized signature database

Devirtualization (Experimental)

Module Status Notes
VM Handler Analyzer Working Pattern-based handler classification
MBA Solver Working Z3 SMT solver, max 8 variables, timeout-bounded
CFO Simplifier Framework Pattern library defined, application incomplete
Binary Rewriter Framework Patch/relocation infrastructure

Instrumentation (Experimental)

Frida integration for dynamic analysis: process spawning, script injection, API call logging, anti-analysis detection. Requires frida package.


Report Schema

JSON reports follow a documented schema at r2morph/reporting/report_schema.json. Each report includes:

  • metadata: tool version, timestamp, duration, platform
  • input/output: binary path, architecture, format, function count
  • passes: per-pass mutation counts, timing, diff summaries
  • mutations: flat list with address, bytes, disassembly, function, section
  • validation: mode, results, symbolic coverage
  • gate_evaluation: severity gate outcomes for CI
  • summary: aggregated statistics

Requirements

  • Python 3.10+
  • radare2
  • Optional: lief (PE/Mach-O/section creation), angr (symbolic validation), frida (instrumentation), z3-solver (MBA simplification)

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Support the Project

If you find r2morph useful, consider supporting its development:

Buy Me A Coffee

License

This project is licensed under the MIT License - see the LICENSE file for details.

Attribution Required:


Made with dedication for the reverse engineering community

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

r2morph-0.3.0.tar.gz (508.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

r2morph-0.3.0-py3-none-any.whl (594.6 kB view details)

Uploaded Python 3

File details

Details for the file r2morph-0.3.0.tar.gz.

File metadata

  • Download URL: r2morph-0.3.0.tar.gz
  • Upload date:
  • Size: 508.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for r2morph-0.3.0.tar.gz
Algorithm Hash digest
SHA256 d0f7dbcc092ff4a6b24fb89634190777632141e24b08047cb0fd1b387244094e
MD5 813c93a8c4a2926755ca37bb67f6a92f
BLAKE2b-256 23ec5c4f0f2f2a0bb5d3157a3bb8745c2d90f32d9f192b0f538d2a16a373289f

See more details on using hashes here.

Provenance

The following attestation bundles were made for r2morph-0.3.0.tar.gz:

Publisher: release.yml on seifreed/r2morph

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file r2morph-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: r2morph-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 594.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for r2morph-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3898204bac384711cec16208395f36aac2de5878078980391fb5d100bca26383
MD5 49c9cff7ef6da8f0e3889f93bfc22206
BLAKE2b-256 8d84f51cdd2d738b89c14b95f04c8b4b2f9f5ac0fda96037dbab2274dc0fca50

See more details on using hashes here.

Provenance

The following attestation bundles were made for r2morph-0.3.0-py3-none-any.whl:

Publisher: release.yml on seifreed/r2morph

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page