花指令
花指令
概念
花指令,junk code
,也就是垃圾代码。实际上花指令的确是一些不影响程序逻辑的垃圾机器码,它存在的唯一意义就是干扰反汇编引擎和人为分析
花指令在真实代码中插入一些垃圾代码的同时还保证原有程序的正确执行,而程序无法很好地反编译,难以理解程序内容,达到混淆视听的效果,因此在程序的静态分析对抗中可以起到效果(也包括使re题变复杂
分类
花指令大致可以分为可执行花指令和不可执行花指令两类
可执行花指令
可执行的花指令本质是将指令的组成部分重新解释执行,这种花指令可以破坏反编译的分析,使得栈指针在反编译引擎中出现异常
不可执行花指令
这种花指令本质上是在跳转指令之后插入一个多字节指令的字节,欺骗反汇编器将这个字节之后的几个字节当成一个多字节指令解释,进而造成后续指令反汇编出错,而这部分花指令代码在程序的正常执行过程中不会被执行
构造与patch
反汇编算法
常见的反汇编算法有两类,一类是线性扫描反汇编,对输入的数据逐字节翻译成汇编代码,因此简单地在jmp
后插入0xe8
(0xe8
是call
指令的机器码)就能骗到
另一类是递归下降反汇编,是一种基于控制流分析的算法,这类算法优先反汇编可达的代码,例如IDA。针对这类算法,可以通过设置永真或者永假条件,导致程序一定会执行,因为ida反汇编会优先反汇编接下去的部分(false分支)
其它更加详尽的花指令构造方法,这里引路大佬的文章
构造案例
我在学习花指令知识时看到的一个很好的例子
patch的方法-NOP
上图是一个典型的不可执行花指令(call
指令的地址不存在),而且这里就是我们上面提到的经典的在jmp
后插入0xe8
构造花指令的方法,我们将两条指令化为机器码看得更清楚(右键Undifine或快捷键U)
0x75
是jnz
的机器码,0xe8
是call
的机器码
对付这种花指令,可以将jnz
这个无效跳转直接nop掉(右键nop),至于call
指令的部分不要这样,下面详述
例题-[HDCTF2019]Maze
其实上面的图来源于一道re题
前面upx脱壳的过程略,ida打开
看到标红地方是一个典型的不可执行花命令,这个数据明显不是地址,而且很有可能是指令,所以先不要直接nop
上面是一个没有用的跳转,那就把2C处的jnz
给nop掉
2E处转为code(方法上文有),发现果然2F处是一个pop,并且下面一堆被IDA未识别的数据也一起转为指令了
此时数据地址是红色的,选中_mian
函数头,快捷键P将其声明为函数,F5查看伪代码并分析
是个走迷宫的题啦~