论坛首页 逆向工程技术区 阅读主题

花指令分析

192 浏览 2 回复
#1 楼主 2026-06-01 21:08:55
花指令:在代码中插入的不影响程序运行的垃圾指令(脏字节),让反编译器无法反编译起到混淆代码的作用。反汇编算法主要可以分为两类:递归下降算法和线性扫描算法。线性扫描算法线性扫描算法p1从程序的入口点开始反汇编,然后整个代码段进行扫描,反汇编扫描过程中所遇到的每条指令。线性扫描算法的缺点在于在冯诺依曼体系下,无法区分数据和代码,从而导致将代码段中嵌入的数据误解释为指令的操作码,一致最后得到错误的反汇编结果。递归下降递归下降采取另外一种不同的方法来定位指令。递归下降算法强调控制流的概念。控制流根据一条指令是否被另一条指令引用来决定是否对其进行反汇编,遇到非控制转移指令时顺序进行反汇编,而遇到控制转移指令时则从转移地址处开始进行反汇编。通过构造必然条件或者互补条件,使得反汇编出错。花指令的名言:构造永恒跳转,插入垃圾数据我们通过在代码中内嵌汇编指令实现插入花指令。在不同的编译器中我们嵌入汇编的格式也不同。主要的编译器分别为msvc和gcc,我们每个例子都会写出两种不同编译器的实现方法。msvc内嵌汇编gcc内嵌汇编常用的脏字节编码构造跳转使插入的垃圾数据不被执行来欺骗反编译器。我们将插入的垃圾数据称为脏字节。下面就是我们插入花指令常用的脏字节。接下来我们介绍常见的花指令实现方式和清除方法。这种 jmp 单次跳转只能骗过线性扫描算法,会被ida识别(递归下降)。msvc 编译器实现gcc 编译器实现我们将程序编译后利用ida打开查看直接f5成功
查看汇编代码,发现了我们插入的花指令。很明显这种花指令无法骗过ida。
和单次跳转一样,这种也会被ida识别。msvc 编译器实现gcc 编译器实现同样ida打开成功f5。查看汇编代码,查看我们插入的花指令。显然这种花指令也无法骗过ida。
这种花指令去除方式也很简单,特征也很明显,因为是近跳转,所以ida分析的时候会分析出jz或者jnz会跳转几个字节,这个时候我们就可得到垃圾数据的长度,将该长度字节的数据全部nop掉即可解混淆。msvc 编译器实现gcc 编译器实现ida打开文件报红,f5反编译不成功。很明显这种花指令骗过了ida。接下来我们进行去除。看到条件跳转到s,则中间的全部为垃圾数据。将其全部nop掉。选中nop掉的数据的那一行,按快捷键c将数据解释为代码。然后选中main函数头部,按p创建函数。然后即可f5反编译。msvc 编译器实现gcc 编译器实现很明显,先对ebx进行xor之后,再进行test比较,zf标志位肯定为1,就肯定执行跳转 s1,也就是说中间0xC7永远不会执行。不过这种一定要注意:记着保存ebx的值先把ebx压栈,最后在pop出来。解混淆的时候也需要稍加注意,需要分析一下哪里是哪里是真正会跳到的位置,然后将垃圾数据nop掉,本质上和前面几种没什么不同。ida打开程序无法反编译,可以看到我们插入的花指令。根据汇编代码判断哪里s1永远不会执行。然后将插入的垃圾数据nop掉。之后选中nop掉的数据的那一行,按快捷键c将数据解释为代码。然后选中main函数头部,按p创建函数。然后即可f5反编译。call之类的本质:push 函数返回地址然后 jmp 函数地址ret指令的本质:pop eip代码中的esp存储的是函数返回地址,对[esp]+8,就是函数的返回地址+8,正好盖过代码中的函数指令和垃圾数据。msvc 编译器实现gcc 编译器实现ida打开看到我们插入的花指令,分析代码,call s直接跳转到s并将下一行代码入栈。则0x83h永远不会被执行,并且将其地址入栈。add指令将栈顶数据即0x83h地址加上8,则栈上地址为0x115e。经过retn指令后,执行流直接跳到0x48h。则不被执行的0x83和0xf3h都是垃圾数据,将它们nop即可。jmp的条指令是inc eax的第一个字节,inc eax和dec eax低效影响。这种共用opcode确实比较麻烦。
msvc 编译器实现gcc 编译器实现这里我们先运行一下程序,发现程序只是用于输出hello world!。通过汇编代码逻辑分析我们发现jmp指令跳转到了loc_1151标签的后一字节处即0x1152。 我们首先通过快捷键u将loc_1151标签处的汇编指令解释为机器码。 然后先将0x1152后面的汇编指令解释为机器码,之后在0x1152处按快捷键c将其解释为汇编代码。可以看到现在的汇编代码符合程序功能,我们通过此判断0xebh到0x48h都是花指令。 我们重新将他们通过快捷键u解释为机器码,然后在0x48h的下面即0x1154处按快捷键c将它们解释为汇编代码。 然后将0xebh到0x48h全部nop掉。 之后选中main函数头部,按快捷键p创建函数。然后即可f5反编译。 我们可以通过将花指令定义为宏来在代码中快速插入花指令。除汇编指令共用之外,上面有3个类别花指令ida无法正常识别所以就只对第一种jnx和jx的花指令进行自动化处理所有的跳转指令,互补跳转指令只有最后一个不同抄大佬的代码参考链接:花指令总结-安全客 - 安全资讯平台 (anquanke.com)参考链接:逆向分析基础 --- 花指令实现及清除_jmp花指令逆向-CSDN博客参考链接:CTF逆向Reverse 花指令介绍 and NSSCTF靶场入门题目复现_花指令原理ctf-CSDN博客#include<stdio.h>

---
来源: 看雪论坛
原文链接: https://bbs.kanxue.com/thread-282725.htm
#2 2026-06-01 21:08:55
跟着大佬学习
#3 2026-06-01 21:08:55
.text:004118C7
汇编指令共用opcode:
.text:004118C7             __$EncStackInitEnd_1:                   ; CODE XREF: _main:__$EncStackInitEnd_1↑j
.text:004118C7 EB FF                       jmp     short near ptr __$EncStackInitEnd_1+1
.text:004118C7             ; -----------------------------------------------------------------
$EncStackInitEnd_1+1跳转的是ff,所以eb就是垃圾指令,然后吧eb手动nop掉就行了

请登录后参与讨论

立即登录 注册账号