深入浅出angr(三)
字数 736 2025-08-06 08:35:35
深入浅出angr(三):内存与寄存器操作详解
1. 内存直接存取基础
angr提供了对内存和寄存器进行直接操作的能力,主要通过SimMemory类实现。
1.1 固定地址变量初始化
对于.bss段等固定地址的变量,可以使用claripy直接进行初始化:
# 示例:初始化.bss段的变量u
u = claripy.BVS('u', 8) # 8bit的符号变量
state.memory.store(0x804a021, u) # 存储到固定地址
关键点:
- 需要声明
add_options={"SYMBOLIC_WRITE_ADDRESSES"}选项 - 使用
state.memory.store(address, value)进行存储
2. 内存操作方法
angr提供了两种主要的内存操作方法:
2.1 直接存储方法
state.memory.store(address, value)
2.2 内存切片方法
# 设置DWORD值
state.mem[address].dword = value
# 设置WORD值
state.mem[address].word = value
支持的数据类型:
dword、word、long、intuint8_t、uint32_t等
3. 寄存器操作
3.1 直接寄存器访问
state.regs.esp = value # 设置ESP寄存器
3.2 通过内存间接访问寄存器
# 示例:设置栈上传入的参数
state.mem[state.regs.esp:].dword = 0x401064 # 第一个参数
state.mem[state.regs.esp+4:].dword = 0x4010e4 # 第二个参数
4. 实战案例解析
4.1 案例1:flareon2015_2
Windows程序参数传递设置:
s = b.factory.blank_state(addr=0x401084) # 跳过API调用
s.memory.store(s.regs.esp+12, s.solver.BVV(40, s.arch.bits)) # 参数3
s.mem[s.regs.esp+8:].dword = 0x402159 # 参数2
s.mem[s.regs.esp+4:].dword = 0x4010e4 # 参数1
s.mem[s.regs.esp:].dword = 0x401064 # 返回地址
4.2 案例2:angrbird (反调试绕过)
# 设置初始状态绕过反调试
state.regs.rbp = state.regs.rsp
state.mem[state.regs.rbp - 0x74].uint32_t = 0x40
state.mem[state.regs.rbp - 0x70].uint64_t = 0x1000
state.mem[state.regs.rbp - 0x68].uint64_t = 0x1008
4.3 案例3:google2016_unbreakable_1 (两种解法)
方法一:命令行输入约束
argv = claripy.BVS("argv", 0x43*8)
state = p.factory.entry_state(args=["./unbreakable", argv])
state.libc.buf_symbolic_bytes = 0x43 + 1 # 扩展符号缓冲区大小
# 添加可打印字符约束
for byt in argv.chop(8):
state.add_constraints(state.solver.And(byt >= ord(' '), byt <= ord('~')))
方法二:直接内存注入
flag_chars = [state.solver.BVS('flag_%d' % i, 8) for i in range(0x43)]
for flag_chr in flag_chars:
state.add_constraints(state.solver.And(flag_chr >= ord(' '), flag_chr <= ord('~')))
for i in range(0x43):
state.memory.store(INPUT_ADDR+i, flag_chars[i])
5. 高级技巧
5.1 符号缓冲区大小调整
state.libc.buf_symbolic_bytes = 0x43 + 1 # 默认只有60字节
5.2 内存内容提取
found_state.solver.eval(found_state.memory.load(0x402159, 40), cast_to=bytes)
5.3 状态初始化选项
add_options={angr.options.LAZY_SOLVES} # 避免探索不可满足路径
6. 总结
- 使用
state.memory.store和state.mem[]进行内存操作 - 直接通过
state.regs访问寄存器 - 对于Windows程序,需要正确设置栈布局
- 可通过调整起始地址绕过反调试
- 对符号变量添加约束可提高求解效率
- 必要时扩展符号缓冲区大小
掌握这些内存和寄存器操作技巧,可以更灵活地使用angr进行二进制分析。