壳原理和PE自制壳
壳原理和PE自制壳
加壳原理
壳的原理本身很简单,就是可执行文件的节被加密/压缩,然后在给加密/压缩好的文件附加一个可以解密/解压的stub节,修改头表来修改OEP,以达到自解密的效果,最后stub节会自行跳转正确的OEP.
步骤
那么就可以抽象出一下加壳器和Stub,加壳器需要执行:
- 加载可执行文件并加密
- 附加Stub
- 加载Stub
- 添加新节
- 修复Stub重定位
- 保存原始OEP
- 移植
- 设置新OEP
- 去掉随机基址
- 保存文件
Stub要执行:
- 合并自身.text,.data,.rdata
- 通过PEB动态寻址获得
GetProcAddress函数 - 解密
- 修改为原始OEP
注意点
Q:Stub为什么要是dll格式呢? A:dll必须有重定位表,方便重定位.
Q:为什么要重定位? A:当我们做加载Stub这一步时,实际上是操作系统的加载器把它如同可执行文件一样加载在了内存(不懂建议去看一下程序员的自我修养),故而里面的地址已经被重定位过了,但是我们在内存中复制的时候,是把这个给复制过去,那在新的exe文件里绝对寻址肯定是错误的地址,我们要重新搞一下.
Q:为什么要去掉随机基址? A:方便Stub获取基址.
Q:为什么Stub编译时要合并代码段和数据段? A:保证移植时都可以移植过去,用编译器指令即可实现
Q:什么是PEB动态寻址,为什么要这样做? A:具体如何做请看文章,原理就是通过PEB的信息获取kernel32基址,再通过基址获得导出表,再通过导出表获得GetProcAddress地址,因为stub的导入表并没有被移植过来。
实现
这是我的实现:T0FV404/Homemade-encryption-pack
实际上是模仿和学习大佬文章和源码:
[原创]C++写壳详解之基础篇-加壳脱壳-看雪-安全社区|安全招聘|kanxue.com
[原创]C++写壳之高级篇-加壳脱壳-看雪-安全社区|安全招聘|kanxue.com (这篇讲述了许多如何加大脱壳难度的方法,值得一看)
一些说明
高级篇那篇文章一些东西需要多说一下:
- IAT加密:加壳器修改源程序IAT的RVA为执行壳的IAT的RVA,故而加载器是导入壳的所需的函数.壳解密时手动加载dll,把原本IAT的放到自己申请内存的花指令中,在把这个代码的地址放入源程序IAT中,最后改回源程序IAT.
- hash加密:实际上就是模拟
GetProcAddress,但是通过自定义的hash算法比对,以达到隐藏API调用的目的.

浙公网安备 33010602011771号