【问题标题】:Is CreateProcessW deprecated?CreateProcessW 是否已弃用?
【发布时间】:2014-04-19 11:02:25
【问题描述】:

我找不到准确的答案,所以我决定问一下。

我一直在阅读“Windows 内部调试”,在示例中它告诉我在 kernel32!CreateProcessW 上设置断点。

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

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

可能是因为下面的列表中没有“kernel32!CreateProcessW”。

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!CreateProcessWStub 一切正常,但我想知道为什么我找不到并将断点设置为 kernel32!CreateProcessW。 p>

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

我对这个领域非常陌生,如果这是一个完全愚蠢的问题,我深表歉意。不过还是感谢您阅读。

【问题讨论】:

  • 我也注意到了这一点,并认为这是由于 API 的变化。你会在KERNELBASE.DLL 中找到CreateProcessW。虽然使用依赖仍然会在KERNEL32.DLL 中显示CreateProcessW,所以我对如何正确解释事物也有些困惑。

标签: debugging windbg


【解决方案1】:

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

这里有一些详细信息可以帮助您了解您所观察到的内容。 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!CreateProcess 的原因,可能只是 WinDbg 的一个 bug。在这种情况下,符号不是 .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 符号或导出符号,但不能同时使用两者。

【讨论】:

    猜你喜欢
    • 2023-03-08
    • 2018-09-12
    • 2017-12-06
    • 2017-08-11
    • 1970-01-01
    • 2017-11-16
    • 2011-07-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多