6. Использование YARA из Python

Функции YARA могут быть использованы в Python-скриптах с помощью библиотеки yara-python. Как только библиотека будет построена и установлена, как описано в п. 1.1, вы получите доступ к полному потенциалу YARA из ваших скриптов Python. Первый шаг-импорт библиотеки YARA:

import yara

Затем вам нужно будет скомпилировать ваши правила YARA, прежде чем применять их к вашим данным:

rules = yara.compile(filepath='/foo/bar/myrules')

Аргумент по умолчанию - filepath, поэтому вам не нужно явно указывать его имя:

rules = yara.compile('/foo/bar/myrules')

Вы также можете скомпилировать свои правила из файлового объекта:

fh = open('/foo/bar/myrules')
rules = yara.compile(file=fh)
fh.close()

Или вы можете скомпилировать их непосредственно из строки Python:

rules = yara.compile(source='rule dummy { condition: true }')

Если вы хотите скомпилировать группу файлов или строк одновременно, вы можете сделать это, используя filepaths или sources в наименовании аргумента:

rules = yara.compile(filepaths={
        'namespace1':'/my/path/rules1',
        'namespace2':'/my/path/rules2'
})

rules = yara.compile(sources={
        'namespace1':'rule dummy { condition: true }',
        'namespace2':'rule dummy { condition: false }'
})

Обратите внимание, что и filepaths, и sources должны быть словарями с ключами строкового типа. Ключи словаря используются в качестве идентификатора пространства имен, позволяющего различать правила с одинаковыми именами в разных источниках, как это происходит во втором примере с именем dummy.

Метод compile также имеет необязательный логический параметр с именем include, который позволяет вам контролировать, следует ли принимать директиву include в исходных файлах, например:

rules = yara.compile('/foo/bar/my_rules', includes=False)

Если исходный файл содержит директивы include, показанный пример вызовет исключение.

Если используется include, можно установить обратный вызов Python, чтобы определить собственный источник для импортируемых файлов (по умолчанию они читаются с диска). Эта функция обратного вызова устанавливается с помощью необязательного параметра include_callback. Он получает следующие параметры:

  • requested_filename: файл, запрошенный с помощью include
  • filename: файл, содержащий директиву include, если применимо, иначе None
  • namespace: пространство имен

И возвращает запрошенные источники правил в виде одной строки.

Если вы используете внешние переменные в своих правилах, вы должны определить эти внешние переменные либо при компиляции правил, либо при применении правил к некоторому файлу. Чтобы определить ваши переменные в момент компиляции, вы должны передать параметр externals методу compile. Например:

rules = yara.compile('/foo/bar/my_rules’,
        externals= {'var1': 'some string’, 'var2': 4, 'var3': True})

Параметр externals должен представлять собой словарь с именами переменных в качестве ключей и связанным значением типа строка, целое число или логическая переменная.

Метод compile также принимает необязательный логический аргумент error_on_warning. Этот аргумент указывает YARA давать исключение при выдаче предупреждения во время компиляции. Такие предупреждения обычно выдаются, когда ваши правила содержат некоторую конструкцию, которая может замедлять сканирование. Значение по умолчанию для аргумента error_on_warning - false.

Во всех случаях compile возвращает экземпляр класса yara.Rules Rules. Этот класс имеет метод save, который можно использовать для сохранения скомпилированных правил в файл:

rules.save('/foo/bar/my_compiled_rules')

Скомпилированные правила могут быть загружены позже с помощью метода load:

rules = yara.load('/foo/bar/my_compiled_rules')

Начиная с YARA 3.4, save и load принимают файловые объекты. Например, вы можете сохранить ваши правила в буфере памяти с помощью этого кода:

import StringIO

buff = StringIO.StringIO()
rules.save(file=buff)

Сохраненные правила могут быть загружены из буфера памяти:

buff.seek(0)
rule = yara.load(file=buff)

Результатом загрузки также является экземпляр класса yara.Rules.

Экземпляры Rules также имеют метод match, который позволяет применять правила к файлу:

matches = rules.match('/foo/bar/my_file')

Но вы также можете применить правила к строке Python:

with open('/foo/bar/my_file', 'rb') as f:
        matches = rules.match(data=f.read())

Или к запущенному процессу:

matches = rules.match(pid=1234)

Как и в случае с compile, метод match может получать определения для внешних переменных в аргументе externals.

matches = rules.match('/foo/bar/my_file',
        externals= {'var1': 'some other string', 'var2': 100})

Внешние переменные, определенные во время компиляции, не требуют повторного определения при последующих вызовах метода match. Однако вы можете переопределить любую переменную по мере необходимости или сделать дополнительные определения, которые не были сделаны во время компиляции.

В некоторых ситуациях, связанных с очень большим набором правил или большими файлами, метод match может занять слишком много времени для запуска. В этих ситуациях вам может пригодиться аргумент timeout:

matches = rules.match('/foo/bar/my_huge_file', timeout=60)

Если match не завершается до истечения указанного количества секунд, возникает исключение TimeoutError.

Вы также можете указать функцию обратного вызова при вызове метода match. По умолчанию предоставленная функция будет вызываться для каждого правила, независимо от того, соответствует оно или нет. Вы можете выбрать, когда вызывается ваша функция обратного вызова, установив для параметра which_callbacks одно из значений: yara.CALLBACK_MATCHES, yara.CALLBACK_NON_MATCHES или yara.CALLBACK_ALL. По умолчанию используется yara.CALLBACK_ALL. Ваша функция обратного вызова должна ожидать один параметр типа dictionary и должна возвращать CALLBACK_CONTINUE для перехода к следующему правилу или CALLBACK_ABORT, чтобы прекратить применять правила к вашим данным.

Например:

import yara

def mycallback(data):
        print data
        return yara.CALLBACK_CONTINUE

matches = rules.match('/foo/bar/my_file', callback=mycallback, which_callbacks=yara.CALLBACK_MATCHES)

Переданный словарь будет примерно таким:

{
        'tags': ['foo', 'bar'],
        'matches': True,
        'namespace': 'default',
        'rule': 'my_rule',
        'meta': {},
        'strings': [(81L, '$a', 'abc'), (141L, '$b', 'def')]
}

Поле matches указывает, соответствует ли правило данным или нет. Поля strings - это список совпадающих строк с векторами вида:

(<offset>, <string identifier>, <string data>)

Метод match возвращает список экземпляров класса yara.Match. Экземпляры этого класса имеют те же атрибуты, что и словарь, передаваемый в функцию обратного вызова.

Вы также можете указать функцию обратного вызова модуля при вызове метода match. Предоставленная функция будет вызываться для каждого импортированного модуля, который сканировал файл. Ваша функция обратного вызова должна ожидать один параметр типа словаря и должна возвращать CALLBACK_CONTINUE для перехода к следующему правилу или CALLBACK_ABORT, чтобы прекратить применять правила к вашим данным.

Например:

import yara

def modules_callback(data):
        print data
        return yara.CALLBACK_CONTINUE

matches = rules.match('/foo/bar/my_file', modules_callback=modules_callback)

Переданный словарь будет содержать информацию из модуля.

Вы также можете обнаружить, что размеры по умолчанию для стека для соответствующего механизма в YARA или размер по умолчанию для максимального количества строк в правиле слишком малы. В libyara API вы можете изменить их, используя переменные YR_CONFIG_STACK_SIZE и YR_CONFIG_MAX_STRINGS_PER_RULE через функцию yr_set_configuration в libyara. Инструмент командной строки предоставляет их в качестве аргументов командной строки --stack-size (-k) и --max-strings-per-rule. Чтобы установить эти значения через API-интерфейс Python, вы можете использовать yara.set_config с любым из двух stack_size и max_strings_per_rule или обоими, указанными как kwargs. На момент написания этой статьи размер стека по умолчанию составлял 16384, а максимальное число строк по умолчанию для правила составляло 10000.

Например:

yara.set_config(stack_size=65536)
yara.set_config(max_strings_per_rule=50000, stack_size=65536)
yara.set_config(max_strings_per_rule=20000)

6.1. Описание

yara. compile(…)

Компиляция правил YARA из исходников.

Должны быть указаны filepath, source, file, filepaths или sources. Остальные аргументы являются необязательными.

Параметры:

  • filepath (str) – Путь к исходному файлу.
  • source (str) – Строка, содержащая код правил.
  • file (file-object) – Исходный файл в виде файлового объекта.
  • filepaths (dict) – Словарь, где ключи - это пространства имен, а значения - пути к исходным файлам.
  • sources (dict) – Dictionary where keys are namespaces and values are strings containing rules code.
  • externals (dict) – Словарь с внешними переменными. Ключи - это имена переменных, а значения - значения переменных.
  • includes (boolean) – true, если директивы include разрешены, или false в противном случае. Значение по умолчанию: true.
  • error_on_warning (boolean) – Если предупреждения рассматриваются как ошибки, возникает исключение.

Возвращает: Скомпилированный объект правил.

Возвращаемый тип: yara.Rules

Исключения

  • YaraSyntaxError – Если была обнаружена синтаксическая ошибка.
  • YaraError – Если произошла ошибка.

yara. load(…)

Изменено в версии 3.4.0.

Загрузка скомпилированных правил из пути или файлового объекта. Необходимо указать либо filepath, либо file.

Параметры:

  • filepath (str) – Путь к файлу с скомпилированными правилами.
  • file (file-object) – Файловый объект, поддерживающий метод read.

Возвращает: Скомпилированный объект правил.

Возвращаемый тип: yara.Rules.

Исключения: YaraError - Если при загрузке файла произошла ошибка.


yara. set_config(…)

Установка переменных конфигурации, доступных через API yr_set_configuration.

Укажите либо stack_size, либо max_strings_per_rule. Эти kwargs принимают целочисленные значения без знака в качестве входных данных и присваивают предоставленное значение переменным в yr_set_configuration (...) - YR_CONFIG_STACK_SIZE и YR_CONFIG_MAX_STRINGS_PER_RULE соответственно.

Праметры:

  • stack_size (int) – Размер стека, используемый для YR_CONFIG_STACK_SIZE.
  • max_strings_per_rule (int) – Максимальное количество строк, разрешенное для правила YARA. Будет сопоставлен с YR_CONFIG_MAX_STRINGS_PER_RULE.

Возвращает: - .

Возвращаемый тип: - .

Исключения: YaraError - Если произошла ошибка.


class yara. Rules

Экземпляры этого класса возвращаются функцией yara.compile () и представляют собой набор скомпилированных правил.

match (filepath, pid, data, externals=None, callback=None, fast=False, timeout=None, modules_data=None, modules_callback=None, which_callbacks=CALLBACK_ALL)

Сканирование файла, памяти процесса или строки данных.

Должны быть указаны filepath, pid или data. Остальные аргументы являются необязательными.

Параметры:

  • filepath (str) – Путь к сканируемому файлу.
  • pid (int) – Идентификатор сканируемого процесса.
  • data (str) – Сканируемые данные.
  • externals (dict) – Словарь с внешними переменными. Ключи - это имена переменных, а значения - значения переменных.
  • callback (function) – Функция обратного вызова, вызываемая для каждого правила.
  • fast (bool) – Если true, выполняется сканирование в быстром режиме.
  • timeout (int) – Прерывает сканирование, если количество указанных секунд истекло.
  • modules_data (dict) – Словарь с дополнительными данными к модулям. Ключи - это имена модулей, а значения - байтовые объекты, содержащие дополнительные данные.
  • modules_callback (function) – Функция обратного вызова, вызываемая для каждого модуля.
  • which_callbacks (int) – Целое число, которое указывает, в каких случаях должна вызываться функция обратного вызова. Возможные значения: yara.CALLBACK_ALL, yara. CALLBACK_MATCHES и yara.CALLBACK_NON_MATCHES.

Исключения:

  • YaraTimeoutError – Если тайм-аут был достигнут.
  • YaraError – Если во время сканирования произошла ошибка.

save(…)

Изменено в версии 3.4.0.

Сохраняет скомпилированные правила в файл. Необходимо указать либо путь к файлу, либо файл.

Параметры:

  • filepath (str) – Путь к файлу.
  • file (file-object) – Файловый объект, поддерживающий метод write.

Исключения: YaraError Если при сохранении файла произошла ошибка.


class yara. Match

Объекты, возвращаемые yara.match (), представляют совпадения.

rule

Имя совпавшего правила.

namespace

Пространство имен, связанное с совпавшим правилом.

tags

Массив строк, содержащих теги, связанные с совпавшим правилом.

meta

Словарь, содержащий метаданные, связанные с совпавшим правилом.

strings

Список кортежей, содержащих информацию о соответствующих строках. Каждый кортеж имеет форму: (<смещение>, <строковый идентификатор>, <строковые данные>).