CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-yara-python

Python interface for YARA, a powerful malware identification and classification tool

Overall
score

85%

Evaluation85%

0.94x

Agent success when using this tile

Overview
Eval results
Files

compilation.mddocs/

Rule Compilation and Loading

Rule compilation transforms textual YARA rules into optimized Rules objects that can efficiently scan data. The compilation process supports various input sources, external variables, include mechanisms, and namespace organization.

Capabilities

Basic Rule Compilation

Compile YARA rules from source strings with the fundamental compile function.

def compile(source=None, filepath=None, file=None, filepaths=None, sources=None, 
           includes=True, externals=None, error_on_warning=False, include_callback=None):
    """
    Compile YARA rules from various sources.
    
    Parameters:
    - source (str, optional): YARA rules as a string
    - filepath (str, optional): Path to a single rules file
    - file (file-like, optional): File-like object containing rules
    - filepaths (dict, optional): Mapping of namespaces to file paths
    - sources (dict, optional): Mapping of namespaces to rule strings
    - includes (bool): Enable include directive processing (default: True)
    - externals (dict, optional): External variables for rules
    - error_on_warning (bool): Treat warnings as errors (default: False)
    - include_callback (callable, optional): Callback for handling includes
    
    Returns:
    Rules: Compiled rules object ready for matching
    
    Raises:
    SyntaxError: If rules contain syntax errors
    """

Basic compilation example:

import yara

# Simple rule compilation
rules = yara.compile(source='''
rule MalwarePattern {
    strings:
        $suspicious = "eval("
        $encoded = { 4D 5A }  // MZ header
    condition:
        $suspicious or $encoded
}
''')

File-Based Compilation

Compile rules from files on disk or file-like objects.

Single file compilation:

# From file path
rules = yara.compile(filepath="/path/to/rules.yar")

# From file object
with open("rules.yar", "r") as f:
    rules = yara.compile(file=f)

# From StringIO/BytesIO (file-like objects)
import io

rule_content = '''
rule TestRule {
    strings:
        $test = "pattern"
    condition:
        $test
}
'''

# Using StringIO
rule_stream = io.StringIO(rule_content)
rules = yara.compile(file=rule_stream)

# Using BytesIO (Python 3)
rule_bytes = rule_content.encode('utf-8')
byte_stream = io.BytesIO(rule_bytes)
rules = yara.compile(file=byte_stream)

Multi-Source Compilation with Namespaces

Organize rules from multiple sources using namespaces for better organization and conflict resolution.

Multiple files with namespaces:

rules = yara.compile(filepaths={
    'malware': '/path/to/malware_rules.yar',
    'goodware': '/path/to/goodware_rules.yar',
    'network': '/path/to/network_rules.yar'
})

Multiple sources with namespaces:

rules = yara.compile(sources={
    'basic': 'rule test1 { condition: true }',
    'advanced': '''
        rule test2 {
            strings:
                $hex = { 4D 5A 90 00 }
            condition:
                $hex at 0
        }
    '''
})

External Variables

Pass external variables to rules for dynamic behavior and parameterization.

Supported external variable types:

# Integer externals
rules = yara.compile(
    source='rule test { condition: ext_size > 1000 }',
    externals={'ext_size': 2048}
)

# Float externals  
rules = yara.compile(
    source='rule test { condition: ext_ratio > 0.75 }',
    externals={'ext_ratio': 0.85}
)

# Boolean externals
rules = yara.compile(
    source='rule test { condition: is_executable }',
    externals={'is_executable': True}
)

# String externals
rules = yara.compile(
    source='rule test { condition: filename matches ext_pattern }',
    externals={'ext_pattern': '*.exe'}
)

Include Callback System

Handle include directives dynamically with custom callback functions for modular rule organization.

def include_callback(requested_filename, filename, namespace):
    """
    Handle include directives in YARA rules.
    
    Parameters:
    - requested_filename (str): The filename requested in the include directive
    - filename (str): The file being processed that contains the include
    - namespace (str): The namespace context
    
    Returns:
    str or None: Rule content to include, or None to skip
    """

Include callback example:

def my_include_callback(requested_filename, filename, namespace):
    include_map = {
        'common.yar': '''
            rule CommonPattern {
                strings:
                    $common = "suspicious"
                condition:
                    $common
            }
        ''',
        'network.yar': '''
            rule NetworkPattern {
                condition:
                    uint16(0) == 0x5A4D  // MZ signature
            }
        '''
    }
    return include_map.get(requested_filename)

rules = yara.compile(
    source='include "common.yar" include "network.yar" rule main { condition: true }',
    include_callback=my_include_callback
)

Rule Serialization

Save compiled rules to disk for performance optimization and reuse across sessions.

class Rules:
    def save(self, filepath=None, file=None):
        """
        Save compiled rules to file.
        
        Parameters:
        - filepath (str, optional): Path to save compiled rules
        - file (file-like, optional): File-like object to write to
        """

Save compiled rules:

# Save to file path
rules.save(filepath="compiled_rules.yarc")

# Save to file object
with open("rules.yarc", "wb") as f:
    rules.save(file=f)

# Save to BytesIO (file-like object)
import io

# Save to memory buffer
buffer = io.BytesIO()
rules.save(file=buffer)

# Get the compiled rules as bytes
compiled_data = buffer.getvalue()
print(f"Compiled rules size: {len(compiled_data)} bytes")

Rule Loading

Load previously compiled and saved rules for immediate use without recompilation.

def load(filepath=None, file=None):
    """
    Load previously saved compiled rules.
    
    Parameters:
    - filepath (str, optional): Path to saved rules file
    - file (file-like, optional): File-like object to read from
    
    Returns:
    Rules: Loaded rules object ready for matching
    """

Load compiled rules:

# Load from file path
rules = yara.load(filepath="compiled_rules.yarc")

# Load from file object
with open("rules.yarc", "rb") as f:
    rules = yara.load(file=f)

# Load from BytesIO (file-like object)
import io

# Assume compiled_data is bytes from previous save operation
buffer = io.BytesIO(compiled_data)
rules = yara.load(file=buffer)

# Complete save/load example with memory buffers
original_rules = yara.compile(source='rule test { condition: true }')

# Save to memory
save_buffer = io.BytesIO()
original_rules.save(file=save_buffer)

# Load from memory
load_buffer = io.BytesIO(save_buffer.getvalue())
restored_rules = yara.load(file=load_buffer)

# Both rules should behave identically
matches1 = original_rules.match(data="test")
matches2 = restored_rules.match(data="test")

Advanced Compilation Options

Control compilation behavior with advanced options for specific use cases.

Disable includes:

# This will raise SyntaxError if source contains include directives
try:
    rules = yara.compile(
        source='include "test.yar" rule main { condition: true }',
        includes=False
    )
except yara.SyntaxError as e:
    print(f"Include directive not allowed: {e}")

Treat warnings as errors:

rules = yara.compile(
    source='rule test { condition: true }',
    error_on_warning=True
)

Rule Object Inspection

Access individual rules within a compiled Rules object through iteration.

class Rules:
    """Compiled YARA rules container supporting iteration."""
    def __iter__(self):
        """Iterate over individual Rule objects."""

class Rule:
    """Individual YARA rule representation."""
    identifier: str  # Rule name/identifier
    tags: list      # List of rule tags
    meta: dict      # Rule metadata dictionary

Inspect compiled rules:

# Iterate over all rules in the compiled Rules object
for rule in rules:
    print(f"Rule: {rule.identifier}")
    print(f"Tags: {rule.tags}")
    print(f"Metadata: {rule.meta}")

# Rules object supports standard iteration protocols
rule_list = list(rules)          # Convert to list
rule_count = len(rule_list)      # Count rules (indirect)
first_rule = next(iter(rules))   # Get first rule

# Enumerate rules
for i, rule in enumerate(rules, 1):
    print(f"Rule {i}: {rule.identifier}")
    if rule.tags:
        print(f"  Tags: {', '.join(rule.tags)}")
    if rule.meta:
        print(f"  Metadata: {rule.meta}")

Install with Tessl CLI

npx tessl i tessl/pypi-yara-python

docs

compilation.md

config.md

index.md

matching.md

tile.json