花指令
一、花指令概述
1.概念:花指令是,由设计者特别构思,希望使静态反汇编的时候出错,让破解者无法清楚正确地反汇编程序的内容,迷失方向。
2.分类:分为可执行式与不可执行式
可执行式:就是能够执行这些花指令,但执行这些代码没有任何意义,执行前后不改变任何寄存器的值(当然eip这种除外),同时这部分代码也会被反汇编器正常识别。
这种花指令的目的就是:
(1)增大逆向者的工作量,可能一串代码看了很久,到最后分析出来没有任何用处。
(2)然后,这种花指令可以破坏反编译的分析,使得栈指针在反编译引擎中出现异常例如
sub_411880 endp ; sp-analysis failed
不可执行类:是这部分花指令代码在程序的正常执行过程中不会被执行
目的:
就是会导致在IDA里面查看是看到一些不正确的汇编指令
3.实现原理:或者说是为什么加了某些花指令,就会反编译不了,主要还是因为,一些反编译工具,如IDA采用的是线性反编译。文件都是二进制构成的,一部分二进制转换为十六进制,就是所谓的机器码,而机器码就可以转换为对应的汇编指令,如
55就相当于push ebp
8B EC就相当于mov ebp,esp
E8 ??????就相当于跳转指令
而现在IDA采用线性扫描,就是一个个读取机器码,或者读取几个机器码然后输出其对应的汇编指令。现在思考,如果我向一串机器码中插入一个垃圾机器码,是不是IDA就可能输出错误的汇编代码,导致反编译失败。而这些垃圾机器码就是我们加上的花指令。
4.添加花指令原则:
(1)一定不会影响整个程序的运作。
(2)构造永恒跳转,添加垃圾数据!
二、一些准备工作
1.什么是内敛汇编
_asm
{
push ebp
mov ebp,esp
sub esp,3D
}
大括号里面就用来写汇编代码。
2._emit 立即数
_emit e8
_emit c3
这个就是用来插入垃圾代码的。
3.一些IDA的功能使用
(1)查看机器码和栈顶指针
(2)改机器码或者栈顶,这个就调试的时候在介绍了。
(3)d键,c键,p键,这个也在调试的时候说了。
三、开始调试各种含有花指令的文件
1.样本1
源代码如下
#include<stdio.h>
#include<windows.h>
int main()
{
printf("hello!");
__asm {
xor eax,eax
test eax,eax
je LABEL1
jne LABEL2
LABEL2:
_emit 0x5e
and eax,ebx
_emit 0x50
xor eax,ebx
_emit 0x74
add eax,edx
LABEL1:
}
printf("world");
return 0;
}
放到IDA里面分析。
按d键后。
nop机器码,圈住机器码的开头然后点击Edit—Patch program—change byte
注意还要,将原来d键后的位置,按c键重新分析一下,才能在函数开头按p键。
去花后
2.样本2
源代码如下
#include<stdio.h>
int main(void)
{
int a=1;
printf("hello ");
if(a==0)
{
_asm
{
_emit 0xe8;
_emit 0xc3;
}
}
else
printf("world");
return 0;
}
调试过程如下
按了d键,c键展开,重新布局之后
nop后,按p键,就可以f5看伪代码了。
3.样本3
源代码如下
#include<stdio.h>
#include<windows.h>
int a=1;
int main()
{
printf("hello!");
__asm {
push eax;
xor eax, eax;
test eax, eax;
jnz LABEL1;
jz LABEL2;
LABEL1:
_emit 0xE8;
LABEL2:
mov byte ptr[a], 0;
call LABEL3;
_emit 0xFF;
LABEL3:
add dword ptr ss : [esp] , 8;//这里的8是经过调试而得,使执行ret指令时正好到达mov byte ptr[a], 2;,而掩盖_emit 0xFF;__emit 0x11;这两个垃圾值。
ret;
__emit 0x11;
mov byte ptr[a], 2;
pop eax;
}
printf("world");
return 0;
}
调试过程
看机器码
然后用d键和c键使整个逻辑看起来清晰一些。这个过程可以用另一个软件dbg来看一些垃圾代码,因为在dbg里面每执行一步就可以看到正确的语句,就可以看到正确的机器码,然后挑出垃圾代码。
然后c键重新分析,然后p键,发现下半段会有个sp-analysis failed
既然这样就直接把那个call loc_40104C后面一部分全部nop了,也不会对整个流程产生影响。
然后p键,就发现可以f5看伪代码了。