• angr学习(三)


    loader

    查看模拟的内存空间,获取入口点、内存边界、模拟寄存器、地址偏移、重定位。。。
    查看加载的模块信息(主程序、共享库、无法解析的库)
    解析符号,通过符号查找对应内存地址,符号判断其导出或导入来确定所在模块,获取模块的导入信息

    加载选项: 可选择是否加载相应共享库
    指定加载程序所需反编译模块

    符号化函数 在SimProcedures中实现了大量的符号化函数,Project会尝试用符号化函数代替程序中对库函数的外部调用。通过angr.SIM_PROCEDURES字典调用,模块名+库函数名双重映射。
    hook:通过对指定地址设置hook使其执行指定函数,可以是符号化函数,或自定义函数。

    Solver Engine

    符号表示、约束求解

    符号表示
    BV:bitvector
    构造符号值或具体值的一个比特容器,它具有大小。

    例子:

    • 建立一个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)

    BitvectorValues
    这些值并不是简单数值(不可以直接参与算术运算),它是一个bit序列,可以用有界整数(可以直接参与算术运算)来解释。

    # 64-bit bitvectors with concrete values 1 and 100
    >>> one = state.solver.BVV(1, 64)
    >>> one
     <BV64 0x1>
    >>> one_hundred = state.solver.BVV(100, 64)
    >>> one_hundred
     <BV64 0x64>
    
    # create a 27-bit bitvector with concrete value 9
    >>> weird_nine = state.solver.BVV(9, 27)
    >>> weird_nine
    <BV27 0x9>
    
    >>> one + one_hundred
    <BV64 0x65>
    
    # You can provide normal python integers and they will be coerced to the appropriate type:
    >>> one_hundred + 0x100
    <BV64 0x164>
    
    # The semantics of normal wrapping arithmetic apply
    >>> one_hundred - one*200
    <BV64 0xffffffffffffff9c>

    如果两个bitvector的长度不同是不能共同运算的,需要将其扩展:

    >>> weird_nine.zero_extend(64 - 27)
    <BV64 0x9>
    >>> one + weird_nine.zero_extend(64 - 27)
    <BV64 0xa>

    BitvectorSymbols

    # Create a bitvector symbol named "x" of length 64 bits
    >>> x = state.solver.BVS("x", 64)
    >>> x
    <BV64 x_9_64>
    >>> y = state.solver.BVS("y", 64)
    >>> y
    <BV64 y_10_64>
    
    >>> x + one
    <BV64 x_9_64 + 0x1>
    
    >>> (x + one) / 2
    <BV64 (x_9_64 + 0x1) / 0x2>
    
    >>> x - y
    <BV64 x_9_64 - y_10_64>

    符号bit序列运算结果不是bit序列,而是一个抽象语法树(AST),由.op.args组成,即操作符和操作数。

    >>> tree = (x + 1) / (y + 2)
    >>> tree
    <BV64 (x_9_64 + 0x1) / (y_10_64 + 0x2)>
    >>> tree.op
    '__div__'
    >>> tree.args
    (<BV64 x_9_64 + 0x1>, <BV64 y_10_64 + 0x2>)
    >>> tree.args[0].op
    '__add__'
    >>> tree.args[0].args
    (<BV64 x_9_64>, <BV64 0x1>)
    >>> tree.args[0].args[1].op
    'BVV'
    >>> tree.args[0].args[1].args
    (1, 64)

    符号约束
    当两个AST进行比较时会产生另一个AST,以符号化boolean为结果的AST。

    约束求解

    >>> state.solver.add(x > y)
    >>> state.solver.add(y > 2)
    >>> state.solver.add(10 > x)
    >>> state.solver.eval(x)
    4

    通过向求解器中加入约束条件(实际为一个个AST),最后求解器会得到一个满足该约束树的最大/小值。

  • 相关阅读:
    算法_2022_分类
    算法_2022_时间&空间复杂度
    JWT详解
    LDAP是什么?
    Bootstrap Blazor 开源UI库介绍Table 虚拟滚动行
    .Net Core 配置文件读取 IOptions、IOptionsMonitor、IOptionsSnapshot
    .NET 7 来了!!!
    git 配置提交模板
    .NET 反向代理YARP 部署Https(SSL)
    .NET 反向代理YARP
  • 原文地址:https://www.cnblogs.com/fancystar/p/7868964.html
Copyright © 2020-2023  润新知