汇编语言其实就是机器指令的符号化,从某种程度上看,它只是更容易理解一点的机器指令而已。每一条汇编语句,在汇编时,都会根据 cpu 特定的指令符号表将汇编指令翻译成二进制代码。
反编译可以将一个二进制程序反汇编成汇编代码。机器的一般格式为:指令+数据。
反汇编的大致过程是:首先会确定指令开始的首地址,然后根据这个指令字判断是哪个汇编语句,然后再将后面的数据反汇编出来。在这一步的反汇编过程中存在漏洞:如果有人故意将错误的机器指令放在了错误的位置,那反汇编时,就有可能连同后面的数据一起错误地反汇编出来,这样,看到的就可能是一个错误的反汇编代码。这就是 “花指令”,简而言之,花指令是利用了反汇编时单纯根据机器指令字来决定反汇编结果的漏洞。
花指令:(junk code) 意思是程序中有一些花指令,是一堆汇编指令组成,对于程序来说,是一堆废话,加不加花指令都不影响程序的正常运行,编写的花指令要终始保持堆栈的平衡。为了使反汇编的时候出错,让破解者无法清楚正确地反汇编程序的内容,迷失方向。经典的是一些跳转指令,目标位置是另一条指令的中间,这样在反汇编的时候便会出现混乱。花指令有可能利用各种 jmp, call, ret, 一些堆栈技巧,位置运算等。
去除花指令,跟去除混淆不一样,花指令只是一些迷惑的语句,混淆可能包含的更多一些。
花指令是企图隐藏掉不想被逆向工程的代码块(或其它功能)的一种方法,在真实代码中插入一些垃圾代码的同时还保证原有程序的正确执行,而程序无法很好地反编译, 难以理解程序内容,达到混淆视听的效果。
简单的说就是在代码中混入一些垃圾数据阻碍你的静态分析。花指令的首要目的依然是加大静态分析的难度,让你难以识别代码的真正意图,然后,这种花指令可以破坏反编译的分析,使得栈指针在反编译引擎中出现异常。
花指令分类:花指令大致可以分为可执行花指令和不可执行花指令两类:
1.可执行花指令指的是这部分花指令代码在程序的正常执行过程中会被执行,但执行这些代码没有任何意义,执行前后不改变任何寄存器的值(当然eip这种除外),同时这部分代码也会被反汇编器正常识别。
2.不可执行花指令指的是这部分花指令代码在程序的正常执行过程中不会被执行,不可执行花指令是利用反汇编器线性扫描算法的缺陷使得静态分析的时候会看到一些错误的代码。
去花指令
1.动态调试可以发现不可以执行的花指令。
写花指令的原则:
1.写花指令的基本原则就是要保持堆栈的平衡。
写花指令细细品味下面一段比喻:
把一段花指令比喻成一道数学运算题,把汇编指令(push pop等)比喻成加减乘除,把寄存器或数据(eax,ebx,1等)比喻成数字(1,2,3等),那么要保持花指令堆栈的平衡,等于保持这道数学题的结果是0。