我必须创建一个导出一些符号(函数)的包装 DLL。在其资源中,它包含另一个真正完成这项工作的加密DLL。
在包装器 DLL 初始化时,它会解密原始文件,将其保存在文件中,然后通过LoadLibrary
. 但是我想避免将此 DLL 保存在文件中。
我知道这并不能保证防弹保护,实际上可以转储进程虚拟内存并在那里看到它。我也知道可以创建一个带有FILE_FLAG_DELETE_ON_CLOSE
属性的文件,这样可以确保在进程终止后立即删除该文件。但我仍然想知道是否有“不是从文件”加载 DLL 的选项。
到目前为止,我想到了以下几点:
- 分配具有充分保护的虚拟内存块(
PAGE_EXECUTE_READ
或PAGE_EXECUTE_READWRITE
)。最好在映像首选基址。 - 在那里提取/解密 DLL 映像。
- 如果图像基地址不是其首选地址 - “手动”进行重定位。即 - 分析重定位表并就地修补图像。
- 处理图像导入。加载其依赖 DLL 并填充符号地址。
- 调用其初始化函数 (
DllMain
)。
也就是说,我可以做装载机的工作。但不幸的是,在某些区域,通过上述技巧加载的 DLL 的行为会有所不同,因为从操作系统的角度来看,它不是正确加载的 DLL。这包括以下内容:
- 需要DLL “
DllMain
模块句柄”,这只是它的基地址。它可以在调用各种 API 函数时使用此句柄,例如LoadResource
. 这些电话可能会失败。 - 异常处理会有问题。操作系统不会看到 DLL 的
SAFESEH
部分,因此不会调用其内部异常处理代码(它是 64 位 DLL,意味着异常处理SAFESEH
是强制性的)。
这是我的问题:是否有 API 可以将 DLL 正确加载到进程地址空间而无需将其放在文件中?例如,它的替代变体LoadLibrary
适用于文件映射而不是文件系统文件?
提前致谢。