angr--学习笔记(二)
以angr_CTF为例
处理格式化字符串输入的时候,可以选择初始状态不再entry_state开始,而是通过符号化寄存器自己设置初始状态
参考教程,做了些许改动,脚本是这样的:
import angr import sys import claripy def Go(): p=angr.Project("./03registers",auto_load_libs=False) istate=p.factory.blank_state(addr=0x080488D1) passwd0=claripy.BVS('passwd0',32) passwd1=claripy.BVS('passwd1',32) passwd2=claripy.BVS('passwd2',32) istate.regs.eax=passwd0 istate.regs.ebx=passwd1 istate.regs.edx=passwd2 sm=p.factory.simulation_manager(istate) def succ(state): output1=state.posix.dumps(1) if b'Good Job.' in output1: return True else: return False def _abort(state): output2=state.posix.dumps(1) if b'Try again.' in output2: return True else: return False solution=sm.explore(find=succ,avoid=_abort) if solution.found: solution0=format(solution.found[0].solver.eval(passwd0),'x') solution1=format(solution.found[0].solver.eval(passwd1),'x') solution2=format(solution.found[0].solver.eval(passwd2),'x') s=solution0+""+solution1+""+solution2 print(s) else: raise Exception("error") if __name__=="__main__": Go()
1.istate=p.factory.blank_state(addr=0x080488D1)
在状态预设中,可以选择entry_state(),意为设置成从程序的入口点状态,或者
.blank_state() 空状态,通过addr参数进行赋值可以指定任意地址创建新状态
##一个状态代表某个时刻的程序实例镜像,可以通过该状态访问或者设置寄存器、内存信息
state.regs.eax
state.mem[index]
2. passwd0=claripy.BVS('passwd0',32)
位向量:可以理解成约束求解时的自变量
BVV(value,size) //用变量值和大小创建位向量
BVS(name,size) //用变量名和大小创建位向量
passwd0=claripy.BVS('passwd0',32) //创建名字为passwd0的位向量,可以理解成列方程时设出的自变量
3.istate.regs.eax=passwd0
设置状态的寄存器值,符号化寄存器值含义就是将寄存器内存储的值设为自变量,而后类别列方程加入约束条件内
设置好此时刻的状态后,便可以将此状态提交给simulation_manager,准备执行
4.sm=p.factory.simulation_manager(istate)
从istate处开始执行
5.solution=sm.explore(find=succ,avoid=_abort)
.explore()方法使sm从该状态开始符号执行,到达succ位置后停止,路径结果保持在solution中,我们讲solution理解成保持了满足条件的路径信息的列表,通过solution.found[0]可以访问第一个路径,通常只有一个
6.solution.found[0].solver.eval(passwd0)
求解设出的自变量passwd0
angr其他模块记录:
状态:
访问内存
state.memory.load(addr,size) //读内存
state.memory.store(addr,val) //将val写入内存
history插件:记录状态的执行路径
for addr in state.history.bbl_addrs: print hex(addr)
//按顺序输出基本块的地址
模拟管理器Simulation Managers
接口step:
state.step() 执行基本块
state.run() 一直执行到结束
.explore()方法:
探索执行路径,以便找到符合预期的路径
求解引擎
state.claripy.solver() 访问求解引擎
solver.eval(expression) //求出一个可行解
solver.min() //求出最小可行解
solver.max() //求出最大可行解
.add添加约束条件
state.solver.add(x > y) state.solver.add(y > 2) state.solver.add(10 > x) state.solver.eval(x)
分析
project.analyses.name() 进行调用
name:
CFGFast: 快速获得控制流程图
CFGEmulated:符号执行方法获得控制流程图