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

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

但是在此之前,它使用 .symfix 调试器命令来设置调试器符号搜索路径以指向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可能已被弃用...

我是这个领域的新手,如果这是一个完全愚蠢的问题,我深表歉意。但是还是感谢您阅读它。

最佳答案

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

这里有一些更多的细节,以帮助您了解正在观察的内容。 Windows团队经常移动代码,在最近的几个发行版中,他们习惯于将较大的DLL分解为较小的DLL,其中包括kernel32,ole32,user32,gdi32等。这不是什么新东西,是Raymond Chen的wrote about this在2006年。但是Raymond描述的机制是基于转发器的,而您在kernel32!CreateProcessW中看到的是一个 stub ,即调用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的人们决定使用 stub 而不是转发器,对我来说,像大多数其他重构一样,简单地转发调用似乎更有效率。

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符号或导出符号,但不能同时使用两者。

关于debugging - 不推荐使用CreateProcessW吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23169172/

10-15 16:45