Package: plyara
ParseYARArules 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 modulePLYfor lexing YARA rules.This is a community-maintained fork of theoriginal plyaraby8u1a. The “plyara” trademark
is used with permission.InstallationPlyara requires Python 3.6+.Install with pip:pip3 install plyaraUsageUse the plyara Python library in your own applications:>>>importplyara>>>parser=plyara.Plyara()>>>mylist=parser.parse_string('rule MyRule { strings: $a="1"\ncondition: false }')>>>>>>importpprint>>>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 includedplyarascript 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:$ cat example.yar
rule silent_banker : banker
{
    meta:
        description = "This is just an example"
        thread_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
}

$ plyara example.yar
[
    {
        "condition_terms": [
            "$a",
            "or",
            "$b",
            "or",
            "$c"
        ],
        "metadata": [
            {
                "description": "This is just an example"
            },
            {
                "thread_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        thread_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"
        ]
    }
]Reusing The ParserIf 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()forfileinfiles:withopen(file,'r')asfh:yararules=parser.parse_string(fh.read())rules+=yararulesparser.clear()MigrationIf you used an older version of plyara, and want to migrate to this version,
there will be some changes required. Most importantly, the parser object
instantiation has changed. It was:# Old style - don't do this!importplyara.interpasinterprules_list=interp.parseString(open('myfile.yar').read())But is now:# New style - do this instead!importplyaraparser=plyara.Plyara()rules_list=parser.parse_string(open('myfile.yar').read())The existing parsed keys have stayed the same, and new ones have been added.When reusing aparserfor multiple rules and/or files, 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.ContributingIf you find a bug, or would like to see a new feature, Pull Requests andIssuesare always welcome.By submitting changes, you agree to release those changes under the terms
of theLICENSE.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, and pyflakes.  See the
.travis.yml file for exact use.  For more information on these linters,
please refer to the Python Code Quality Authority:http://meta.pycqa.org/en/latest/DiscussionYou may join our IRC channel on irc.freenode.net #plyara