2

我试图了解 Windows 如何在用户空间中递归加载 DLL。

以跟踪kernel32.ReadProcessMemory为例:

的第一步ReadProcessMemory是 IAT kernel32

00007FF901F6AFA0 | 48:FF25 21D20500 | jmp qword ptr ds:[<&ReadProcessMemory>] |

哪个jmpkernelbase.ReadProcessMemory

00007FF9002D22F0 | 48:83EC 48               | sub rsp,48                                   |
00007FF9002D22F4 | 48:8D4424 30             | lea rax,qword ptr ss:[rsp+30]                |
00007FF9002D22F9 | 48:894424 20             | mov qword ptr ss:[rsp+20],rax                |
00007FF9002D22FE | 48:FF15 C3521400         | call qword ptr ds:[<&ZwReadVirtualMemory>]   |
<snip>

callntdll.ZwReadVirtualMemory

00007FF902F5C840 | 4C:8BD1                  | mov r10,rcx                                  |
00007FF902F5C843 | B8 3F000000              | mov eax,3F                                   | 3F:'?'
00007FF902F5C848 | F60425 0803FE7F 01       | test byte ptr ds:[7FFE0308],1                |
00007FF902F5C850 | 75 03                    | jne ntdll.7FF902F5C855                       |
00007FF902F5C852 | 0F05                     | syscall                                      |
00007FF902F5C854 | C3                       | ret                                          |
00007FF902F5C855 | CD 2E                    | int 2E                                       |
00007FF902F5C857 | C3                       | ret                                          |

所以这个例子中用户模式的流程是:

  1. kernel32.ReadProcessMemory
  2. kernelbase.ReadProcessMemory
  3. ntdll.ZwReadVirtualMemory

期望是上述每个 DLL 在加载时都可以根据它们的 IAT/从其他 DLL 导入的函数“找到”适当的函数。

使用dumpbin和跟踪IMPORTSthis 是正确的kernel32.ReadProcessMemory(哪里api-ms-win-core-memory-l1-1-0.dllApiSetfor kernelbase.dll):

    api-ms-win-core-memory-l1-1-0.dll
             180078178 Import Address Table
             18009E120 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                          35 VirtualQueryEx
                          <snip>
                          1C ReadProcessMemory

然而,这不是真的kernelbase.dll-NtReadVirtualMemory是进口的,但ZwReadVirtualMemory不是进口的:

    ntdll.dll
             1801A67C8 Import Address Table
             180262A48 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                         893 __C_specific_handler
                         <snip>
                         205 NtReadVirtualMemory

所以,我的问题是:在 DLL 加载过程中,如果没有导入,如何kernelbase.dll识别“位置” ?ZwReadVirtualMemory

ZwReadVirtualMemory函数由 调用kernelbase.dll,所以它一定已经在某个时候被解析/存储在 IAT 中,但是这在技术上是如何发生的呢?

这些函数解析到相同的地址时NtReadVirtualMemory,加载器映射到的地方是否有一些间接?ZwReadVirtualMemory

4

0 回答 0