How to Extend YARA Rules in SkillSpector for Custom Malware Signatures

SkillSpector merges built-in and user-supplied YARA rule directories at scan time, compiling them into namespaced rule sets that detect custom malware signatures alongside default patterns.

SkillSpector is NVIDIA's open-source static analysis framework that ships with a built-in YARA analyzer for malware detection. The tool allows security researchers to extend YARA rules by adding custom signature files without modifying core code. This guide explains how the rule loading pipeline works and how to integrate your own malware signatures using the CLI and Python API.

How SkillSpector's YARA Analyzer Loads Custom Rules

The static_yara analyzer implements a flexible loading mechanism that combines built-in signatures with user-provided rules. The implementation resides in src/skillspector/nodes/analyzers/static_yara.py.

The CLI Flag and State Management

The entry point for custom rules is the --yara-rules-dir flag defined in src/skillspector/cli.py (lines 167-171). When invoked, the CLI stores the supplied path in the global scan state under state["yara_rules_dir"] as defined in src/skillspector/state.py (lines 73-74).

The analyzer checks this state field during initialization. If present, it triggers the custom rule loading logic alongside the built-in set.

The Rule Loading Pipeline

When the analysis graph reaches the YARA node, the _load_rules() helper executes the following sequence:

  1. Collect built-in rules from src/skillspector/yara_rules/ (referenced as _BUILTIN_RULES_DIR)
  2. Gather user rules via _collect_rule_files() if yara_rules_dir is set, scanning for *.yar and *.yara extensions
  3. Build namespace map using _build_namespace_map() to assign "default" namespace to built-in rules and the directory name to custom rules
  4. Compile and cache the merged list via yara.compile(filepaths=...), storing the result in _compiled_rules
  5. Hash detection using _content_hash() to detect changes and reload only when the rule set modifications occur

For each file analyzed, _match_file() scans content against the compiled rule set and emits an AnalyzerFinding for every match.

Creating Custom Malware Signatures

Write your YARA rules using standard syntax and save them with .yar or .yara extensions. SkillSpector imposes no special requirements beyond valid YARA syntax.

rule MyCustomMalware
{
    meta:
        description = "Detects a specific custom malware family"
        severity    = "high"
    strings:
        $s1 = "malicious_string"
        $c2 = { 4D 5A ?? ?? 00 }
    condition:
        $s1 or $c2
}

Save this file to a dedicated directory, such as ~/my_yara_rules/custom_malware.yar.

Running SkillSpector with Extended Rules

Command Line Usage

Pass your custom directory to the --yara-rules-dir flag:

skillsppector scan path/to/your/project \
    --yara-rules-dir ~/my_yara_rules \
    --format sarif

The analyzer automatically merges your signatures with the built-in rules from src/skillspector/yara_rules/ and compiles them under distinct namespaces.

Python API Usage

When invoking SkillSpector programmatically, set the yara_rules_dir parameter in the scan state:

from skillspector.cli import _scan_state

state = _scan_state(
    input_path="path/to/project",
    format="sarif",
    no_llm=True,
    yara_rules_dir="/home/user/my_yara_rules"
)

# The pipeline executes with your custom rules loaded

Verifying Your Custom Rules Loaded

To confirm your rules were compiled correctly, inspect the namespace map programmatically:

from pathlib import Path
from skillspector.nodes.analyzers import static_yara

# Force reload to refresh the cache

static_yara._compiled_rules = None
static_yara._load_rules(extra_dir=Path("/home/user/my_yara_rules"))

# Check the namespace assignments

files = static_yara._collect_rule_files(Path("/home/user/my_yara_rules"))
namespace_map = static_yara._build_namespace_map(files)
print(namespace_map)

You should see output mapping your rule files to their directory-based namespace:

{'/home/user/my_yara_rules/custom_malware.yar': 'my_yara_rules'}

This confirms the YARA engine will evaluate your custom signatures alongside the built-in set.

Summary

  • SkillSpector supports custom YARA rules through the --yara-rules-dir CLI flag and corresponding state field.
  • The _load_rules() function in src/skillspector/nodes/analyzers/static_yara.py merges built-in rules from src/skillspector/yara_rules/ with user-provided directories.
  • Rules are compiled under namespaces to prevent conflicts, with built-in rules using "default" and custom rules using their directory name.
  • The analyzer caches compiled rules using a content hash to avoid recompilation during long scans.
  • Any file matching *.yar or *.yara in the specified directory is automatically included without code changes.

Frequently Asked Questions

What file extensions does SkillSpector recognize for YARA rules?

SkillSpector recognizes both .yar and .yara extensions. The _collect_rule_files() function in src/skillspector/nodes/analyzers/static_yara.py scans directories for files matching these patterns and includes them in the compilation step.

How does SkillSpector handle namespace conflicts between built-in and custom rules?

The analyzer uses _build_namespace_map() to assign distinct namespaces to each rule source. Built-in rules from src/skillspector/yara_rules/ receive the "default" namespace, while custom rules inherit their directory name as the namespace. This prevents identifier collisions while allowing rules to coexist in the same compilation unit.

Can I reload rules without restarting the scan?

The analyzer caches compiled rules in _compiled_rules and monitors the rule set via _content_hash(). If the hash of the rule files changes between scans, the analyzer automatically recompiles the rules. However, within a single scan execution, the compiled rules remain cached for performance.

Where are the built-in YARA rules stored in the repository?

The default rule set ships in src/skillspector/yara_rules/ at the root of the repository. These rules are always loaded unless explicitly disabled, and they serve as the foundation upon which custom signatures are layered when you specify --yara-rules-dir.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →