FAQ

原文

这是一个关于angr的常见问题的集合,这些问题包括“我如何做X?”
如果您的问题是“如何修复X问题”,请参阅安装说明的“故障排除”部分。

为什么叫angr

angr分析的核心是在VEX IR上,当某件事令人烦恼(vexing)时,它会让你生气(angry)。

“angr”应该如何被风格化?

全部小写,即使是在句子的开头。
这是一个anti- proper名词。

我如何获得关于angr正在做什么的诊断信息?

angr使用标准的日志模块进行日志记录,每个包和子模块都创建一个新的日志记录器。

获取调试输出最简单的方法如下:

import logging
logging.getLogger('angr').setLevel('DEBUG')

你可能想要使用info或者其他任何东西来代替。默认情况下,angr启用WARNING级别的日志。

每个angr模块都有自己的记录器字符串,通常是它上面的所有python模块,加上它自己,用点连接起来。例如,angr.analyses.cfg。由于python logging模块的工作方式,您可以通过为父模块设置详细级别来为模块中的所有子模块设置详细级别。例如,logging.getLogger(' angry .analyses'). setlevel ('INFO')将使CFG以及所有其他分析记录在INFO级别。

为什么angr这么慢

这很复杂

我怎么用angr发现bug?

很复杂!最简单的方法是定义一个“错误条件”,例如,“指令指针变成了一个符号变量”,然后运行符号探索,直到找到匹配该条件的状态,然后将输入转储为一个测试用例。但是,您很快就会遇到状态爆炸问题。如何处理这事取决于你自己。你的解决方案可以简单到添加一个避免条件,也可以复杂到实现CMU的MAYHEM系统作为一种探索技术。

为什么选择VEX而不是其他IR(比如LLVm,REIL,BAP等)

我们在angr中有两个设计目标,这两个目标影响了我们的选择:
1.Angr需要能够分析来自多个体系结构的二进制文件。这要求使用IR来保持我们的清醒,并要求IR支持许多体系结构。
2.我们想要实现一个二进制分析引擎,而不是二进制提升器。许多项目开始和结束时都执行一个提升器,这是一个耗时的过程。我们需要一些已经存在并且已经支持提升多个架构的东西。
在网上搜索,主要的选择是:

  • LLVM显然是第一个候选对象,但将二进制代码清晰地提升到LLVM是一件痛苦的事情。这两种解决方案要么是通过QEMU提升到LLVM, QEMU很老土(它的唯一实现似乎非常紧密地集成到S2E中),要么是McSema,它当时只支持x86,但后来经过重写,得到了x86-64和aarch64的支持。
  • TCG是QEMU的IR,但提取它似乎也非常困难,文档也非常稀缺。
  • REIL看起来很有前途,但是还没有一个标准的参考实现可以支持我们想要的所有体系结构。这似乎是一个很好的学术工作,但要使用它,我们必须执行我们自己的升降机,这是我们希望避免的。
  • BAP是另一种可能性。当我们开始开发angr时,BAP只支持提升x86代码,BAP的最新版本只提供给BAP作者的学术合作者。这是两件让人无法接受的事。BAP后来变得开放了,但它仍然只支持x86_64、x86和ARM。
  • VEX是为许多体系结构提供开放库和支持的唯一选择。另外,它有很好的文档记录,并且是专门为程序分析而设计的,这使得它在angr中非常容易使用。
    虽然angr现在使用了VEX,但没有根本原因不能使用多个IRs。在angry .engines.vex软件包之外,angr有两部分是针对vex的:
  • 跳转标签(例如,用于返回的Ijk_Ret,用于调用的Ijk_Call,等等)是VEX枚举。
  • VEX将寄存器视为内存空间,angr也是如此。虽然我们提供了state.regs.rax和friends的访问,但在后台,它做的是state.registers.load(8,8),其中前8是rax到寄存器文件的vex定义偏移量。
    为了支持多个IRs,我们需要对这些东西进行抽象,或者将它们的标签转换为VEX类似物。

为什么有些ARM地址是off-by-one ?

为了对ARM代码地址的THUMB-ness进行编码,我们将最低位设置为1。这种约定来自LibVEX,并不是完全由我们选择的!如果你看到一个奇数的ARM地址,这仅仅意味着地址- 1的代码处于THUMB模式。

我如何序列化angr对象?

Pickle可以做到 。然而,python将默认使用一个非常旧的pickle协议,该协议不支持更复杂的python数据结构,因此您必须指定一个更高级的数据流格式。最简单的方法就是pickle.dumps(obj, -1).

UnsupportedIROpError(“浮点支持禁用”)是什么意思?

如果你使用的是CGC分析,比如driller或rex,这可能会突然出现。angr中的浮点支持在CGC分析中被禁用,原因如下:

  • Libvex对浮点数的表示是不精确的——它将x87用于计算的80位扩展精度格式转换为64位双精度格式,从而不可能得到精确的结果
  • 在angr中,对于libvex报告的实际原始操作本身的实现支持非常有限,所以如果你走得太远,你经常会得到一个不太友好的“不支持的操作”错误
  • 对于实现了哪些操作,在符号计算(AST重复数据删除,操作崩溃)期间允许跟踪的基本优化没有用于浮点运算,导致了巨大的AST
  • 在z3中有一些内存损坏的bug,当您使用大量的混合浮点运算和位向量运算时,这些bug很容易被触发。我们还没有能够得到一个测试案例,不涉及“只是运行angr”的z3人调查。

我们只是在符号执行引擎中禁用了浮点支持,而不是尝试处理所有这些问题。允许执行的浮点操作,我们启用了一个叫做https://github.com/angr/angr/blob/master/angr/exploration_techniques/oppologist.py的勘探技术--抓住这些问题,具体化他们的输入,并运行有问题的指令,通过qemu的unicorn引擎,允许继续执行。直观的感觉是,浮点运算的特定值通常不会影响开发过程。

如果您看到这个错误并终止分析,可能是因为您没有正确安装或配置unicorn。如果你只是在某个地方的日志中看到这个问题,那只是有人在提醒你,你没有什么可担心的。

为什么angr的CFG与IDA的CFG不同?

两个主要原因:

  • IDA不会在函数调用时分割基本块。angr会,因为它们是控制流的一种形式,基本块结束于控制流指令。您通常不需要超图来执行自动分析。
  • 如果另一个块跳到基本块的中间,IDA将拆分基本块。这被称为基本块归一化,而angr默认情况下不会这么做,因为大多数静态分析都没有必要这么做。你可以通过传递normalize=True到CFG分析来启用它。

为什么在SimInspect断点期间从状态读取时,会得到不正确的寄存器值?

当启用优化时,libVEX将消除单个基本块中的重复寄存器写。关闭IR优化,让一切看起来都是正确的。
在指令指针的情况下,即使禁用了优化,libVEX也经常会忽略中间块写。在这种情况下,您应该使用state.scratch.in_addr获取当前指令指针。

你可能感兴趣的:(FAQ)