是否有 Windbg 命令来查明进程是 32 位进程还是 64 位进程?
Is there a Windbg command to find out if a process is a 32-bit one or a 64-bit one?
是否有 Windbg/NTSD 命令告诉我在实时调试会话中附加的进程是 32 位进程还是 64 位进程?
你能告诉我两个吗:
- 非托管进程?
和
- 托管的?
对于托管的,我可以在 C# 中以编程方式找到它,但我仍然想知道是否有用于此的 Windbg 命令。
更新
我正在调试的目标进程是 Microsoft Word (winword.exe)。 Office 版本是 2016,但我不确定它是 32 位还是 64 位二进制文件。以下是一些观察结果:
目标位置是C:\Program Files (x86)\Microsoft Office\root\Office16\WinWord.exe
pipe (|
) 命令只告诉我 PID,进程是否附加到调试器以及加载图像的路径(如中所述#1 以上)。
我正在 64 位机器上调试它。所以,r 揭示了 64 位寄存器。
在附加到一个没有崩溃的实时、健康的进程后(我刚刚打开 MS Word 并说 "Attach to Process"),当前线程的调用堆栈 (k
) 读取wow64cpu!CpupSyscallStub+0x9
用于最顶层的调用。这与#1 表明该进程是一个 32 位进程。
命令已经尝试过
- !peb(进程环境块):告诉我们处理器架构,而不是正在调试的进程的位数。
- |
- vertarget
- r(指示我的处理器的寄存器大小,但不告诉我有关过程)
但我想知道是否有办法找出答案。
32位/64位决定
为了快速测试我经常使用
lm m wow64
检查是否加载了 WOW64 层。如果是,则为 32 位进程。
这种方法在很多情况下都有效,因为 OS 今天可能是 64 位的。但是,您也可以有一个 32 位的 32 位转储 OS,在这种情况下,这种方法效果不佳。
比较权威的做法是
.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 OS 转储,但我认为这样说是安全的
- 如果PEB32不为0,则为32位进程
- 如果PEB64为0,则为32位OS
如果知道模块名称,还可以查看文件头:
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
.NET决定
类似于WOW64层,可以检查.NET:
lm m mscorwks
lm m clr
lm m coreclr
当然可以通过 LoadLibrary()
直接从本机代码加载这样的 DLL,而不是使用 .NET,但我认为这是一种很少有人想愚弄你的用法。
是否有 Windbg/NTSD 命令告诉我在实时调试会话中附加的进程是 32 位进程还是 64 位进程?
你能告诉我两个吗:
- 非托管进程?
和
- 托管的?
对于托管的,我可以在 C# 中以编程方式找到它,但我仍然想知道是否有用于此的 Windbg 命令。
更新
我正在调试的目标进程是 Microsoft Word (winword.exe)。 Office 版本是 2016,但我不确定它是 32 位还是 64 位二进制文件。以下是一些观察结果:
目标位置是C:\Program Files (x86)\Microsoft Office\root\Office16\WinWord.exe
pipe (
|
) 命令只告诉我 PID,进程是否附加到调试器以及加载图像的路径(如中所述#1 以上)。我正在 64 位机器上调试它。所以,r 揭示了 64 位寄存器。
在附加到一个没有崩溃的实时、健康的进程后(我刚刚打开 MS Word 并说 "Attach to Process"),当前线程的调用堆栈 (
k
) 读取wow64cpu!CpupSyscallStub+0x9
用于最顶层的调用。这与#1 表明该进程是一个 32 位进程。
命令已经尝试过
- !peb(进程环境块):告诉我们处理器架构,而不是正在调试的进程的位数。
- |
- vertarget
- r(指示我的处理器的寄存器大小,但不告诉我有关过程)
但我想知道是否有办法找出答案。
32位/64位决定
为了快速测试我经常使用
lm m wow64
检查是否加载了 WOW64 层。如果是,则为 32 位进程。
这种方法在很多情况下都有效,因为 OS 今天可能是 64 位的。但是,您也可以有一个 32 位的 32 位转储 OS,在这种情况下,这种方法效果不佳。
比较权威的做法是
.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 OS 转储,但我认为这样说是安全的
- 如果PEB32不为0,则为32位进程
- 如果PEB64为0,则为32位OS
如果知道模块名称,还可以查看文件头:
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
.NET决定
类似于WOW64层,可以检查.NET:
lm m mscorwks
lm m clr
lm m coreclr
当然可以通过 LoadLibrary()
直接从本机代码加载这样的 DLL,而不是使用 .NET,但我认为这是一种很少有人想愚弄你的用法。