ImportDLLInjection – 通过修改内存中的 PE 头来注入 DLL 的另一种方法

原文链接:https://www.x86matthew.com/view_post?id=import_dll_injection

这篇文章展示了我最近提出的一个相当简单的 DLL 注入想法。我在网上快速浏览了一下,看看有没有其他人使用过这种方法,但找不到任何结果。(更新:hasherezade 提到微软在 MSDetours 中名为 DetourCreateProcessWithDlls 的函数中使用了非常相似的方法)

此方法不需要创建临时线程、修改可执行代码或更改线程上下文。

简而言之,我们将修改新创建进程内存中的 PE 标头,以将我们自己的 DLL 添加到导入描述符列表中。

我的想法如下:

这是有效的,因为新创建的挂起进程只有ntdll.dll最初加载 – 这意味着我们可以在加载剩余的 DLL 之前操作内存中的导入表。这种方法可靠,在我的测试中效果很好。

这种方法的主要缺点是它只能用于将 DLL 注入新进程。无法使用此方法注入已运行的进程,因为仅在进程首次启动时才处理导入描述符列表。

此方法的另一个小缺点是目标 DLL 需要导出至少一个函数。Windows 不会加载具有空白导入查找表(至少在我的系统上)的导入 DLL,因此我在导入序号 #1 的查找表中添加了一个条目。此导出条目必须存在于目标 DLL 中,否则目标进程将无法启动。我将在本文末尾包含示例 DLL 的代码。

我们不能保证有足够的空间在现有的 PE 头数据中添加额外的模块条目。为了解决这个问题,我将现有的导入描述符列表复制到我在内存中分配的更大的缓冲区中。然后将新的 DLL 附加到此列表中,并在VirtualAddress和Size字段中IMAGE_DIRECTORY_ENTRY_IMPORT更新为指向新列表。

成功注入后恢复原始 PE 标头可消除任何篡改迹象。但是,目标 DLL 不会以任何方式隐藏 – 它将像任何其他合法加载的 DLL 一样在内存中公开可见。

完整代码如下:

Sample DLL:

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部