>>> 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>}
import angr
p = angr.Project("test")
ex = p.surveyors.Explorer(find=(0x400844, ), avoid=(0x400855,))
ex.run()
print ex.found[0].state.posix.dumps(0)
>>> 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)
# 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)>
# 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>
# get the integer
>>> print s.se.any_int(s.regs.rax)
# get the string
>>> print s.se.any_str(s.memory.load(0x1000, 10, endness='Iend_LE'))
# storing data
>>> s.regs.rax = aaaa
>>> s.memory.store(0x1000, aaaa, endness='Iend_LE')
>>> s.memory.store(s.regs.rax, aaaa, endness='Iend_LE')
p = angr.Project('./vul')
st = p.factory.full_init_state(args=['./vul'])
# Constrain the first 28 bytes to be non-null and non-newline
for _ in xrange(28):
k = st.posix.files[0].read_from(1)
st.se.add(k != 0)
st.se.add(k != 10)
# Constrain the last byte to be a newline
k = st.posix.files[0].read_from(1)
st.se.add(k == 10)
# Reset the symbolic stdin's properties and set its length
st.posix.files[0].seek(0)
st.posix.files[0].length = 29
p = angr.Project('./vul',
load_options={'auto_load_libs': True},
use_sim_procedures=True,
exclude_sim_procedures_func='strcmp')
class my_strcmp(simuvex.SimProcedure):
def run(self):
...
return ...
p.hook_symbol('strcmp', my_strcmp)
>>> 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
一整个集成符号执行
path, path_group, factory, ...
脚本示例
对于这样的题目 我们有多种方式写
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)
entry_state: a SimState initialized to the program state at the binary's entry point
blank_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)
# 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)>
# 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>
将指令转换成中间语言 (IR) 、分析 IR 并且模拟
i.e., 不只知道他是什么,还知道他做了什么
state, symbolic memory, SimProcedure
设置符号变量以及 solver 、收集限制式(约束条件)
是一个前端界面,而后端可以是各种 solver ,比如 z3
一整个集成符号执行
path, path_group, factory, ...
脚本示例
对于这样的题目 我们有多种方式写
entry_state: a SimState initialized to the program state at the binary's entry point
blank_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)
# 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)>
Environment – shared library
Exploration Strategy – BFS – DFS
Explosion – path explosion – path pruning
SimProcedure
p = angr.Project('./vul',
load_options={'auto_load_libs': True},
use_sim_procedures=True,
exclude_sim_procedures_func='strcmp')
Hook symbol
class my_strcmp(simuvex.SimProcedure):
def run(self):
...
return ...
p.hook_symbol('strcmp', my_strcmp)