是不是弃用了CreateProcessW?

ken*_*dev 5 debugging windbg

我找不到一个确切的答案,所以我决定问.

我一直在阅读"Inside Windows Debugging",在示例中它告诉我在kernel32上设置一个断点!CreateProcessW.

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

0:000> bp kernel32!CreateProcessW
Couldn't resolve error at 'kernel32!CreateProcessW'
Run Code Online (Sandbox Code Playgroud)

这可能是因为下面的列表中没有"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>
Run Code Online (Sandbox Code Playgroud)

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

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

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

sev*_*tov 13

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

这里有一些更多细节可以帮助您理解您正在观察的内容.Windows团队经常移动代码,对于最后几个版本,他们有将较大的DLL分解为较小的DLL的强烈习惯,其中包括kernel32,ole32,user32,gdi32等等.这不是新的,Raymond Chen 在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 
Run Code Online (Sandbox Code Playgroud)

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


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

在这种情况下,我不知道为什么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
Run Code Online (Sandbox Code Playgroud)

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

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)
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

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