花指令与SMC
软件保护措施
一般许多软件有很多保护措施,如静态保护(花指令,加密,加壳,混淆),动态保护(反调试,反虚拟机)
花指令
反汇编原理
1,线性扫描算法
2,递归行进算法
工具 | 反汇编算法 |
---|---|
OllyDbg | 线性扫描算法/递归行进算法(按住“Ctrl +A”组合键时) |
SoftICe | 线性扫描算法 |
WinDBG | 线性扫描算法 |
W32Dasm | 线性扫描算法 |
IDA pro | 递归行进算法 |
常见反汇编工具所使用的反汇编算法
而在一些指令中加入一个字符通常会引起错误的反汇编
1 | __asm { |
_emit是直接插入一个数的写法,而在汇编指令中,e9常常会被认为是jmp的前缀,而反汇编遇到时会将e9以及后面4个字节一共五个字节当作jmp指令处理
而在这个新插入的字节却不会影响原本的程序运行,因为jmp label1为无条件跳转,所以cpu永远不会执行到__emit 0xe9但却会影响到反汇编,这也起到了保护程序正常运行的目的
在反汇编窗口可以看见反编译器将其错误的解析为jmp指令
而对于这种情况,使用递归行进算法的ida可以完美识别
可以看到ida成功的将e9识别为数据
然而这只是最简单的花指令,要骗过ida,因为ida是根据分支跳转,可以把jmp替换为两条互补的条件跳转指令
1 | __asm { |
修改完之后我们再放入ida中看看
可以看到这次ida没有处理成功,因为ida是根据控制指令,去到不同的分支,在不同的分支中再采用线性算法,当遇到jz,jnz时,两种情况ida都需要处理,当ida不跳转时,并紧接着来到了E9的位置并将E9当作jmp指令
SMC技术
SMC全程Self Modifying Code技术,代码自修改技术,也就是说,在一段代码执行之前,可以对其进行修改,一般用来加密核心功能逻辑,也是加壳技术的基础
比如有如下两段代码一段为初始化代码而另一段为加密后代码,用ida打开蓝色代码可以正常看到,而红色部分在ida中则是加密后的16进制数据
如如下一段代码
1 |
|
其中有一个函数encrypt_fun()
1 |
|
这一个函数可以对important_fun进行一个加密操作
运行之后
上面为加密后的字节码,下面为加密前的字节码,而函数smc_test()
1 | void smc_test() { |
这段函数通过VirtualAlloc分配了一段内存,会将加密的这段指令拷贝至内存中,接着利用decrypt_fun函数进行一个解密工作,再通过call指令直接调用这段代码