Day10:壳与脱壳(二)
二次断点法、一次断点法、特征查找法(均基于Xdbg)、Dll手动脱壳
寻找OEP的方法(二)
二次断点法
又叫内存镜像法,原理是壳程序解析时会从.rsrc段获取资源,解析后回到代码段,因此可以通过现在.rsrc段设置内存读取断点,然后在代码段(.text/.code)设置内存写入断点来监控壳程序执行。
通常这个方法是基于OllyDbg的,但是从原理出发Xdbg也不是不能用。除了有一步是在OllyDbg中设置忽略所有异常,Xdbg好像没有这个设置选项,但是经过实测是可以用这个方法在Xdbg脱upx壳的。
Upx脱壳示例:
Xdbg载入程序,先在“断点”模块把预设的断点删除,避免程序在非关注的异常处(断点处)停下

然后到“内存映射”模块找到程序的.rsrc(注意所属方为用户),下一次性内存读取断点

shift+F9运行,然后在上方的upx0处下一次性内存写入断点

shift+F9运行,回到“CPU”模块,会发现下方不远处就有一个大跳(隔得有点远截不到eip和大跳的同框图),在大跳前下断点,F9运行到断点处,然后步进就可以到达OEP了
但是有一点奇怪的地方:结合upx的解析原理,upx好像是从upx1段加载数据解析到upx0段的(AI说的,不确定对不对),所以按道理,在upx1处下内存读取断点不是也有类似的监控效果吗?但是实测这样子会跑飞🤔有过一个想法就是,因为在upx1段下了读取断点,壳程序解析前中断了,然后又在upx0段下写入断点,然后按道理应该停在解析然后写入这一步,就是解析了还没写入,或者说刚刚写入一次,那这样也不至于直接调试终止吧🤔
一次断点法(二次断点法plus)
这个方法是基于二次断点法和upx实测出来的,因为根据壳程序解析的原理,最终都会发生向内存写入解析完的数据的操作,所以直接在写入的地方下内存写入断点,这样调试器中断的地方就离OEP不远了(接近壳程序解析的尾声,但还是远到截不到eip和大跳的同框图)
示例
首先,同样要先去掉预设断点

然后在“内存映射”模块给upx0下一次性内存写入断点/给upx1下一次性内存读取断点

shift+F9运行,中断的地方就差不多是壳程序解析写入/开始解析的地方了,在下方大跳前F2断点+F9运行一步到位,然后就可以跳转到OEP了
特征查找法
借助特征指令popad,在程序区域搜索指令,然后下断点运行至此,再接着运行到OEP处
示例:
F9运行到程序区域,此时断在pushad

右键在当前区域搜索命令popad

双击搜索结果跳转,下方不远处就是到OEP的大跳了。直接在jmp前一条指令下断点,F9到此,然后步进

Dll手动脱壳
若出现Dll程序加壳的情况,可以先把Dll程序转化成exe程序,然后使用和exe手动脱壳一样的步骤即可
示例:
用DIE打开Dll程序,可以看到显示加了upx壳

点击“区块”下方的“>”,打开文件结构界面

取消勾选右上角”只读“,然后点击IMAGE_FILE_HEADER,取消勾选”标志“中的”Dll“(图中未取消)

此时可以发现,Characteristics的值变了
然后把dll后缀改成exe就可以按照exe手动脱壳的步骤进行脱壳了
Day10:壳与脱壳(二)