
A powerful Python library and CLI tool for parsing, analyzing, and manipulating YARA rules through Abstract Syntax Tree (AST) representation
<p align="center">
<img src="https://img.shields.io/badge/YARAAST-YARA%20Parser%20&%20AST-blue?style=for-the-badge" alt="YARAAST">
</p>
<h1 align="center">yaraast</h1>
<p align="center">
<strong>Parse, analyze, and transform YARA rules with a Python AST toolkit</strong>
</p>
<p align="center">
<a href="https://github.com/seifreed/yaraast/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/seifreed/yaraast/ci.yml?branch=main&style=flat-square&logo=github&label=CI" alt="CI"></a>
<a href="https://github.com/seifreed/yaraast/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-green?style=flat-square" alt="License: MIT"></a>
<img src="https://img.shields.io/badge/python-3.11--3.14-blue?style=flat-square&logo=python&logoColor=white" alt="Python 3.11-3.14">
</p>
<p align="center">
<a href="https://github.com/seifreed/yaraast/stargazers"><img src="https://img.shields.io/github/stars/seifreed/yaraast?style=flat-square&logo=github" alt="GitHub Stars"></a>
<a href="https://github.com/seifreed/yaraast/issues"><img src="https://img.shields.io/github/issues/seifreed/yaraast?style=flat-square&logo=github" alt="GitHub Issues"></a>
<a href="https://github.com/seifreed/yaraast/tree/main/docs"><img src="https://img.shields.io/badge/docs-GitHub-blue?style=flat-square&logo=readthedocs&logoColor=white" alt="Docs"></a>
</p>
---
## Overview
**yaraast** is a Python library for parsing and manipulating YARA-family rules using Abstract Syntax Trees (AST). It supports classic YARA, YARA-L, and YARA-X workflows with automatic dialect detection and CLI tooling.
### Key Features
| Feature | Description |
|---------|-------------|
| **Multi-dialect Parsing** | Parse YARA, YARA-L, and YARA-X from files or strings |
| **Automatic Dialect Detection** | Unified parser auto-detects rule dialects |
| **AST Tooling** | Build, transform, diff, and serialize ASTs |
| **Formatting & Validation** | CLI commands for parse/format/validate workflows |
| **Streaming Support** | Parse very large files with streaming mode |
| **Ecosystem Integrations** | Optional LSP and libyara-related capabilities |
### Supported Rule Ecosystem
```text
Dialects YARA, YARA-L, YARA-X
Parsers Standard parser, unified parser, streaming parser
Outputs YARA, JSON, YAML, AST tree views
Tooling CLI, visitors, builders, serialization, semantic checks
```
Support levels differ by dialect. Classic YARA is stable, YARA-X is beta,
YARA-L is experimental, and automatic dialect detection is best effort. See
the [compatibility matrix](https://github.com/seifreed/yaraast/blob/main/docs/compatibility.md) for the exact engines and
capabilities exercised by CI.
---
## Installation
### From PyPI (Recommended)
```bash
pip install yaraast
```
### From Source
```bash
git clone https://github.com/seifreed/yaraast.git
cd yaraast
python3 -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -e .
```
---
## Quick Start
```python
import yaraast
yara_code = """
rule example {
strings:
$a = "malware" nocase
condition:
$a
}
"""
document = yaraast.parse(yara_code)
print(document.ast.rules[0].name)
```
---
## Usage
### Command Line Interface
```bash
# Parse and print normalized YARA
yaraast parse rules.yar
# Parse to JSON
yaraast parse rules.yar --format json
# Parse with explicit dialect
yaraast parse rules.yar --dialect yara-x
# Validate file (syntax + parse checks)
yaraast validate rules.yar
# Format file in-place (AST-based formatter)
yaraast fmt rules.yar
# Check formatting without modifying file
yaraast fmt rules.yar --check
```
### Core CLI Commands
| Command | Description |
|--------|-------------|
| `parse` | Parse a rule file and output YARA/JSON/YAML/tree |
| `validate` | Validate rules and run validation subcommands |
| `fmt` | AST-based formatter (with `--check` and `--diff`) |
| `format` | Format input into a target output file |
| `validate-syntax` | Syntax-focused validation entrypoint |
| `lsp` | Launch Language Server Protocol features |
---
## Python Library
### Unified Parsing
```python
from pathlib import Path
import yaraast
source = "rule example { condition: true }"
# Auto-detect dialect
document = yaraast.parse(source)
# Force specific dialect
document = yaraast.parse(source, dialect="yara")
# Parse files, generate new source, and format canonically
Path("rules.yar").write_text(source, encoding="utf-8")
file_document = yaraast.parse_file("rules.yar")
generated = yaraast.generate(file_document)
formatted = yaraast.format_canonical(source, dialect="yara")
# Preserve every byte outside an explicit UTF-8 byte edit
offset = source.encode("utf-8").index(b"true")
rewritten = yaraast.rewrite_lossless(
source,
[yaraast.SourceEdit(offset, offset + 4, "false")],
)
# Public parsers apply bounded defaults. Override them per operation when needed.
limits = yaraast.ResourceLimits(max_input_bytes=1024 * 1024, parse_deadline=5.0)
document = yaraast.parse(source, resource_limits=limits)
cancel = yaraast.CancellationToken()
cancel.cancel()
# yaraast.parse(source, cancellation_token=cancel) raises ParseCancelledError
```
`ResourceLimits()` disables all bounds explicitly. CLI parsing uses the public
defaults; LSP parsing uses tighter input, token, nesting, pattern, and deadline
limits and never caches a partial result after cancellation or a limit failure.
### Direct Parser + Visitor
```python
from pathlib import Path
from yaraast.parser import Parser
from yaraast.visitor import BaseVisitor
class RuleCollector(BaseVisitor):
def __init__(self):
self.rules = []
def visit_rule(self, node):
self.rules.append(node.name)
super().visit_rule(node)
ast = Parser(Path("rules.yar").read_text(encoding="utf-8")).parse()
collector = RuleCollector()
collector.visit(ast)
print(collector.rules)
```
---
## Optional Dependencies
```bash
# LSP support
pip install yaraast[lsp]
# libyara integration
pip install yaraast[libyara]
# Performance tooling
pip install yaraast[performance]
# Visualization support
pip install yaraast[visualization]
# Runtime support bundle
pip install yaraast[all]
# Runtime and development tooling
pip install yaraast[dev-all]
```
## Runtime Docs
- Dialect compatibility: [docs/compatibility.md](https://github.com/seifreed/yaraast/blob/main/docs/compatibility.md)
- LSP runtime internals: [docs/lsp-runtime.md](https://github.com/seifreed/yaraast/blob/main/docs/lsp-runtime.md)
- LSP parity report: [docs/lsp-parity-report.md](https://github.com/seifreed/yaraast/blob/main/docs/lsp-parity-report.md)
- Latest runtime benchmark artifact: [docs/benchmarks/lsp-runtime-latest.json](https://github.com/seifreed/yaraast/blob/main/docs/benchmarks/lsp-runtime-latest.json)
---
## Requirements
- Python 3.11, 3.12, 3.13, or 3.14
- See [pyproject.toml](https://github.com/seifreed/yaraast/blob/main/pyproject.toml) for full dependency and extras list
---
## Contributing
Contributions are welcome. See [CONTRIBUTING.md](https://github.com/seifreed/yaraast/blob/main/CONTRIBUTING.md) for setup, quality checks, and workflow guidelines.
1. Fork the repository
2. Create a branch (`git checkout -b feature/your-change`)
3. Commit changes (`git commit -m "Add your change"`)
4. Push (`git push origin feature/your-change`)
5. Open a Pull Request
Project policy is documented in [SECURITY.md](https://github.com/seifreed/yaraast/blob/main/SECURITY.md),
[CODE_OF_CONDUCT.md](https://github.com/seifreed/yaraast/blob/main/CODE_OF_CONDUCT.md), [CHANGELOG.md](https://github.com/seifreed/yaraast/blob/main/CHANGELOG.md), and
[MIGRATING.md](https://github.com/seifreed/yaraast/blob/main/MIGRATING.md).
---
## License
This project is licensed under the MIT License - see [LICENSE](https://github.com/seifreed/yaraast/blob/main/LICENSE).
**Author**
- Marc Rivero ([[email protected]](mailto:[email protected]))
- Repository: [github.com/seifreed/yaraast](https://github.com/seifreed/yaraast)
---
<p align="center">
<sub>Built for malware analysis and detection engineering workflows</sub>
</p>