Reverse-花指令
菜鸡的花语就是菜就多练
☝️🤓
🙌🙌🙌🙌
感觉自己是啥都了解一点但是确实啥也不会
什么是花指令?
花指令在我的理解就是垃圾指令,在不影响真实代码中加入一些垃圾代码从而影响反汇编的正常运行,主要是用来影响逆向分析人员的的静态分析的。
简单的花指令
花指令分为两种
- 可执行花指令
- 不可执行花指令
可执行花指令
顾名思义就是可以执行的花指令,在程序运行时执行,并且不会改变寄存器的值,目的增加静态分析的难度。
不可执行花指令
不可执行的花指令通常情况下会反编译的时候报错,这种情况时插入了一些不完整的汇编指令,导致反编译失败。
花指令必须满足的两个特征
- 垃圾数据必须是合法指令的一部分
- 程序运行时,花指令必须位于实际不可执行的代码路径
原理
反汇编算法可以分为两类:
- 递归下降算法、
从程序入口开始进行反汇编,然后对整个代码段进行扫描,反汇编扫描过程中每个遇到的每条指令。
缺点:在芬诺伊曼系结构下。无法区分数据和代码,从而导致代码段嵌入的数据解释为指令的操作码,从而导致反编译失败。
- 线性扫描算法
强调控制流的概念,控制流根据一条指令是否被另一条指令应用决定是否对它进行反汇编,遇到非控制流的指令时顺序进行反汇编,而遇到控制流的转移的指令从转移地址开始进行反汇编,通过构造必然条件或者互补条件,使反汇编失败。
花指令的构造
永恒跳转
最简单的jump指令
1 | jmp LABEL1 |
这种jump单次跳转,只能骗过线性扫描算法,会被ida识别(递归下降)
多次跳转
1 | __asm { |
这种和单次一样也会被识别,可以这样改写
1 | __asm { |
其他构造类型
jnz和jz的互补跳转
1 | __asm { |
跳转指令构造花指令
1 | __asm { |
call&ret构造花指令
1 | __asm { |
解题方法
没有什么特别的好方法,就是区分垃圾数据就行。然后就nop掉就行
还有就是动调,我的理解就是找到最后的判断结果那下断点,然后进行F9即可。
例题
复现一下咯!
donntyousee
2025-全国大学生软件创新大赛软件系统安全赛
怎么说呢?
那道题发现是道ELF文件先常规看一下架构
1 | bbq@ubuntu:~$ checksec chall |
amd64,ida打开
打开后发现时看见有一个ret指令,把他nop掉之后
可以看见mian函数
这里看一下这两个函数
这里不直接看反汇编建议,直接看流程图,这里调用了r8寄存器里的地址,我们跟踪过去看看
但是遇到同样的ret指令,我们把它去掉就行了
然后我们跟踪一下这个函数
看这个函数和上面的rc4也很明显,找到密钥和密文即可,最下面的sub_405CAA
函数是主要逻辑
看见密文了
简单提取一下
1 | data=[0x25,0xCD,0x54,0xAF,0x51,0x1C,0x58,0xD3,0xA8,0x4B,0x4F,0x56,0xEC,0x83,0x5D,0xD4,0xF6,0x47,0x4A,0x6F,0xE0,0x73,0xB0,0xA5,0xA8,0xC3,0x17,0x81,0x5E,0x2B,0xF4,0xF6, 0x71,0xEA, 0x2F, 0xFF, 0xA8, 0x63, 0x99, 0x57] |
异或也是常见的了
最主要的就是找密钥了
找到在这
去花之后,看见
密钥存在
但是这里有一个踩坑点,这里有一个反调试,这里看见的密钥不是最终的,而是静态编译下的密文
这样的话,密文就找到了
1 | KEY= [0x92, 0x1C, 0x2B, 0x1F, 0xBA, 0xFB, 0xA2, 0xFF, 0x07, 0x69,0x7D, 0x77, 0x18, 0x8C] |
然后正常解就行了。
这里是用了厨子
dart{y0UD0ntL4cKg0oD3y34T0F1nDTh3B4aUtY}
怎么说呢?
Rafflesia-pcb2024
这是道花指令的题
由于好久没逆了,本来就菜结果跟不会了,还是跟着复现了一手
打开之后很明显的花指令
so,我们nop一手
反编译成功后是有个base编码和加了个异或0x18的问题
但是问题肯定不会这么简单
SO,在我们动调的时候就发现了,肯定是还有东西的
函数栏里找到callback函数
在nop一手
遇到JZ的时候换一手就可以了
导航图动调一手就可以发现有一个换表的过程
最后直接换表就行了
参考文献: