gpt4 book ai didi

debugging - 将 DLL 固定在内存中(增加引用计数)

转载 作者:行者123 更新时间:2023-12-02 23:47:26 24 4
gpt4 key购买 nike

我正在尝试运行应用程序,但该应用程序由于访问冲突而退出。在调试器中运行应用程序,我可以看到这是由卸载的库引起的。我迫不及待地等待应用程序的下一个版本,因此我正在尝试解决该问题。

我想知道WinDbg是否提供了一种增加加载模块的引用计数的方法,类似于C++ LoadLibrary()调用。然后我可以中断模块加载并增加受影响的 DLL 的引用计数,看看我是否可以使用该应用程序。

我已经查找过以 .load!load.lock!lock 开头的命令WinDbg 帮助中的 、 .mod!mod 。 .load 会将 DLL 作为扩展加载到调试器进程中,而不是加载到目标进程中。

更新

忘记提及我没有源代码,因此我不能简单地实现 LoadLibrary() 调用作为解决方法并重新编译。

Hans Passant 的评论引导我进入 .call,我尝试像这样使用它

.call /v kernel32!LoadLibraryA("....dll")

但它给出了错误消息

Symbol not a function in '.call /v kernel32!LoadLibraryA("....dll")'

更新2

可能 .call 中的文件名字符串应该是指向目标进程中某些内存的指针,而不是驻留在我键入命令的 WinDbg.exe 中的字符串。这再次意味着我可能会分配一些内存来存储其中的字符串,因此这可能会变得更加复杂。

最佳答案

在windbg中使用.call对我来说一直很挑剔。我相信您遇到了麻烦,因为 kernel32 只有公共(public)符号,因此调试器不知道它的参数是什么样的。

那么让我们看看一些替代方案......

简单的方法

你可以去拿一个像Process Hacker这样的工具,我认为这是对任何调试器工具箱的精彩补充。它可以选择将 DLL 注入(inject)到进程中。

Process Hacker Inject Dll

在幕后,它调用 CreateRemoteThread 在目标进程中生成一个线程,该线程在所选 DLL 上调用 LoadLibrary。运气好的话,这将增加模块引用计数。您可以通过在dll注入(inject)前后运行!dlls命令来验证windbg中的LoadCount是否已增加。

艰难的道路

您还可以深入研究 Windows 用于跟踪进程加载的模块的内部数据结构并使用 LoadCount。这在 Windows 版本之间会发生变化,并且是一个严重的禁忌。但是,我们正在调试,那么,到底是什么? 让我们这样做。

首先使用 !dlls 获取已加载模块的列表。假设我们关心your.dll;我们可能会看到类似的内容:

0x002772a8: C:\path\to\your.dll
Base 0x06b80000 EntryPoint 0x06b81000 Size 0x000cb000 DdagNode 0x002b3a10
Flags 0x800822cc TlsIndex 0x00000000 LoadCount 0x00000001 NodeRefCount 0x00000001

我们可以看到当前的加载计数为1。要修改它,我们可以使用模块路径之前打印的地址。它是进程为该模块保存的 ntdll!_LDR_DATA_TABLE_ENTRY 的地址。

r? @$t0 = (ntdll!_LDR_DATA_TABLE_ENTRY*) 0x002772a8

现在您可以将 LoadCount 成员更改为更大的值,如下所示:

?? @$t0->LoadCount = 2

但是,正如我所说,这些内容会随着 Windows 的新版本而发生变化。在 Windows 8 上,LoadCount 成员已从 _LDR_DATA_TABLE_ENTRY 移出并移至新的 ntdll!_LDR_DDAG_NODE 结构中。现在取而代之的是一个 ObsoleteNodeCount,这不是我们想要的。

在 Windows 8 上,我们将运行以下命令:

?? @$t0->DdagNode->LoadCount = 2

现在是时候检查我们的工作了...

0x002772a8: C:\path\to\your.dll
Base 0x06b80000 EntryPoint 0x06b81000 Size 0x000cb000 DdagNode 0x002b3a10
Flags 0x800822cc TlsIndex 0x00000000 LoadCount 0x00000002 NodeRefCount 0x00000001

太棒了。现在是2了。在我们说可以之前,这将给 FreeLibrary 上一堂关于卸载 DLL 的课。

要点

首先尝试简单的方法。如果这不起作用,您可以开始查看 Windows 用于跟踪此类内容的内部数据结构。我不提供困难的方法,希望您能真正尝试一下,但它可能会让您将来更熟悉 !dlls 命令和这些数据结构。

不过,所有修改 LoadCount 都会让您确认您看到 DLL 在应有的卸载之前被卸载。如果在人为增加 LoadCount 后问题消失,这意味着您已经证实了您的理论,您将不得不采取不同的方法来调试它 - 弄清楚它何时以及为何被卸载。

关于debugging - 将 DLL 固定在内存中(增加引用计数),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24574146/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com