pe_to_shellcode源码分析
1.编译
1 |
|
如下图所示:
2.分析
- dos->e_lfanew 长度不能大于1024
- Optional->Magic 可以判断32位数
- Optional->Subsystem 可以判断窗口或控制台
- 必须要有重定位表、不支持.NET程序
- 加载资源:64位的资源id为102,32位的资源id为101
2.1 Packer
2.1.1 映射PE
将PE文件从文件状态转换到内存状态,关键代码如下:
2.1.2 拼接Loader
从资源节中读取Loader数据(32位id为101、64位id为102),将Loader拼接到PE文件的末尾,关键代码如下:
将启动Loder的ShellCode填入DOS垃圾区域,关键代码如下:
2.1.3 修复节表
为了避免作为ShellCode执行时需要拉伸PE,直接将节表的文件偏移及大小修复为内存偏移及大小,关键代码如下:
如果是64位.NET程序,需要将OEP修改为0,代码如下:
如果是32位.NET程序,需要找到_CorExeMain函数,并寻找间接跳转指令,将OEP修改为间接跳转指令位置,代码如下:
2.2 RunShellCode
2.2.1 Loader启动
很巧妙,充分利用PE头部,将4D5A用作指令,并将垃圾区域作为Loader启动器,代码如下:
上述代码解释:
使用call pop获取当前指令地址,减去固定偏移即可得到ImageBase
根据Packer填入的原始SizeOfImage加上ImageBase得到Packer地址
call Loader代码,ImageBase作为参数
2.2.2 Loader
Loader原理为常规的PE Loader,主要包括修复重定位表、动态解析API修复IAT表、执行TLS回调,执行入口点。
2.2.2.1 获取必要API
ShellCode基本手段,解析PEB->Ldr,从模块链表中获取模块基址,再比对hash,解析导出表,获取函数地址,代码如下:
2.2.2.2 修复重定位表
解析PE,完成固定地址的重定位,代码如下:
2.2.2.3 修复IAT表
常规套路,根据INT表去获取导入函数地址来填充IAT表,代码如下:
2.2.2.4 执行TLS回调
如果存在TLS回调函数,全部执行,代码如下:
2.2.2.5 执行入口点
如果是DLL,需要给定参数再去执行入口点,exe则直接执行,代码如下:
至此,程序控制权交给原程序,完成ShellCode加载。
pe_to_shellcode源码分析
http://helloymf.github.io/2022/10/21/pe-to-shellcode-yuan-ma-fen-xi/