提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
本篇参照官网规则,将yara语法总结如本文部分
//通配符:可以用来代替某些未知的字节,并与人和内容匹配
rule WildcardExample
{
strings:
//使用'?'作为通配符,一个?代表一位
$hex_string = { 00 11 ?? 33 4? 55}
condition:
$hex_string
}
//跳转:可以匹配长度可以变化的字符串
rule JumpExample
{
strings:
//使用'[]'作为跳转,与任何长度为0~n字节的内容匹配
$hex_string1 = { 00 11 [n] 44 55 }
$hex_string2 = { 00 11 [0-n] 44 55 }
//实例,string3和string4完全相同
$hex_string3 = { 00 11 [0-2] 44 55 }
$hex_string4 = { 00 11 ?? ?? 44 55 }
condition:
$hex_string1 or $hex_string2
}
//也可以使用类似正则表达式的方法
rule AlternativeExample
{
strings:
$hex_string = { 00 11 ( 22 | 33 44 ) 55 }
/*
该表达式可以匹配一下内容:
00 11 22 55
或 00 11 33 44 55
*/
condition:
¥hex_string
}
//方法整合
rule AlternativeExample2
{
string2:
$hex_string = { 00 11 ( 33 44 | 55 | 66 ?? 88 ) 99 }
condition:
&hex_string
}
/*
转义符号:
\" //双引号
\\ //反斜杠
\t //制表符
\n //换行符
\xdd //十六进制的任何字节
修饰符:
nocase: 不区分大小写
wide: 匹配2字节的宽字符
ascii: 匹配1字节的ascii字符
xor: 匹配异或后的字符串
fullword:匹配完整单词
private: 定义私有字符串
*/
rule CaseInsensitiveTextExample
{
strings:
$text_string = "foobar" nocase //不区分大小写
$wide_string = "Borland" wide //匹配宽字符
$wide_and_ascii_string = "Borland" wide ascii //同时匹配2种类型的字符串
$xor_string = "This program cannot" xor //匹配所有可能的异或后的字符串
$xor_wide_ascii_string = "This program canot" xor wide ascii //匹配所有可能异或后的wide ascii字符串
$xor_egde_string = "This program cannot" xor(0x01-oxff) //限定异或的范围
$full_string = "domain" fullword //全词匹配(匹配:www.domain.com 匹配:www.my-domain 不匹配:www.mydomain.com)
$private_string = "foobar" private //私有字符串可以正常匹配规则,但似乎永远不会在输出中显示
condition:
$text_string
}
/*
all of them 匹配规则中的所有字符串
any of them 匹配规则中的任意字符串
all of ($a*) 匹配所有以$a开头的字符串
any of ($a,$b,$c) 匹配$a,$b,$c中的任意一个字符串
1 of ($*) 匹配规则中的任意一个字符串
*/
//"#"标识符:用于匹配字符串在文件或内存中出现的次数
rule CountExample
{
strings:
$a = "dummy1"
$b = "dummy2"
condition:
//a字符串出现6次,b字符串出现10次
#a == 6 and #b > 10
}
/*
"@"标识符:
可以使用@a[i],获取字符串$a在文件或者内存中,第i次出现的偏移或者虚拟地址
小标索从1开始,并非0
如果i大于字符串出现的次数,结果为NaN(not a number 非数值)
*/
/*
"!"标识符:
可以使用!a[i],获取字符串$a在文件或者内存中,第i次出现时的字符串长度
下标同@一样从1开始
!a是!a[1]的简写
*/
//"at"标识符:用于匹配字符串在文件或者内存中的偏移
rule AtExample
{
strings:
$a = "dummy1"
$b = "dummy2"
condition:
//a和b字符串分别出现在文件或者内存的100和200偏移处
$a at 100 and $b at 200
}
//"in"标识符:用于在文件或者内存的某个地址范围内匹配字符串
rule InExample
{
strings:
$a = "dummy1"
$b = "dummy1"
condition:
$a in (0..100) and $b in (100..filesize)
}
//"filesize"关键字:用于匹配文件大小
rule FileSizeExample
{
condition:
//filesize只能在文件时才有用,对进程无效
//KB MB后缀只能与十进制大小一起使用
filesize > 200KB
}
//"entrypoint":用于匹配PE或ELF文件的入口点(高版本使用PE模块的pe.entry_point代替)
rule EntryPointExample1
{
strings:
$a = { E8 00 00 00 00 }
condition:
$a at entrypoint
}
rule EntryPointExample2
{
strings:
$a = { 9c 50 66 A1 ?? ?? ?? 00 66 A9 ?? ?? 58 0F 85 }
condition:
$a in (entrypoint..entrypoint + 10)
}
//"intxxx uintxxx":从指定的文件或内存偏移处读取数据
//小端:有符号整数
int8(<offset or virtual address>)
int16(<offset or virtual address>)
int32(<offset or virtual address>)
//小端:无符号整数
uint8(<offset or virtual address>)
uint16(<offset or virtual address>)
uint32(<offset or virtual address>)
//"intxxxbe uintxxxbe":从指定的文件或内存偏移处读取数据
//大端:有符号整数
int8be(<offset or virtual address>)
int16be(<offset or virtual address>)
int32be(<offset or virtual address>)
//大端:无符号整数
uint8be(<offset or virtual address>)
uint16be(<offset or virtual address>)
uint32be(<offset or virtual address>)
//应用实例
rule IsPE
{
condition:
//判断是否是PE文件
uint16(0) == 0x5A4D and uint32(uint(0x3C)) == 0x00004550
}
//"of"关键词:用于匹配多个字符串中的某几个
rule OfExample1
{
strings:
$a = "dummy1"
$b = "dummy2"
$c = "dummy3"
conditon:
2 of ($a,$b,$c)//三个字符串只需匹配任意两个
}
//"for xxx of xxx:(xxx)"
/*
功能:对多个字符串匹配相同的规则
格式: for AAA of BBB : ( CCC )
含义:在BBB字符串集合中,至少有AAA个字符串,满足了CCC的条件表达式,才算匹配成功。在CCC条件表达式中,可以使用$一次代替BBB字符串集合中的每一个字符串。
for ... of其实就是of的特别版,所以下面两个例子的作用相同
any of ($a,$b,$c)
for any of ($a,$b,$c) : ( $ )
所有字符串,在文件或内存中出现的次数必须大于3,才算匹配成功
for all of them : ( # > 3 )
所有以$a开头的字符串,在文件或内存中第二次出现的位置必须小于9
for all of ($a*) : (@[2] < 0x9)
*/
//"for xxx i in (xxx) : (xxx)"
/*
格式:for AAA BBB in (CCC):(DDD)
含义:作用与for of相似,只是增加了下标变量和下表范围,具体看实例
$b在文件或内存中出现的前3次偏移,必须与$a在文件或者内存中出现的前3次偏移+10相同
for all i in (1,2,3) : (@a[i] + 10 == @b[i])
for all i in (1..3) : (@a[i] + 10 == @b[i])
$a每次在文件或内存中出现的位置,都必须小于100
for all i in (1..#a) : ( @a[i] < 100 )
其他
for any i in (1..#a) : ( @a[i] < 100 )
for 2 i in (1..#a) : ( @a[i] < 100 )
*/
//引用其他规则
rule Rule1
{
strings:
$a = "dummy1"
condition:
$a
}
rule Rule2
{
strings:
$a = "dummy2"
condition:
$a and Rule1
}
//全局规划(global rule)可以在匹配其他规则前优先筛选,比如在匹配目标文件前优先筛选出小于2MB的文件,再匹配其他规则
global rule SizeLimit
{
condition:
filesize < 2MB
}
//私有规则(private rule)可以避免规则匹配的结果混乱,比如使用私有规则进行匹配时,YARA不会输出任何匹配到私有规则信息
//私有规则单独使用的意义不大,一般需要配合"引用其他规则"的功能一起使用
//私有规则也可以和全局规划一起使用,只需要添加"private"、"global"关键字即可
private rule PrivateRuleExample
{
...
}
//规则标签:可以在YARA输出时仅展示你敢兴趣的规则,而过滤掉其他规则的输出信息,可以为规则添加多个标签
rule TagExample1: Foo Bar Baz
{
...
}
rule TagExample2: Bar
{
...
}
//导入模块:使用"import"导入模块,可以自己编写模块,也可以使用官方或者其他的第三方模块。在导入模块后,就可以开始使用模块导出的变量和函数,例如:
import "pe"
import "cuckoo"
pe.entry_point == 0x1000
cuckoo.http_request(/someregexp/)
//外部变量:允许你在使用YARA -d命令时指定一个自定义数据,该数据可以是整数、字符串、布尔变量、具体如下:
//使用布尔变量和一个整数变量作为判断条件
rule ExternalVariableExample2
{
condition:
bool_ext_var or filesize < int_ext_var
}
//字符串变量可以与以下运算符一起使用:
//contains:如果字符串包含指定的字符串,返回True
//matches:如果字符串匹配给定的正则表达式时,返回Ture
rule ExternalVariableExample3
{
condition:
string_ext_var1 contains "text" and
steing_ext_var2 marches /[a-z]+/
}
//文件包含:作用于C语言一样,可以包含其他规则到当前文件中
include "other.yar"
//相对路径
include "./includes/other.yar"
include ",./includes/other.yar"
//全路径
include "/home/plusvic/yara/includes/other.yar"