Is it known what the differences between the Window 7 and Windows 8 PE loader are?

I'm trying to hand-craft a simple executable PE image file. It runs well in Windows 7, but is rejected by Windows 8.

The file is linked here: http://lars.nocrew.org/tmp/W7-ok.exe

Microsoft (R) COFF/PE Dumper Version 8.00.50727.762

Dump of file W7-ok.exe
PE signature found

             14C machine (x86)
               0 number of sections
               0 time date stamp Thu Jan 01 00:00:00 1970
               0 file pointer to symbol table
               0 number of symbols
              E0 size of optional header
             10F characteristics
                   Relocations stripped
                   Line numbers stripped
                   Symbols stripped
                   32 bit word machine

             10B magic # (PE32)
            0.00 linker version
               0 size of code
               0 size of initialized data
               0 size of uninitialized data
             24C entry point (0040024C)
               0 base of code
               0 base of data
          400000 image base (00400000 to 0040025B)
               4 section alignment
               4 file alignment
            0.00 operating system version
            0.00 image version
            4.00 subsystem version
               0 Win32 version
             25C size of image
             230 size of headers
               0 checksum
               3 subsystem (Windows CUI)
               0 DLL characteristics
               0 size of stack reserve
               0 size of stack commit
               0 size of heap reserve
               0 size of heap commit
               0 loader flags
               2 number of directories
               0 [       0] RVA [size] of Export Directory
             1B8 [       0] RVA [size] of Import Directory


The difference is that Windows 8 requires all regular structures (exports, imports, TLS, exception handlers, relocations... that is, everything described by Data Directory entries) to be located wholly inside a section. The only exception is the Bound Import Table, which is stored external to any section, to avoid "polluting" the contents, since the Bound Import Table data are discarded after use. The Bound Import Table is also meaningless in the presence of ASLR, anyway, since the addresses will almost never match.

In the absence of any section, you have to find the DLL bases and resolve the imports yourself.

If you create a single section to hold your import table, then it will load in both environments.

  • I added a single .text section to hold all code, data, and the import table. I have yet to test it in Windows 8. Dec 25 '15 at 9:06
  • I have now verified that this fixes the problem in Windows 8. Dec 29 '15 at 11:24
  • Also had to increase number of data directories from 2. 16 works, although all pointers except to the IAT are 0. Dec 30 '15 at 14:56
  • yes, I overlooked the count. It must be at least 13, to cover the IAT directory which is also checked by the loader. Dec 30 '15 at 16:42

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.