花指令初探
1.0 - 概念
简单来说就是通过添加一些垃圾数据导致IDA分析的时候会把这些垃圾数据当成代码阻碍静态分析同时保证该程序能正常运行,我的理解是一般花指令是不会阻碍动态调试的但是却能破坏静态分析。
2.0 - 分类
2.1 - 可执行式花指令
可执行式花指令指的是能够正常运行的但又不改变原始程序逻辑性的一组无用指令。
这类花指令有如下特点:①可以正常运行;②不改变任何寄存器的值;③反汇编器可以正确反汇编该指令。
这种类别的花指令组合形式很多,常常用在病毒代码的变形引擎中,病毒在传播时通过变形引擎随机产生一组该类别花指令并插入到病毒正常代码中,可以改变病毒的特征码,从而起到变形的作用。
2.2 - 不可执行式花指令(垃圾指令)
不可执行式花指令是指被插入到原始代码中但又不改变原始程序逻辑性的一组无用字节。
这类花指令有如下特点:①不可以正常运行;②不改变任何寄存器的值;③反汇编器可能会错误反汇编这些字节。
根据反汇编的工作原理,只有当花指令同正常指令的开始几个字节被反汇编器识别成一条指令时,才能有效破坏反汇编的结果。因此,插入的花指令应当是一些不完整的指令,被插入的不完整指令可以是随机选择的。正因为不可执行花指令有这些特点,该类花指令才能应用到软件保护中。
3.0 - 常见不可执行式花指令
不可执行花指令是利用反汇编器线性扫描算法的缺陷使得静态分析的时候会看到一些错误的代码 。
3.1 - 最典型的形式:
jmp Label1
db thunkcode1;//垃圾数据
Label1:
......
解析:
1.Jmp可以用call,ret,loop等替换
2.该垃圾数据通常是一条多字节指令的操作码,例如在thunkcode1处放入0E8h,由于0E8h是call指令的操作码,因此对0E8h进行解码时就会将它后面的4个字节,也就是Malicious Code的前4个字节看作是调用目标地址,从而造成反汇编过程中的错误,达到隐藏恶意代码的目的。
3.类似的机器码还有很多,常见的有0E8h,0E9h,0EBh,0FFh,0B8h等
3.1.1 - 一个简单的例子:
分析:图中jz后的地址出现了一个奇怪的东西:
一般来说,汇编语言的跳转应该是直接是一个地址,而不会出现+2这种情况,出现这种情况一般是由脏字导致,于是我们把爆红的地方按快捷键u转化为数据,可以看到,D92,D93处是垃圾数据,正常的函数应该是从unk_401D94处开始的,而由于脏字的加入导致反编译失败。
去除方法:按快捷键c把unk_401D94后的数据转化成代码,同时把垃圾数据nop掉即可
3.2 - 基本形式的叠加和嵌套
也就是把多个花指令套在一起的形式
1.多节形式
JMP Label1
Db thunkcode1
Label1:
......
JMP Label2
Db thunkcode2
Label2:
......
//多写几个脏字
2.多层乱序
JMP Label1
Db thunkcode1
Label2:
......
JMP Label3
Db thunkcode3
Label1:
......
JMP Label2
Db thunkcode2
Label3:
......
//把多个脏字套在一起形成一个大脏字(bushi
3.3 - jx/jnx类型
首先介绍汇编语言jz和jnz:
jnz结果不为零(或不相等)则转移。
jz即零标志为1就跳转。
JNZ(或JNE)(jump if not zero, or not equal),汇编语言中的条件转移指令。结果不为零(或不相等)则转移。
3.3.1 - 一个简单的例子
可以看到,0xE8和后面的机器码结合后破坏了IDA的反编译,从而出现爆红的地方
考虑如何去除:
先按快捷键转化为数据,然后把0E8h后面的数据按快捷键c转化为代码即可
3.3.2 - 两个简单的例子
可以发现jnz和jz后面的地址出现了奇怪的+1,先把爆红的地方undefine成数据
发现地址后面的+1已经消失了,出现了0B8h这个垃圾数据,但是如果直接对后面的数据使用快捷键c中的analyze选项发现仍然不能正常反编译
于是对未分析完的数据进行force选项强制转化成代码
4.0 - 待更新
今天列举的也只是花指令的一些皮毛,也算是简单了解了一下最简单的花指令的原理和patch方法,但是非常缺乏实战经验,遇到不一样类型的花指令也很难去除,也不会用插件自动去花,看来还是有很多要学的啊:<
参考资料:
https://blog.csdn.net/zhangmiaoping23/article/details/38400393
https://www.anquanke.com/post/id/208682