Sign up ×
Reverse Engineering Stack Exchange is a question and answer site for researchers and developers who explore the principles of a system through analysis of its structure, function, and operation. It's 100% free, no registration required.

How to check if Windows executable is 64-bit reading only its binary. Without executing it and not using any tools like the SDK tool dumpbin.exe with the /headers option.

share|improve this question

3 Answers 3

up vote 19 down vote accepted

Executable type is indicated by PE header, download documentation.

The first word (two bytes) of PE header indicates target machine, here is a list of possible values:

0x0000 - The contents of this field are assumed to be applicable to any machine type
0x01d3 - Matsushita AM33
0x8664 - x64
0x01c0 - ARM little endian
0x01c4 - ARMv7 (or higher) Thumb mode only
0xaa64 - ARMv8 in 64-bit mode
0x0ebc - EFI byte code
0x014c - Intel 386 or later processors and compatible processors
0x0200 - Intel Itanium processor family
0x9041 - Mitsubishi M32R little endian
0x0266 - MIPS16
0x0366 - MIPS with FPU
0x0466 - MIPS16 with FPU
0x01f0 - Power PC little endian
0x01f1 - Power PC with floating point support
0x0166 - MIPS little endian
0x01a2 - Hitachi SH3
0x01a3 - Hitachi SH3 DSP
0x01a6 - Hitachi SH4
0x01a8 - Hitachi SH5
0x01c2 - ARM or Thumb (“interworking”)
0x0169 - MIPS little-endian WCE v2

So to check if it is 64-bit, we need to look for:

0x8664 - x64
0xaa64 - ARMv8 in 64-bit mode
0x0200 - Intel Itanium processor family

And as Bob mentioned, here is a list of some more machine types (see 11 pg.), however it is not very likely to find them.

share|improve this answer
Don't forget 0x0200 (Itanium). That would be IA-64, as opposed to x86-64 (AMD64). There's a couple more "64-bit" machine types possible, but you're very unlikely to find them in the wild (0x0284 is the 64-bit Alpha AXP, from the 1999 documentation, and not supported by Windows after NT4/2000RC). – Bob Aug 8 '14 at 10:55
@Bob Thank, edited to include your info. – ST3 Aug 8 '14 at 11:09
For a visual reference, image showing the location of the PE header with 0x8664 (highlighted): (notepad++ hex-editor plugin) – zamnuts Aug 8 '14 at 14:47
To quickly find the target machine value: Take the DWORD at offset 0x3C. Add four to this value. That is the offset of the Machine WORD. (Both are little endian) – user1354557 Aug 25 '14 at 21:45
Where do you find 0xaa64 - ARMv8 in 64-bit mode? I have not such #define in winnt.h. – SerG Feb 12 at 14:34

It's easier to check Magic of Optional Header.

For a valid exe, only two values are possible:

0x10B - PE32  - 32 bit
0x20B - PE32+ - 64 bit
share|improve this answer

dumping the contents of ST3's answer into a powershell snippet in a ready to use format

if($args.Count -eq 0) { "provide a file name or path to file";exit }
if((test-path -path $args) -ne $true) { "file doesnt seem to exist" ; exit }
$fs = New-Object IO.Filestream($args , [Io.FileMode]::Open)
$br = New-Object IO.BinaryReader($fs)
if($br.Readchar()-ne'M'){"no mz";exit};if($br.Readchar()-ne'Z'){"no mz";exit}
$fs.Seek(0x3c,[IO.SeekOrigin]::Begin) | Out-Null
$elfaw_new = $br.ReadUInt32();
if($br.Readchar()-ne'P'){"no pe";exit};if($br.Readchar()-ne'E'){"no pe";exit}
$mctypeoff = $$peheader+4,[IO.SeekOrigin]::Begin)
$mctype= $br.ReadUInt16()
switch($mctype) {
  0x0000 { "{0:x4} {1}" -f  $mctype , "Unknown machine type"}
  0x01d3 { "{0:x4} {1}" -f  $mctype , "Matsushita AM33"}
  0x8664 { "{0:x4} {1}" -f  $mctype , "x64"}
  0x01c0 { "{0:x4} {1}" -f  $mctype , "ARM little endian"}
  0x01c4 { "{0:x4} {1}" -f  $mctype , "ARMv7 (or higher) Thumb mode only"}
  0xaa64 { "{0:x4} {1}" -f  $mctype , "ARMv8 in 64-bit mode"}
  0x0ebc { "{0:x4} {1}" -f  $mctype , "EFI byte code"}
  0x014c { "{0:x4} {1}" -f  $mctype , "Intel 386 or later family processors"}
  0x0200 { "{0:x4} {1}" -f  $mctype , "Intel Itanium processor family"}
  0x9041 { "{0:x4} {1}" -f  $mctype , "Mitsubishi M32R little endian"}
  0x0266 { "{0:x4} {1}" -f  $mctype , "MIPS16"}
  0x0366 { "{0:x4} {1}" -f  $mctype , "MIPS with FPU"}
  0x0466 { "{0:x4} {1}" -f  $mctype , "MIPS16 with FPU"}
  0x01f0 { "{0:x4} {1}" -f  $mctype , "Power PC little endian"}
  0x01f1 { "{0:x4} {1}" -f  $mctype , "Power PC with floating point support"}
  0x0166 { "{0:x4} {1}" -f  $mctype , "MIPS little endian"}
  0x01a2 { "{0:x4} {1}" -f  $mctype , "Hitachi SH3"}
  0x01a3 { "{0:x4} {1}" -f  $mctype , "Hitachi SH3 DSP"}
  0x01a6 { "{0:x4} {1}" -f  $mctype , "Hitachi SH4"}
  0x01a8 { "{0:x4} {1}" -f  $mctype , "Hitachi SH5"}
  0x01c2 { "{0:x4} {1}" -f  $mctype , "ARM or Thumb (`“interworking`”)"}
  0x0169 { "{0:x4} {1}" -f  $mctype , "MIPS little-endian WCE v2"}

usage as follows

:\>powershell -f binstreamtest.ps1
provide a file name or path to file

:\>powershell -f binstreamtest.ps1 1
file doesnt seem to exist

:\>powershell -f binstreamtest.ps1 shell32.dll
014c Intel 386 or later family processors

:\>powershell -f binstreamtest.ps1 c:\WINDOWS\system32\ntkrnlpa.exe
014c Intel 386 or later family processors

:\>powershell -f binstreamtest.ps1 xxx\test32.exe
014c Intel 386 or later family processors

:\>powershell -f binstreamtest.ps1 xxx\test64.exe
8664 x64
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.