为啥内存中加载的 DLL 与原始 DLL 文件不完全对应?

Posted

技术标签:

【中文标题】为啥内存中加载的 DLL 与原始 DLL 文件不完全对应?【英文标题】:Why the DLL loaded in memory doesn't fully correspond to the original DLL file?为什么内存中加载的 DLL 与原始 DLL 文件不完全对应? 【发布时间】:2021-08-07 17:22:20 【问题描述】:

如果我在任何地方错了,请纠正我......

我想做的事: 在通过 WinDBG 进行远程内核调试期间,我想在某个 DLL 中找到某个函数,该函数正在由 Windows 服务加载。 (IDA + VirtualKD + VMWare VM 中的 WinDBG 插件与 Windows 10 x64)。 我需要做内核模式,因为我需要切换进程并查看所有内存

我做了什么:

    我在 IDA 中找到了函数的偏移量(不幸的是,DLL 没有调试符号)。 以内核模式连接到虚拟机。 通过遍历 svchost 进程 (!process 0 0 svchost.exe) 并查看其 PEB 中的 CommandLine 字段 (C:\Windows\system32\svchost.exe -k ...) 找到服务进程。 切换到进程(.process /i <address>; g),刷新模块列表(.reload) 在用户模块列表中找到目标 DLL 并获取其基地址。

问题: 加载到内存中的 DLL 与原始 DLL 文件不完全对应,所以我在那里找不到函数。 当我跳转到<dll_base_address> + <function_offset> 这样的地址时,那里和周围什么都没有。但是我用这个方法发现了一些其他的功能,所以看起来是正确的。 然后我试图根据原始DLL文件找到属于该函数的字节序列,也一无所获。 该函数使用我在数据部分中找到的字符串,但它们没有外部参照。 看起来那个功能已经完全消失了……

我做错了什么?

P.S.:我还将内存从 <dll_start> 转储到 <dll_end> 并将其与原始文件进行比较。除了不同的跳转地址和偏移量,有时汇编代码完全漏掉了……

【问题讨论】:

数据从哪个地址开始丢失?如果它是页面偏移量,则可能它当前已被调出。它将显示为?? @thomas-weller,谢谢!似乎内存页面已被调出。 .pagein 命令成功了 【参考方案1】:

内存页面似乎被调出。 .pagein 命令成功了

【讨论】:

【参考方案2】:

看起来,一些内存页面被调出(移动到辅助存储)。该命令从二级存储中加载页面,并在反汇编中显示:

.pagein /f /p <process_address> <memory_page_address>

查看更多:The DLL is partly missed in remote kernel debugging

【讨论】:

以上是关于为啥内存中加载的 DLL 与原始 DLL 文件不完全对应?的主要内容,如果未能解决你的问题,请参考以下文章

什么是.dll文件

将LIB中的代码加入目标模块(EXE或者DLL)文件中

读取 ntdll.dll + offset 会导致访问冲突

在 C/C++ (Win64) 中从内存中加载 64 位 DLL

在VS2010中加载dll文件时的第一次机会异常

转储内存中加载的 Python 模块的内容