代码覆盖率 - 模糊测试

逆向工程 二元分析 静态分析 模糊测试
2021-06-25 02:55:50

我最近一直在对 Adob​​e Reader 进行模糊测试。

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

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

目前,我正在使用 PIN 来执行此操作。但是,它没有显示我已经涵盖了多少个基本块。

我的目标是创建一个脚本来扫描给定的目录并将所有基本块写入文件中,以便我可以创建图形等等。

3个回答

众所周知,在一般情况下,可执行文件的正确反汇编是不可判定的(这个问题显然与著名的图灵机停机问题有关)。

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

然而,有几种技术可以尝试达到指令的最大努力覆盖范围。最有效的技术之一是对程序进行具体的和象征性的探索。这是在 Microsoft Research SAGE 工具中实现的。请参阅Patrice Godefroid 的主页

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

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

希望这有帮助。

您可以编写 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;
}
...

二进制级别的代码覆盖率分析可以静态或动态进行。除其他外,静态检测可以比 Pin 等动态工具提供显着的性能改进。然而,在某种程度上,它被认为是脆弱的,即它会破坏二进制文件。例如,请参阅afl-qemu 中关于静态重写的最后一个注释因此,像 DynamoRIO 这样的动态覆盖分析工具drcov更受欢迎。

也就是说,本文(披露:此处为第一作者)描述bcov了一种工具,与流行的 DBI 工具 Pin 和 DynamoRIO 相比,该工具能够利用静态检测同时实现更好的透明度。然而,这项工作需要精心策划,其中结合了:

  • 探针修剪。利用优势分析来修剪不提供额外覆盖信息的基本块。这可以将所需探针的数量减少到基本块总数的 46%。
  • 精确的跳转表分析。恢复的控制流图中的不精确会导致检测的二进制文件中断。因此,恢复间接跳跃的目标是必要的。这反过来又启用了跳转表条目的检测。
  • 各种静态仪器技巧。积极覆盖填充字节并在相邻的基本块中绕道而行。

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

更新

的源代码bcov现已可用