Fuzz testing

看如下这段代码

 

 1 None.gif int  func1( int  a, char  b,  char  c)
 2 None.gif
 3 ExpandedBlockStart.gifContractedBlock.gif {
 4InBlock.gif
 5InBlock.gif         if(a>0&&a<100&& b==0 && c==255)
 6InBlock.gif
 7ExpandedSubBlockStart.gifContractedSubBlock.gif         {
 8InBlock.gif
 9InBlock.gif                   printf("trig a bug");
10InBlock.gif
11InBlock.gif                   return 0;
12ExpandedSubBlockEnd.gif         }

13InBlock.gif
14InBlock.gif         return 1;
15ExpandedBlockEnd.gif}

16 None.gif


这段代码的意思就是在参数

a,b,c 所组成的参数空间中的 一个 特殊的 取值范围内即当 0<a<100 ,b=0,c=255 这个特殊 空间的时候会触发一个特殊的 bug. 当然实际的情况要比这种情况复杂的多。但是总会隐藏着类似的 bug.

如何通过测试找到这些bug呢?这是一个问题,如何在一堆API的参数中找到这样的bug,这是一个大问题。嗯我们现在就讨论这个问题。


从我们便于理解的角度上看这个问题。其实我们希望我们的测试用例能够在一定概率的情况下在整个参数空间中触及到这个
bug的触发参数区域。

最笨的办法就是枚举测试空间,这个实际上并不是一个可行的方法。参数空间会随着参数的个数增加产生参数空间爆炸。

那到底该怎么办呢?在有限的资源下最大可能的找到这样的有问题的参数样本,可行的办法就是一堆随机的参数来然后通过合适的组合来尽可能的覆盖整个参数空间。现在问题就是如何产生合适的随机数了。下面我们就讨论一下如何或者比较好的随机数和如何比较好的组合在一起。

随机数:

随机数在软件开发中应用很广泛,在通信,加密,游戏中都需要随机数发生器。那什么是随机数呢?

随机数至少应该具备两个条件:

1. 数字序列在统计上是随机的。

2. 不能通过已知序列来推算后面未知的序列。

 

只有实际物理过程才是真正随机的。而一般来说,计算机是很确定的,它很难得到真正的随机数。所以计算机利用设计好的一套算法,再由用户提供一个种子值,得出被称为“伪随机数”的数字序列,这就是我们平时所使用的随机数。

 

这种伪随机数字足以满足一般的应用,但它不适用于加密等领域,因为它具有弱点:

 

1. 伪随机数是周期性的,当它们足够多时,会重复数字序列。

2. 如果提供相同的算法和相同的种子值,将会得出完全一样的随机数序列。

3. 可以使用逆向工程,猜测算法与种子值,以便推算后面所有的随机数列。

 

即是说: 随机序列 = F(算法, 种子)

 

说到随机数的产生不得不提的是我们的随机数发生器往往是可以预测的。例如我们常用的随机rand 函数就是一个可以预测的。

  int   __cdecl   rand   (void ) 
  { 

  return(((holdrand   =   holdrand   *   214013L   +   2531011L)   >>   16)   &   0x7fff); 

  }  

在这个的背后其实是用的是Knuth pseudo-random number-generating 技术。Knuth 在这本书中"Seminumerical Algorithms," Vol. 2 of The Art of Computer Programming (Addison-Wesley, 1981)发表了这个算法。在实际的应用中我们如何产生适合应用的随机数是根据实际情况定的。比如我们在输入参数的安全性方面没有任何先验知识的情况下,均匀分布是比较好的。在有先验知识或者是白盒测试的情况下正态分布可能是比较好的随机数分布。

这些分布的产生一般都是先产生一个平均分布然后求对应分布的逆。网上能找到一堆伪随机数生成器的代码。下面就随便给一个。如何产生一个更好的伪随机数,以后再说吧。

 1 None.gif double  AverageRandom( double  min, double  max)
 2 ExpandedBlockStart.gifContractedBlock.gif {
 3InBlock.gif    
 4InBlock.gif    int minInteger = (int)(min*10000);
 5InBlock.gif    int maxInteger = (int)(max*10000);
 6InBlock.gif    int randInteger = rand()*rand();
 7InBlock.gif    int diffInteger = maxInteger - minInteger;
 8InBlock.gif    int resultInteger = randInteger % diffInteger + minInteger;
 9InBlock.gif    return resultInteger/10000.0;
10ExpandedBlockEnd.gif}

11 None.gif double  Normal( double  x, double  miu, double  sigma)   
12 ExpandedBlockStart.gifContractedBlock.gif {
13InBlock.gif    return  1.0/sqrt(2*PI*sigma) * exp(-1*(x-miu)*(x-miu)/(2*sigma*sigma));
14ExpandedBlockEnd.gif}

15 None.gif double  NormalRandom( double  miu, double  sigma, double  min, double  max)
16 ExpandedBlockStart.gifContractedBlock.gif {
17InBlock.gif    double dResult;
18InBlock.gif    double dScope;
19InBlock.gif    double dNormal;
20InBlock.gif    do
21ExpandedSubBlockStart.gifContractedSubBlock.gif    {
22InBlock.gif        dResult = AverageRandom(min,max);
23InBlock.gif        dScope = AverageRandom(0,Normal(miu, miu, sigma));
24InBlock.gif        dNormal = Normal(dResult, miu, sigma);
25ExpandedSubBlockEnd.gif    }
while( dScope > dNormal);
26InBlock.gif    return dResult;
27InBlock.gif    
28ExpandedBlockEnd.gif}

29 None.gif

产生了随机数以后,参数进行适当的组合对对应的 API 函数进行测试,这样就能在数学上保证尽可能得覆盖到对应得参数空间。最大可能的找到 bug

 

对于白盒测试来讲这种测试方法就更加适合,因为可以找一些比较合适的值作为初始值然后再产生随机的参数,就可以更有针对性的找到bug

其实这是一种测试-FUZZ testing 的基本思想.

转载于:https://www.cnblogs.com/oceancloud/archive/2007/07/12/814844.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值