• angr初探


    前言

    在搞fuzz的时候发现了一个比较难以解决的问题。例如if(*buf == "\xde\xad\xbe\xef"),我们如果想通过纯fuzz去进入这个if的分支,那么概率极其微小。这就使我不得不去尝试通过一些其他的方法去解决这个问题。于是我想到了一个比较出名符号执行的工具————angr。这篇文章记录笔者入门angr的过程。

    环境安装

    angr 的安装

    angr的安装非常简便,通过pip即可,不过貌似angr因为会依赖很多其他的库,所以它的创作者推荐把他装在虚拟环境当中,不过笔者就直接装在虚拟机里了。

    pip3 install angr
    

    学习环境安装

    我这里用的是github上的一个项目对angr进行入门学习。

    git clone https://github.com/jakespringer/angr_ctf.git
    

    angr 基本使用方法

    angr.Project

    这是我们分析一个二进制文件的第一步,就是创建一个angr.Project类,我们的后续操作都将基于这个类展开。并且我们可以通过所创建的project获取二进制文件的一些基本信息。如:project.arch可以获得这个二进制文件的架构,project.entry可以获得这个二进制文件的起始地址,proj.filename获得这个二进制文件的名字。

    例如:

    import sys
    import angr
    
    bin_path = "./00_angr_find"
    project = angr.Project(bin_path)
    
    print(project.arch)
    print(hex(project.entry))
    print(project.filename)
    

    结果:

    
    0x80490b0
    ./00_angr_find
    

    project.factory

    project.factory为我们提供了一些实用的类的构造器

    project.factory.block(address)

    angr是以基本块为单位进行的分析,project.factory.block(address)可以获得给定地址所在的基本块.pp()可以获得该基本块的汇编代码。

    例如:

    block = project.factory.block(project.entry)
    block.pp()
    

    结果:

             _start:
    80490b0  endbr32 
    80490b4  xor     ebp, ebp
    80490b6  pop     esi
    80490b7  mov     ecx, esp
    80490b9  and     esp, 0xfffffff0
    80490bc  push    eax
    80490bd  push    esp
    80490be  push    edx
    80490bf  call    0x80490e7
    
    project.factory.entry_state()

    project.factory.entry_state()用来获取一个程序的初始执行状态。

    project.factory.blank_state(addr)

    project.factory.blank_state(addr=...)用来获取一个程序从指定地址开始执行的空白状态。

    state - 模拟执行状态

    无论是project.factory.entry_state(),还是project.factory.blank_state(addr=...),都会返回一个模拟执行状态,我们可以把它存放到某个变量里,如存到state里。

    state.regs

    state.regs可以获取一些寄存器的值,如state.regs.esp即可获得esp的值。我们可以对其直接进行加减操作。

    例如:

    init_state = project.factory.entry_state()
    
    print(init_state.regs.esp)
    init_state.regs.esp-=12
    print(init_state.regs.esp)
    

    结果:

    
    
    
    state.memory

    state.memory是访问内存接口的一种形式。state.memory.load(addr, size_in_bytes):获取该地址上指定大小的位向量。state.memory.store(addr, bitvector):将一个位向量存储到指定地址、

    state.posix

    state.posixPOSIX相关的环境接口,例如state.posix.dumps(fileno)获取对应文件描述符上的流。

    simulation_manager - 模拟执行器

    angr将一个状态的执行方法独立成一个SimulationManager类,有以下两种写法:

    1、simgr = proj.factory.simgr(state)
    
    2、simgr = proj.factory.simulation_manager(state)
    
    simgr.step()

    simgr.step():以基本块为单位的单步执行。

    simgr.explore(find)

    simgr.explore(find):路径探索,即执行到指定地址并进行约束求解,将执行完成的状态放在simgr.found列表中,若无法求解则该列表为空。


    __EOF__

  • 本文作者: 狒猩橙
  • 本文链接: https://www.cnblogs.com/pwnfeifei/p/17135984.html
  • 关于博主: 评论和私信会在第一时间回复。或者直接私信我。
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 声援博主: 如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。
  • 相关阅读:
    https的加密过程
    Flutter自定义可拖动组件
    【Mysql系列】(一)MySQL语句执行流程
    单目标应用:基于狐猴优化算法(Lemurs Optimizer,LO)的微电网优化调度MATLAB
    study
    Redis布隆过滤器和布谷鸟过滤器
    MySQL Sharding + 读写分离配置说明
    FFmepg--内存IO模式
    2022-08-21 星环科技-C++开发笔试
    为安卓编写Linux内核驱动程序
  • 原文地址:https://www.cnblogs.com/pwnfeifei/p/17135984.html