模糊测试:使用随机输入破坏事物

我们将从最简单的测试生成技术之一开始,随机文本生成(也称为模糊测试)的关键思想是将一串随机字符输入程序,以达到发现故障。

一个简单的模糊器

尝试完成此任务并构建一个模糊生成器。这个想法是生成随机字符,将它们添加到缓冲区字符串变量 () 中,最后返回字符串out。
random.randrange(start, end)-返回一个随机数
range(start, end)-创建一个迭代器
chr(n)-返回一个带有ASCll代码的字符n

import random
def fuzzer(max_length: int = 100, char_start: int = 32, char_range: int = 32)->str:
    string_length = random.randrange(0, max_length + 1)
    out = ""
    for i in range(0, string_length):
        out += chr(random.randrange(char_start, char_start + char_range))
    return out

该函数返回一串随机字符:fuzzer()
在这里插入图片描述
例如,我们还可以生成一系列小写字母。
在这里插入图片描述

模糊测试外部程序

如果我们实际调用一个带有模糊测试输入的外部程序会发生什么?首先,我们创建一个包含模糊测试数据的输入文件,然后,我们将此输入文件输入到所选程序中。

创建输入文件

import os
import tempfile
basename = "input.txt"
tempdir = tempfile.mkdtemp()
FILE = os.path.join(tempdir, basename)
print(FILE)

在这里插入图片描述
现在可以打开这个文件进行写入

data = fuzzer()
with open(FILE, "w") as f:
    f.write(data)

验证该文件是否确实创立并写入

contents = open(FILE).read()
print(contents)
assert(contents == data)

在这里插入图片描述

调用外部程序

采用算术表达式对其进行计算

import os
import subprocess
program = "bc"
with open(FILE, "w") as f:
    f.write("2 + 2\n")
result = subprocess.run([program, FILE],
                        stdin=subprocess.DEVNULL,
                        stdout=subprocess.PIPE,
                        stderr=subprocess.PIPE,
                        universal_newlines=True)  

长时间运行的模糊测试

现在让我们将大量输入到我们的测试程序中,看看它是否会在某些程序上崩溃。将所有结果存储在变量中,作为输入数据和实际结果。

trials = 100
program = "bc"

runs = []

for i in range(trials):
    data = fuzzer()
    with open(FILE, "w") as f:
        f.write(data)
    result = subprocess.run([program, FILE],
                            stdin=subprocess.DEVNULL,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE,
                            universal_newlines=True)
    runs.append((data, result))

模糊测试器的发现

缓冲区溢出

许多程序都内置了输入和输入元素的最大长度。像 C语言中,很容易在程序(或程序员)甚至没有注意到的情况下超过这些长度,从而触发所谓的缓冲区溢出。
模拟缓冲区溢出行为:

def crash_if_too_long(s):
    buffer = "Thursday"
    if len(s) > len(buffer):
        raise ValueError
from ExpectError import ExpectError
trials = 100
with ExpectError():
    for i in range(trials):
        s = fuzzer()
        crash_if_too_long(s)
Traceback (most recent call last):
  File "/var/folders/n2/xd9445p97rb3xh7m1dfx8_4h0006ts/T/ipykernel_21451/292568387.py", line 5, in <cell line: 2>
    crash_if_too_long(s)
  File "/var/folders/n2/xd9445p97rb3xh7m1dfx8_4h0006ts/T/ipykernel_21451/2784561514.py", line 4, in crash_if_too_long
    raise ValueError
ValueError (expected)

缺少错误检查

许多编程语言没有异常,而是在特殊情况下有函数返回特殊错误代码。例如,C 函数通常从标准输入返回一个字符;如果不再有可用的输入,则返回特殊值(文件末尾)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

稚皓君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值