欢迎访问察北家纺网

反汇编工具(电脑软件反汇编)

频道:科普故事 日期: 浏览:1230

       在实际逆向分析的过程中,经常遇到一些关键函数或代码段被原作者使用一些代码混淆技术保护起来。代码混淆是将原代码转换成另一种功能上等价,但实际上难以阅读和理解的代码。经过混淆的代码中,常常夹杂着大量无意义的花指令,大多数反汇编工具将不能很好的进行识别,通常会将其反汇编成有效的指令,需要浪费大量的时间和精力人工去分析。 这时就可以使用angr用于辅助逆向分析。

       本期安仔课堂,ISEC实验室的张老师为大家分析自动化二进制,从此CTF逆向分析不用愁!

       一、Angr简介

       Angr是一个基于符号执行的二进制程序分析框架。能对二进制程序进行反汇编并转化为中间语言表示、符号执行、程序插桩、控制流分析、数据相关性分析。

       什么是符号执行?

       符号执行是一种重要的形式化方法和软件分析技术,通过使用符号执行技术,将程序中变量的值表示为符号值和常量组成的计算表达式,符号是指取值集合的记号,程序计算的输出被表示为输入符号值的函数,其在软件测试和程序验证中发挥着重要作用,并可以应用于程序漏洞的检测。

       符号执行的发展是从静态符号执行到动态符号执行到选择性符号执行,动态符号执行会以具体数值作为输入来模拟执行程序,是混合执行(concolic execution)的典型代表,有很高的精确度。

       Angr的架构

图1

       1.CLE模块

       二进制的装载组建是CLE(CLE Load Everything),它负责装载二进制对象以及它所依赖的库,生成地址空间,表示该程序已加载并可以准备运行。

       2.ArchInfo模块

       Archinfo是包含特定于体系结构的信息的类的集合。例如,little-endian amd64、little-endian i386。

       3.PyVex模块

       PyVex是中间语言,Angr使用Valgrind的中间语言——VEX来完成这方面的内容。VEX中间语言抽象了几种不同架构间的区别,允许在他们之上进行统一的分析。各种中间语言在设计理念上有很多的共通点

       4. SimuVEX模块

       SimuVEX模块是中间语言VEX执行的模拟器,它允许你控制符号执行。

       5.Clarity模块

       这个模块主要专注于将变量符号化,生成约束式并求解约束式,这也是符号执行的核心所在,在Angr中主要是利用微软提供的z3库去解约束式。

       二、Angr安装

       Linux

       首先安装依赖

图2

       安装angr

图3

       Mac OS

       首先安装依赖

图4

       安装angr

图5

       三、Angr使用介绍

       有一个程序test,该程序要求两个特定的输入,以获得正确的结果。在IDA中简单分析test,如下图:

图6

图7

       complex_function使用了大量的代码混淆技术,无法在IDA中生成反编译代码,难以直接分析,这时就能用Angr自动求解。

       Angr的第一个操作将始终是将二进制文件加载到Project中。

图8

       可以查看Project一些基本属性:

图9

       Arch是目标程序的体系架构,本例中为little-endian amd64

       Entry是目标程序的入口地址

       Filename是目标程序的文件名

       在加载二进制文件后,需要加载二进制文件到内存中,Angr将使用CLE模块去完成加载,与Project相同可以查询一些关于程序加载的信息。

图10

       Angr以block为单位分析代码,我们可以从block中获取许多有用的信息,例如代码汇编及指令数。

图11

       Angr使用SimState保存程序执行状况,包含程序的内存、寄存器、文件系统数据......任何会在执行中存在可修改的数据都可以在SimState中找到。

图12

       Angr是用bitvectors储存数据,bitvectors使用一系列位保存数据,同时还有一个length属性表示位宽度。

       Simulation manager是angr重要的接口之一,用于模拟执行。我们先使用程序的初始状态创建simulation manager,然后执行符号执行,可以看到我们进入了下一个block。

图13

       在多数情况下,我们不会模拟计算整个程序,而是选择部分代码进行模拟,以减少计算量。同时我们也要手动修复寄存器以及堆栈,保证程序可以正确执行。

图14

       Claripy是Angr的求解器引擎,利用的是微软提供的Z3库解约束式,password是所要求解的变量。

       之后就能利用initial state初始化simulation manager,simulation manager会查找所有可能路径,直到找到答案或遍历了所有可能路径。

图15

       输出获得的结果。

图16

       0x2c3b9b18(742103832)和0xe7a9608(3886637191)就是我们想要的结果。

图17

       最后,以一个简单的例子来说明符号执行的过程

图18

       如上,x==888888并且y>444444就会输出Good!,由人工计算能很快得出结果,但若希望程序自动计算出有效的x与y的值,最简单的方法是使用两个随机数输入,尝试x和y的随机值,很明显,在获得答案前需要大量重复的计算。

       对于符号执行而言,x和y被视为符号变量, 最开始x和y也是两个随机的输入,例如可以将其视为x=y=1。在具体执行中,第2行的z将会被设置为表达式2y, 第3行遇到第一个分支,因x(1)≠888888而失败,这里会得出一个不等式x≠888888,这个被视为路径条件,对于所有路径条件判断为true的输入而言,它们的执行路径是相同的。

       在一般情况下,希望程序尽可能遵循不同的执行路径,修改遇到的最后一个路径条件x ≠888888,改为x = 888888。然后 使用一些自动求解器来构造满足当前路径条件的输入变量x和y。 在这种情况下,程序可能得到求解出的值x = 888888,y = 1。

       再次执行程序,此次会到达程序的第4行,遇到第二个分支, 由于x(888888)> z(z=2y=2)再一次失败。此时的路径条件是X = 888888和x > z,再一次重新尝试,x > z将会被替换为x<z,然后求解查找x,y满足x=888888,z=2y和x<z三个条件的变量输入。

       例如,可能会得到x=888888,y=444445。此次的输入成功输出Good! 那么就由程序自动计算出了一个解x=888888,y=444445。