导出的WriteProcessMemory 函数实际上指向kernel32!WriteProcessMemoryStub 存根,它本身跳转到kernel32!__imp_WriteProcessMemory,后者重定向到kernelbase DLL,这是该函数的“真实”位置。
让我们检查一下链接转储:
C:>link /dump /exports c:\windows\system32\kernel32.dll | findstr /I WriteProcess
1579 62A 00036C50 WriteProcessMemory
0x36C50 是函数“WriteProcessMemory”驻留在 kernel32 中的 RVA(由导出表给出)。现在在windbg:
0:007> ln kernel32 + 0x36c50
Browse module
Set bu breakpoint
(00007ff9`4a6e6c50) KERNEL32!WriteProcessMemoryStub | (00007ff9`4a6e6c60) KERNEL32!ZombifyActCtxStub
我们有一个精确匹配,实际上是KERNEL32!WriteProcessMemoryStub 函数。如果我们看一下:
0:007> u KERNEL32!WriteProcessMemoryStub
KERNEL32!WriteProcessMemoryStub:
00007ff9`4a6e6c50 48ff2599150400 jmp qword ptr [KERNEL32!_imp_WriteProcessMemory (00007ff9`4a7281f0)]
00007ff9`4a6e6c57 cc int 3
我们可以看到它只是跳转到 KERNEL32!_imp_WriteProcessMemory(位于 kernel32 的 .idata 部分的某处)。
现在,如果我们查看此位置包含的内容,我们有一个指针:
0:007> dp KERNEL32!_imp_WriteProcessMemory L1
00007ff9`4a7281f0 00007ff9`496f0ca0
如果我们问windbg这个指针是什么:
0:007> ln 00007ff9`496f0ca0
Browse module
Set bu breakpoint
(00007ff9`496f0ca0) KERNELBASE!WriteProcessMemory | (00007ff9`496f0dc4) KERNELBASE!OpenWow64CrossProcessWorkConnection
Exact matches:
KERNELBASE!WriteProcessMemory (void)
我们可以看到实际上WriteProcessMemory 的“真实”位置实际上是在kernelbase.dll。
注意:您实际上可以使用dps 将最后两个命令合二为一:
0:007> dps KERNEL32!_imp_WriteProcessMemory L1
00007ff9`4a7281f0 00007ff9`496f0ca0 KERNELBASE!WriteProcessMemory
使用的 Windbg 命令: