我面临的问题之一是代码覆盖率。如何确定已涵盖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生成自动密钥生成器的应用;
关于二进制分析的一些博客文章;
> ...
无论如何,通过更好地处理二进制程序和提供更好的支持,仍然有足够的空间来实现新工具。因此,随时开始! ;-)
希望有帮助。
#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
的源代码现已可用。
评论
亲爱的恐怖:您可能会忘记最近在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