是否有 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 并说"附加到进程"),当前线程 (
k
) 的调用堆栈读取最顶层调用的wow64cpu!CpupSyscallStub+0x9
。这与 #1 一起表明该进程是一个 32 位进程。
已尝试的命令
- !peb(进程环境块):告诉我们处理器体系结构,而不是正在调试的进程的位数。
- |
- 目标
- r(表示我的处理器的寄存器大小,并且不告诉我该过程)
但我想知道是否有办法找出答案。
32 位/64 位决策
对于我经常使用的快速测试
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 操作系统转储,但我认为可以肯定地说
- 如果 PEB32 不为 0,则为 32 位进程。
- 如果 PEB64 为 0,则为 32 位操作系统
如果您知道模块名称,还可以检查文件头:
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,但我认为这是想要愚弄您的人的罕见用法。