前两篇文章介绍了两种加花的方法

  1. call $+5等技巧获得当前EIP,并跳转到指令中间
  2. 子函数劫持父函数流程

本文介绍一些更复杂的jxx,各种迷惑反汇编引擎的花式patch技巧

失败的尝试

先吐槽一下,jz&jnz跳转到同样的地址,形如

这个技巧根本就对抗不了IDA的反汇编引擎,线性扫描算法递归下降算法已经有所了解,但是各种资料都会提到这个做法,我这里尝试了根本就没用,不知道是不是我的打开方式不对

除非jz&jnz又跳转到之前提过的EB花指令上,但这也没有什么新意

jmp到jmp+1

首先我们在一堆noppatch EB FF,效果如下

jmp的指令位于地址0x140001018,而跳转到的指令是0x140001019,跳转到了jmp指令中间

接下来我们利用FF做一些手脚,比如改成序列EB FF C0

注意到FF C0表示的是inc eax

再在之后添加FF C8,也就是dec eax

IDA中如图

这里我手动把0xEB看作了数据,但实际上这样会导致IDA的栈平衡分析失败

动态调试

这样的实际跳转流程是:

  1. jmp => jmp+1

  1. inc eax
  2. dec eax

可以看到,动态调试时会暴露花指令所有的细节,但是想让IDA F5就不像之前按一下d视作数据一样了

如果把地址jmp+1看作代码,那么一定会破坏原来的jmp指令,似乎陷入了尴尬的境地...

不过本程序因为只是单一技巧的示例,我们人工分析后发现这三条指令其实什么也没干

把原先的EB FF C0直接nop三连即可

更复杂的布局

  1. mov ax,05EBH,再XOR eax,eax,一般来说不会有什么影响,只是清零了EAX

    其中有一个EB,是我们布局的关键

  2. patch 74 FA,相当于jz jz-6,跳转到刚才的EB上,如图

0x140001005+2看作代码

和刚才一样,这里简单的按d识别数据会破坏jmp指令

  1. 0x14000100D的指令再改成迷惑反汇编器的EB

动态调试

patch好之后,用IDA重新打开,画风很诡异

在这里下断点后

跳转到0x7FF6466B1007

再按一下c,识别成代码,跳转到原执行流EB 05也就是跳转到下一条指令地址 + 5的地址

去花

因为没有加反调试,动调不难发现花指令的执行逻辑,直接nopN连即可

IDAPythonpatch代码如下

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,不过应该也差别不大

点击收藏 | 1 关注 | 1 打赏
  • 动动手指,沙发就是你的了!
登录 后跟帖