欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创]Angr基础笔记

[原创]Angr基础笔记

最近学习angr,整理了一下相关资料内容

Angr

官方文档
https://github.com/angr/angr-doc
https://angr.io/api-doc/
https://docs.angr.io/

Angr架构简介

  • CLE(CLE Loading Everything)。angr工具第一步就是将二进制文件加载到cle.loader类里.loader类加载所有的对象并导出一个进程内存的抽象。生成该程序已加载和准备运行的地址空间。具体的源码分析可以参考这里
    >>> 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)
    
    
  • path_group
    import angr
    
    p = angr.Project("test")
    
    initial_state = p.factory.entry_state()
    
    pg = p.factory.path_group(initial_state)
    
    pg.explore(find=(0x4005d1,))
    
    print pg
    
    # <PathGroup with 18 deadended, 4 active, 1 found>
    
    print pg.found[0]
    
    # <Path with 64 runs (at 0x4005d1)>
    
    print pg.found[0].state.posix.dumps(0)
    
    # input_string
    
    
  • SimState
    • 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)
      
      

      如何设置args

      import angr
      
      import claripy
      
      p = angr.Project("test")
      
      args = claripy.BVS('args', 8*16)
      
      initial_state = prog.factory.entry_state(args=["./vul", args])
      
      pg = p.factory.path_group(initial_state)
      
      pg.explore(find=(0x4005d1,))
      
      print pg
      
      # <PathGroup with 18 deadended, 4 active, 1 found>
      
      print pg.found[0]
      
      # <Path with 64 runs (at 0x4005d1)>
      
      print pg.found[0].state.posix.dumps(0)
      
      # input_string
      
      

      Claripy后端

      # 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)>
      
      
  • 建立一个32bit的符号值容器 "x":
    claripy.BVS('x',32)
  • 建立一个32bit的具体值(0xc001b3475)容器:
    claripy.BVV(0xc001b3a75,32)
  • 建立一个32bit的步进值,从1000到2000能被10整除的数:
    claripy.SI(name='x',bits=32,lower_bound=1000,upper_bound=2000,stride=10)
  • 如果两个bitvector的长度不同是不能共同运算的,需要将其扩展:
    # 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>
    
    

Memory Access

在内存位置上放符号变量
方便我们追踪并求解内存位置上的值

import angr

p = angr.Project('./vul')

s = p.factory.blank_state(addr=0x80485c8)

bvs = s.se.BVS('to_memory', 8*4)

s.se.add(bvs > 1000)

s.memory.store(0x08049b80, bvs, endness='Iend_LE')

pg = p.factory.path_group(s, immutable=False)

注意这里的s.se.add(bvs > 1000),构造了一个符号限制表达式。类似的逻辑限制表达式如下表:

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功