6

I have an .exe file that I am unable to run on Windows 10. I suspect that it is because the binary is 16 bit. Is there a simple way to check? Something like Alexander Revo's answer would be great.

8

Windows has extended the old DOS executable format multiple times, so if you look at a 'modern' Windows executable, right near the beginning there will be a MZ (or possibly ZM if the executable is for a system that uses the opposite bit order). This designates the header for the second DOS executable format, known simply as the MZ format.

Beyond that, you'll see some apparent gibberish, followed by something along the lines of 'This program can't be run in DOS mode.'. That gibberish is actually a really simple DOS program that prints out a message to tell the user that that program can't be run in DOS.

After that, you have the header for the actual executable, which may start with one of four pairs of letters, NE, LX, LE, or PE. If you don't see one of these and the above mentioned message, it's a 16-bit DOS application.

NE executables (known as 'New Executables') are currently deprecated. They were the first 'new' format extended form MZ, and were originally developed for Windows 1.0. They are always invariably 16-bit Windows executables, and were officially used with Windows 1.0-3.x, MS-DOS 4.0 (but not later versions), OS/2 1.x, and the OS/2 versions of Windows up through NT 5.0 (Windows 2000). These can not be run natively on 64-bit Windows, and will not properly display an application icon on 32-bit versions of Windows since Vista.

LX executables (one of two varieties of 'Linear Executables') are 32-bit executables in a format that was used by OS/2 2.x and newer, and by some DOS Extenders. These are not supported under any modern version of Windows (and I think they may never have been supported, though I'm not sure).

LE executables (the other type of 'Linear Executable') are an odd case, and may even technically contain 64-bit code. They were also introduced with OS/2 2.0 (just like LX executables), but were designed to be used for hardware drivers. The VxD driver model used in Windows 3.x and 9x utilized this format. They were never used for user applications, and thus are not at all supported on newer versions of Windows.

PE executables, more commonly known as 'Portable Executables' are the format used by modern Windows systems, and were designed for 32-bit code (and thus never supported 16-bit code). There is also an extension called 'PE32+', which is used for 64-bit Windows binaries, .NET CIL binaries (which are bit-width agnostic), and a number of other things which use different extensions (for example, UEFI drivers and applications, which use a .efi extension, are PE32+ format).

Using this information, you can use the same general check suggested in the answer you linked to in your question. If you just see the MZ and not the short message followed by some gibberish and then one of the four above letter pairs within the first 4kB of the file, it's just a DOS executable, otherwise, it's one of those four formats. The only one of those formats that should work natively on Windows 10 is the PE format.

As an example, here's a hexdump of the first 512 bytes of a 64-bit Windows executable (specifically, one of the components of the BOINC client software):

00000000: 4d5a 9000 0300 0000 0400 0000 ffff 0000  MZ..............
00000010: b800 0000 0000 0000 4000 0000 0000 0000  ........@.......
00000020: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000030: 0000 0000 0000 0000 0000 0000 1801 0000  ................
00000040: 0e1f ba0e 00b4 09cd 21b8 014c cd21 5468  ........!..L.!Th
00000050: 6973 2070 726f 6772 616d 2063 616e 6e6f  is program canno
00000060: 7420 6265 2072 756e 2069 6e20 444f 5320  t be run in DOS 
00000070: 6d6f 6465 2e0d 0d0a 2400 0000 0000 0000  mode....$.......
00000080: c88d b31c 8cec dd4f 8cec dd4f 8cec dd4f  .......O...O...O
00000090: 8594 4e4f 9aec dd4f e39a 414f 88ec dd4f  ..NO...O..AO...O
000000a0: 1fa2 454f 8eec dd4f e39a 434f 8eec dd4f  ..EO...O..CO...O
000000b0: e39a 774f 9fec dd4f e39a 764f 89ec dd4f  ..wO...O..vO...O
000000c0: 8594 5e4f 8dec dd4f 8594 594f 8dec dd4f  ..^O...O..YO...O
000000d0: 9771 414f 85ec dd4f 8cec dc4f 14ed dd4f  .qAO...O...O...O
000000e0: 9771 764f d0ec dd4f 9771 474f 8dec dd4f  .qvO...O.qGO...O
000000f0: 9771 404f 8dec dd4f 5269 6368 8cec dd4f  .q@O...ORich...O
00000100: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000110: 0000 0000 0000 0000 5045 0000 6486 0600  ........PE..d...
00000120: 4c88 ea5a 0000 0000 0000 0000 f000 2200  L..Z..........".
00000130: 0b02 0a00 00fe 0a00 0092 0b00 0000 0000  ................
00000140: c0e4 0800 0010 0000 0000 0040 0100 0000  ...........@....
00000150: 0010 0000 0002 0000 0500 0200 0000 0000  ................
00000160: 0500 0200 0000 0000 0020 1b00 0004 0000  ......... ......
00000170: 489f 1700 0300 4081 0000 1000 0000 0000  H.....@.........
00000180: 0010 0000 0000 0000 0000 1000 0000 0000  ................
00000190: 0010 0000 0000 0000 0000 0000 1000 0000  ................
000001a0: 0000 0000 0000 0000 8cc6 0e00 6801 0000  ............h...
000001b0: 0030 1400 9cd6 0600 00a0 1300 a884 0000  .0..............
000001c0: 0094 1600 2019 0000 0010 1b00 2001 0000  .... ....... ...
000001d0: e01c 0b00 1c00 0000 0000 0000 0000 0000  ................
000001e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000001f0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

Notice first the MZ in the first two bytes, followed by the data for the DOS program that tells you that it can't be run under DOS if you try to run it there, followed by the PE signature in bytes 280 and 281. You can also see these particular elements in a text editor, though it's a lot harder to read.

Note however that there is also the very real possibility that it's not a Windows executable at all, and someone just gave it the wrong name. Windows will usually recognize something as being a 16-bit executable and say that that's why it can't run it.

| improve this answer | |
  • "right near the beginning there will be a MZ" how are you seeing this? Hex editor? – Moab Jun 25 '18 at 20:50
  • @Moab Either one, though a text editor is a bit easier as every system has one. I'll update my answer tomorrow with an example. – Austin Hemmelgarn Jun 26 '18 at 1:42
  • What is the difference between LE and LX, other than 1 byte in the header? I wasn't able to find detailed documentation about LE online. How to detect whether an LE exacutable contains 16-bit or 32-bit code? – pts Apr 7 at 15:38
  • 1
    @pts I'm not actually sure myself. OS/2 was technically before my time and I've never really had enough experience dealing with it to know anything more about the binary formats it used other than what I've mentioned above. Documentation for both is severely lacking, but that's unfortunately normal when there was no real free software community to speak of for the platform. You might find some more info mong the documentation for the osFree project though. – Austin Hemmelgarn Apr 7 at 15:42
  • 1
    In the meantime I was able to find program-transformation.org/Transform/PcExeFormat which distinguishes LE and LX. For example, header fields 0x0 (signature) and 0x2c are different, and executable entries are different (e.g. they have the offset of entry point at different locations). – pts Apr 7 at 15:58
3

If Windows can't run your application because it's 16-bit, it will tell you this explicitly. There's no need to guess.

Windows 10 retains the same compatibility policy that previous versions have had; the 64-bit versions cannot run 16-bit software. The 32-bit version can run 16-bit software, but unlike previous versions, you'll need to add NTVDM support via Windows Features.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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