week2-re-花指令
Week2-re
花指令
就是脏代码
有不可执行花指令和可执行花指令
通常在 ida 中表现为爆红的部分,就像这次校赛中的 hua
利用反汇编算法的缺陷(线性扫描算法,递归进行算法)
关于构造
通过构造必然条件或者互补条件使反汇编出错
简单 jmp
只能骗过线性扫描算法,ida 能够正常识别
多层跳转
多了几层跳转,和 jum 差不多
可以将花指令进行改写,让 ida 错误识别,达到目的
jnx 和 jx 条件跳转
利用 jz(当 零标志位(ZF)为 1 时跳转)和 jnz(当 零标志位(ZF)为 0 时跳转)的互补条件跳转指令代替 jmp
通常在去除的过程中可以看到很明显的标志(像 jz 和 jnz 这样)分析得到 jz 和 jnz 的长度,然后全部 nop 掉
永真(永假)条件跳转
这种情况下程序一定会一直执行(就是没有被 ida 识别出来)
ida 反汇编优先反汇编 false 分支部分,调用某些函数返回确定值,来构造永真或永假条件
call&ret 构造花指令
利用 call 和 ret,在函数中修改返回地址,从而跳过 thunkcode 到正常流程,干扰 ida 正常识别。
call 指令:将下一条指令地址压入栈,再执行跳转。
ret 指令:将保存的地址取出,跳转执行。
例题
[NSSRound#3 Team]jump_by_jump
反汇编进入后,在 main 处按 U
再将 E8 改为 90
再向上找到 main 函数
按 P
获得 flag NSSCTF{Jump_b9_jump!}
[NSSRound#3 Team]jump_by_jump_revenge
进反汇编
选中 jmp near ptr 0C086A4CCh
,使用快捷键 D 转换为硬指令:
选中 db 0E9h
,右键 > Patching > Change byte,将开头的 E9 改为 90
选中 db 90h
,按快捷键 C 将硬指令转换为代码
在 main_0
函数起始处按快捷键 P,重新生成函数
解除花指令
这个时候 main 函数已经被成功修复
进入 main_0 函数后
看到 if ( !j_strcmp(Str1, "~4G~M:=WV7iX,zlViGmu4?hJ0H-Q*") )
所以 str1 还原后就是 flag
这个利用脚本来完成
1 | cipher = '~4G~M:=WV7iX,zlViGmu4?hJ0H-Q*' |
运行后得到 flag NSSCTF{Jump_b9_jump!_r3V3n9e}
[GFCTF 2021]wordy
打开进入反汇编
我们需要先找到如何使花指令变为正常指令
我们先随意挑选一行,右键 Patch,修改前两个字节为 90,有其中的一行修改后 mov 变成 jmp,那么这个 EB 就是我们需要修改的地方,一个一个找太麻烦了,直接利用 idapython 脚本来处理
1 | start = 0x1144 |
这样就把所有的 EB 修改为 90 了
然后找到 main 函数,按 P 重新创建函数,按 F5 进入函数,但是我们发现运行出来不对,看到 You didn't find Flag
我们重新进入反汇编,
1 | mov dword ptr [rbp-4], 0 |
把这一段 nop 掉
最后 main 函数是这样的两个部分
当 v4
为真(非零)时,程序会输出 G F C T F { ... }
格式的 Flag,否则输出 You didn't find Flag
。