我最近一直在模糊Adobe Reader。

我面临的问题之一是代码覆盖率。如何确定已涵盖Adobe Reader及其库中的所有基本块。

是否有任何脚本或工具可以静态地找到所有选定EXE和DLL的基本块?我的意思是,我想在相应的EXE和库中获取所有基本块。

当前,我正在使用PIN来这样做。但是,它没有显示我已经覆盖了多少个基本块。图等等。

#1 楼

众所周知,在通常情况下,无法正确分解可执行文件(此问题显然与图灵机的著名暂停问题有关)。

因此,提取二进制文件的所有基本块程序是一个非常困难的问题。

但是,有几种技术可以尝试尽最大努力覆盖指令。最有效的技术之一是同时使用程序的具体探索和符号探索。这是在Microsoft Research SAGE工具中实现的。请参阅Patrice Godefroid的主页。

不幸的是,SAGE工具仅供Microsoft Research内部使用。但是,实际上,Patrice Godefroid的第一个想法来自许多其他工具,例如:



KLEE(测试小功能,教程);

Mayhem(请参阅本文);

乔纳森·萨尔万(Jonathan Salwan)的Pintool内存模糊测试(使用Pin和Binary分析的内存模糊测试:使用Pin和z3的共模执行,博客文章);

EGAS是Moflow项目的SAGE克隆部分,并基于BAP平台;

SébastienLecomte的FuzzWin;

基于此的二进制Fuzzers集合想法;

通过符号执行进行半自动输入制作,并应用于Rolf Rolles生成自动密钥生成器的应用;

关于二进制分析的一些博客文章;
> ...

无论如何,通过更好地处理二进制程序和提供更好的支持,仍然有足够的空间来实现新工具。因此,随时开始! ;-)

希望有帮助。

评论


亲爱的恐怖:您可能会忘记最近在SSTIC 2014上展示的FuzzWin(这是源代码github.com/piscou/FuzzWin的链接)。我个人已经实现了一个非常相似的工具,但是使用了更简单的方法。我阅读了Godefroid的论文,但是目前我还没有找到针对x86-64指令的任何可靠的IR,因此我忽略了它,并基于Pin实现了应用层反向执行。

– Ta Thanh Dinh
2014年6月24日,0:11



您绝对正确,我忘记了在SSTIC'14上展出的FuzzWin。我将其添加到列表中。关于IR,有几种工具提出了自己的建议,但不幸的是,似乎没有人同意一种独特的格式(IR似乎是您每次都要重做的东西)。但是,它们彼此之间极为相似,我相信在这些格式之间可以进行翻译。

–恐怖
2014年6月24日6:26



谢谢恐怖。但是我正在寻找一种解决方案,该解决方案可以找到二进制程序的基本块(无源代码)而无需动态运行它。

– john4tech
14年6月25日在8:47

然后,Insight框架中的metasm,miasm或cfgrecovery工具的反汇编程序可以完成此任务。他们都使用静态技术来分解二进制文件。我还建议您查看BAP(尽管它并不完全可用)。最后,此工具和项目列表也可能会有所帮助。

–恐怖
2014年6月25日在8:51



我发现我正在寻找类似的工具。 Pyew是最有前途的工具之一。谢谢恐怖

– john4tech
14年6月25日在9:07

#2 楼

您可以编写IDA脚本或创建IDA插件来收集程序中的所有基本块。可以在http://www.hexblog.com/ida_pro/files/coverit.zip中找到收集所有基本块的示例插件代码-

...
// Find all basic blocks in the specified area
static bool gather_basic_blocks(ea_t ea1, ea_t ea2)
{
  show_wait_box("Finding basic blocks");
  ea_t start = BADADDR;
  bool ok = true;
  int cnt = 0;
  while ( true )
  {
    if ( wasBreak() )
    {
      ok = false;
      break;
    }
    if ( ++cnt == 1000 )
    {
      showAddr(ea1);
      cnt = 0;
    }
    if ( start == BADADDR )
    {
      ea1 = nextthat(ea1, ea2, f_isCode, NULL);
      if ( ea1 >= ea2 )
        break;
      start = ea1;
    }
    while ( ea1 < ea2 )
    {
      if ( !ua_ana0(ea1) )
        break;
      ea1 = get_item_end(ea1);
      if ( is_basic_block_end(true) )
        break;
    }
    if ( ea1 != start )
      bbs[start] = ea1 - start; // remember the bb start and size
    if ( !isCode(get_flags_novalue(ea1)) )
      start = BADADDR;
    else
      start = ea1;
  }
  hide_wait_box();
  return ok;
}
...


评论


是的,我们可以使用IDA Pro来做到这一点。但是我不想依靠IDA。这就是为什么我试图编写一个无需使用IDA pro就能找到应用程序基本块的脚本。基本上,我的目标是创建一个无需运行即可找到基本块的程序(如果可能)。

– john4tech
14年6月25日在8:44

要找到基本块,您需要一个反汇编程序。 IDA是反汇编程序,您找到的任何替代解决方案仍将基于反汇编程序或反汇编程序库。

–詹森·格夫纳(Jason Geffner)
2014年6月25日14:14

#3 楼

二进制级别的代码覆盖率分析可以静态或动态地进行。除其他外,静态仪器可以大大改善动态功能,例如Pin。但是,在某些传统上,它被认为是易碎的,即它破坏了二进制文件。例如,请参阅有关在afl-qemu中进行静态重写的最后说明。因此,诸如DynamoRIO的drcov之类的动态覆盖率分析工具更为流行。

,这篇论文(披露:此处是第一作者)描述了bcov,该工具能够利用静态仪器同时在与流行的DBI工具Pin和DynamoRIO相比,透明度更高。但是,这项工作需要精心安排,将以下内容结合在一起:


探针修剪。利用优势分析来修剪不提供其他覆盖率信息的基本块。这样可以将所需探针的数量减少到基本块总数的46%。
精确的跳转表分析。恢复的控制流程图中的不精确性可能导致检测到的二进制文件损坏。因此,有必要恢复间接跳跃的目标。依次启用了跳转表条目的检测。
各种静态检测技巧。大量重写填充字节并在相邻基本块中包含弯路。

工具bcov支持x86-64 ELF二进制文件。它可以在进程关闭时转储单个coverage文件。该文件包含一个布尔值的静态数组,指示单个基本块的覆盖范围。这意味着可以对文件本身使用简单的布尔运算来合并(或扩散)多个测试的覆盖率数据,而无需先对数据文件进行后处理。此功能提高了模糊处理工作流程的效率。

更新

bcov的源代码现已可用。