初步认识手脱upx壳
手脱upx壳
手脱upx壳
工具准备:xdbg32,ExeinfoPE
前言:因为我们在CTF中经常会遇见upx壳,在有些题中我们无法直接通过工具进行脱壳,这时我们就需要进行手脱upx壳来进行逆向分析了。
以BUUCTF中新年快乐.exe为例(本题可以直接upx -d进行脱壳)进行说明:
首先我们ExeinfoPE看一下exe的基本信息:
发现是32位的upx壳,我们将它用xdbg32打开:
F9运行到入口(可以设置入口断点方便一点:在xdbg上方”选项“中选择”选项“,里面就有入口断点的设置):
第一步
首先要找到OEP去壳后的程序起点。这里常用的有三个方法:
一:我们可以看有大跳转的地方:
我们直接看E9跳转的地址就是我们要找的OEP了,不过这个方式很多壳我们是没有办法找到的。
二:根据ESP定律设置硬件断点(ESP定律:是计算机用语,意思是向堆栈中压入下一行程序的地址,其实就是会出现很多pushad):
我们在这里设置一个断点,再F9运行就会程序断在恢复原状态的popad位置,之后我们运行过去,就可以找到OEP。
三:通过内存断点找到OEP。
内存断点是通过修改页的属性来将程序断下来。这种方法由于你修改了页的属性在壳运行的时候你会收到很多异常。需要通过调试越过这些异常最后到达OEP。
第二步:dump数据
原因:因为程序在计算机中运行时,在内存、CPU、I/O等设备上的数据都是动态的(或者说是易失的),也就是说数据使用完或者发生异常就会丢掉。如果我想得到某些时刻的数据(有可能是调试程序Bug或者收集某些信息),就要把他转储(dump)为静态(如文件)的形式。否则,这些数据你永远都拿不到。
我们可以利用xdbg自己的插件scylla来dump数据:
但是dump下来的程序我们是无法正常打开的,因为我们没有修改IAT表,IAT表类似linux中的PLT表。windows的PE加载器运用动态链接的方式,将dll中的API位置填补到正确位置。然后脱壳后的程序并不是正常打开,这就导致了IAT未被正确填补需要手动或者利用工具填补IAT表。
第三步:用scylla将IAT表补完。
我们依次点击 IAT Autosearch, Get Imports 找到并获取导入表 右下角 Dump -> Fix Dump(注意最后Fix Dump要选中之前dump出的程序。)
此时便脱壳完成了,操作还是比较简单的,难点在于一些题中OEP藏的很深,还需要不断的练习才能更加准确,快速的找到OEP。