是否有 Windbg 命令来确定进程是 32 位还是 64 位?



是否有 Windbg/NTSD 命令告诉我在实时调试会话中附加到的进程是 32 位进程还是 64 位进程?

你能告诉我两个:

  1. 非托管流程?

  1. 一个托管的?

对于托管的,我可以在 C# 中以编程方式找到它,但我仍然想知道是否有用于此的 Windbg 命令。

更新

我正在调试的目标进程是Microsoft Word (winword.exe)。Office版本是2016年,但我不确定它是32位还是64位二进制文件。以下是一些观察结果:

  1. 目标位置是C:\Program Files (x86)\Microsoft Office\root\Office16\WinWord.exe

  2. pipe(|)命令只告诉我PID,进程是否附加到调试器以及加载图像的路径(如上面的#1中所述)。

  3. 我正在 64 位机器上调试它。因此,r 显示 64 位寄存器。

  4. 在附加到一个没有崩溃的实时、健康的进程后(我刚刚打开 MS Word 并说"附加到进程"),当前线程 (k) 的调用堆栈读取最顶层调用的wow64cpu!CpupSyscallStub+0x9。这与 #1 一起表明该进程是一个 32 位进程。

已尝试的命令

  1. !peb(进程环境块):告诉我们处理器体系结构,而不是正在调试的进程的位数。
  2. |
  3. 目标
  4. 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,但我认为这是想要愚弄您的人的罕见用法。

最新更新