0x00 花指令概念

花指令是企图隐藏掉不想被逆向工程的代码块(或其它功能)的一种方法,在真实代码中插入一些垃圾代码的同时还保证原有程序的正确执行,而程序无法很好地反编译, 难以理解程序内容,达到混淆视听的效果。
简单的说就是在代码中混入一些垃圾数据阻碍你的静态分析。

0x01 花指令分类

可执行花指令

1.可执行花指令指的是这部分花指令代码在程序的正常执行过程中会被执行,但执行这些代码没有任何意义,执行前后不改变任何寄存器的值(当然eip这种除外),同时这部分代码也会被反汇编器正常识别。
2.首先,花指令的首要目的依然是加大静态分析的难度,让你难以识别代码的真正意图;然后,这种花指令可以破坏反编译的分析,使得栈指针在反编译引擎中出现异常。(当然我们知道栈指针实际上是没有问题的,只不过反编译引擎还有待完善的空间)

不可执行式花指令

  1. 花指令虽然被插入到了正常代码的中间,但是并不意味着它一定会得到执行,这类花指令通常形式为在代码中出现了类似数据的代码,或者IDA反汇编后为jmupout(xxxxx)。
  2. 这类花指令一般不属于CPU可以识别的操作码,那么就需要在上面用跳转跳过这些花指令才能保证程序的正常运行。

0x02 花指令的实现

c语言加花指令,花指令的应用_天眼查的博客-CSDN博客

简单jmp

能骗过OD ,但IDA采用递归扫描能够正常识别

1
2
3
4
5
6
7
8
9
10
#include<stdio.h>
int main() {
__asm{
jmp label1;
__emit 0xe8;
label1:
}
printf("Hello World!");
return 0;
}

多级jmp

本质上和简单jmp一样,只是多了几层跳转,仍旧无法干扰IDA

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<stdio.h>
int main() {
__asm{
start://花指令开始
jmp label1;
__emit 0xe8;
label1:
jmp label2;
__emit 0xe8;
label2:
jmp label3;
__emit 0xe8;
label3:
}
printf("Hello World!");
return 0;
}

简单加花

在IDA中反汇编错误,在w32dasm中反汇编错误,但是在OD中反汇编正确

1
2
3
4
5
6
7
8
9
10
11
void Function()
{
_asm jz label
_asm jnz label
_asm __emit 0e8h //e8是call指令
label:
Input++;
Output++;
Input+=Output;
printf("函数结果:%d,%d",Input,Output);
}

复杂加花

加花后,IDA与OD均反汇编错误

类似于加壳
1.  记录程序的原入口点,
2.  找到PE文件的空白区域,在空白区域内写入花指令(或者添加新节)
3.  把入口点地址改为新入口地址
4.  花指令执行完后跳转到原入口点地址
在程序执行时,程序将从新的入口地址执行,即花指令先被执行,然后再执行程序原来的入口地址功能。
增加了静态分析的难度,提高了代码的信息隐藏效果,该方法一般应用于病毒的免杀中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void Function()
{
_asm xor eax,eax
_asm test eax,eax
_asm jz label1
_asm jnz label0
label0:
_asm __emit 0e8h
label1:
Input++;
Output++;
Input+=Output;
printf("函数结果:%d,%d",Input,Output);
}

0x03 花指令的清除

手动清除

找到所有的花指令,重新设置数据和代码地址,或者将花指令设置为nop(0x90)