angr学习(一)

基本属性

首先,我们有一些关于这个项目的基本属性:它的CPU体系结构,文件名以及入口点的地址。

>>> import monkeyhex # this will format numerical results in hexadecimal
>>> proj.arch
<Arch AMD64 (LE)>
>>> proj.entry
0x401670
>>> proj.filename
‘/bin/true‘

arch是archinfo.Arch对象的一个实例,用于编译程序的任何体系结构,在本例中是little-endian amd64。它包含大量关于运行的CPU的文书数据,您可以在闲暇时阅读这些数据。你关心的常见问题是arch.bits,arch.bytes(其中一个是主要Arch类的@property声明),

arch.name和arch.memory_endness。

entry是二进制的入口点!

filename是二进制文件的绝对文件名

The loader(加载器)

从二进制文件加载到在虚拟地址空间中非常复杂!我们有一个叫CLE的模块来处理这个问题。 CLE的结果,称为加载程序,在.loader属性中可用。我们将详细介绍如何尽快使用它,

但是现在只要知道你可以用它来查看angr加载程序时同时加载的共享库,并对加载的地址空间进行基本的查询。

>>> proj.loader
<Loaded true, maps [0x400000:0x5004000]>

>>> proj.loader.shared_objects # may look a little different for you!
{‘ld-linux-x86-64.so.2‘: <ELF Object ld-2.24.so, maps [0x2000000:0x2227167]>,
‘libc.so.6‘: <ELF Object libc-2.24.so, maps [0x1000000:0x13c699f]>}

>>> proj.loader.min_addr
0x400000
>>> proj.loader.max_addr
0x5004000

>>> proj.loader.main_object # we‘ve loaded several binaries into this project. Here‘s the main one!
<ELF Object true, maps [0x400000:0x60721f]>

>>> proj.loader.main_object.execstack # sample query: does this binary have an executable stack?
False
>>> proj.loader.main_object.pic # sample query: is this binary position-independent?
True

The factory

Angr中有很多类,其中大部分需要实例化一个项目。而不是让你到处将项目作为参数传递,我们提供project.factory,它有几个方便的常用对象的构造函数,你会经常使用。

本节还将介绍几个基本的angr概念。

Blocks

angr分析代码是以基本块(在编译器构造中,基本块是一个直线代码序列,除了入口外没有分支,除了出口处没有分支)为单位。

首先,project.factory.block( ),它用来从给定的地址提取一个基本的代码块。你将得到一个Block对象,它可以告诉你关于代码块的很多有趣的事情:

>>> block = proj.factory.block(proj.entry) # lift a block of code from the program‘s entry point
<Block for 0x401670, 42 bytes>

>>> block.pp() # pretty-print a disassembly to stdout
0x401670: xor ebp, ebp
0x401672: mov r9, rdx
0x401675: pop rsi
0x401676: mov rdx, rsp
0x401679: and rsp, 0xfffffffffffffff0
0x40167d: push rax
0x40167e: push rsp
0x40167f: lea r8, [rip + 0x2e2a]
0x401686: lea rcx, [rip + 0x2db3]
0x40168d: lea rdi, [rip - 0xd4]
0x401694: call qword ptr [rip + 0x205866]

>>> block.instructions # how many instructions are there?
0xb
>>> block.instruction_addrs # what are the addresses of the instructions?
[0x401670, 0x401672, 0x401675, 0x401676, 0x401679, 0x40167d, 0x40167e, 0x40167f, 0x401686, 0x40168d, 0x401694]
 

此外,您可以使用Block对象来获取代码块的其他表示形式:

>>> block.capstone # capstone disassembly
<CapstoneBlock for 0x401670>
>>> block.vex # VEX IRSB (that‘s a python internal address, not a program address)
<pyvex.block.IRSB at 0x7706330>
 

States

Project对象只代表程序的“初始化映像”。当你用angr执行执行时,使用的是一个代表模拟程序状态的特定对象 (SimState)。

>>> state = proj.factory.entry_state()
<SimState @ 0x401670>

一个SimState包含一个程序的内存,寄存器,文件系统数据...任何会在执行中改变的“实时数据”都会在这个state中。稍后我们将介绍如何与状态进行深入交互,但现在让我们使用state.regs和state.mem来访问这个状态的寄存器和内存:

>>> state.regs.rip # get the current instruction pointer
<BV64 0x401670>
>>> state.regs.rax
<BV64 0x1c>
>>> state.mem[proj.entry].int.resolved # interpret the memory at the entry point as a C int
<BV32 0x8949ed31>

这里是如何从python ints转换为bitvectors,然后再返回:

>>> bv = state.solver.BVV(0x1234, 32)        # create a 32-bit-wide bitvector with value 0x1234
<BV32 0x1234>                                # BVV stands for bitvector value
>>> state.solver.eval(bv)                    # convert to python int
0x1234

您可以将这些位向量存储回寄存器和内存,也可以直接存储一个python整数,并将其转换为适当大小的位向量:

>>> state.regs.rsi = state.solver.BVV(3, 64)
>>> state.regs.rsi
<BV64 0x3>

>>> state.mem[0x1000].long = 4
>>> state.mem[0x1000].long.resolved
<BV64 0x4>

使用array [index]表示法指定一个地址

使用<type>来指定内存应该被解释为<type>(通用值:char,short,int,long,size_t,uint8_t,uint16_t ...)

从那里,你可以:

存储一个值,无论是一个bitvector或一个python int

使用.resolved将该值作为bitvector

使用.concrete将该值作为python int

如果尝试去获取其他寄存器,可能会遇到看起来很奇怪的值:

>>> state.regs.rdi
<BV64 reg_48_11_64{UNINITIALIZED}>

它仍旧是一个64bit 的bitvector,但它不包含一个数值,而是一个名称,叫做symbolic variable(符号变量),它是符号执行的基础。

Simulation Managers(模拟化管理器)

如果一个state表示处在某个时间点的程序,那么一定会有方法使它达到下一个时间点。Simulation Manager是angr中的主要接口,用于进行执行或者说模拟。

首先,我们创建simulation manager,

>>> simgr = proj.factory.simgr(state) # TODO: change name before merge
<SimulationManager with 1 active>
>>> simgr.active
[<SimState @ 0x401670>]

造函数会参数一个state或state列表。

simulation manager含有几个stash,默认的stash,active,由传入的state初始化。

我们开始执行

>>> simgr.step()

可以再次查看存活的stash,注意到它已经改变,而且这并不会修改原来的state,SimState对象在执行过程中透明。可以安全的使用单个state作为任意一次执行的起点。

>>> simgr.active
[<SimState @ 0x1020300>]
>>> simgr.active[0].regs.rip # new and exciting!
<BV64 0x1020300>
>>> state.regs.rip # still the same!
<BV64 0x401670>

Analyses

angr预先打包了几个内置analyses,可以利用它们来获取程序中一些有趣的信息:

>>> proj.analyses. # Press TAB here in ipython to get an autocomplete-listing of everything:
proj.analyses.BackwardSlice        proj.analyses.CongruencyCheck        proj.analyses.reload_analyses
proj.analyses.BinaryOptimizer      proj.analyses.DDG                    proj.analyses.StaticHooker
proj.analyses.BinDiff              proj.analyses.DFG                    proj.analyses.VariableRecovery
proj.analyses.BoyScout             proj.analyses.Disassembly            proj.analyses.VariableRecoveryFast
proj.analyses.CDG                  proj.analyses.GirlScout              proj.analyses.Veritesting
proj.analyses.CFG                  proj.analyses.Identifier             proj.analyses.VFG
proj.analyses.CFGAccurate          proj.analyses.LoopFinder             proj.analyses.VSA_DDG
proj.analyses.CFGFast              proj.analyses.Reassembler

如何构建并使用一个快速控制流程图:

# Originally, when we loaded this binary it also loaded all its dependencies into the same virtual address space
# This is undesirable for most analysis.
>>> proj = angr.Project(‘/bin/true‘, auto_load_libs=False)
>>> cfg = proj.analyses.CFGFast()
<CFGFast Analysis Result at 0x2d85130>

# cfg.graph is a networkx DiGraph full of CFGNode instances
# You should go look up the networkx APIs to learn how to use this!
>>> cfg.graph
<networkx.classes.digraph.DiGraph at 0x2da43a0>
>>> len(cfg.graph.nodes())
951

# To get the CFGNode for a given address, use cfg.get_any_node
>>> entry_node = cfg.get_any_node(proj.entry)
>>> len(list(cfg.graph.successors(entry_node)))
2

翻译自:https://docs.angr.io

时间: 2024-10-24 20:13:21

angr学习(一)的相关文章

符号执行-基于python的二进制分析框架angr

转载:All Right 符号执行概述 在学习这个框架之前首先要知道符号执行.符号执行技术使用符号值代替数字值执行程序,得到的变量的值是由输入变 量的符号值和常量组成的表达式.符号执行技术首先由King在1976年提出 ,经过三十多年的发展,现在仍然被广泛研究,它在软件测试和程序验证中发挥着重 要作用.符号执行是一种重要的形式化方法和静态分析技术,它使用数学和逻辑 首先定义一些基本概念.程序的路径(path)是程序的一个语句序列,这个 语句序列包括程序的一些顺序的代码片段,代码片段之间的连接是由

Vue.js学习笔记:属性绑定 v-bind

v-bind  主要用于属性绑定,Vue官方提供了一个简写方式 :bind,例如: <!-- 完整语法 --> <a v-bind:href="url"></a> <!-- 缩写 --> <a :href="url"></a> 绑定HTML Class 一.对象语法: 我们可以给v-bind:class 一个对象,以动态地切换class.注意:v-bind:class指令可以与普通的class特

Java多线程学习(吐血超详细总结)

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 目录(?)[-] 一扩展javalangThread类 二实现javalangRunnable接口 三Thread和Runnable的区别 四线程状态转换 五线程调度 六常用函数说明 使用方式 为什么要用join方法 七常见线程名词解释 八线程同步 九线程数据传递 本文主要讲了java中多线程的使用方法.线程同步.线程数据传递.线程状态及相应的一些线程函数用法.概述等. 首先讲一下进程和线程

微信小程序学习总结(2)------- 之for循环,绑定点击事件

最近公司有小程序的项目,本人有幸参与其中,一个项目做下来感觉受益匪浅,与大家做下分享,欢迎沟通交流互相学习. 先说一下此次项目本人体会较深的几个关键点:微信地图.用户静默授权.用户弹窗授权.微信充值等等. 言归正传,今天分享我遇到的关于wx:for循环绑定数据的一个tips:  1. 想必大家的都知道wx:for,如下就不用我啰嗦了: <view class="myNew" wx:for="{{list}}">{{item.title}}<view

【安全牛学习笔记】

弱点扫描 ╋━━━━━━━━━━━━━━━━━━━━╋ ┃发现弱点                                ┃ ┃发现漏洞                                ┃ ┃  基于端口五福扫描结果版本信息(速度慢)┃ ┃  搜索已公开的漏洞数据库(数量大)      ┃ ┃  使用弱点扫描器实现漏洞管理            ┃ ╋━━━━━━━━━━━━━━━━━━━━╋ [email protected]:~# searchsploit Usage:

winform学习日志(二十三)---------------socket(TCP)发送文件

一:由于在上一个随笔的基础之上拓展的所以直接上代码,客户端: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Net.Sockets; using Sys

零基础的人该怎么学习JAVA

对于JAVA有所兴趣但又是零基础的人,该如何学习JAVA呢?对于想要学习开发技术的学子来说找到一个合适自己的培训机构是非常难的事情,在选择的过程中总是 因为这样或那样的问题让你犹豫不决,阻碍你前进的步伐,今天就让小编为您推荐培训机构新起之秀--乐橙谷Java培训机构,助力你成就好未来. 选择java培训就到乐橙谷 北京有什么好的Java培训机构?来乐橙谷北京学Java,零基础走起,乐橙谷Java基础班授课老师经验非常丰富,课程内容安排合理,适合于有一点点Java基础甚至一点都不会Java的同学学

最全解析如何正确学习JavaScript指南,必看!

划重点 鉴于时不时,有同学私信问我:怎么学前端的问题.这里统一回复一下,如下次再遇到问我此问题同学,就直接把本文链接地址发给你了. "前端怎么学"应该因人而异,别人的方法未必适合自己.就说说我的学习方法吧:我把大部分时间放在学习js上了.因为这个js的学习曲线,先平后陡.项目实践和练习啥的,我不说了,主要说下工作之外的时间利用问题.我是怎么学的呢,看书,分析源码.个人这几天统计了一下,前端书籍目前看了50多本吧,大部分都是js的.市面上的书基本,差不多都看过. 第一个问题:看书有啥好处

轻松学习C语言编程的秘诀:总结+灵感

目前在准备一套C语言的学习教程,所以我这里就以C语言编程的学习来讲.注意,讲的是"轻松学习",那种不注重方法,拼命玩命的方式也有其效果,但不是我提倡的.我讲究的是在方式方法对头.适合你.减轻你学习负担和心里压力的前提下,才适当的抓紧时间. 因此,探索一种很好的学习方法就是我所研究的主要内容. 众所周知,学习C语言并非易事,要学好它更是难上加难.这和你期末考试背会几个题目的答案考上满分没多大关系,也就是说你考试满分也说明不了你学好.学精通了C语言.那么怎么才算学精通C语言?闭着眼睛对自己