常见脱壳方法

预备知识

1.PUSHAD (压栈) 代表程序的入口点,
2.POPAD (出栈) 代表程序的出口点,与PUSHAD想对应,一般找到这个OEP就在附近
3.OEP:程序的入口点,软件加壳就是隐藏了OEP(或者用了假的OEP/FOEP),只要我们找到程序真正的OEP,就可以立刻脱壳。

除了单步调试都选分析代码是比较好


方法一:单步跟踪法

  1. 用OD载入,点“不分析代码!”
  2. 单步向下跟踪F8,实现向下的跳。也就是说向上的跳不让其实现!(通过F4)
  3. 遇到程序往回跳的(包括循环),我们在下一句代码处按F4(或者右健单击代码,选择断点——>运行到所选)
  4. 绿色线条表示跳转没实现,不用理会,红色线条表示跳转已经实现!
  5. 如果刚载入程序,在附近就有一个CALL的,我们就F7跟进去,不然程序很容易跑飞,这样很快就能到程序的OEP
  6. 在跟踪的时候,如果运行到某个CALL程序就运行的,就在这个CALL中F7进入
  7. 一般有很大的跳转(大跨段),比如 jmp XXXXXX 或者 JE XXXXXX 或者有RETN的一般很快就会到程序的OEP。

Btw:在有些壳无法向下跟踪的时候,我们可以在附近找到没有实现的大跳转,右键–>“跟随”,然后F2下断,Shift+F9运行停在“跟随”的位置,再取消断点,继续F8单步跟踪。一般情况下可以轻松到达OEP!


方法二:ESP定律法

ESP定理脱壳(ESP在OD的寄存器中,我们只要在命令行下ESP的硬件访问断点,就会一下来到程序的OEP了!)

  1. 开始就点F8,注意观察OD右上角的寄存器中ESP有没突现(变成红色)。(这只是一般情况下,更确切的说我们选择的ESP值是关键句之后的第一个ESP值)

    image-20200603233002501

  2. 在命令行下:dd XXXXXXXX(指在当前代码中的ESP地址,或者是hr XXXXXXXX),按回车!

    或者点数据窗口中跟随image-20200603233038717

  3. 选中下断的地址这里前面部分随便挑个00都可以

    image-20200603233126679

    ,断点—>硬件访问—>字节。

  4. 按一下F9运行程序

    image-20200603233147265

    有两个return,慢慢步过

    image-20200603233227320

    看到这样的界面,右键分析->从模块中删除分析,成功来到OEP

    image-20200603233310032

    删除断点,右键dump,完事


方法三:内存镜像法

  1. 用OD打开软件!

  2. 点击选项——调试选项——异常,把里面的忽略全部√上!CTRL+F2重载下程序!

  3. 按ALT+M,打开内存镜象,找到程序的第一个.rsrc.按F2下断点,

image-20200603234557621

然后按SHIFT+F9运行到断点,接着再按ALT+M,打开内存镜象,找到程序的第一个.rsrc上面的.text(也就是00401000处),按F2下断点!然后按SHIFT+F9(或者是在没异常情况下按F9),(多按几次),直接到达程序OEP!

image-20200603234256376ps. 壳如果要把原来加密或压缩的代码运行起来就必须要解压和解密原来的代码。这一个过程可以将他看做是对代码段(code段)的写入,一个EXE文件的有code段,data段,rsrc段…依次排列在你的内存空间中,只要你在data断或者rsrc段下内存访问断点,那么中断的时候code段就已经解压完毕了。这时我们再对code段下内存访问断点,不就可以到达OEP了吗? 1.对data段下内存访问断点而中断是因为内存写入中断,目的是断在对对data段的解压时,这时壳要对data段写数据,但是code段已经解压 完毕。
2.对code段下内存访问断点而中断是因为内存执行中断,目的当然就是寻找OEP了


方法四:一步到达OEP

  1. 开始按Ctrl+F,输入:popad(只适合少数壳,包括UPX,ASPACK壳),然后按下F2,F9运行到此处
  2. 当然可能不只有一个popad,所以如果发现在之前就跑飞,Ctrl + L下一个,(其实可以先把所有都打上)
  3. 来到大跳转处,点下F8,到达OEP!

方法五:最后一次异常法

  1. 用OD打开软件
  2. 点击选项——调试选项——异常,把里面的√全部去掉!CTRL+F2重载下程序
  3. 一开始程序就是一个跳转,在这里我们按SHIFT+F9,直到程序运行,记下从开始按SHIFT+F9到程序运行的次数m!
  4. CTRL+F2重载程序,按SHIFT+F9(这次按的次数为程序运行的次数m-1次)
  5. 在OD的右下角我们看见有一个"SE 句柄",这时我们按CTRL+G,输入SE 句柄前的地址!
  6. 按F2下断点!然后按SHIFT+F9来到断点处!
  7. 去掉断点,按F8慢慢向下走!
  8. 到达程序的OEP!

方法六:模拟跟踪法

  1. 先试运行,跟踪一下程序,看有没有SEH暗桩之类,
  2. ALT+M打开内存镜像,找到(包含=SFX,imports,relocations)

内存镜像,项目 30
地址=0054B000
大小=00002000 (8192.)
Owner=check 00400000
区段=.aspack
包含=SFX,imports,relocations
类型=Imag 01001002
访问=R
初始访问=RWE

  1. 地址为0054B000,如是我们在命令行输入tc eip<0054B000,回车,正在跟踪ing。。(或者调试->设置条件)

Btw:大家在使用这个方法的时候,要理解他是要在怎么样的情况下才可以使用。

模拟跟踪法的原理就是模拟你手动的按 F7也就是 StepInto 步入.一般来说如果是压缩壳的话,里面没有什么陷进和一些比较大的循环.这样的话只要 tc eip<XXXX “XXXX”也就是壳段的首地址.这样的话,当EIP的值小于XXXX了,就证明跑完壳的代码段了…自然也就到了.text代码段了

这里我查看内存镜像

image-20200604002211671

chushi的代码段就这么长,让其小于004B0000,步入,直接到了OEP,原因是壳区在源代码前运行,代码段却在源代码后面,所以eip再次到源代码段的时候就是到OEP了


方法七:“SFX”法

  1. 设置OD,忽略所有异常,也就是说异常选项卡里面都打上勾
  2. 切换到SFX选项卡,选择“字节模式跟踪实际入口(速度非常慢)”,确定。
  3. 重载程序(如果跳出是否“压缩代码?”选择“否”,OD直接到达OEP)