是不是弃用了CreateProcessW?

时间:2014-04-19 11:02:26

标签: debugging windbg

我无法找到准确的答案,所以我决定提问。

我一直在阅读" Inside Windows Debugging"在示例中,它告诉我在 kernel32!Cre​​ateProcessW 上设置断点。

但在此之前,它使用 .symfix debugger命令将调试器符号搜索路径设置为指向Microsoft在线符号服务器。当我尝试设置断点时,我得到一个错误,它无法解析函数(或类似的东西)。它看起来像这样。

0:000> bp kernel32!CreateProcessW
Couldn't resolve error at 'kernel32!CreateProcessW'

这可能是因为没有" kernel32!Cre​​ateProcessW"在下面的列表中。

0:000> x kernel32!CreateProcess*
76b90cb9 KERNEL32!CreateProcessWithTokenW (void)
76b90d84 KERNEL32!CreateProcessAsUserW (void)
76b90d84 KERNEL32!CreateProcessWithLogonW (void)
76b4e225 KERNEL32!CreateProcessWStub = <no type information>
76b72e04 KERNEL32!CreateProcessInternalAStub = <no type information>
76b72e15 KERNEL32!CreateProcessInternalWStub = <no type information>
76b72de2 KERNEL32!CreateProcessAStub = <no type information>
76b72df3 KERNEL32!CreateProcessAsUserWStub = <no type information>

如果我将断点设置为 kernel32!Cre​​ateProcessWStub ,一切都会顺利但我想知道为什么我找不到并将断点设置为 kernel32!Cre​​ateProcessW

本书可能侧重于使用Windows 7的读者。我使用的是Windows 8.1,并认为kernel32!Cre​​ateProcessW可能已被弃用......

我对这个领域非常陌生并且如果这是一个完全愚蠢的问题而道歉。但无论如何,感谢你阅读它。

1 个答案:

答案 0 :(得分:13)

绝对不会弃用

CreateProcessW。此外,唯一记录的入口点仍然在kernel32.dll中,因此对于所有意图和目的,您应该继续通过kernel32.dll调用CreateProcessW,而不是通过kernelbase.dll。

以下是一些有助于了解您所观察到的内容的细节。 Windows团队经常移动代码,并且在最后几个版本中,他们有将较大的DLL分解为较小的DLL的强烈习惯,其中包括kernel32,ole32,user32,gdi32等等。这不是新的,Raymond Chen wrote about this在2006年。然而Raymond所描述的机制是基于转发器,而你在这里看到的kernel32!CreateProcessW是一个存根,即调用kernelbase的函数!CreateProcessW然后返回:

0:014> u kernel32!CreateProcessWStub l14
KERNEL32!CreateProcessWStub:
00007ffd`83cf58a8 4c8bdc          mov     r11,rsp
00007ffd`83cf58ab 4883ec58        sub     rsp,58h
00007ffd`83cf58af 488b8424a8000000 mov     rax,qword ptr [rsp+0A8h]
00007ffd`83cf58b7 498943f0        mov     qword ptr [r11-10h],rax
... skip ...
00007ffd`83cf58f5 ff1555871100    call    qword ptr [KERNEL32!_imp_CreateProcessW (00007ffd`83e0e050)]
00007ffd`83cf58fb 4883c458        add     rsp,58h
00007ffd`83cf58ff c3              ret 

您可以看到调用的函数是kernelbase!CreateProcessW


0:014> ln poi kernel32!_imp_CreateProcessW
(00007ffd`82f92604)   KERNELBASE!CreateProcessW   |  (00007ffd`82f926d0)   KERNELBASE!MakeLocHashNode
Exact matches:
    KERNELBASE!CreateProcessW (no parameter info)

我在这种情况下我不知道为什么Windows人员决定使用存根而不是转发器,对我来说,像大多数其他重构一样,简单地转发呼叫会更有效率

Windows 8.1中的Kernel32.dll仍包含导出符号CreateProcessW。命令link /dump /exports打印出所有导出符号:

c:\>link /dump /exports c:\Windows\System32\kernel32.dll | findstr CreateProcessW
        220   DB 000058A8 CreateProcessW = CreateProcessWStub

您可以使用相同的命令来确定应将断点设置到的位置。同样对于转发出口:

c:\>link /dump /exports c:\Windows\System32\kernel32.dll | findstr EnterCriticalSection
        298  129          EnterCriticalSection (forwarded to NTDLL.RtlEnterCriticalSection)
       1418  589          TryEnterCriticalSection (forwarded to NTDLL.RtlTryEnterCriticalSection)

WinDbg无法解析符号kernel32!Cre​​ateProcess的原因可能只是WinDbg中的一个错误。在这种情况下,符号不是.PDB文件的一部分,但包含在PE映像的特殊部分中,显然WinDbg不处理它。有趣的是,如果.PDB文件不可用,WinDbg很乐意使用PE图像的导出表:

0:014> .sympath .
0:014> .reload
Reloading current modules ....
0:014> x kernel32!CreateProcessW
00007ffd`83cf58a8 <b>KERNEL32!CreateProcessW</b> (no parameter info)

显然,WinDbg决定使用PDB符号或导出符号,但不能同时使用两者。