花指令
首页
文章
漏洞
SRC导航
内容精选
输入关键词搜索
APP 登录| 注册
如何识别并避开花指令
阅读量 30475 | 稿费 200
分享到: QQ空间 新浪微博 微信 QQ facebook twitter
发布时间:2017-12-11 10:03:59
译文声明
本文是翻译文章,文章原作者Nick Harbour,文章来源:fireeye.com
原文地址:https://www.fireeye.com/blog/threat-research/2017/12/recognizing-and-avoiding-disassembled-junk.html
译文仅供参考,具体内容表达以及含义原文为准
×
前言
在逆向工程师的职业生涯之中,有一个常见的问题一直在困扰着他们,就是有时会耗费大量的时间去阅读并研究花指令(Junk Code)。所谓花指令,并不是程序真正需要执行的指令,而是一段在不影响程序正常运行前提下迷惑反编译器的汇编指令。借助花指令,可以增加反编译过程的难度。有时,工程师发现可执行代码出现在他们没有预料到的地方,从而误以为发现了一个漏洞,或发现了一个最新的恶意软件样本,然而事实上,他们遇到的很可能就是花指令。
在这篇文章中,我们将讨论如何识别花指令,并了解它与实际代码之间的区别。我们将重点关注x86系统中的反汇编过程,但在许多其他的结构中也会存在类似的问题,大家可以参考。
1. 问题描述
通常,在反编译花指令过程中,我们所犯的第一个错误就是:因为它可以被反编译成有效的指令,所以就将其假设为实际的代码。我们知道,x86的指令集是紧密排列的,其中有许多都是以单字节编码。一眼望去,不管我们反编译任何数据,都能得到看起来有效的x86代码。
举例来说,我生成了一个16KB的随机数据文件,并将其反编译。这样一来,就产生了6455个有效的32位x86指令,以及239字节无法识别的数据。这就意味着,超过98%的随机数据可以被反编译成有效指令,剩下的则无法被解析为有效指令。为了进一步说明,我们一起来看看这个随机数据最开始部分的反汇编,其中包含了一些指令,以及1字节无法识别的数据。
如上所示,其中的第一列是数据偏移量,本文中所有的反汇编指令都以此来表示。第二列是组成该条指令的字节,而第三列则是这些字节相应的反汇编表示。除去标红的0x16之外,反汇编后所得到的全部指令都是有效的。尽管偏移0x16的内容看起来像是指令,但“db”仅仅是用于声明一个字节的汇编符号,反汇编程序并不会将其识别为指令的一部分。正如前面所说,x86的指令集非常密集,因此每个字节都有可能是一条指令的开始部分。在这种情况下,0xF6有可能是指令的有效开始,但由于与后面的0x4E组合之后没有形成有效的操作数,因此0xF6就被视为了无效。在16字节的随机数据中,274个无法识别的字节共包含27种不同的值。而在这27种不同的值之中,唯一一个在英文字符串范围内的,是字母“b”(0x62)。
在这里,我们重点关注了更为主流的32位反汇编过程,但同样的情况也会发生在16位和64位英特尔汇编指令之中。当上述随机数据被反编译成16位代码时,其中的96%将被解析为有效指令。而假如反编译成64位,有效指令占比则为95%。
你可能会说,有可能随机数据中会连续出现较多的0,这就意味着在这个区域中没有代码。然而,高级的反编译器能够智能识别出大量0的出现,判断出它们并非代码,但这部分仍会被反汇编成有效的x86指令,如下所示:
更进一步,如果我们使用英语文本生成随机数据,就会更具有迷惑性。我尝试使用一个包含随机英文字符(lorem ipsum,即“乱数假文”)的60KB的文件,并对其进行了反编译,得到了23170条指令,其中没有任何无法识别的数据。因此,我们现在生成的随机数据,100%都可以反编译成有效指令。下面的片段展示的是“乱数假文”前三个单词(Lorem ipsum dolor)的反编译结果:
很显然,面对这样的花指令,我们就要花费更多的精力去从中辨别出真正的代码。
2. 解决方案
目前来说,我们应对这一问题的最好武器恐怕是人的大脑,但我们还是应该想办法,借助一些启发式算法,利用脚本更好地过滤掉这些花指令。由此也可以看出,即使是经验丰富的逆向工程师,也要不断学习了解这类的代码片段,提升发现花指令的能力。
2.1 特权指令
在x86处理器中,会通过四个Ring级别来进行访问控制的保护,听起来就像指环王一样。其中,有两个Ring基本上不使用。内核模式的执行发生在Ring0,而用户模式发生在Ring3。某些指令只能在Ring0中执行。有许多特殊的特权指令,也恰好是单字节的操作码,并且经常出现在反编译的花指令之中。让我们再来看看之前的“乱数假文”,但在这次,我将重点标记其中的特权指令:
如果我们发现,某段代码并不是作为操作系统引导加载程序、内核或者设备驱动程序运行的,那么一旦看到这些特权指令,就应该意识到该反汇编实际上并不是有效的代码。标红的这些,都是从硬件端口读写数据的输入/输出指令。这些指令必须在设备驱动程序中使用,如果在Ring3用户模式中执行,会产生异常。即使我们现在反编译的是内核代码,这些指令出现的频率也比正常情况下高出很多。下面是一些常见的Ring0指令列表,经常会作为花指令使用:
l IN (INS, INSB, INSW, INSD)
l OUT (OUTS, OUTSB, OUTSW, OUTSD)
l IRET
l IRETD
l ARPL
l ICEBP / INT 1
l CLI
l STI
l HLT
2.2 不常见的指令
在用户模式下,有一些合法但却并不常见的Ring3指令,由于这些指令都是从编译代码而来,并不是直接人工编写的汇编语言,因此就显得格外奇怪。我们可以将这类指令分为三小类,分别为:过于便捷的指令、不常见的数学运算和远指针指令。接下来让我们仔细研究一下。
(1) 过于便捷的指令
l ENTER
l LEAVE
l LOOP (LOOPE/LOOPZ, LOOPNE/LOOPNZ)
l PUSHA
l POPA
其中,ENTER和LEAVE指令经常被汇编语言的编写者用于函数的开始和结束,但它们并不实用,也不能与PUSH、MOV、SUB这些指令一起完成。因此,当前的编译器更倾向于避免使用ENTER和LEAVE,绝大多数的程序员也都不会去使用它们。这些指令在操作码中大约占比1%,经常被用作花指令来使用。
LOOP指令(包括带有条件的LOOPZ、LOOPNZ指令)提供了一种非常直观有效的方式来编写汇编语言中的循环。但编译器一般不会使用这些指令,它们通常会创建自己的循环,并使用JMP(无条件跳转指令)以及其他条件跳转指令。
PUSHA和POPA指令的作用是将所有的16位通用寄存器压入堆栈或取出堆栈。对于编写者来说,这两个指令就像宏一样方便。由于它们还可以存储或恢复堆栈指针本身,因此它们非常复杂。所以编码器并不会在函数的一开始存储它们,再在函数的结尾恢复它们。在编译的代码中不会存在这些指令,但由于它们也同样占据了1%左右的操作码范围,因此也经常被用作花指令。
(2) 不常见的数学运算
浮点指令
l F*
l WAIT/FWAIT
浮点指令通常是以字母“F”开始。尽管有一小部分程序会使用浮点数学运算,但大部分程序都不会使用。浮点指令在操作码范围中占有较大比例,所以在花指令中特别常见。在这里,代码设计的知识往往能够在逆向工程的尝试中派上用场。如果我们对一个3D图形程序进行逆向,就会发现其中存在大量的浮点指令,这是正常的。但如果我们对恶意软件进行逆向,浮点数学运算就不太可能会出现在其中。最后需要特别说明的一点是,Shellcode经常会使用一些浮点指令,用来得到指向其自身的指针。
l SAHF
l LAHF
SAHF的作用是将寄存器AH的值传送到标志寄存器PSW,LAHF则是反过来将PSW的值保存到AH。由于这一操作只能通过编程时明确的语句来实现,并不会从高级语言中翻译而来,所以编译器通常情况下不会输出这些指令。其实,即使是人工编写的汇编代码,也很少使用这两个指令。并且它们还是单操作码范围内的单字节指令,同样常常作为花指令。
ASCII调整指令
l AAA
l AAS
l AAM
l AAD
这一系列的“AA”指令,作用是在汇编语言中以十进制的形式来处理数据。同样,由于这些指令在早期比较流行,现在已经不被广泛使用,所以理论上不应该经常出现。它们同样也是单字节指令。
l SBB
SBB指令与SUB相似,只不过它将进位标志(Carry Flag)添加到源操作数之中。该指令在合法的代码中,特别是在对大于机器字长的数字进行运算时也能见到。然而,SBB指令有9个以上的操作码,占比3.5%。尽管并不是单字节指令,但由于其拥有多种形式和众多操作码,所以会被用作花指令。
l XLAT
XLAT是汇编语言查表指令。由于它并不能直接翻译成某个特定的高级语言结构,所以编译器一般不会使用该指令。它同样也是一个单字节指令,因此它是花指令的概率,要比人工使用该指令的概率更大一些。
l CLC
l STC
l CLD
l STD
这些指令会清除/设置进位标志及目的标志(Destination Flag)。这些指令可能会在流操作的附近出现,我们通常会在REP前缀的地方看到它们。同样,它们都是单字节指令,经常用作花指令。
(3) 远指针指令
l LDS
l LSS
l LES
l LFS
l LGS
在英特尔的架构中,远指针(Far Pointer)不会存在于16位之中。但是,设置远指针的指令,仍然会占用两个单字节的操作码,还占用了双字节操作码中的3个值。因此,这些指令也会作为花指令出现。
2.3 频繁出现的指令前缀
x86中的指令可以带有前缀,我们将其称为指令前缀。指令前缀的作用是修改后面指令的行为,最常见的一种就是改变操作数的大小。例如,我们正在以32位的模式执行指令,但希望能使用16位寄存器或操作数执行计算,那么就可以在计算指令中添加一个前缀,以告知CPU,这是一个16位的指令,并不是32位。
这样的指令前缀有很多,但非常不巧的是,其中的一大部分都在ASCII的字母范围之内。这也就意味着,如果我们反汇编了一个ASCII的文本(比如之前的“乱数假文”),那就会出现特别多的指令前缀。
如果我们在对一个32位的代码进行反汇编,却发现它大量使用了16位的寄存器(比如使用了AX、BX、CX、DX、SP、BP,而不是EAX、EBX、ECX、EDX、ESP、EBP),此时就要意识到,现在在看的很有可能就是花指令。
反汇编器会在指令助记符(Instruction Mnemonic)前添加特定的符号来表示其他前缀。如果我们在代码中能看到下面这些关键词,很有可能会是花指令:
l LOCK
l BOUND
l WAIT
段选择器
l FS
l GS
l SS
l ES
在16位模式下,会使用段寄存器(CS、DS、FS、GS、SS、ES)进行寻址的存储。程序的代码通常是基于CS“代码段”寄存器来实现引用的,而程序处理的数据是从DS“数据段”寄存器引用的。ES、FS、GS是额外的数据段寄存器,用于32位代码。段选择器(Segment Selector)的前缀字节,可以添加在指令之前,从而强制使其基于特定的段来引用内存,而不是基于其默认的段。由于上述这些都占用了单字节操作码空间,因此也会在花指令中频繁出现。在我的随机数据中,有一个反编译后的指令,是GS寄存器的段选择符前缀使其不指向地址存储器:
相比于普通代码来说,花指令会更加频繁地使用这些段寄存器,并且编译器不会产生输出。我们再看看另外一个例子:
该指令会从堆栈中弹出SS“堆栈段”寄存器。这是一个完全有效的指令,然而,由于这是反编译的32位代码,段寄存器并不会像16位那样进行改变。同样,如果只有上面几行代码,会出现另一个奇怪的指令:
32位的体系结构中,支持更多段寄存器的寻址。这条指令的作用是将一些数据移动到第七个段寄存器中,我的反编译器将其命名为“segr7”。
3. 总结
由于花指令的存在,最好的情况是浪费分析人员的时间和精力,而最坏的情况恐怕是会误导我们的分析过程,让我们去分析错误的数据。通过本文,我们学会了识别常见的反汇编花指令,并对其频繁出现的原因做以详细地分析。
希望通过本文的阅读,可以让你在以后的工作中轻松识别出花指令,从而节约工作时间,确保分析的准确性。
本文翻译自 fireeye.com, 原文链接 。如若转载请注明出处。
汇编语言 Junkcode 反编译
P!chu 分享到: QQ空间 新浪微博 微信 QQ facebook twitter
|推荐阅读
2018安恒杯11月赛-Web&Crypto题解
2018-11-26 10:02:02
U2F安全协议分析
2018-11-24 10:00:48
二十年重回首——CIH病毒源码分析
2018-11-23 15:20:19
Cookie Maker:隐藏在Google Docs中的恶意网络
2018-11-23 14:30:40
|发表评论
发表你的评论吧
昵称
越南邻国宰相
换一个
|评论列表
还没有评论呢,快去抢个沙发吧~
P!chu
May the shell be with you.
文章
141
粉丝
24
TA的文章
利用PNG像素隐藏PE代码:分析PNG Dropper新样本
2018-11-23 16:00:25
使用邮件实现C&C通信:新型木马Cannon分析
2018-11-22 15:20:01
Android通过RSSI广播泄漏敏感数据漏洞披露(CVE-2018-9581)
2018-11-15 09:00:40
Office 365团队:针对使用恶意InPage文档的恶意活动分析
2018-11-12 10:30:45
WordPress插件WooCommerce任意文件删除漏洞分析
2018-11-11 10:00:07
输入关键字搜索内容
相关文章
2018安恒杯11月赛-Web&Crypto题解
U2F安全协议分析
二十年重回首——CIH病毒源码分析
Cookie Maker:隐藏在Google Docs中的恶意网络
情报分析与研判之图片信息挖掘(1)
威胁情报专栏:谈谈我所理解的威胁情报——认识情报
热门推荐
文章目录
前言
1. 问题描述
2. 解决方案
2.1 特权指令
2.2 不常见的指令
2.3 频繁出现的指令前缀
3. 总结
安全客Logo
安全客
安全客
关于我们
加入我们
联系我们
用户协议
商务合作
合作内容
联系方式
友情链接
内容须知
投稿须知
转载须知
合作单位
安全客
安全客
Copyright © 360网络攻防实验室 All Rights Reserved 京ICP备08010314号-66
Loading...0daybank
文章评论