RE April 23, 2020

windows下的壳研究

Words count 3.7k Reading time 3 mins. Read count 0

一、什么是壳

加壳的全称是可执行程序资源压缩,是保护文件的常用手段。加壳过的程序可以直接运行,但是不能查看源代码。要经过脱壳才可以查看源代码。

加壳是利用特殊的算法,对EXE、DLL文件里的资源进行压缩、加密。类似WINZIP 的效果,只不过这个压缩之后的文件,可以独立运行,解压过程完全隐蔽,都在内存中完成,因此我们需要dump内存。

壳的类型通常分为压缩壳和加密壳两类。压缩壳的特点是减小软件体积大小,加密保护不是重点,

例如: Aspack, UPX(ctf比赛中中最常见的壳), PeCompact等压缩壳

加密壳种类比较多,不同的壳侧重点不同,一些壳单纯保护程序,另一些壳提供额外的功能,如提供注册机制、使用次数、时间限制等。

例如: Pelock, Telock, Svk Protector等一般难度加密壳, Acpr, Aspr, Armadillo(单进程), pespin 1.1, enigma Protecotr 等稍复杂加密壳

• OEP

•OEP:(Original Entry Point),程序的入口点。软件加壳一般隐藏了程序真实的OEP(或者用了假的OEP), 我们需要寻找程序真正的OEP,才可以完成脱壳。

•一般加壳程序在使用Ollydbg等动态调试工具时,会停在壳的预处理块。即处在对于程序原始代码块的解压或解密操作之前,在运行完程序自脱壳模块后,会停留在程序加壳之前的OEP位置,此时是dump程序的最佳时期。脱壳时在真实OEP处下int3断点,就可以捕捉到程序代码段完全恢复的状态。因此,寻找加壳程序的正确OEP,也成了手动脱壳时的第一要务。

•1.3 IAT

•IAT:(Import Address Table),导入地址表。由于导入函数就是被程序调用但其执行代码又不在程序中的函数,这些函数的代码位于一个或者多个DLL中。当PE文件被装入内存的时候,Windows装载器才将DLL 装入,并将调用导入函数的指令和函数实际所处的地址联系起来(动态连接),这操作就需要导入表完成。其中导入地址表就指示函数实际地址。 多数加壳软件在运行时会重建导入地址表,因此获取加壳程序正确的导入地址表也是手动脱壳操作中的一个关键问题。

手动脱壳最佳方法:ESP定律

ESP定律法是脱壳的利器,是应用频率最高的脱壳方法之一。

ESP定律的原理在于程序中堆栈平衡的合理利用。由于在程序自解密或者自解压过程中,不少壳会先将当前寄存器内容压栈,如使用pushad,在解压结束后,会将之前的寄存器值出栈,如使用popad。因此在寄存器出栈时,往往程序代码被自动恢复,此时硬件断点触发。然后在程序当前位置,只需要少许单步跟踪,就很容易到达正确的OEP位置。

二、手动esp定律脱壳

程序:ddctf一道逆向题

image-20200423173951632

发现了upx的壳,然后利用x32dbg去脱壳,这里od试了不行,可能是od插件的问题~

载入到x64dbg:

先F9到达程序加壳的点,记住pushad和popad是成对的

image-20200423174309886

这条指令是将我们程序的入口点状态压入当前寄存器中,f8一下,看下寄存器状态:

image-20200423174357875

可以看到esp和eip的变化,这里跟踪下esp,右键,内存跟踪转到

image-20200423174447291

然后选中当前的0x607AA0地址,下个硬件访问断点4字节:

image-20200423174623085

接着F9一下:

image-20200423174652380

可以发现它执行了popad,这里将程序入口状态还原到寄存器,有个大跳jmp,图中可看到,这里将鼠标放到jmp,然后f4按2次:

image-20200423174822212

进行大跳转回到程序的入口点oep,F8一下得到:

image-20200423174907868

这就是没有加壳的程序的入口点了,得到了正确的oep后我们需要进行脱壳操作,选择插件中的scylla,点击dump,然后得到dump出来的程序了,有个dump标志,图中可以看到的:

image-20200423175059217

接下来,我们需要修复IAT符号表,这里回到x32dbg中,选择那个misc中的option:

image-20200423175234080

然后accept下:

image-20200423175306514

接着点击IAT search,然后再点击get imports:

image-20200423175340932

这里是把原来程序中的符号表给得到了,然后dump出来的是没有符号表的,这里通过fix dump实现dump程序加载入符号表,所以fix dump点击一下:

image-20200423175457338

打开我们的dump程序,完成!

image-20200423175526204

这里有syc的那个程序就是我们的脱好壳的程序

image-20200423175603750

可以发现从upx1到upx0了,完美,脱壳结束!

如果程序开了内存地址随机化,记得先关闭随机化即可,操作如下:

在exe文件中找到dllcharacteristic(动态库属性)

image-20201021105626854

把dll can move取消,即将0x40改成0x00即可,或者直接在010edit中找到这个值改为00,这样就关闭了随机化。

0%