selph
selph
发布于 2022-07-12 / 302 阅读
1
0

脱壳基础:手工方法学习笔记

本文主要是基于参考资料[1]视频学习笔记,部分描述来自参考资料[2]别人的整理

主要在x86dbg中进行实验,其中有些方法貌似是只有在OD中才有(已标注是OD方法)

脱壳方法整理

对于不同语言写的程序,OEP长的样子不一样,可以使用同语言写个Demo,来看看长什么样

1. ESP定律

exe程序执行的正常流程如下:1. 初始化CRT环境,2. 运行用户函数,3. 清理CRT环境;用户程序是中间某一个步骤进行调用的函数,如果程序要正常运行,那么就需要在该函数调用前后保证栈的位置不变,不然会影响到函数返回导致奔溃

在一些壳的代码中,会在栈中保存(例如pushad)一些内容(寄存器环境),在最后恢复PE完成之后再还原(popad)

如果在栈中pushad保存的数据只有在解压完成之后popad的时候才会被访问到,所以只需要在pushad指令执行后,对入栈的一个地址下访问断点,然后运行,即可在最后恢复寄存器环境的时候断下来,然后就可以手动跳转到真正的入口点,借助x86dbg的插件syclla进行dump和PE修复,即可完成脱壳

2. 单步跟踪

有时候没法ESP定律直接脱,就需要单步跟踪来处理,一步一步跟踪到OEP

因为壳的代码处理完一定会跳转到OEP上去执行,只要知道OEP长什么样,就知道什么时候跳转到了OEP上

不断单步步过,遇到call跑飞了,就进入call继续单步步过,对于向上的跳转不用跟入,直到走到OEP

3. 两次断点

调试器设置,忽略全部异常

第一次断点:模块的.rsrc段下个F2断点

然后shift+F9,运行无视首个断点

然后下第二个断点:解码段地址下F2断点

然后shift+F9,运行无视首个断点

接下来使用单步跟踪法,找OEP

4. 最后一次异常

调试器设置,不忽略所有异常

shift+F9进行运行,记录异常的次数,重新载入,然后跳转到最后一次异常触发的地方,找到异常处理程序地址,下断点,从这个断点处单步跟踪找OEP

5. SFX(OD)

OD中的方法,步骤:

  1. 将OD设置为忽略所有异常;
  2. 在OD的“调试选项”对话框的“SFX”选项卡中选择“字节模式跟踪实际入口”选项并确定;
  3. 将待脱壳程序载入OD,待程序载入完成后,会直接停在OEP处。

6. 模拟跟踪(OD)

OD中的方法,指的时模拟单步跟踪来进行查找OEP。

通常的方法:

  • 将待脱壳程序载入OD中,先简单的跟踪一下程序,看看有没有SEH暗桩;
  • 使用两次断点法,断到第二次断点的位置去继续操作(不然分析量太大,就会很慢)
  • 按键盘上的“ALT+F9”打开OD的内存窗口,找到“SFX,输入表,资源”的行,并记录此行的内存地址;
  • 在OD的命令行窗口执行命令“tc eip<上一步中记录下的地址”,命令执行后就会跟踪到OEP。

7. 出口标志

明显的出口标志是popad,之后不远处就会跳转到OEP,所以通过搜索所有的popad指令,找到后面有大跳转的那个地方,去找OEP

可能可以查到一堆,可以一个一个试,如果执行不到,说明可能不是

x86dbg操作:右键,搜索,当前区域,命令,popad

8. 秒到OEP

啥也不管,直接运行,让程序解压解密结束,然后正常执行

接下来把堆栈窗口拉到最底下,从调用堆栈中找到OEP函数调用的地址,记下地址

然后重新调试,然后硬件断点断在OEP,进行脱壳

参考资料


评论