转自:https://xz.aliyun.com/t/4972
前两篇文章介绍了两种加花的方法
- 用
call $+5
等技巧获得当前EIP,并跳转到指令中间
- 子函数劫持父函数流程
本文介绍一些更复杂的jxx
,各种迷惑反汇编引擎的花式patch
技巧
失败的尝试
先吐槽一下,jz
&jnz
跳转到同样的地址,形如
这个技巧根本就对抗不了IDA的反汇编引擎,线性扫描算法和递归下降算法已经有所了解,但是各种资料都会提到这个做法,我这里尝试了根本就没用,不知道是不是我的打开方式不对
除非jz
&jnz
又跳转到之前提过的EB
花指令上,但这也没有什么新意
jmp到jmp+1
首先我们在一堆nop
里patch EB FF
,效果如下
jmp的指令位于地址0x140001018
,而跳转到的指令是0x140001019
,跳转到了jmp指令中间
接下来我们利用FF
做一些手脚,比如改成序列EB FF C0
注意到FF C0
表示的是inc eax
再在之后添加FF C8
,也就是dec eax
IDA中如图
这里我手动把0xEB
看作了数据,但实际上这样会导致IDA的栈平衡分析失败
动态调试
这样的实际跳转流程是:
- jmp => jmp+1
- inc eax
- dec eax
可以看到,动态调试时会暴露花指令所有的细节,但是想让IDA F5就不像之前按一下d
视作数据一样了
如果把地址jmp+1
看作代码,那么一定会破坏原来的jmp
指令,似乎陷入了尴尬的境地...
不过本程序因为只是单一技巧的示例,我们人工分析后发现这三条指令其实什么也没干
把原先的EB FF C0
直接nop
三连即可
更复杂的布局
-
先mov ax,05EBH
,再XOR eax,eax
,一般来说不会有什么影响,只是清零了EAX
其中有一个EB
,是我们布局的关键
-
再patch 74 FA
,相当于jz jz-6
,跳转到刚才的EB
上,如图
把0x140001005+2
看作代码
和刚才一样,这里简单的按d
识别数据会破坏jmp
指令
- 把
0x14000100D
的指令再改成迷惑反汇编器的EB
动态调试
patch
好之后,用IDA重新打开,画风很诡异
在这里下断点后
跳转到0x7FF6466B1007
再按一下c
,识别成代码,跳转到原执行流EB 05
也就是跳转到下一条指令地址 + 5
的地址
去花
因为没有加反调试,动调不难发现花指令的执行逻辑,直接nop
N连即可
用IDAPython
的patch
代码如下
def NopBytes(start, length):
for i in range(0, length):
PatchByte(start + i, 0x90)
MakeCode(start)
NopBytes(addr, n)
补充
一般花指令都是有规律可以找的,找到以后nop
即可
写到这里,在想有没有简单nop
不能轻松处理的,比如本文提到的会破坏原先的jmp
如果程序中本来就有合适的jmp
系列指令,比如EB xxx
,跳转到原程序流程上,再根据这段偏移构造我们自己的代码块,可能会稍微复杂一些,因为不能直接把必要的原程序直接nop
,不过应该也差别不大