YARA规则摘要

原文链接:https://yara.readthedocs.io/en/v3.7.0/writingrules.html

  • 注释
  • 字符串
    • 十六进制字符串
    • 文本字符串
      • 字符串修饰
      • 正则表达式
  • 条件
    • 匹配次数
    • 匹配文件偏移或虚拟地址
    • File size
    • 取值
    • 字符串集合
    • 多个字符串应用同一个条件
    • 使用匿名变量
    • 匹配结果遍历
    • 引用其它规则
  • 规则设置
    • 全局规则
    • 私有规则
    • 规则标签
    • 元数据
  • 使用模块
  • 未定义的值
  • 扩展变量
  • 包含文件

一个简单的yara规则示范:

rule ExampleRule
{
    strings:
        $my_text_string = "text here"
        $my_hex_string = { E2 34 A1 C8 23 FB }

    condition:
        $my_text_string or $my_hex_string
}

yara规则由rule引导,后跟一个类似C语言变量格式的字符串作为规则名称,长度不能超过128字节。花括号定义规则内容。

规则中用户定义的字符串变量由$字符引导,变量由字母、数字或下划线组成,不能是保留的关键字。

yara规则中的关键字:

all and any ascii at condition contains
entrypoint false filesize fullword for global in
import include int8 int16 int32 int8be int16be
int32be matches meta nocase not or of
private rule strings them true uint8 uint16
uint32 uint8be uint16be uint32be wide

字符串变量可以是由双引号""界定的文本内容,也可以是花括号{}界定的十六进制字符串。

注释

类似于C语言,支持行注释//和块注释/**/

字符串

十六进制字符串

  • 占位符?
    示例:{ E2 34 ?? C8 A? FB }?代表任意值的半字节内容。

  • 范围[x-y](0<=x<=y)
    示例:{ F4 23 [4-6] 62 B4 [6] EA BB [10-] FF [-]}
    [4-6]代表任意4-6个字节;
    [6][6-6]的简写形式,代表6个字节;
    [10-]代表10个字节及以上;
    [-]代表任意多个字节。

  • 多选|
    示例:{ F4 23 ( 62 B4 | 56 | 45 ?? 67 ) 45 }
    圆括号内使用|字符分隔的内容匹配任意一个即可。

文本字符串

双引号界定的文本内容:"foobar"
转义字符:

\" 双引号
\\ 反斜杠
\t Tab
\n 换行符
\xdd 定义字节

字符串修饰

  • nocase
    查找时需要忽略大小写:$text_string = "foobar" nocase
  • ascii
    默认定义的字符串为ascii格式,可以省略。
  • wide
    定义宽字符:$wide_string = "Borland" wide。仅通过在ascii字符之间插入0字节实现,不支持非ascii字符。
    同时定义宽字符和ascii字符:$wide_and_ascii_string = "Borland" wide ascii
  • fullword
    全字搜索:$text_string = "foobar" fullword。搜索时确保字符串的前后字节不是字母。

正则表达式

元字符:

\ 转义元字符
^ 匹配文件开头
$ 匹配文件末尾
| 多选
() 分组
[] 字符集

量词:

* 匹配0或多次
+ 匹配1或多次
? 匹配0或1次
{n} 匹配n次
{n,} 匹配至少n次
{,m} 匹配最多m次
{n,m} 匹配n到m次

默认使用贪婪模式匹配,在量词后面追加?字符切换为非贪婪模式。

其它转义字符:

\t Tab
\n 换行
\r 回车
\f 换页
\a Alarm
\xNN 定义字节

字符类:

\w 匹配一个字母数字下划线中的字符
\W 匹配一个非字母数字下划线中的字符
\s 匹配一个空白字符
\S 匹配一个非空白字符
\d 匹配一个数字字符
\D 匹配个非数字字符
\b 匹配一个字的边界(3.3.0)
\B 匹配一个非字边界(3.3.0)

条件

类似于编程语言的布尔表达式,支持逻辑运算符:and,or,not,关系运算符:>=,<=,<,>,==,~=,算术运算符:+,-,*,\,%,位运算符:&,|,<<,>>,~,^。条件中出现的数字默认为十进制,如果要使用十六进制需要加上前导内容0x

字符串变量可以直接作为布尔值使用,存在匹配时为true,否则为false
示例:

rule Example
{
    strings:
        $a = "text1"
        $b = "text2"
        $c = "text3"
        $d = "text4"

    condition:
        ($a or $b) and ($c or $d)
}

匹配次数

字符串变量的前导字符$替换成#,代表该字符串在目标(文件或进程)出现的次数,可以直接在条件表达式中使用。

rule CountExample
{
    strings:
        $a = "dummy1"
        $b = "dummy2"

    condition:
        #a == 6 and #b > 10
}

匹配文件偏移或虚拟地址

使用at指定字符串在指定位置进行匹配。

rule AtExample
{
    strings:
        $a = "dummy1"
        $b = "dummy2"

    condition:
        $a at 100 and $b at 200
        //或在指定的范围内匹配
        //$a in (0..100) and $b in (100..filesize)
}

@a[i]:获取第i个匹配的偏移或地址。i从1开始计数。如果i超出范围则返回一个空值。
!a[i]:获取第i个匹配结果的长度。i从1开始计数。!a代表第一个匹配结果的长度。

File size

filesize代表目标文件的长度字节,如果目标是进程则该变量无意义。

rule FileSizeExample
{
    condition:
       filesize > 200KB
}

KB前面的数字只能是十进制,还支持MB。(GB是否支持文档没说)

取值

int8(or virtual address>)
int16(or virtual address>)
int32(or virtual address>)
uint8(or virtual address>)
uint16(or virtual address>)
uint32(or virtual address>)
int8be(or virtual address>)
int16be(or virtual address>)
int32be(or virtual address>)
uint8be(or virtual address>)
uint16be(or virtual address>)
uint32be(or virtual address>)

u开头的读取无符号整数,be结尾的按big-endian字节序读取。
示例:

rule IsPE
{
  condition:
     // MZ signature at offset 0 and ...
     uint16(0) == 0x5A4D and
     // ... PE signature at offset stored in MZ header at 0x3C
     uint32(uint32(0x3C)) == 0x00004550
}

字符串集合

使用of关键字检查任意或多个字符串的匹配。示例:

rule OfExample1
{
    strings:
        $foo1 = "dummy1"
        $foo2 = "dummy2"
        $bar1 = "dummy3"
        $bar2 = "dummy4"

    condition:
        2 of ($foo1,$foo2,$bar1,$bar2) //至少有两个匹配
        //或使用以下形式匹配规则内字符串变量
        //2 of($foo*,$bar*)
        //或使用$*匹配规则内所有字符串变量($*与them相同)
        //2 of ($*)
        //2 of them
        //of前面的数字可以使用以下关键字:
        //any of them //匹配任意一个
        //all of them //匹配所有
        //all of ($foo*)
}

多个字符串应用同一个条件

语法:for expression of string_set : ( boolean_expression )
示例:

any of ($a,$b,$c)
for any of ($a,$b,$c) : ( $ )
for all of them : ( # > 3 )
for all of ($a*) : ( @ > @b )

圆括号中的占位符功能:
$代表正在评估的字符串;
#代表正在评估的字符串出现的次数;
@代表正在评估的字符串第一个匹配所在的偏移或虚拟地址。

使用匿名变量

rule AnonymousStrings
{
    strings:
        $ = "dummy1"
        $ = "dummy2"

    condition:
        1 of them
}

匹配结果遍历

语法:for expression identifier in indexes : ( boolean_expression )
示例:

rule Occurrences
{
    strings:
        $a = "dummy1"
        $b = "dummy2"

    condition:
        for all i in (1,2,3) : ( @a[i] + 10 == @b[i] )
        //也可写为
        //for all i in (1..3) : ( @a[i] + 10 == @b[i] )
        //可使用变量代替循环范围
        //for all i in (1..#a) : ( @a[i] < 100 )
}

引用其它规则

示例:

rule Rule1
{
    strings:
        $a = "dummy1"

    condition:
        $a
}

rule Rule2
{
    strings:
        $a = "dummy2"

    condition:
        $a and Rule1
}

规则设置

全局规则

全局规则在所有其它规则之前评估,如果结果为false则不会再评估其它规则。允许存在多个全局规则。
示例:

global rule SizeLimit
{
    condition:
        filesize < 2MB
}

私有规则

私有规则不会像全局规则一样对结果产生影响,评估后也不会提交给yara,但可以与其它规则混合使用。
示例:

private rule PrivateRuleExample
{
    ...
}

可以对一个规则同时定义全局和私有属性,评估后不会提交给yara,但必须满足条件。

规则标签

规则后面添加标签,用于过滤输出。在命令行使用时通过-t --tag=选项指定需要输出的标签。一个规则允许有多个标签,使用空格隔开。标签的名称格式与变量相同。
示例:

rule TagsExample1 : Foo Bar Baz
{
    ...
}

rule TagsExample2 : Bar
{
    ...
}

元数据

仅用于存储规则的附加信息,不能在条件中使用,支持文本、整数和布尔值字符串(true/false)。
示例:

rule MetadataExample
{
    meta:
        my_identifier_1 = "Some string data"
        my_identifier_2 = 24
        my_identifier_3 = true

    strings:
        $my_text_string = "text here"
        $my_hex_string = { E2 34 A1 C8 23 FB }

    condition:
        $my_text_string or $my_hex_string
}

使用模块

必须在规则外部导入模块:

import "pe"
import "cuckoo"

使用.引用模块变量:

pe.entry_point == 0x1000
cuckoo.http_request(/someregexp/)

未定义的值

yara确保模块中未定义的变量在使用时结果永远为undefinedpe.entry_point指向PE文件的入口地址,但是在扫描一个非PE文件时,该变量是没有值的。示例:

import "pe"

rule Test
{
  strings:
      $a = "some string"

  condition:
      $a and pe.entry_point == 0x1000
}

该规则匹配结果始终为undefined。但是如果将条件改为$a or pe.entry_point == 0x1000,且目标不是PE文件,则以$a的结果为准。

扩展变量

扩展变量由外部定义,可以在条件中直接使用。
示例1:

rule ExternalVariableExample1
{
    condition:
       ext_var == 10
}

示例2:

rule ExternalVariableExample3
{
    condition:
        string_ext_var contains "text"
}

rule ExternalVariableExample4
{
    condition:
        string_ext_var matches /[a-z]+/is
}

正则表达式末尾追加i表示忽略大小写,追加s表示只在同一行进行匹配。

外部变量必须在运行时定义。yara-python中的compilematch函数的externals参数可以指定外部变量。外部变量的值支持文本、整数和布尔值。在命令行可以通过-d选项定义。

包含文件

使用include关键字包含其它规则文件。在Linux系统中允许使用相对路径或绝对路径,在windows中必须使用绝对路径。
Linux系统示例:

include "./includes/other.yar"
include "../includes/other.yar"
include "/home/plusvic/yara/includes/other.yar"

Windows系统示例:

include "c:/yara/includes/other.yar"
include "c:\\yara\\includes\\other.yar"

你可能感兴趣的:(逆向分析)