笔记单步跟踪法与UPX的脱壳理解
Posted dilexliu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了笔记单步跟踪法与UPX的脱壳理解相关的知识,希望对你有一定的参考价值。
用PEiD查壳

UPX v0.89.6 - v1.02 / v1.05 - v1.22 这个是入门的壳,只是一个简单的压缩壳
用Stud_PE查看PE文件头信息

主要是看一下ImageBase的值 00400000,这是一个16进制数。在后面OD载入后,可以用这个值在内存映像中查看PE文件加载到内存后的情况。 还有EntryPoint的值: 0000E8C0 程序入口
OD载入看内存映像

用OD载入,ALT+M打开这个窗口,就可以看到upx.exe程序加载到内存后的映像,主要有四块,但重要的是区段UPX0和区段UPX1。因为区段UPX0就是原程序压缩后的代码存放区,而区段UPX1就是UPX壳的执行代码。
OD中单步跟踪,找OEP
F8键单步跟踪法,学习了前辈总结的两点:
①程序都向下执行的,所以遇到向上的jump,鼠标配合F4键,跳过向上的jump;

遇到向下的jmp直接F8继续执行。

运行到0040E8E9可以看到这是一个向上跳转,而且通过下边的提示窗口得知这个跳转是已实现的。这时,就需要用鼠标点一下0040E8EB这一行, 也就是跳转的下一行。

再按一下F4键,就可以通过上面向上跳的jump了

※注意:

运行到这里,会遇到一个特殊情况,就是向上jump后面还是一个向上jump,我们可以用鼠标选中0040E974行的jump,再按F4,运行到0040E974行

oh,no~~ 还是向上跳的, 那就老方法,鼠标选中下一行,再按F4?
不行,0040E974行的下一行, 是一个nop指令,而OD是不能在nop上下断点的, 所以要注意。
因此我们可以顺势再向下一行,鼠标选中0040E97C行, 再按F4通过:

②当发生区段间的跳转, 证明程序即将运行到OEP。

运行到上图的位置时, 因为已经到了壳代码区的最尾部了,因为从这个位置到区段的结尾,内存都是00,为空。
在0040EA06行上, 也是一个向上跳转, 但这些还用老方法的时候,就会发现,程序根本就不会暂停在0040EA08行,而是程序直接就运行了。这是因为这个jump向上执行的过程,执行了一个直接跳转到0040EA0E行的指令, 这个可以跟踪一下。所以这里可以鼠标直接选中0040EA0E行,再F4。

执行到这里, 后面是没代码, 而且这个jump很奇怪,没有红线标明会跳转到哪里了?
那是因为这是个长跳,就是长距离的跳转。就很可能是区段间的跳转哦!我可是有证据的:
先把内存映像拿下来:

这行指令是在 0040EA0F行上, 很明显是属于UPX1区段的。
但指令: jmp UPX.004010CC, 明显是属于UPX0区段的哦,是不是从UPX1区段跳转到UPX0区段了!
前辈总结过,区段间跳转,很可能就是进入到OEP的时候,所以我们再F8跟踪下去:

到这里, 就是脱壳后的OEP了。至于我为什么会知道呢?前辈的经验!
找到OEP后,OllyDump把脱壳后程序保存
程序暂停在004010CC行,就可以鼠标在汇编窗右键:

这是一个OllyDump插件,怎么加插件可以百度一下~~~~

在dump的时候,要注意一下入口点地址,一般OD跟踪的都是可以通过EIP作为OEP。
另外就是下边的重建输入表, 对于UPX加壳的, 可以直接使用这里面的, 如果不使用会怎么样,等一下再说。
基本上没什么问题了, 就点击一下【脱壳】按钮进行保存,再运行一下保存后的可以执行文件,测试一下!没问题就OK了。
最后是再用PEiD查一下脱壳后的文件是否脱干净了:

用工具重建输入表
在这里,就不使用OllyDump里的重建输入表功能,一样在不选中重建输入表的情况下脱壳:

这样脱壳出来的文件是不可执行的:

因为在加壳后,程序的输入表都被破坏的,所以很多时候脱壳后都需要修复一下程序的输入表,这里用到的工具叫: Import REC
Import REC的使用
①跟踪到OEP的OD,千万不要关
②运行Import REC,在【选取一个活动进程】下面选取正在脱壳的程序进程, 然后还需要在右边【需要的IAT信息】中,在【OEP】项输入OD跟踪到的OEP, 再点击【自动查找IAT】, 最后点一下【获取输入表】。

因为UPX壳并没有对API进行钩取,所以不用多做其他操作。但在其他一些壳中,壳会对API进行钩取,这时就需要点一下【无效函数】按钮,显示出一些无效函数的列表, 再进行清除就好!
③在完成上面的步骤后, 就可以点击【转储到文件】按钮,会弹出一个选择文件的窗口,这时我们需要选中在OD用OllyDump脱壳出来的文件就行了,再点打开。

④去查看一下, 会多了一个文件,要做测试运行一下并再查一下壳


重建PE文件

到了上面的步骤,其实脱壳的工作都基本上算完成了,但回想一下,加壳后的程序,是有两个比较重要的区段UPX0、UPX1,其实UPX1是存放壳代码的,但脱壳后,壳代码就没用了,那干嘛还留着呢?
在重建PE文件时, 需要用到工具LordPE,先运行LordPE:

运行后,不要把文件拖进来,而是点【PE编辑器】按钮:


打开了需要重建的文件后, 会显示上面的窗口, 这里点右边的区段,再如下操作:

选中需要删除的区段,鼠标右键,在右键菜单中点击【清除区段】,再关闭【区段表】窗口,回到【PE编辑器】窗口, 先点一下【保存】,再点【确认】哦!
此时窗口自动关闭,回到LoadPE, 这里需要点击右侧的【重建PE】按钮:

选中刚刚操作的文件:

就自动重建完成的:

最后, 一定要运行一下做测试! OK~~~~
附件列表
以上是关于笔记单步跟踪法与UPX的脱壳理解的主要内容,如果未能解决你的问题,请参考以下文章