Skip to main content

plyara

PyPi Version

Parse YARA rules into a dictionary representation.

Plyara is a script and library that lexes and parses a file consisting of one more YARA rules into a python dictionary representation. The goal of this tool is to make it easier to perform bulk operations or transformations of large sets of YARA rules, such as extracting indicators, updating attributes, and analyzing a corpus. Other applications include linters and dependency checkers.

Plyara leverages the Python module PLY for lexing YARA rules.

This is a community-maintained fork of the original plyara by 8u1a. The "plyara" trademark is used with permission.

Installation

Plyara requires Python 3.10+.

Install with pip:

pip install plyara

Usage

Use the plyara Python library in your own applications:

>>> import plyara
>>> parser = plyara.Plyara()
>>> mylist = parser.parse_string('rule MyRule { strings: $a="1" \n condition: false }')
>>>
>>> import pprint
>>> pprint.pprint(mylist)
[{'condition_terms': ['false'],
  'raw_condition': 'condition: false ',
  'raw_strings': 'strings: $a="1" \n ',
  'rule_name': 'MyRule',
  'start_line': 1,
  'stop_line': 2,
  'strings': [{'name': '$a', 'type': 'text', 'value': '1'}]}]
>>>

Or, use the included plyara script from the command line:

$ plyara -h
usage: plyara [-h] [--log] FILE

Parse YARA rules into a dictionary representation.

positional arguments:
  FILE        File containing YARA rules to parse.

optional arguments:
  -h, --help  show this help message and exit
  --log       Enable debug logging to the console.

The command-line tool will print valid JSON output when parsing rules:

rule silent_banker : banker
{
    meta:
        description = "This is just an example"
        threat_level = 3
        in_the_wild = true
    strings:
        $a = {6A 40 68 00 30 00 00 6A 14 8D 91}
        $b = {8D 4D B0 2B C1 83 C0 27 99 6A 4E 59 F7 F9}
        $c = "UVODFRYSIHLNWPEJXQZAKCBGMT"
    condition:
        $a or $b or $c
}

Command-line tool:

plyara example.yar

JSON Output:

[
    {
        "condition_terms": [
            "$a",
            "or",
            "$b",
            "or",
            "$c"
        ],
        "metadata": [
            {
                "description": "This is just an example"
            },
            {
                "threat_level": 3
            },
            {
                "in_the_wild": true
            }
        ],
        "raw_condition": "condition:\n        $a or $b or $c\n",
        "raw_meta": "meta:\n        description = \"This is just an example\"\n        threat_level = 3\n        in_the_wild = true\n    ",
        "raw_strings": "strings:\n        $a = {6A 40 68 00 30 00 00 6A 14 8D 91}\n        $b = {8D 4D B0 2B C1 83 C0 27 99 6A 4E 59 F7 F9}\n        $c = \"UVODFRYSIHLNWPEJXQZAKCBGMT\"\n    ",
        "rule_name": "silent_banker",
        "start_line": 1,
        "stop_line": 13,
        "strings": [
            {
                "name": "$a",
                "type": "byte",
                "value": "{6A 40 68 00 30 00 00 6A 14 8D 91}"
            },
            {
                "name": "$b",
                "type": "byte",
                "value": "{8D 4D B0 2B C1 83 C0 27 99 6A 4E 59 F7 F9}"
            },
            {
                "name": "$c",
                "type": "text",
                "value": "UVODFRYSIHLNWPEJXQZAKCBGMT"
            }
        ],
        "tags": [
            "banker"
        ]
    }
]

Additional Information

Reusing The Parser

If you want to reuse a single instance of the parser object for efficiency when parsing large quantities of rule or rulesets, the new clear() method must be used.

rules = list()
parser = plyara.Plyara()

for file in files:
    with open(file, 'r') as fh:
        yararules = parser.parse_string(fh.read())
        rules += yararules
    parser.clear()

Breaking Change: Import Effects

Background

Imports are available to be used in a rule even if not used in a condition. Also, any module which is imported at all is used in processing all files scanned using the ruleset regardless if the import is used anywhere. Some users require that all rules affected by a particular import include that import in the dictionary output of plyara. At the same time, many users expect that a particular rule not include an import if that import is not used in the rule.

New Parameter: Import Effects

A new class constructor parameter called import_effects has been added to the parser. This parameter defaults to False which is a breaking change. Users who wish to retain the behavior from versions before 2.2, will need to set this parameter to True like so:

parser = plyara.Plyara(import_effects=True)

Note

When reusing a parser for multiple rules and/or files and import_effects is enabled, be aware that imports are now shared across all rules - if one rule has an import, that import will be added to all rules in your parser object.

Breaking Change: Logic Hash Versions

Logic hashes now prepend a version number as well as the algorithm used to the hash itself. This will make future changes and revisions easier for uses to track. The old behavior is accessed using the legacy parameter on the utils.generate_hash() utility function.

rules = Plyara().parse_string(input_string)
rulehash = generate_hash(rules[0], legacy=True)

Pre-Processing

If the output of a particular rule looks incorrect after parsing by Plyara, you may be able to mitigate the problem by using YARA-X's fmt command for pre-processing. If you do notice a problem that requires pre-processing, please also open an issue.

yr fmt foo.yar

Contributing

  • If you find a bug, or would like to see a new feature, Pull Requests and Issues are always welcome.
  • By submitting changes, you agree to release those changes under the terms of the LICENSE.
  • Writing passing unit tests for your changes, while not required, is highly encouraged and appreciated.
  • Please run all code contributions through each of the linters that we use for this project:
    • pycodestyle
    • pydocstyle
    • pyflakes
  • For more information on these linters, please refer to the Python Code Quality Authority

Cloning

To properly clone this repository including the git submodule for PLY, use the following command:

git clone --recurse-submodules https://github.com/plyara/plyara.git

Installing for Development

For coverage to work properly, the package must be installed in editable mode with the optional dependencies for tests.

pip install -e '.[tests]'

Unit Tests

python -m unittest discover

Coverage

coverage run -m unittest discover
coverage report -m

Release files for plyara 2.2.8

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for plyara 2.2.8
File Size Uploaded
plyara-2.2.8.tar.gz 68.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for plyara 2.2.8
File Interpreter ABI Platform
plyara-2.2.8-py3-none-any.whl Python 3 none any Details

Total release size: 123.9 kB

Release files / plyara-2.2.8.tar.gz

Download URL plyara-2.2.8.tar.gz
Size 68.7 kB
Tags Source
SHA-256 checksum
How to use checksums
ce6a5be6bdc172f78bb10d2e220409c76bd46b3da9ff43e53bbe84d1eede9700
BLAKE2b-256 checksum
How to use checksums
374b0441fb4595df522053c1899ed3280d0bb3b8bc3fa1de415b87ec3537ec62
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.2

Release files / plyara-2.2.8-py3-none-any.whl

Download URL plyara-2.2.8-py3-none-any.whl
Size 55.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8b2a3b46c0963976010a69d3ddd280a77dcd6cf1097408ff573b5af5df04d06d
BLAKE2b-256 checksum
How to use checksums
c36210ecb9f3d6a5e620e3ae496a048838697a7113ccace02cb360f24015b065
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.2

Release history Release notifications | RSS feed

This release

2.2.8 This release

2 release files

2.2.7

2 release files

2.2.6

2 release files

2.2.5

2 release files

2.2.4

2 release files

2.2.3

2 release files

2.2.2

2 release files

2.2.1

2 release files

2.2.0

2 release files

2.1.1

2 release files

2.1.0

1 release file

2.0.3

2 release files

2.0.2

2 release files

2.0.1

2 release files

2.0.0

2 release files

1.4.1

2 release files

1.4.0

2 release files

1.3.3

2 release files

1.3.2

2 release files

1.3.1

2 release files

1.3.0

2 release files

1.2.8

2 release files

1.2.7

2 release files

1.2.6

2 release files

1.2.5

2 release files

1.2.4

2 release files

1.2.3

2 release files

1.2.2

2 release files

1.2.1

2 release files

1.2.0

2 release files

0.1.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page