[原创]Angr基础笔记
最近学习angr,整理了一下相关资料内容
Angr
官方文档
https://github.com/angr/angr-doc
https://angr.io/api-doc/
https://docs.angr.io/
Angr架构简介

CLE(CLE Loading Everything)。angr工具第一步就是将二进制文件加载到cle.loader类里.loader类加载所有的对象并导出一个进程内存的抽象。生成该程序已加载和准备运行的地址空间。具体的源码分析可以参考这里>>> print b.loader.find_symbol_got_entry('__libc_start_main') >>> print b.loader.main_bin.imports {'__gmon_start__': <cle.elf.ELFRelocation at 0x7f9928941650>, '__libc_start_main': <cle.elf.ELFRelocation at 0x7f9928941dd0>, '__stack_chk_fail': <cle.elf.ELFRelocation at 0x7f9928941590>, 'fgets': <cle.elf.ELFRelocation at 0x7f9928941550>, 'getenv': <cle.elf.ELFRelocation at 0x7f9928406810>, 'printf': <cle.elf.ELFRelocation at 0x7f99284062d0>, 'ptrace': <cle.elf.ELFRelocation at 0x7f99286cca10>, 'puts': <cle.elf.ELFRelocation at 0x7f99284068d0>}PyVEX- 将指令转换成中间语言 (IR) 、分析 IR 并且模拟
- i.e., 不只知道他是什么,还知道他做了什么
- state, symbolic memory, SimProcedure
Claripy- 设置符号变量以及 solver 、收集限制式(约束条件)
- 是一个前端界面,而后端可以是各种 solver ,比如 z3
angr&surveyors- Surveyors
通过构建Surveyors的方法import angr p = angr.Project("test") ex = p.surveyors.Explorer(find=(0x400844, ), avoid=(0x400855,)) ex.run() print ex.found[0].state.posix.dumps(0) - path_group
import angr p = angr.Project("test") initial_state = p.factory.entry_state() pg = p.factory.path_group(initial_state) pg.explore(find=(0x4005d1,)) print pg # <PathGroup with 18 deadended, 4 active, 1 found> print pg.found[0] # <Path with 64 runs (at 0x4005d1)> print pg.found[0].state.posix.dumps(0) # input_string - SimState
entry_state: a SimState initialized to the program state at the binary's entry pointblank_state: a SimState object with little initialization>>> import angr >>> b = angr.Project('/bin/true') >>> s = b.factory.blank_state(addr=0x08048591) >>> s = b.factory.entry_state() # The first 5 bytes of the binary >>> print s.memory.load(b.loader.min_addr(), 5)如何设置args
import angr import claripy p = angr.Project("test") args = claripy.BVS('args', 8*16) initial_state = prog.factory.entry_state(args=["./vul", args]) pg = p.factory.path_group(initial_state) pg.explore(find=(0x4005d1,)) print pg # <PathGroup with 18 deadended, 4 active, 1 found> print pg.found[0] # <Path with 64 runs (at 0x4005d1)> print pg.found[0].state.posix.dumps(0) # input_stringClaripy后端
# Create a 32-bit symbolic bitvector "x" >>> claripy.BVS('x', 32) # Create a 32-bit bitvectory with the value 0x12345678 >>> claripy.BVV(0x12345678, 32) <BV32 BVV(0x12345678, 32)>
- 建立一个32bit的符号值容器 "x":
claripy.BVS('x',32) - 建立一个32bit的具体值(0xc001b3475)容器:
claripy.BVV(0xc001b3a75,32) - 建立一个32bit的步进值,从1000到2000能被10整除的数:
claripy.SI(name='x',bits=32,lower_bound=1000,upper_bound=2000,stride=10) - 如果两个bitvector的长度不同是不能共同运算的,需要将其扩展:
# 64-bit bitvectors with concrete values 1 and 100 >>> one = state.solver.BVV(1, 64) >>> one <BV64 0x1> # create a 27-bit bitvector with concrete value 9 >>> weird_nine = state.solver.BVV(9, 27) >>> weird_nine <BV27 0x9> >>> weird_nine.zero_extend(64 - 27) <BV64 0x9> >>> one + weird_nine.zero_extend(64 - 27) <BV64 0xa>
Memory Access
在内存位置上放符号变量
方便我们追踪并求解内存位置上的值
import angr
p = angr.Project('./vul')
s = p.factory.blank_state(addr=0x80485c8)
bvs = s.se.BVS('to_memory', 8*4)
s.se.add(bvs > 1000)
s.memory.store(0x08049b80, bvs, endness='Iend_LE')
pg = p.factory.path_group(s, immutable=False)
注意这里的s.se.add(bvs > 1000),构造了一个符号限制表达式。类似的逻辑限制表达式如下表:
注意:上传附件及图片大小不得大于30M。
⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途。
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。
复制成功


