是否有 Windbg/NTSD 命令可以告诉我在实时调试会话中附加的进程是 32 位进程还是 64 位进程?
您能告诉我两者吗:
和
对于托管的,我可以在 C# 中以编程方式找到它,但我仍然想知道是否有一个 Windbg 命令。
更新
我正在调试的目标进程是Microsoft Word(winword.exe)。 Office 版本是 2016,但我不确定它是 32 位还是 64 位二进制文件。以下是一些观察结果:
目标位置是 C:\Program Files (x86)\Microsoft Office oot\Office16\WinWord.exe
管道 (
|
) 命令只告诉我 PID、进程是否附加到调试器以及加载图像的路径(如上面 #1 中所述)。我正在 64 位机器上调试它。所以,r 显示了 64 位寄存器。
在附加到一个实时、健康的进程且没有崩溃的情况下(我刚刚打开 MS Word 并说“附加到进程”),当前线程的调用堆栈 (
k
) 会读取 wow64cpu!CpupSyscallStub+0x9
作为最顶层的调用。 #1 表明该进程是 32 位进程。命令已尝试过
但我想知道是否有办法找到答案。
为了快速测试,我经常使用
lm m wow64
检查 WOW64 层是否已加载。如果是这样,那么它是一个 32 位进程。
这种方法在很多情况下都有效,因为现在操作系统可能是 64 位。但是,您也可以拥有 32 位操作系统的 32 位转储,在这种情况下,此方法效果不佳。
更权威的方法是
.load wow64exts
!info
不幸的是,它会提供大量输出,因此很难在脚本中使用。
32 位输出看起来像
0:000> !info
PEB32: 0xe4d000
PEB64: 0xe4c000
Wow64 information for current thread:
TEB32: 0xe50000
TEB64: 0xe4e000
[...]
如果是 64 位的话
0:000> !info
Could not get the address of the 32bit PEB, error 0
PEB32: 0
PEB64: 0x6b33c50000
Wow64 information for current thread:
TEB32: 0
TEB64: 0x6b33c51000
[...]
我没有可用的 32 位 Windows 操作系统转储,但我认为可以肯定地说这一点
如果您知道模块名称,还可以检查文件头:
0:000> .shell -ci "!dh -f notepad" findstr "machine"
8664 machine (X64)
.shell: Process exited
vertarget
正如评论中所建议的,对于 32 位应用程序的 64 位故障转储效果不佳。
$ptrsize
本来就很好,但这取决于调试器模式:
0:000> ? $ptrsize
Evaluate expression: 8 = 00000000`00000008
0:000> .effmach x86
Effective machine: x86 compatible (x86)
0:000:x86> ? $ptrsize
Evaluate expression: 4 = 00000004
与WOW64层类似,您可以检查.NET:
lm m mscorwks
lm m clr
lm m coreclr
当然,可以直接从本机代码通过
LoadLibrary()
加载这样的 DLL,而不是使用 .NET,但我认为有人想欺骗你,这是一种罕见的用法。
这个 WinDbg 命令将告诉您给定模块是为什么“机器类型”构建的。对于 x64,该值为 0x8664。对于 x86,该值为 0x14c。机器类型值的完整列表可在此处找到: https://learn.microsoft.com/en-us/windows/win32/debug/pe-format
dx @$curprocess.Modules.Where(x => x.Name.ToLower().Contains("foo.dll")).Select(x => x.Contents.Headers.FileHeader.Machine),x