PE 打包程序:打包映像基地址的问题

逆向工程 聚乙烯 包装工
2021-06-15 23:41:22

我正在编写一个基本的 PE 打包程序,它的工作只是在内存中执行附加的目标 PE。我花了几天时间来熟悉这种格式,我认为我已经很好地掌握了它的目的。这些是我使用的方法:

  1. 首先,目标通过插入到nasm生成的目标文件.data部分与加载器捆绑在一起,然后与加载器一起编译。
  2. 执行时,检查图像数据目录,并通过加载所需的库和函数正确绑定导入地址表。
  3. PE 及其所有部分需要在内存中正确布局,因此ImageBaseSizeOfImage被读取,并为接下来的两个操作分配足够的虚拟内存。
  4. PE 标头被写入新位置。
  5. 节数据通过节头收集,每个节都被写入新的内存空间,每个节都写入其指定的虚拟地址。VirtualProtect()还设置了适当的权限
  6. 最后,OptionalHeader.AddressOfEntryPoint被调用。

当然,加载器有一个奇特的图像库,以免与标准0x00400000冲突我的问题出在那里的某个地方。几乎每个.exe都剥离了重定位表,因此如果所需的基址不可用,则无法进行基址重定位。具有非标准图像库的加载程序在一定程度上解决了该问题。目标所需的基础仅在大约 50% 的运行中可用。我试图找出其他 50% 中可能占用内存的内容,并且发现它几乎总是一个section view至于什么,或谁,我不知道。我试过同时使用NtUnmapViewOfSectionNtFreeVirtualMemory,但它们并不能解决问题。第一个似乎引入了内存损坏,第二个什么也不做。有什么方法可以声明那段记忆吗?下面是从ProcessHacker截图:

欢迎所有想法。

2个回答

你可能想要:

  1. 给你的打包器存根有相同的标准 ImageBase
  2. 在别处分配内存
  3. 将(EIP 独立的,为了方便起见)存根代码重新定位到那里
  4. 在没有任何风险的情况下在原始 ImageBase 重建原始代码。

尝试从流程挖空中获取代码灵感。

这是在新空间上远程运行它的一个:https : //github.com/hasherezade/libpeconv/tree/master/run_pe https://github.com/m0n0ph1/Process-Hollowing

尝试:

  1. 从新分配的内存中运行打包加载器(将加载器 shellcode 复制到 RWX 分配的内存并从其运行。)
  2. 取消映射加载器 PE 映像,重新分配,并将其替换为新的 PE 映像
  3. 从新的 PE 映像动态导入函数
  4. 跳转到新 PE 镜像的入口点

我还没有深入研究资源加载。但是如果新的 PE 映像使用 LoadResource,它可能会改为读取加载器的。不确定这一点。

您可以从调试 UPX 打包示例中获得更多想法。