我正在编写一个基本的 PE 打包程序,它的工作只是在内存中执行附加的目标 PE。我花了几天时间来熟悉这种格式,我认为我已经很好地掌握了它的目的。这些是我使用的方法:
- 首先,目标通过插入到nasm生成的目标文件的
.data
部分与加载器捆绑在一起,然后与加载器一起编译。 - 执行时,检查图像数据目录,并通过加载所需的库和函数正确绑定导入地址表。
- PE 及其所有部分需要在内存中正确布局,因此
ImageBase
和SizeOfImage
被读取,并为接下来的两个操作分配足够的虚拟内存。 - PE 标头被写入新位置。
- 节数据通过节头收集,每个节都被写入新的内存空间,每个节都写入其指定的虚拟地址。
VirtualProtect()
还设置了适当的权限。 - 最后,
OptionalHeader.AddressOfEntryPoint
被调用。
当然,加载器有一个奇特的图像库,以免与标准0x00400000
库冲突。我的问题出在那里的某个地方。几乎每个.exe
都剥离了重定位表,因此如果所需的基址不可用,则无法进行基址重定位。具有非标准图像库的加载程序在一定程度上解决了该问题。目标所需的基础仅在大约 50% 的运行中可用。我试图找出其他 50% 中可能占用内存的内容,并且发现它几乎总是一个section view。至于什么,或谁,我不知道。我试过同时使用NtUnmapViewOfSection
和NtFreeVirtualMemory
,但它们并不能解决问题。第一个似乎引入了内存损坏,第二个什么也不做。有什么方法可以声明那段记忆吗?下面是从ProcessHacker截图:
。
欢迎所有想法。