You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在angr中对堆侧效应施加约束以获取符合目标输出的函数输入

问题原因
  • 约束逻辑倒置:你要求解的是执行strcpy后buffer内容为hello,但当前代码是在strcpy执行前就给buffer指向的内存写死了hello,函数运行时strcpy会直接覆盖这块内存,你没有为strcpy执行后的结果加任何约束,符号输入str_in无任何约束限制,求解器会返回任意合法值,自然每次运行结果随机。
  • 无效初始化逻辑:你构造的word_sym以及对应赋值、添加约束的代码完全多余,这些初始值会被strcpy覆盖,不会对最终结果产生任何约束作用。
正确实现方案

正确逻辑是:先确保buffer指针有效,执行完test_fn之后,再给buffer指向的内存添加等于hello\0的约束,再求解输入,修改后代码如下:

import angr
import claripy
import angr.sim_type as T

if __name__ == '__main__':
    path = './test'
    target = 'test_fn' 
    target_buf = 'buffer' 

    word = b'hello\0'
    word_len = len(word)

    program = angr.Project(path, auto_load_libs=False)
    fn = program.loader.find_symbol(target)
    buf = program.loader.find_symbol(target_buf)

    fn_addr = fn.rebased_addr
    buf_addr = buf.rebased_addr

    cc = program.factory.cc(func_ty=T.SimTypeFunction(
        args=[T.parse_type('char*')],
        returnty=T.parse_type('void')
        ))
    
    # 自定义返回地址用于定位函数执行完成的位置
    ret_addr = 0xdeadbeef
    str_in = claripy.BVS('input', 8 * word_len)
    fn_call_state = program.factory.call_state(
        fn_addr, 
        angr.calling_conventions.PointerWrapper(str_in), 
        cc=cc,
        ret_addr=ret_addr
    )
    # 给全局buffer指针分配有效堆内存
    ptr_out = fn_call_state.heap.allocate(word_len)
    fn_call_state.memory.store(buf_addr, ptr_out)

    simgr = program.factory.simgr(fn_call_state)
    # 执行到函数返回
    simgr.explore(find=ret_addr)
    
    if simgr.found:
        s = simgr.found[0]
        # 添加约束:strcpy执行完成后buffer内容等于目标字符串
        final_buf_content = s.memory.load(ptr_out, word_len)
        s.solver.add(final_buf_content == word)
        # 求解得到正确输入
        print(s.solver.eval(str_in, cast_to=bytes))

运行上述代码会输出预期结果b'hello\x00'。

内容的提问来源于stack exchange,提问作者ragingSloth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 04:57:01