Zum Inhalt springen

YARA-X Cheat Sheet

Overview

YARA-X is the official next-generation rewrite of YARA, the industry-standard pattern matching tool used by malware researchers, threat hunters, and security teams worldwide. Built from the ground up in Rust, YARA-X delivers significant performance improvements, better error handling, stricter rule validation, and enhanced reliability compared to the original C-based YARA. It maintains backward compatibility with existing YARA rules while introducing new features such as improved regular expression support, better Unicode handling, and a more robust module system.

YARA-X is designed as a drop-in replacement for YARA in most workflows. It provides the same core functionality — scanning files, processes, and memory against pattern-based rules to classify and identify malware families, variants, and suspicious behaviors. Rules combine text strings, hexadecimal patterns, regular expressions, and conditions with boolean logic. YARA-X includes built-in modules for parsing PE, ELF, Mach-O, .NET, and other file formats, allowing rules to reference structural metadata beyond raw byte patterns. The Rust implementation eliminates entire categories of memory safety bugs and provides better multithreading support for high-throughput scanning environments.

Installation

Pre-built Binaries

# Download latest release
wget https://github.com/VirusTotal/yara-x/releases/latest/download/yr-x86_64-unknown-linux-gnu.gz
gunzip yr-x86_64-unknown-linux-gnu.gz
chmod +x yr-x86_64-unknown-linux-gnu
sudo mv yr-x86_64-unknown-linux-gnu /usr/local/bin/yr

# macOS
wget https://github.com/VirusTotal/yara-x/releases/latest/download/yr-x86_64-apple-darwin.gz
gunzip yr-x86_64-apple-darwin.gz
chmod +x yr-x86_64-apple-darwin
sudo mv yr-x86_64-apple-darwin /usr/local/bin/yr

Via Cargo (Rust)

# Install Rust toolchain if needed
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Install YARA-X CLI
cargo install yara-x-cli

# Verify
yr --version

Python Bindings

pip install yara-x

# Verify
python3 -c "import yara_x; print(yara_x.__version__)"

From Source

git clone https://github.com/VirusTotal/yara-x.git
cd yara-x
cargo build --release
sudo cp target/release/yr /usr/local/bin/

Core Commands

CommandDescription
yr scan <rules> <target>Scan file or directory against rules
yr scan -r <rules_dir> <target>Recursively load rules from directory
yr check <rules>Validate rule syntax
yr fmt <rules>Format/prettify rule files
yr dump <file>Dump module data for a file
yr completion <shell>Generate shell completions
# Scan a single file
yr scan rules.yar suspicious.exe

# Scan a directory recursively
yr scan rules.yar /malware/samples/

# Scan with multiple rule files
yr scan rule1.yar rule2.yar rule3.yar target.exe

# Scan with all rules in a directory
yr scan -r /opt/yara-rules/ target.exe

# Show matched strings
yr scan --print-strings rules.yar target.exe

# Show metadata from matched rules
yr scan --print-meta rules.yar target.exe

# Scan with timeout (seconds)
yr scan --timeout 120 rules.yar large_file.bin

# Output as JSON
yr scan --output-format json rules.yar target.exe

# Only show specific number of matches
yr scan --max-matches-per-rule 5 rules.yar target_dir/

# Scan with specific modules disabled
yr scan --disable-module dotnet rules.yar target.exe

Rule Validation and Formatting

# Check rule syntax
yr check my_rules.yar

# Check all rules in directory
yr check -r /opt/yara-rules/

# Format rules (fix indentation, style)
yr fmt my_rules.yar

# Format and overwrite in place
yr fmt --in-place my_rules.yar

# Dump PE module data for a file
yr dump --module pe sample.exe

# Dump all available module data
yr dump sample.exe

Rule Writing

Basic Rule Structure

rule ExampleRule {
    meta:
        author = "analyst"
        description = "Detect example malware family"
        date = "2026-01-15"
        reference = "https://example.com/report"
        severity = "high"
        hash = "a1b2c3d4..."

    strings:
        $str1 = "malicious_string"
        $str2 = "another_string" nocase
        $hex1 = { 4D 5A 90 00 03 00 }
        $regex1 = /https?:\/\/[a-z0-9\-\.]+\.[a-z]{2,}/

    condition:
        uint16(0) == 0x5A4D and
        ($str1 or $str2) and
        #hex1 > 2
}

String Modifiers

rule StringModifiers {
    strings:
        $plain = "hello world"
        $nocase = "password" nocase          // Case-insensitive
        $wide = "config" wide                // UTF-16LE
        $both = "data" ascii wide            // Both encodings
        $fullword = "cmd" fullword           // Word boundary match
        $xor = "secret" xor                  // XOR with all single-byte keys
        $xor_range = "secret" xor(0x01-0xFF) // XOR with specific range
        $base64 = "admin" base64             // Base64 encoded
        $base64wide = "admin" base64wide     // Base64 of wide string

    condition:
        any of them
}

Hex Patterns

rule HexPatterns {
    strings:
        // Exact bytes
        $exact = { 4D 5A 90 00 }

        // Wildcards
        $wild = { 4D 5A ?? 00 }

        // Nibble wildcards
        $nibble = { 4D 5? ?0 00 }

        // Jumps (variable length)
        $jump = { E8 [4] 85 C0 }           // Exactly 4 bytes between
        $range = { E8 [2-6] 85 C0 }        // 2 to 6 bytes between
        $unlimited = { E8 [-] 85 C0 }      // Any number of bytes

        // Alternatives
        $alt = { (4D | 5A) 90 00 }

    condition:
        any of them
}

Conditions

rule ConditionExamples {
    strings:
        $a = "string_a"
        $b = "string_b"
        $c = "string_c"

    condition:
        // Boolean logic
        $a and ($b or $c)

        // Count of matches
        #a > 3                    // More than 3 occurrences
        #a in (100..500) >= 2     // At least 2 in byte range

        // String position
        $a at 0                   // At offset 0
        $a in (0..1024)          // Within first 1KB

        // File size
        filesize < 1MB

        // Set operations
        any of ($a, $b, $c)
        all of them
        2 of ($a, $b, $c)
        any of ($str*)           // Wildcard on string names

        // Integer functions
        uint16(0) == 0x5A4D      // MZ header
        uint32(0) == 0x464C457F  // ELF header
        int32(pe.entry_point) == 0xCCC3  // INT3 + RET at EP
}

Module Usage

PE Module

import "pe"

rule SuspiciousPE {
    condition:
        pe.is_pe and
        pe.number_of_sections > 7 and
        pe.entry_point_raw > pe.sections[pe.number_of_sections - 1].raw_data_offset and
        pe.timestamp > 1700000000 and
        not pe.is_signed
}

rule HighEntropySections {
    condition:
        pe.is_pe and
        for any section in pe.sections : (
            section.name == ".text" and
            math.entropy(section.raw_data_offset, section.raw_data_size) > 7.0
        )
}

ELF Module

import "elf"

rule SuspiciousELF {
    condition:
        elf.type == elf.ET_EXEC and
        elf.machine == elf.EM_X86_64 and
        elf.number_of_sections < 3
}

Math Module

import "math"

rule HighEntropy {
    condition:
        math.entropy(0, filesize) > 7.5
}

rule SpecificEntropy {
    condition:
        math.entropy(0, 1024) > 7.0 and
        math.mean(0, filesize) > 200
}

Advanced Usage

Python API

import yara_x

# Compile rules
compiler = yara_x.Compiler()
compiler.add_source('''
rule test {
    strings:
        $a = "malware"
    condition:
        $a
}
''')
rules = compiler.build()

# Scan file
results = rules.scan_file("suspect.exe")
for rule in results.matching_rules:
    print(f"Matched: {rule.identifier}")
    for pattern in rule.patterns:
        for match in pattern.matches:
            print(f"  Offset: {match.offset}, Length: {match.length}")

# Scan data
with open("suspect.exe", "rb") as f:
    data = f.read()
results = rules.scan(data)

Performance Tuning

# Parallel scanning with multiple threads
yr scan --threads 8 rules.yar /malware/samples/

# Scan with limited stack size (for complex rules)
yr scan --stack-size 32768 rules.yar target.exe

# Skip files larger than threshold
find /samples -type f -size -10M | xargs -P4 yr scan rules.yar

Migrating from YARA to YARA-X

# Check compatibility of existing rules
yr check legacy_rules.yar

# Common migration issues:
# 1. Stricter type checking in conditions
# 2. Some deprecated features removed
# 3. Module API differences

# Format rules to YARA-X style
yr fmt --in-place legacy_rules.yar

Rule Development Workflow

# Validate rules before deployment
yr check -r /opt/yara-rules/

# Test rule against known samples
yr scan new_rule.yar /malware/confirmed/family_x/

# Test for false positives
yr scan new_rule.yar /known-good/system32/

# Dump module info for rule development
yr dump --module pe target.exe

Troubleshooting

IssueSolution
Rule compilation errorRun yr check for detailed error messages with line numbers
Performance degradationReduce regex complexity, avoid unbounded jumps [-], add filesize conditions
False positivesAdd filesize constraints, use fullword modifier, combine with PE/ELF module checks
Module not foundCheck available modules with yr dump, verify YARA-X version supports the module
Encoding issues in stringsUse explicit ascii, wide, or nocase modifiers
Stack overflow on complex rulesIncrease stack size with --stack-size flag
Legacy rule incompatibilityCheck YARA-X migration guide, fix stricter type requirements
Slow directory scanningUse --threads for parallelism, exclude large non-target files