使用模糊测试库(Python)

1 投票
2 回答
1166 浏览
提问于 2025-04-16 02:48

我正在尝试使用这个库:http://pastebin.com/xgPXpGtw(使用示例:http://pastebin.com/fNFAW3Fh)。

我遇到了一些问题,因为我不想像他那样把所有的字节分割成一个数组。

我的测试脚本看起来是这样的:

import random
from random import *

def onerand(packet):
    pack  = packet[:]
    byte = str(chr(choice(range(256))))
    pack[choice(range(len(packet)))]= byte
    print "fuzzing rand byte:%s\n" % (byte.encode("hex"))
    return pack

test = "\x63\x63\x63\x63\x63\x63\x63\x63\x63\x63\x63\x63\x63\x63"

while True:
   print onerand(test)

实际上返回的是:

Traceback (most recent call last):
  File "test.py", line 14, in <module> 
    print onerand(test)
  File "test.py", line 7, in onerand
    pack[choice(range(len(packet)))]= byte
TypeError: 'str' object does not support item assignment

那么我该怎么做才能在测试参数上使用那个函数呢?

谢谢!

2 个回答

3

在Python中,字符串是不可变的。你把一个字符串传给函数onerand,参数名是packet,然后复制它并给它一个本地名字pack(这仍然是一个字符串,所以也是不可变的),接着你尝试去做

pack[whatever] = byte

这里的索引并不重要:你是在尝试修改这个不可变的字符串。错误信息就是在告诉你这一点,我觉得说得很清楚:你不能这样做。

我不想把所有字节分割成一个数组。

如果你需要修改其中的一些内容,那你肯定不能用字符串。你对数组有什么意见呢?可以用import array,然后用pack = array.array('c', packet)来代替pack = packet[:],这样你就能快乐地生活下去了——array.array非常紧凑且速度快,而且它是可变的!

编辑:你也可以用列表来实现,就像被接受的答案那样,但这样做的性能代价会非常高。例如:

$ py26 -mtimeit -s's="".join([str(x)[0] for x in range(99)]); import array
> ' 'a=array.array("c",s); a[23]="b"; b=a.tostring()'
1000000 loops, best of 3: 1.09 usec per loop
$ py26 -mtimeit -s's="".join([str(x)[0] for x in range(99)]); import array
> ' 'a=list(s); a[23]="b"; b="".join(a)'
100000 loops, best of 3: 7.68 usec per loop

list是一种比array.array更通用的结构,而你在这里其实只需要array.array,所以选择错误的数据结构会导致速度下降超过七倍。(在Python 2.7中情况稍微好一点,速度下降“只有”四倍多——但是,想想如果你要买一台比现在快四倍的机器要花多少钱,也许你会同意,即使速度提升“只是”4倍多,而不是7倍多,仍然是值得的;-)

2

与其使用 pack = packet[:],不如用 pack = list(packet),然后在最后用 return ''.join(pack) 来返回结果。

你不能直接替换字符串中的一个字节,但你可以先把字符串转换成一个字符列表,替换掉其中的一个元素,然后再转换回字符串。

撰写回答