以调试器友好的方式从 RAM 加载本机 C++ .dll

2024-04-02

问题目前仅涉及 Windows - 其他操作系统目前不太相关。

只需通过快速谷歌搜索 - 就可以从 RAM 加载本机 .dll,例如有以下库:

https://www.joachim-bauch.de/tutorials/loading-a-dll-from-memory/ https://www.joachim-bauch.de/tutorials/loading-a-dll-from-memory/

=>

https://github.com/fancycode/MemoryModule https://github.com/fancycode/MemoryModule

https://forum.nim-lang.org/t/7943 https://forum.nim-lang.org/t/7943

但所有这些都需要:

  1. 深入了解PE文件格式
  2. 大多数这些方法对调试器不友好。

我检查过的内容 - windowsLoadLibraryA / LoadLibraryW被定向到ntdll.dll / LdrLoadDll- 可以从这里找到有关事情如何运作的最佳图片:https://github.com/hlldz/RefleXXion https://github.com/hlldz/RefleXXion

即使这样我也没有 Windows 源代码 - 我已经从 Wine 检查了相同的功能:

Ldr加载DLL:https://source.winehq.org/source/dlls/ntdll/loader.c#3169 https://source.winehq.org/source/dlls/ntdll/loader.c#3169

加载_dll:https://source.winehq.org/source/dlls/ntdll/loader.c#3083 https://source.winehq.org/source/dlls/ntdll/loader.c#3083

加载本机DLL:https://source.winehq.org/source/dlls/ntdll/loader.c#2564 https://source.winehq.org/source/dlls/ntdll/loader.c#2564

NtMapViewOfSection:https://source.winehq.org/source/dlls/ntdll/unix/virtual.c#4469 https://source.winehq.org/source/dlls/ntdll/unix/virtual.c#4469

查找_dll_文件:https://source.winehq.org/source/dlls/ntdll/loader.c#3021 https://source.winehq.org/source/dlls/ntdll/loader.c#3021

打开_dll_文件:https://source.winehq.org/source/dlls/ntdll/loader.c#2467 https://source.winehq.org/source/dlls/ntdll/loader.c#2467

可疑加载 dll 通过以下函数调用发生:NtOpenFile, NtQueryAttributesFile, NtCreateSection/NtOpenSection, NtMapViewOfSection (*)

(更多信息可以在

https://github.com/Hagrid29/PELoader https://github.com/Hagrid29/PELoader

https://gist.github.com/bats3c/59932dfa1f5bb23dd36071119b91af0f https://gist.github.com/bats3c/59932dfa1f5bb23dd36071119b91af0f

https://www.octawian.ro/fisiere/situri/asor/build/html/_downloads/122f95f9a032396603a837c53b125bb8/Russinovich_M_WinInternals_part1_7th_ed.pdf https://www.octawian.ro/fisiere/situri/asor/build/html/_downloads/122f95f9a032396603a837c53b125bb8/Russinovich_M_WinInternals_part1_7th_ed.pdf )

我也在想我是否可以覆盖NtOpenFile并只需重定向文件打开(在https://github.com/SegaraRai/PathRedirector https://github.com/SegaraRai/PathRedirector方式) 到不同的路径 - 但主要问题是存储文件的替代位置是什么?

我在想如果 NtOpenFile 甚至可以打开设备,那么也许只是替换文件 使用某种命名管道(https://learn.microsoft.com/en-us/windows/win32/ipc/named-pipe-client https://learn.microsoft.com/en-us/windows/win32/ipc/named-pipe-client) - 但随后在地图中了解这与 NtMapViewOfSection 的配合情况。

由于我无法找到此类挂钩或操作的任何工作示例(例如LoadLibary("\\.\pipe\mynamedpipe_as_dll")) - 始终存在这样的组合不被简单支持的风险。

是否可以纯粹从 RAM 加载本机 .dll:

  1. 不使用文件系统(不将 .dll 存储在临时文件夹中)
  2. 不涉及自定义驱动程序(如 Dokan)?
  3. 那么加载的 .dll 仍然对调试器友好吗?
  4. 与PE文件格式结构没有紧密绑定(或者尽可能少地使用PE结构)

如果您错过了更多信息,请检查我自己的本机 dll 加载实验(也许可以提供一些解决问题的提示):

https://github.com/tapika/test_native_dll_loading https://github.com/tapika/test_native_dll_loading https://github.com/tapika/test_native_dll_loading/discussions/2 https://github.com/tapika/test_native_dll_loading/discussions/2


区分调试和发布用例。在调试时,将 DLL 保存在临时文件中并使用 LoadLibrary 加载,这将启用调试。在发布版本中,从内存运行,无法进行调试。

这是另一个想法,来自考虑链接的 Guthub 问题。如果目的是让用户在构建 ReadyToRun 可执行文件时提供自己的压缩/解压缩逻辑,请让他们将其作为static库(对象)而不是 DLL。较大的项目已经将内容打包到单个可执行文件中,可能会在执行过程中进行一些链接。

另一个想法是让用户以某种解释性语言提供编解码器,并可选择插入支持调试的解释器。 Windows 带有内置的 JavaScript 解释器,查找 Active Scripting 并调试这些是免费的。不过,性能可能无法与本机代码实现相提并论。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

以调试器友好的方式从 RAM 加载本机 C++ .dll 的相关文章

随机推荐