
Una potente biblioteca de Python y herramienta CLI para analizar, examinar y manipular reglas YARA mediante la representación de Árbol de Sintaxis Abstracta (AST).
yaraast es una biblioteca de Python para analizar y manipular reglas de la familia YARA mediante Árboles de Sintaxis Abstracta (AST). Admite flujos de trabajo clásicos de YARA, YARA-L y YARA-X con detección automática de dialectos y herramientas de línea de comandos.
| Característica | Descripción |
|---|---|
| Análisis multidialecto | Analiza YARA, YARA-L y YARA-X desde archivos o cadenas |
| Detección automática de dialectos | El analizador unificado detecta automáticamente los dialectos de las reglas |
| Herramientas AST | Construye, transforma, compara y serializa AST |
| Formato y validación | Comandos CLI para flujos de trabajo de análisis/formato/validación |
| Soporte de streaming | Analiza archivos muy grandes con modo de streaming |
| Integraciones del ecosistema | Capacidades opcionales relacionadas con LSP y libyara |
Dialectos YARA, YARA-L, YARA-X
Analizadores Analizador estándar, analizador unificado, analizador de streaming
Salidas YARA, JSON, YAML, vistas de árbol AST
Herramientas CLI, visitantes, constructores, serialización, comprobaciones semánticas
Los niveles de soporte difieren según el dialecto. El YARA clásico es estable, YARA-X está en beta, YARA-L es experimental y la detección automática de dialectos es un esfuerzo de mejor esfuerzo. Consulta la matriz de compatibilidad para conocer los motores y las capacidades exactas que se ejercitan en CI.
pip install yaraast
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 .
import yaraast
yara_code = """
rule example {
strings:
$a = "malware" nocase
condition:
$a
}
"""
document = yaraast.parse(yara_code)
print(document.ast.rules[0].name)
# Analiza e imprime YARA normalizado
yaraast parse rules.yar
# Analiza a JSON
yaraast parse rules.yar --format json
# Analiza con dialecto explícito
yaraast parse rules.yar --dialect yara-x
# Valida archivo (comprobaciones de sintaxis + análisis)
yaraast validate rules.yar
# Formatea archivo en el lugar (formateador basado en AST)
yaraast fmt rules.yar
# Comprueba el formato sin modificar el archivo
yaraast fmt rules.yar --check
| Comando | Descripción |
|---|---|
parse | Analiza un archivo de reglas y genera YARA/JSON/YAML/árbol |
validate | Valida reglas y ejecuta subcomandos de validación |
fmt | Formateador basado en AST (con --check y --diff) |
format | Formatea la entrada en un archivo de salida de destino |
validate-syntax | Punto de entrada de validación centrado en la sintaxis |
lsp | Inicia las funciones del Protocolo de Servidor de Lenguaje |
from pathlib import Path
import yaraast
source = "rule example { condition: true }"
# Detecta el dialecto automáticamente
document = yaraast.parse(source)
# Fuerza un dialecto específico
document = yaraast.parse(source, dialect="yara")
# Analiza archivos, genera nuevo código fuente y formatea de forma canónica
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")
# Conserva cada byte fuera de una edición explícita de bytes UTF-8
offset = source.encode("utf-8").index(b"true")
rewritten = yaraast.rewrite_lossless(
source,
[yaraast.SourceEdit(offset, offset + 4, "false")],
)
# Los analizadores públicos aplican límites predeterminados acotados. Anúlalos por operación cuando sea necesario.
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) lanza ParseCancelledError
ResourceLimits() desactiva explícitamente todos los límites. El análisis CLI utiliza los
valores predeterminados públicos; el análisis LSP utiliza límites más estrictos de entrada, tokens, anidamiento, patrones y plazos,
y nunca almacena en caché un resultado parcial después de una cancelación o un fallo de límite.
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)
# Soporte LSP
pip install yaraast[lsp]
# Integración con libyara
pip install yaraast[libyara]
# Herramientas de rendimiento
pip install yaraast[performance]
# Soporte de visualización
pip install yaraast[visualization]
# Paquete de soporte en tiempo de ejecución
pip install yaraast[all]
# Herramientas de tiempo de ejecución y desarrollo
pip install yaraast[dev-all]
Las contribuciones son bienvenidas. Consulta CONTRIBUTING.md para conocer la configuración, los controles de calidad y las pautas del flujo de trabajo.
git checkout -b feature/your-change)git commit -m "Add your change")git push origin feature/your-change)La política del proyecto está documentada en SECURITY.md, CODE_OF_CONDUCT.md, CHANGELOG.md y MIGRATING.md.
Este proyecto está licenciado bajo la Licencia MIT; consulta LICENSE.
Autor
Diseñado para flujos de trabajo de análisis de malware e ingeniería de detección