Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a Windbg command to find out if a process is a 32-bit one or a 64-bit one?

Is there a Windbg/NTSD command to tell me if a process I have attached to in a live debugging session is a 32-bit one or a 64-bit one?

Could you please tell me for both:

  1. An unmanaged process?

and

  1. A managed one?

For a managed one, I can find that out programmatically in C# but still I'd like to know if there's a Windbg command for this.

UPDATE

The target process I am debugging is Microsoft Word (winword.exe). The Office version is 2016 but I am not sure if it is a 32-bit or a 64-bit binary. Here are some observations:

  1. The target location is C:\Program Files (x86)\Microsoft Office\root\Office16\WinWord.exe

  2. The pipe (|) command tells me nothing more than PID, whether the process is attached to the debugger or not and the path from where the image is loaded (as noted in #1 above).

  3. I am debugging this on a 64-bit machine. So, r reveals 64-bit registers.

  4. Upon attaching to a live, healthy process with no crashes (I just opened MS Word and said "Attach to Process"), the callstack for the current thread (k) reads wow64cpu!CpupSyscallStub+0x9 for the top-most call. This, with #1 suggests that the process is a 32-bit process.

Commands already tried

  1. !peb (Process Environment Block): Tells us the PROCESSOR ARCHITECTURE, not the bitness of the process being debugged.
  2. |
  3. vertarget
  4. r (indicates register size for my processor and does not tell me about the process)

But I'm wondering if there's a way to find out.

like image 755
Water Cooler v2 Avatar asked Apr 09 '17 15:04

Water Cooler v2


1 Answers

32 bit / 64 bit decision

For a quick test I often use

lm m wow64

which checks if the WOW64 layer was loaded. If so, it's a 32 bit process.

This approach works in many cases, because OS is likely 64 bit today. However, you could also have a 32 bit dump of a 32 bit OS, in which case this approach does not work well.

A more authorative approach is

.load wow64exts
!info

which gives a lot of output unfortunately, so it'll be hard to use in a script.

The 32 bit output looks like

0:000> !info

PEB32: 0xe4d000
PEB64: 0xe4c000

Wow64 information for current thread:

TEB32: 0xe50000
TEB64: 0xe4e000

[...]

In case of 64 bit it is

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

[...]

I don't have a 32 bit Windows OS dump available, but I assume it's safe to say that

  • if PEB32 is not 0, it's a 32 bit process.
  • if PEB64 is 0, it's a 32 bit OS

If you know the module name, you can also inspect the file headers:

0:000> .shell -ci "!dh -f notepad" findstr "machine"
    8664 machine (X64)
.shell: Process exited

Things that do not work

vertarget as suggested in the comments does not work well for 64 bit crash dumps of 32 bit applications.

$ptrsize would have been so nice, but it depends on the debugger mode:

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 decision

Similar to the WOW64 layer, you can check for .NET:

lm m mscorwks
lm m clr
lm m coreclr

Of course it might be possible to load such a DLL via LoadLibrary() from native code directly and not using .NET, but I think that's a rare usage of someone who wants to fool you.

like image 92
Thomas Weller Avatar answered Oct 13 '22 16:10

Thomas Weller