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

问题描述

如果我哪里错了,请纠正我...

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

我做了什么:

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

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

我做错了什么?

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

解决方法

似乎内存页被调出。 re 命令成功了

,

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

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

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