首页 > 其他分享 >Angr-Learn-0x4

Angr-Learn-0x4

时间:2024-03-16 14:45:40浏览次数:19  
标签:状态 插件 Angr 0x4 state angr Learn x00 options

Angr-Learn-0x4

注意

本文可以理解为官方文档的简单翻译+一部分个人理解

程序状态

本篇主要讲的是程序状态,比如内存与寄存器等,然后简单介绍angr操作的基本概念。

比如说如何读写内存:

import angr, claripy
>>> proj = angr.Project('/bin/true')
>>> state = proj.factory.entry_state()

# copy rsp to rbp
>>> state.regs.rbp = state.regs.rsp

# store rdx to memory at 0x1000
>>> state.mem[0x1000].uint64_t = state.regs.rdx

# dereference rbp
>>> state.regs.rbp = state.mem[state.regs.rbp].uint64_t.resolved

# add rax, qword ptr [rsp + 8]
>>> state.regs.rax += state.mem[state.regs.rsp + 8].uint64_t.resolved

基本符号执行

我们可以使用state.step()来进行一次符号执行。该方法将执行一步符号执行并返回一个名为angr.engines.successors.SimSuccessors的对象 。在这有几个要点需要理解:

  • 第一:与仿真不同,符号执行的对象可以产生多个后继状态,这些后继状态可以通过多种方式进行分类。而.successors这个对象的属性他是一个包含所有“正常”后继状态的列表。我们在这,要清楚的理解为啥这返回的是列表而不是一个单一的元素。

  • 第二:我们选择“真”分支还是“假”分支?答案是,我们两者都采用!我们生成两个完全独立的后继状态: 一种模拟条件为真的情况,另一种模拟条件为假的情况。在第一个状态中,我们添加模拟情况为真的符号比较作为约束,在第二个状态中,我们添加模拟情况为假的符号比较作为约束。这样,每当我们使用这些后继状态中的任何一个执行约束求解时,状态上的条件都会确保我们获得的任何解决方案都是有效的输入,这将导致执行遵循给定状态所遵循的相同路径

>>> proj = angr.Project('examples/fauxware/fauxware')
>>> state = proj.factory.entry_state(stdin=angr.SimFile)  # ignore that argument for now - we're disabling a more complicated default setup for the sake of education
>>> while True:
...     succ = state.step()
...     if len(succ.successors) == 2:
...         break
...     state = succ.successors[0]

>>> state1, state2 = succ.successors
>>> state1
<SimState @ 0x400629>
>>> state2
<SimState @ 0x400699

>>> input_data = state1.posix.stdin.load(0, state1.posix.stdin.size)

>>> state1.solver.eval(input_data, cast_to=bytes)
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00SOSNEAKY\x00\x00\x00'

>>> state2.solver.eval(input_data, cast_to=bytes)
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00S\x00\x80N\x00\x00 \x00\x00\x00\x00'

状态预设

到目前为止,每当我们使用状态时,我们都是使用project.factory.entry_state()来创建它的。这只是项目工厂中可用的几个状态构造函数之一:

  • .blank_state()构造一个“blank slate”空白状态,其中大部分数据未初始化。当访问未初始化的数据时,将返回一个不受约束的符号值。
  • .entry_state()构造一个准备在主二进制文件的入口点执行的状态。
  • .full_init_state()构造一个准备通过需要在主二进制文件入口点之前运行的任何初始化程序执行的状态,例如共享库构造函数或预初始化程序。当完成这些后,它将跳转到入口点。
  • .call_state()构造一个准备执行给定函数的状态。

您可以通过这些构造函数的几个参数来自定义状态:

  • 这些构造函数都可以接受一个 addr 参数来指定开始的确切地址。
  • 如果你在一个可以接受命令行参数或环境变量的环境中执行,你可以通过 args 传入一个参数列表,并通过 env 传入一个环境变量的字典到 entry_state 和 full_init_state 中。这些结构中的值可以是字符串或位向量,并将作为参数和环境变量序列化到模拟执行的状态中。默认的 args 是一个空列表,所以如果你分析的程序期望至少找到一个 argv[0],你应该总是提供它!
  • 如果你想让 argc 成为符号化的,你可以将一个符号位向量作为 argc 传递给 entry_state 和 full_init_state 构造函数。但要小心:如果你这样做,你还应该在结果状态中添加一个约束,以确保你为 argc 设置的值不会大于你传入 args 的参数数量。
  • 要使用 call state,你应该用 .call_state(addr, arg1, arg2, ...) 调用它,其中 addr 是你想要调用的函数的地址,argN 是该函数的第 N 个参数,可以是 Python 整数、字符串或数组,或者是位向量。如果你想要分配内存并实际传入一个对象的指针,你应该将其包装在 PointerWrapper 中,即 angr.PointerWrapper("point to me!")。这个 API 的结果可能有点不可预测,但我们正在努力改进。
  • 为了指定使用 call_state 为函数调用的约定,你可以传递一个 SimCC 实例作为 cc 参数。我们试图选择一个合理的默认设置,但对于特殊情况,你需要帮助 angr 进行调整。

内存接口

状态选项

可以对 angr 的内部进行很多小调整,这些调整在某些情况下会优化行为,但在其他情况下会产生损害。这些调整是通过状态选项控制的。

在每个 SimState 对象上,都有一组 ( state.options) 其所有启用的选项。每个选项(实际上只是一个字符串)都以某种微小的方式控制 angr 执行引擎的行为。完整的选项域列表以及不同状态类型的默认值可以在附录中找到。您可以通过 访问添加到状态的单独选项angr.options。各个选项均以大写字母命名,但也有一些常见的对象分组,您可能希望将它们捆绑在一起使用,并以小写字母命名。

通过任何构造函数创建 SimState 时,您可以传递关键字参数add_optionsremove_options,它们应该是修改默认初始选项集的选项集。

# Example: enable lazy solves, an option that causes state satisfiability to be checked as infrequently as possible.
# This change to the settings will be propagated to all successor states created from this state after this line.
>>> s.options.add(angr.options.LAZY_SOLVES)

# Create a new state with lazy solves enabled
>>> s = proj.factory.entry_state(add_options={angr.options.LAZY_SOLVES})

# Create a new state without simplification options enabled
>>> s = proj.factory.entry_state(remove_options=angr.options.simplification)

状态插件

除了刚才讨论的一组选项之外,存储在 SimState 中的所有内容实际上都存储在附加到该状态的插件中。到目前为止,我们讨论的状态的几乎每个属性都是一个插件 - memoryregistersmemregssolver等。这种设计允许代码模块化以及为模拟状态的其他方面轻松实现新型数据存储的能力,或者提供插件的替代实现的能力。

例如,普通memory插件模拟平坦内存空间,但分析可以选择启用“抽象内存”插件,该插件使用地址的替代数据类型来模拟独立于地址的自由浮动内存映射,以提供state.memory. 相反,插件可以降低代码复杂性:state.memory并且state.registers实际上是同一插件的两个不同实例,因为寄存器也使用地址空间进行模拟。

全局插件

state.globals是一个非常简单的插件:它实现了标准 Python 字典的接口,允许您在状态上存储任意数据。

历史记录插件

为了更方便地使用这个结构,历史记录还提供了几个高效的迭代器,用于遍历某些值的历史记录。一般来说,这些值存储为 history.recent_NAME,而遍历它们的迭代器就是 history.NAME。例如,for addr in state.history.bbl_addrs: print hex(addr) 将打印出二进制文件的基本块地址跟踪,而 state.history.recent_bbl_addrs 是最近一步执行的基本块列表,state.history.parent.recent_bbl_addrs 是上一步执行的基本块列表等。如果你需要快速获得这些值的平面列表,你可以访问 .hardcopy,例如 state.history.bbl_addrs.hardcopy。不过要记住,基于索引的访问是在迭代器上实现的。

以下是历史记录中存储的一些值的简要列表:

history.descriptions 是对状态执行的每一轮次的字符串描述的列表。

history.bbl_addrs 是状态执行的基本块地址的列表。每轮执行可能有多个地址,而且不是所有地址都对应于二进制代码 - 有些可能是挂钩了 SimProcedures 的地址。

history.jumpkinds 是状态历史中每个控制流转移的处置的列表,作为 VEX 枚举字符串。

history.jump_guards 是列表,列出了状态遇到的每个分支的保护条件。

history.events 是在执行过程中发生的“有趣事件”的语义列表,如存在符号跳转条件、程序弹出消息框,或执行以退出代码终止。

history.actions 通常为空,但如果你向状态添加 angr.options.refs 选项,它将记录程序执行的所有内存、寄存器和临时值访问的日志。

调用堆栈插件

angr 将跟踪模拟程序的调用堆栈。在每个调用指令上,都会将一个帧添加到跟踪的调用堆栈的顶部,并且每当堆栈指针下降到调用最顶层帧的点以下时,都会弹出一个帧。这使得angr能够稳健地存储当前模拟函数的本地数据。

与历史记录类似,调用堆栈也是一个节点链接列表,但没有提供对节点内容的迭代器 - 相反,您可以直接迭代以state.callstack获取每个活动帧的调用堆栈帧,按从大多数到顺序最近到最旧。如果您只想要最上面的框架,那就是state.callstack

  • callstack.func_addr是当前正在执行的函数的地址
  • callstack.call_site_addr是调用当前函数的基本块的地址
  • callstack.stack_ptr是从当前函数开头开始的堆栈指针的值
  • callstack.ret_addr是当前函数返回的位置

复制和合并

这部分主要了解状态的复制与合并:

proj = angr.Project('/bin/true')
s = proj.factory.blank_state()
s1 = s.copy()
s2 = s.copy()

s1.mem[0x1000].uint32_t = 0x41414141
s2.mem[0x1000].uint32_t = 0x42424242
(s_merged, m, anything_merged) = s1.merge(s2)

aaaa_or_bbbb = s_merged.mem[0x1000].uint32_t

标签:状态,插件,Angr,0x4,state,angr,Learn,x00,options
From: https://www.cnblogs.com/7resp4ss/p/18077048

相关文章

  • Angr-Learn-0x3
    Angr-Learn-0x3注意本文可以理解为官方文档的简单翻译+一部分个人理解符号执行与约束求解angr之所以强大并不因为它是一个模拟器,而是它能使用符号变量来执行。使用符号变量算术运算将产生一颗运算树(AST)。AST可以转换为SMT求解器的约束。使用位向量例子:#64-bitbitvectors......
  • 一个现成的用python写的项目, 有GUI,https://github.com/mustafamerttunali/deep-learni
    安装该项目ENV:Win11Anaconda 1.安装Python3.7, 在Anaconda新建一个python3.7环境2.安装VC++buildtool14.0 以上版本,我从下面这个link下载的最新版是17.6.4https://visualstudio.microsoft.com/visual-cpp-build-tools/否则会遇到 3.修改一下requir......
  • 政安晨:【AI认知速成】(一)—— 初步理解Q-learning
    咱们这篇文章将要介绍的AI模型,遍及机器人、自动驾驶汽车、游戏中的NPC等等。Q-Learning是一种强化学习算法,用于解决动态环境下的决策问题。在Q-Learning中,有一个智能体(agent)和一个环境(environment)。智能体通过与环境的交互来学习最优策略,以最大化累计奖励。Q-Learning算法的......
  • Federated Learning with Differential Privacy:Algorithms and Performance Analysis
    2024/2/11大四做毕设的时候第一次读这篇论文,当时只读了前一部分,后面关于收敛界推导证明的部分没有看,现在重新完整阅读一下这篇文章。本文贡献提出了一种基于差分隐私(DP)概念的新框架,其中在聚合之前将人工噪声添加到客户端的参数中,即模型聚合前加噪FL(NbAFL)我们提出了Nb......
  • Efficient Learned Lossless JPEG Recompression
    目录简介创新点模型设置CCCMcompressedcheckerboardcontextmodelPPCMpipelineparallelcontextmodelShiftContext实验设置结果简介本文是GuoLina以及HeDailan商汤团队关于重压缩的第二篇论文,这次该团队将注意力放到了加速解码上。创新点提出Multi-LevelParallelC......
  • 【Coursera GenAI with LLM】 Week 3 Reinforcement Learning from Human Feedback Cl
    Helpful?Honest?Harmless?MakesureAIresponseinthose3ways.Ifnot,weneedRLHFisreducethetoxicityoftheLLM.Reinforcementlearning:isatypeofmachinelearninginwhichanagentlearnstomakedecisionsrelatedtoaspecificgoalbytakin......
  • Sklearn支持向量机
    支持向量机(SupportVectorMachine,SVM)是一种常用的分类算法,它可以用于解决二分类和多分类问题。在Python中,你可以使用Sklearn库来实现SVM。下面是一个简单的例子,展示了如何使用Sklearn进行SVM分类。#导入必要的库fromsklearn.model_selectionimporttrain_test_split......
  • angr使用记录
    由于毕设需要,这几天在使用angr符号执行自动化挖掘格式化字符串漏洞,但是对angr的了解不多,导致在使用的时候屡屡碰壁,在此记录一下。本来写了一个简单的通用检测脚本,但是在使用脚本对CWE-134的一个样例(SARD)进行分析时,发现无法找出漏洞点。检测脚本测试格式化字符串漏洞的逻辑很简单......
  • Practical Learned Lossless JPEG Recompression with Multi-Level Cross-Channel Ent
    目录简介模型DCTCoefficientsRearrangement将系数重排Cross-ColorEntropyModelMatrixContextModelMulti-LevelCross-ChannelEntropyModel创新点实验设置训练数据集:测试数据集:训练细节:结果简介JPEG是一种非常流行的压缩方法,然而最近关于图像压缩的研究主要集中在未压......
  • [论文速览] Learning to Write Stylized Chinese Characters
    Pretitle:LearningtoWriteStylizedChineseCharactersbyReadingaHandfulofExamplesaccepted:IJCAI2018paper:https://arxiv.org/abs/1712.06424code:Noneref:https://www.jiqizhixin.com/articles/2018-01-01-4关键词:字体生成阅读理由:风格内容解耦先行......