这两天学习了“蒙特卡罗猜测”,其核心就是利用计算机程序自动匹配正则表达式。主要模块如下:
- 输入:一个正则表达式,由程序员给出
- 程序:随机产生字符串,匹配正则表达式
- 计时:统计时间及猜测次数
下面,我们首先用代码来实现“蒙特卡罗猜测”,共三个步骤:
第一步,假设我们需要匹配一个正则表达式:
r'[1-2][^2-8][D-F]0+[A-F]'
# 这个正则表达式相当于1/2+0/1/9/A-Z+D/E/F+n个0+A/B/C/D/E/F
# 可以匹配10D0或21E00等等
第二步,自动模拟生成随机字符串:假设32个字符长度,字母表0-9,A-Z,相当于十六进制字符
第三步,形成输出:打印出匹配次数、匹配字符串以及程序关键部位所用时间
具体代码如下:
import re, random, time
segma = '0123456789ABCDE' # 十六进制字母表
def genStr(): # 随机产生字符串
s = ''
global segma # 全局声明
for i in range(32): # 逐一生成随机字符
s += segma[random.randint(0,15)]
return s
regex = re.compile(r'[1-2][^2-8][D-F]0+[A-F]') # 编译正则表达式
count = 0 # 猜测次数
start = time.perf_counter() #计时功能
match = regex.search(genStr()) # 正则表达式查找
while not match:
count += 1
match = regex.search(genStr()) # 不停匹配
print('共模拟了{}次数据,最终匹配到{}-{}'.format(count, match.string, match.group(0))
end = time.perf_counter()
print('匹配数据,共用时{:.5f}秒'.format(end -start))
看到这里,我们应该认真思考一下,这段代码和“病毒特征码扫描工具”的关系。其中:
- 可以用正则表达式来表示病毒特征码片段
- 上面的代码中,我们随机生成一个16进制字符串,而通常,安全工程师也会以16进制的方式打开和编辑非可信程序文件
- 最后是关心的扫描结果,把它们打印出来,和上面也基本一样
通过简单修改,我们就能把程序实现出来,具体代码如下:
import re, random, time, os, binascii
rootdir = 'F:\virusdir' # 病毒文件目录
list = os.listdir(rootdir) #列出文件夹下所有的目录与文件
regex = re.compile(r'[1-2][^2-8][D-F]0+[A-F]') #病毒的特征码用正则表达式来编译表示
count = 0 #扫描到的文件数
start = time.perf_counter() #程序开始计时
for i in range(0,len(list)): #病历目录
path = os.path.join(rootdir,list[i])
if os.path.isfile(path): #逐一对文件的进行匹配操作
with open(path, 'rb') as fi: #二进制打开文件
a = fi.read()
hexstr = binascii.b2a_hex(a) #转化成十六进制
match = regex.search(hexstr) #病毒文件匹配正则表达式
if match:
count += 1 #匹配到病毒文件
print('匹配到第{}个病毒文件,文件名为{},特征码为{}'.format(count, path, match.group(0))
end = time.perf_counter() #程序结束计时
print('文件扫描完成,共用时{:.5f}秒'.format(end -start))
程序功能比较简单,虽然只有18行,我们却已经可以在一些简单的场景中应用它。同时通过学习这段代码,也对进一步深入学习了解病毒扫描工具的实现原理有很大的帮助。
网友评论