# How to Add Custom YARA Rules to SkillSpector for Malware and Hack-Tool Detection

> Learn to add custom YARA rules to NVIDIA SkillSpector to enhance malware and hack tool detection. Effortlessly integrate your rules for improved static analysis.

- Repository: [NVIDIA Corporation/SkillSpector](https://github.com/NVIDIA/SkillSpector)
- Tags: how-to-guide
- Published: 2026-07-08

---

**SkillSpector supports custom YARA rule directories via the `--yara-rules-dir` flag, automatically merging user-supplied `.yar` files with built-in rules for static analysis of skill packages.**

NVIDIA's SkillSpector ships with a built-in YARA analyzer located in `src/skillspector/yara_rules/` that detects malware, hack tools, webshells, and cryptominers. You can extend this detection capability by supplying your own rule files without modifying the core repository. This guide covers the exact CLI workflow, metadata schema, and source code implementation details you need to integrate custom YARA rules.

## How the YARA Analyzer Works

The YARA analyzer node (`static_yara.node`) executes as part of the SkillSpector analysis pipeline. It compiles rule sets once, caches them based on a content hash (`_content_hash`), and scans every artifact extracted from the skill package—including source files and binaries.

### Built-in Rules Location

SkillSpector distributes a curated rule bundle in `src/skillspector/yara_rules/`. These rules cover common threats like webshells, malware families, and exploit patterns. The analyzer loads these automatically on every run.

### Rule Loading and Compilation

When the analyzer executes, it invokes `_load_rules(extra_dir)` in [`src/skillspector/nodes/analyzers/static_yara.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/analyzers/static_yara.py). This method compiles both the built-in rules and any user-supplied directory into a single `yara.Rules` object. The compilation step includes generating a content hash for caching, ensuring that repeated scans of identical rule sets execute quickly.

### State Management

The CLI parses the `--yara-rules-dir` argument in [`src/skillspector/cli.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/cli.py) and stores the path in the global analysis state under the key `yara_rules_dir` (defined in [`src/skillspector/state.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/state.py)). Downstream nodes access this path to locate custom rules on disk.

## Step-by-Step Guide to Adding Custom YARA Rules

### 1. Create Your Rule Directory

Create a directory anywhere on your host machine to store `.yar` or `.yara` files:

```bash
mkdir -p /home/user/custom_yara/extra_rules

```

SkillSpector recursively scans this directory, so you can organize rules into subdirectories.

### 2. Author YARA Rules with SkillSpector Metadata

Each rule file must contain at least one valid YARA rule. Include a `meta` section with specific keys to control how SkillSpector categorizes and reports findings:

- **`category`**: Maps to the rule ID prefix and severity (e.g., `malware`, `hack_tool`, `webshell`, `cryptominer`, `exploit`). The `_CATEGORY_MAP_` in [`static_yara.py`](https://github.com/NVIDIA/SkillSpector/blob/main/static_yara.py) defines the default mappings.
- **`severity`**: Sets the SARIF severity level (e.g., `CRITICAL`, `HIGH`, `MEDIUM`, `LOW`).
- **`confidence`**: Float value between 0 and 1 representing detection confidence.
- **`description`**: Human-readable text included in the finding message.

Example custom rule (`my_malware.yar`):

```yara
rule MyMalware
{
    meta:
        category = "malware"
        severity = "CRITICAL"
        confidence = 0.9
        description = "Detects known malicious payload pattern"

    strings:
        $a = "malicious_string"
        $b = { 6A 40 68 ?? ?? ?? ?? 6A 00 6A 01 6A 02 6A 03 }

    condition:
        any of ($a, $b)
}

```

### 3. Run SkillSpector with the Custom Directory

Pass the absolute path to your rules directory using the `--yara-rules-dir` flag:

```bash
skill-spector scan path/to/skill.zip \
    --yara-rules-dir /home/user/custom_yara \
    --format json \
    --output findings.json

```

The analyzer merges your rules with the built-in set, compiles them, and scans all extracted artifacts.

## Inspecting YARA Findings in Output

For every YARA match, the analyzer creates an `AnalyzerFinding` object. The `_build_message` method in [`static_yara.py`](https://github.com/NVIDIA/SkillSpector/blob/main/static_yara.py) constructs the message string incorporating the rule name, description, and namespace. This finding is then transformed into SARIF format.

Example JSON output for a custom rule match:

```json
{
  "rule_id": "YR1",
  "message": "YARA rule 'MyMalware': Detects known malicious payload pattern",
  "severity": "CRITICAL",
  "location": {
    "file": "src/main.py",
    "startLine": 42
  },
  "confidence": 0.9,
  "tags": ["yara_match"],
  "context": "... snippet of surrounding code ...",
  "matchedText": "malicious_string"
}

```

## Programmatic Access to Rule Compilation

You can manually load and inspect custom rules using the internal API—useful for debugging rule syntax before running a full scan:

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

# Load rules manually

custom_dir = Path("/home/user/custom_yara")
compiled = static_yara._load_rules(custom_dir)  # returns yara.Rules or None

if compiled:
    print(f"Compiled {len(compiled.rules)} rules")
    for rule in compiled.rules:
        print(f"  - {rule.identifier}")

```

## Summary

- **SkillSpector** automatically loads built-in YARA rules from `src/skillspector/yara_rules/` and merges them with user-supplied directories.
- Use the **`--yara-rules-dir`** flag to specify your custom rule path; the CLI stores this in [`state.py`](https://github.com/NVIDIA/SkillSpector/blob/main/state.py) under `yara_rules_dir`.
- Rule files must use `.yar` or `.yara` extensions and include **`meta`** keys (`category`, `severity`, `confidence`, `description`) for proper categorization.
- The **[`static_yara.py`](https://github.com/NVIDIA/SkillSpector/blob/main/static_yara.py)** node compiles rules via `_load_rules()`, caches them using `_content_hash`, and generates SARIF findings via `_build_message()`.
- Custom and built-in rules are compiled together once per run, ensuring optimal performance while maintaining detection coverage.

## Frequently Asked Questions

### What file extensions does SkillSpector recognize for YARA rules?

SkillSpector recognizes files ending in `.yar` or `.yara`. The `_load_rules()` method in [`static_yara.py`](https://github.com/NVIDIA/SkillSpector/blob/main/static_yara.py) scans the specified directory recursively and compiles any files matching these extensions.

### How does SkillSpector resolve conflicts between built-in and custom rules?

SkillSpector merges rule sets before compilation. If duplicate rule identifiers exist, the YARA compiler will raise an error. The analyzer loads built-in rules first, then appends custom rules from the directory specified in `--yara-rules-dir`, compiling them into a single cached rules object.

### What metadata keys are required for proper severity mapping?

While YARA rules function without metadata, SkillSpector specifically looks for **`category`**, **`severity`**, **`confidence`**, and **`description`** in the `meta` section. The `category` key determines the default rule ID prefix and severity mapping via `_CATEGORY_MAP_` in [`static_yara.py`](https://github.com/NVIDIA/SkillSpector/blob/main/static_yara.py).

### Where does SkillSpector cache compiled YARA rules?

The analyzer caches compiled rules based on a content hash (`_content_hash`) calculated from the combined rule text. This cache persists for the duration of the analysis run, ensuring that repeated scans of the same skill package with unchanged rules skip recompilation.