(不定期更新)
记录一些赛时和做题时遇到的花指令……

1. 无用跳转

这种花指令形如下图

image-20210830185219866

存在花指令的情况下,IDA无法正常反汇编出伪代码

image-20210830184951386

分析逻辑

// ……
.text:00401C5E  jmp     short loc_401C6E
.text:00401C5E ;   } // starts at 401BE4
.text:00401C5E ; } // starts at 401B90
.text:00401C5E _main           endp ; sp-analysis failed
.text:00401C5E
.text:00401C60
.text:00401C60 ; =============== S U B R O U T I N E =======================================
.text:00401C60
.text:00401C60
.text:00401C60 ; void __usercall sub_401C60(int@<ebp>)
.text:00401C60 sub_401C60      proc near               ; CODE XREF: _main+EB↓p
.text:00401C60                 add     esp, 4
.text:00401C63                 mov     eax, [ebp-3Ch]
.text:00401C66                 add     eax, 1
.text:00401C69                 mov     [ebp-3Ch], eax
.text:00401C6C                 jmp     short near ptr loc_401C80+1
.text:00401C6C sub_401C60      endp ; sp-analysis failed
.text:00401C6C
.text:00401C6E ; ---------------------------------------------------------------------------
.text:00401C6E ; START OF FUNCTION CHUNK FOR _main
.text:00401C6E
.text:00401C6E loc_401C6E:                             ; CODE XREF: _main+CE↑j
.text:00401C6E ; __unwind { // _main_SEH
.text:00401C6E                 jz      short near ptr loc_401C72+1
.text:00401C70                 jnz     short near ptr loc_401C72+1
.text:00401C72
.text:00401C72 loc_401C72:                             ; CODE XREF: _main:loc_401C6E↑j
.text:00401C72                                         ; _main+E0↑j
.text:00401C72                 call    near ptr 48D4DDh
.text:00401C77                 xor     ax, 7
.text:00401C7B                 call    sub_401C60
.text:00401C80
.text:00401C80 loc_401C80:                             ; CODE XREF: sub_401C60+C↑j
.text:00401C80                 call    near ptr 8BE06210h
.text:00401C85                 dec     ebp
.text:00401C86                 les     ecx, [ecx-0FB7A74h]
.text:00401C86 ; } // starts at 401C6E
.text:00401C86 ; END OF FUNCTION CHUNK FOR _main
.text:00401C86 ; ---------------------------------------------------------------------------
.text:00401C8C                 db 2 dup(0FFh)
.text:00401C8E ; ---------------------------------------------------------------------------
.text:00401C8E ; START OF FUNCTION CHUNK FOR _main
.text:00401C8E
.text:00401C8E loc_401C8E:                             ; CODE XREF: _main+AE↑j
.text:00401C8E ; __unwind { // _main_SEH
.text:00401C8E                 

正常情况下,汇编的执行顺序由上而下,而这里花指令添加的起点在于地址00401C5Ejmp short loc_401C6E指令

跳转至loc_401C6E后,我们发现2条冲突的跳转指令jz short near ptr loc_401C72+1jnz short near ptr loc_401C72+1,很明显这两条必有其一跳转且跳转的地址相同。

到了loc_401C72后,发现call指令是错误的,按下U,IDA直接帮我们筛出了垃圾代码0E8h

image-20210830190014432

执行到下一个call,运行了函数sub_401C60,看到最后又跳转到了loc_401C80+1,此时手动将00401C80中的花指令去除

image-20210830190521363

正是跳转到了loc_401C81,接下来执行了正常的流程

于是可以断定,从00401C5E00401C72这一段都是花指令

我们直接使用KeyPatch或IDAPython去除

(patch脚本参考[IDA脚本专题](..\IDA脚本\IDA Python.md))

去除后

image-20210830194028020

2. 栈址爆炸

image-20210830195107012

形如add rsp, xxxxxxxh的指令,会导致栈过大,patch即可

3. 虚假跳转

WMCTF2021 - Re1

image-20210831131629476

我们知道ebp寄存器是基址指针寄存器(extended base pointer),存放一个指针,这个指针永远指向系统栈最上面一个栈帧的底部。

显而易见ebp断然不可能等于6FDh,因此经过jnb指令之后,将跳转到00140003050处执行,也就是00140003011~00140003050,这一段并不会执行。

当我们查找引用时,会发现有指令进行cmp

image-20210831132123436

U之后,会发现IDA自动将其转换成了DOWRD

那只需要patch这一部分

.text:0000000140003009                 cmp     ebp, 6FDh
.text:000000014000300F                 jnb     short loc_140003050
.text:0000000140003011                 db      2Eh
.text:0000000140003011                 nop     word ptr [rax+rax+00000000h]
.text:000000014000301B                 nop     dword ptr [rax+rax+00h]
.text:0000000140003020                 add     rsp, 4489FFDEh
.text:0000000140003027                 nop     word ptr [rax+rax+00000000h]
.text:0000000140003030                 and     [rax+rdx*4-79h], edx
.text:0000000140003030 ; ---------------------------------------------------------------------------
.text:0000000140003034 dword_140003034 dd 556E2853h            ; DATA XREF: main+20DA↓r

jnb指令patch为jmp

0000000140003009~0000000140003030的其他指令patch为nop即可正常F5

image-20210831132745036

不知出处 - rev3

image-20210906215250336
.text:004016E8                 call    sub_402CA0
.text:004016ED                 push    eax
.text:004016EE                 xor     eax, eax
.text:004016F0                 jz      short loc_4016F4
.text:004016F0 ; ---------------------------------------------------------------------------
.text:004016F2                 db 0E9h
.text:004016F3                 db 0EDh
.text:004016F4 ; ---------------------------------------------------------------------------
.text:004016F4
.text:004016F4 loc_4016F4:                             ; CODE XREF: .text:004016F0↑j
.text:004016F4                 pop     eax
.text:004016F5                 mov     ecx, 5
.text:004016FA                 mov     dword ptr [ebp-94h], 0

很明显eax入栈出栈对称,异或本身即为0

patch完之后就正常显示