diff --git a/doc/5.3_angr.md b/doc/5.3_angr.md index a1a0b42..b4a9859 100644 --- a/doc/5.3_angr.md +++ b/doc/5.3_angr.md @@ -2,6 +2,7 @@ - [安装](#安装) - [使用 angr](#使用-angr) + - [基础功能](#基础功能) - [angr 在 CTF 中的运用](#angr-在-ctf-中的运用) - [参考资料](#参考资料) @@ -19,7 +20,7 @@ $ sudo apt install python-dev libffi-dev build-essential virtualenvwrapper 对于大多数 *nix系统,只需要 `mkvirtualenv angr && pip install angr` 安装就好了。 -如果这样安装失败的话,那么你可以按照这样的顺序: +如果这样安装失败的话,那么你可以按照下面的顺序从 angr 的官方仓库安装: ```text 1. claripy 2. archinfo @@ -27,9 +28,7 @@ $ sudo apt install python-dev libffi-dev build-essential virtualenvwrapper 4. cle 5. angr ``` -从angr的官方仓库安装。 - -附安装方法: +如: ```shell $ git clone https://github.com/angr/claripy $ cd claripy @@ -37,50 +36,168 @@ $ sudo pip install -r requirements.txt $ sudo python setup.py build $ sudo python setup.py install ``` +其他几个库也是一样的。 -其他几个 angr 官方库的安装也是如此。 - -#### 一些 `import angr` 可能出现的问题 -如果你在安装angr之后,进入python环境,在import之后有这样的报错: -```python -Python 2.7.12 (default, Nov 19 2016, 06:48:10) -[GCC 5.4.0 20160609] on linux2 -Type "help", "copyright", "credits" or "license" for more information. ->>> import angr -Traceback (most recent call last): - File "", line 1, in - File "angr/__init__.py", line 25, in - from .project import * - File "angr/project.py", line 592, in - from .analyses.analysis import Analyses - File "angr/analyses/__init__.py", line 22, in - from .reassembler import Reassembler - File "angr/analyses/reassembler.py", line 9, in - import capstone - File "/usr/local/lib/python2.7/dist-packages/capstone/__init__.py", line 6, in - from . import arm, arm64, mips, ppc, sparc, systemz, x86, xcore -ImportError: cannot import name arm ->>> -``` -可以看到,是 capstone 出现了问题,解决方法是重新安装 angr: -```shell -$ sudo pip install -I --no-use-wheel capstone -``` - -若是问题依然存在,那么请先卸载所有的 capstone: -```shell -$ sudo pip3 uninstall capstone -$ sudo pip uninstall capstone -``` -然后再从 pypi 源中获取最新版本安装: -```shell -$ wget https://pypi.python.org/packages/fd/33/d1fc2d01b85572b88c9b4c359f36f88f8c32f2f0b9ffb2d21cd41bad2257/capstone-3.0.5rc2-py2-none-manylinux1_x86_64.whl#md5=ecd7e1e39ea6dacf027c0cfe7eb1bf94 -$ sudo pip2 install capstone-3.0.5rc2-py2-none-manylinux1_x86_64.whl -``` -其他问题可以到官方文档中查看。 +安装过程中可能会有一些奇怪的错误,可以到官方文档中查看。 ## 使用 angr +#### 基础功能 +使用 angr 的第一步是新建一个工程,几乎所有的操作都是围绕这个工程展开的: +```python +>>> import angr +>>> proj = angr.Project('/bin/true') +WARNING | 2017-12-08 10:46:58,836 | cle.loader | The main binary is a position-independent executable. It is being loaded with a base address of 0x400000. +``` +这样就得到了二进制文件的各种信息,如: +```python +>>> proj.filename +'/bin/true' +>>> proj.arch + +>>> hex(proj.entry) +'0x4013b0' +``` + +程序加载时会将二进制文件和共享库映射到虚拟地址中,CLE 模块就是用来处理这些东西的。 +```python +>>> proj.loader + +``` +所有对象文件如下,其中二进制文件是 main object: +``` +>>> proj.loader.all_objects +[, , , , , ] +>>> proj.loader.main_object + +>>> proj.loader.main_object.pic +True +``` +通常我们在创建工程时选择关闭 `auto_load_libs` 以避免 angr 加载共享库: +``` +>>> p = angr.Project('/bin/true', auto_load_libs=False) +WARNING | 2017-12-08 11:09:28,629 | cle.loader | The main binary is a position-independent executable. It is being loaded with a base address of 0x400000. +>>> p.loader.all_objects +[, , , ] +``` + +`project.factory` 提供了很多类对二进制文件进行分析,它提供了几个方便的构造函数。 + +`project.factory.block()` 用于从给定地址解析一个 basic block: +```python +>>> block = proj.factory.block(proj.entry) # 从程序头开始解析一个 basic block +>>> block + +>>> block.pp() # pretty-print,即打印出反汇编代码 +0x4013b0: xor ebp, ebp +0x4013b2: mov r9, rdx +0x4013b5: pop rsi +0x4013b6: mov rdx, rsp +0x4013b9: and rsp, 0xfffffffffffffff0 +0x4013bd: push rax +0x4013be: push rsp +0x4013bf: lea r8, qword ptr [rip + 0x32ca] +0x4013c6: lea rcx, qword ptr [rip + 0x3253] +0x4013cd: lea rdi, qword ptr [rip - 0xe4] +0x4013d4: call qword ptr [rip + 0x205b26] +>>> block.instructions # 指令数量 +11 +>>> block.instruction_addrs # 指令地址 +[4199344L, 4199346L, 4199349L, 4199350L, 4199353L, 4199357L, 4199358L, 4199359L, 4199366L, 4199373L, 4199380L] +``` +另外,还可以将 block 对象转换成其他形式: +```python +>>> block.capstone + +>>> block.capstone.pp() +>>> +>>> block.vex + +>>> block.vex.pp() +``` + +程序的执行需要初始化一个 `SimState` 对象: +```python +>>> state = proj.factory.entry_state() +>>> state + +``` +该对象包含了程序的内存、寄存器、文件系统数据等: +```python +>>> state.regs.rip + +>>> state.regs.rsp + +>>> state.regs.rdi + # 符号变量,它是符号执行的基础 +>>> state.mem[proj.entry].int.resolved + +``` +这里的 BV,即 bitvectors,用于表示 angr 里的 CPU 数据。下面是 python int 和 bitvectors 之间的转换: +```python +>>> bv = state.solver.BVV(0x1234, 32) +>>> bv + +>>> hex(state.solver.eval(bv)) +'0x1234' +>>> bv = state.solver.BVV(0x1234, 64) +>>> bv + +>>> hex(state.solver.eval(bv)) +'0x1234L' +``` +使用 bitvectors 来设置寄存器和内存的值,当直接传入 python int 时,angr 会自动将其转换成 bitvectors: +```python +>>> state.regs.rsi = state.solver.BVV(3, 64) +>>> state.regs.rsi + +>>> state.mem[0x1000].long = 4 +>>> state.mem[0x1000].long.resolved # .resolved 获取 bitvectors + +>>> state.mem[0x1000].long.concrete # .concrete 获得 python int +4L +``` + +初始化的 state 可以经过模拟执行得到一系列的 states,simulation 管理器的作用就是对这些 states 进行管理: +```python +>>> simgr = proj.factory.simulation_manager(state) +>>> simgr + +>>> simgr.active +[] +>>> simgr.step() # 模拟一个 basic block 的执行 + +>>> simgr.active # 模拟状态被更新 +[] +>>> simgr.active[0].regs.rip # active[0] 是当前 state + +>>> state.regs.rip # 但原始的 state 没有变 + +``` + +`project.analyses` 提供了大量函数用于程序分析。 +```python +>>> cfg = p.analyses.CFGFast() # 得到 control-flow graph +>>> cfg + +>>> cfg.graph + # 详细内容请查看 networkx +>>> len(cfg.graph.nodes()) +937 +>>> entry_node = cfg.get_any_node(proj.entry) # 得到给定地址的节点 +>>> entry_node + +>>> len(list(cfg.graph.successors(entry_node))) +2 +``` +如果要想画出图来,还需要安装 matplotlib,Tkinter 等。 +```python +>>> import networkx as nx +>>> import matplotlib.pyplot as plt +>>> nx.draw(cfg.graph) # 画图 +>>> plt.show() # 显示 +>>> plt.savefig('temp.png') # 保存 +``` ## angr 在 CTF 中的运用 diff --git a/doc/8_appendix.md b/doc/8_appendix.md index 536c250..683b3f7 100644 --- a/doc/8_appendix.md +++ b/doc/8_appendix.md @@ -1,4 +1,4 @@ -# 第八章 附录篇 +# 第八章 附录 - [8.1 更多 Linux 工具](8.1_Linuxtools.md) - [8.2 更多 Windows 工具](8.2_wintools.md)