加壳流程大致三部. 先将原PE文件的数据提取出来, 然后对数据进行处理, 最后将解压缩代码和被压缩的数据放入新的文件中得到带壳程序
壳实现
- 加壳流程
- 将原PE文件的数据提取出来
- 压缩
- 将解压缩代码和被压缩的数据放入新的文件中
- 得到带壳程序
2. 具体实现
- 工程
- 加壳器
- 给指定的PE做加壳
- 壳代码
- 解压缩代码
- 加壳器
2.1 加壳器
对PE进行压缩/加密, 生成新的PE
- 验证条件
- 保证PE文件格式正确
- 大致结构
- PE头
- 空节
- 解压缩代码
- 压缩数据
- 加壳器步骤
- 分析原PE, 提取头部数据
- 获取压缩数据
- 获取压缩代码(壳代码)
- 获取节表
- 获取新PE的PE头
- 构建新PE文件
2.2 壳代码
在程序中的地址不固定: 地址无关代码(自我重定位)
- shellcode: 地址无关代码
- 代码中没有访问绝对地址的指令
- 凡是有重定位的地址都是绝对地址.
- vs写shellcode
- 打开随机基址选项(vs默认开着)
- 修改默认入口函数(startCRTmain)
- 链接器-> 高级 -> 入口点
- 以Release编译
- debug会加一些检查
- C/C++所有选项-> 关掉 安全检查(GS)(检查栈)
- 调用库函数需要使用自己写的GetProcAddress
- 壳代码实现流程
- 定位到压缩数据
- 解析PE, 定位压缩数据
- 解压缩
- loadpe
- 定位到压缩数据
扩展
- 压缩API
- 创建句柄: CreateCompressor
- 压缩数据: Compress
- 句柄
- 被压缩数据缓冲区
- 被压缩数据大小
- 压缩后数据缓冲区
- 压缩后数据缓冲区大小
- 压缩后数据大小
- 解压数据: Decompress
- 壳特征:
- 一般需要存储原PE大小
- 当前数据大小(未对齐的实际大小)
- 一般需要申请内存, 存放解压缩数据, 在从内存搬到PE 节区中