前面都是PE的零散的知识,可以通过给PE文件写一个壳将前面的PE相关知识进行汇总
网上看到了一个英文教程(详细看参考),里面包含了给PE加壳和调用LIEF库的操作(这个库很简单);按照教程实现一遍(错误都进行了修正,主要是Part 4),对理解PE文件格式和脱壳很有帮助
下面是结合自己的实践写的笔记,不是教程的原版翻译
教程主要实现的壳的整体功能:
- 1.A PE File will be copied as-is (at first) in a custom section.
- 2.The unpacker will load this PE in memory and jump on it.
源码:https://github.com/jeremybeaume/packer-tutorial
编译器选取
可以使用Visual Studio
或者MinGW
,本教程使用MinGW64
MinGW编译器安装教程:MinGW-w64安装教程——著名C/C++编译器GCC的Windows版本_无知人生 (ivu4e.com)
-
小插曲:由于实验的机器使用的是win10,64位;导致开始使用MinGW64编译时总是达不到预期效果,后来发现MinGW64默认生成的是64位程序,尝试使用
-m32
参数显示缺库,还是不生效(生效是要32位的库是全的才可以,自己电脑不想安装那么多库,不处理了) -
解决:重新下载
i686-8.1.0-release-win32-sjlj-rt_v6-rev0
版本,使用i686-w64-mingw32-gcc.exe
就可以了
教程使用的测试程序:以系统自带的32位计算器进行测试,路径:C:\Windows\SysWOW64\calc.exe
系列汇总
- 写一个PE的壳_Part 1:加载PE文件到内存
- 写一个PE的壳_Part 2:ASLR+修复输入表(IAT)+重定位表支持(.reloc)
- 写一个PE的壳_Part 3:Section里实现PE装载器
- 写一个PE的壳_Part 4:修复对ASLR支持+lief构建新PE
- 写一个PE的壳_Part 5:PE格式修复+lief源码修改
- 写一个PE的壳_Part 6:简单的混淆
文章目录
Part 1:加载PE文件到内存
目的:写一个读取PE文件,分析它的头部信息、将它的节区信息映射到内存的程序(
loader.exe
)
1.main函数框架
main函数实现的主要功能如下:
- 1.读取一个文件,申请一块能放下文件大小的内存
- 2.调用load_PE函数将PE文件读取到上面申请的内存中,然后返回PE文件的EP(暂时先不关心具体的实现)
- 3.从PE文件EP处开始执行
#include <stdio.h>
#include <stdlib.h>
// loads a PE in memory, returns the entry point address
void* load_PE (char* PE_data);
int main(int argc, char** argv) {
if(argc<2) {
printf("missing path argument\n");
return 1;
}
FILE* exe_file = fopen(argv[1], "rb"); //读取一个PE文件
if(!exe_file) {
printf("error opening file\n");
return 1;
}
fseek(exe_file, 0L, SEEK_END</