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:
- Collect built-in rules from
src/skillspector/yara_rules/(referenced as_BUILTIN_RULES_DIR) - Gather user rules via
_collect_rule_files()ifyara_rules_diris set, scanning for*.yarand*.yaraextensions - Build namespace map using
_build_namespace_map()to assign"default"namespace to built-in rules and the directory name to custom rules - Compile and cache the merged list via
yara.compile(filepaths=...), storing the result in_compiled_rules - 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-dirCLI flag and corresponding state field. - The
_load_rules()function insrc/skillspector/nodes/analyzers/static_yara.pymerges built-in rules fromsrc/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
*.yaror*.yarain 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →