反汇编基础学习(一)

参考教材:《IDA Pro权威指南》(第2版)

编程语言

第一代语言:0和1,十六进制码,也称为机器语言字节码,机器语言程序常被称为二进制文件
第二代语言:汇编语言助记符对应具体模式的位模式或操作码
第三代语言:引入了关键字和结构,表达更接近自然语言,常见的CJavaC++ 需要编译器转换为汇编语言或机器语言
第四代语言:用户定义“做什么”而不是“如何做”,依靠更高级的第四代工具,SQLQBE

反汇编和反编译

概念
为了回溯编程过程(或对程序进行逆向工程)使用各种反汇编工具撤销汇编和编译过程,这些工具叫做反汇编器反编译器
反汇编器,以机器语言为输入,汇编语言为输出
反编译器,以汇编语言甚至机器语言为输入,输出结果为高级语言
反汇编困难
编译过程会造成损失:机器语言没有变量名或函数名,变量类型信息只有通过数据的用途来确定
编译属于多对多操作:程序可以通过许多种不同的方式转换成汇编语言,机器语言也可以通过许多不同方式转换成源程序
反编译器非常依赖语言和库
想要准确地反编译一个二进制文件,需要近乎完美的反汇编能力

反汇编目的

分析恶意软件
动态分析和静态分析是分析恶意软件的两种主要技术
动态分析(dynamic analysis)
指在严格控制的环境(沙盒) 中执行恶意软件,并用系统检测实用工具记录其所有行为
静态分析(static analysis)
指试图通过浏览程序代码来理解程序的行为,此时要查看的就是对恶意软件进行反汇编之后得到的代码清单。
分析闭源软件漏洞
把安全审核过程划分为三个阶段:发现漏洞,分析漏洞,开发破解程序(exploit)
第一步通常用模糊测试等动态技术发现程序中潜在可供利用的条件,静态分析则需要更大的努力
发现漏洞后需要进行深入的分析,确定该漏洞是否可被利用,什么情况下可被利用
开发破解程序需要了解变量之间的关系,唯一的办法是查看反汇编代码清单,再通过结合使用反汇编器和调试器,可以开发出破解程序
模糊测试:通过为程序提供大量不常见输入,希望其中某一输入会在程序中造成可被检测、分析、最终可被利用的错误
分析闭源软件的互操作性
如果以二进制的形式发布软件,竞争对手想要创建可以和它互操作的软件或提供插件,将会变得十分困难
分析编译器生成的代码,以验证编译器的性能和准确性
用反汇编工具验编译器是否符合设计规范,分析人员可以从中寻找优化编译输出的机会,也可以验证编译器本身是否容易被攻破
在调试时显示程序指令
在调试中生成代码清单,可能是反汇编最常见的一种用途。但调试器内的反汇编器往往很简单,通常不能批量反汇编,在无法确定函数边界时,有时会拒绝反汇编。

反汇编方法

为满足反汇编要求,反汇编器需要从大量算法中选择一些适当的算法来处理我们提供的文件。反汇编器所使用的算法的质量及其实施效率,将直接影响反汇编代的质量。

基本的反汇编算法以机器语言输入,汇编语言输出
1.确定进行反汇编的代码区域。
指令与数据通常是混杂在一起的,区分它们十分重要。以常见的反汇编可执行文件为例,文件必须符合可执行文件的某种通用格式,例如Windows的可移植可执行文件(PE)格式,Unix的可执行和链接格式(ELF),这些格式通常含有一种机制来确定文件中包含代码和代码入口点的部分位置。
代码入口点:是一个指令地址,一旦程序加载到内存,操作系统会将控制权交给该指令。
2.知道起始指令后,读取地址包含的值,执行一次表查找,将二进制操作码的值与汇编助记符对应起来。
3.获取指令并解码任何所需要的操作之后,需要对它的汇编语言等价形式进行格式化,并将其在反汇编
代码中输出。例如,x86汇编语言所使用的两种主要格式为Intel格式和AT&T格式。
4.输出一条指令后,继续反汇编下一条指令,并重复上述过程,直到反汇编完文件中的所有指令。

两种最主要的反汇编算法

线性扫描反汇编
线性扫描反汇编算法采用一种非常简单的方法来确定需要反汇编的指令的位置:一条指令结束、另一条指令开始的地方。反汇编从一个代码段的第一个字节开始,以线性模式扫描整个代码段,逐条反汇编每条指令,直到完成整个代码段。它不会通过识别别分支等非线性指令来了解程序的控制流。
线性扫描算法主要优点是能够完全覆盖程序的所有代码段,主要缺点是没有考虑到代码中可能混有数据。
gdb,WinDug的反汇编引擎均采用线性扫描算法。

递归下降反汇编算法
递归下降算法强调控制流的概念。控制流根据一条指令是否被另一条指令引用来决定是否对其进行反汇编。根据指令对CPU指令指针的影响分类
1.顺序流指令
顺序流指令将执行权传递给紧随其后的下一条指令。
2.条件分支指令
条件分支指令提供两条可能的执行路径。条件为真,执行分支,并且必须修改指针,使其指向分支的目标;条件为假,则继续以线性模式执行指令,并使用线性扫描方法反汇编下一条指令。递归下降算法会汇编上述两条径。同时,它将分支目标指令的地址添加到稍后才进行反汇编的地址列表中,从而推迟分支目标指令的反汇编过程。
3.无条件分支指令
无条件分支指令不遵循线性流模式,执行权只能传递给一条指令,但那条指令不需要紧接在分支指令后。
4.函数调用指令
函数调用指令的运行方式与无条件跳转指令非常相似,唯一不同是,一旦函数完成,执行权将返回紧跟在调用指令的目标地址被添加到推迟进行反汇编地址列表中,紧跟其后的指令以类似于线性扫描的方式进行反汇编。从被调用函数返回时,如果程序运行出现异常,递归下降就有可能失败。
5.返回指令
有时递归下降算法访问了所有路径。而且,函数返回指令(如x86 ret)没有提供接下来将要执行的指令的信息。这时,如果程序确实正在运行,则可以从运行时栈顶获得一个地址,并从这个地址开始恢复执行。但反汇编器会转而处理前面搁置的延迟反汇编的地址列表。反汇编器从这个列表中取出一个地址,并从这个地址开始继续进行反汇编。递归下降算法因此得名。

递归下降算法的一个主要优点在于,它具有区分代码与数据的强大能力。作为一种基于控制流的算法,它很少会在反汇编过程中错误的将数值作为代码处理。
主要缺点在于,它无法处理间接代码路径,如利用指针表来查找目标地址的跳转或调用。
然而,通过采用一些用于识别指向代码的指针的启发式方法,递归下降反汇编器能够提供所有代码,并清楚地区分代码与数据。
IDA Pro是一种最为典型的递归下降反汇编器。

小结

虽然使用反汇编器没有必要深入了解反汇编算法,但了解算法对逆向工程有很大的帮助,也有助于挑选合适的工具。

  • 3
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

RICKC131

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值