Christian Ammann
Christian Ammann

Reputation: 938

64-Bit PE File without Import Lookup Table

I have a 64 bit hello world application for windows. It was created using the flat assembler (fasm). I do not have the source code anymore, but it is a very simple example which calls:

  1. MessageBoxA()
  2. ExitProcess()

I opened the file in a PE editor (CFF Explorer) and saw: The RVA of "Import Lookup Table" in the "Import Directory Table" is 0x0. Nevertheless, the "Import Address Table" RVA exists, contains pointers to API names and Windows 10 starts the program without complaints.

My question is: Does a PE specification exist which defines this kind of binary? Do other compilers have the same behaviour? Is it a PE+ thing?

Technically, a missing "Import Lookup Table" is no big deal because the same data is available in "Import Address Table" (although overwritten by the PE loader). But the Microsoft documentation (https://learn.microsoft.com/en-us/windows/desktop/debug/pe-format#the-idata-section) does not cover this kind of .idata section.

Upvotes: 1

Views: 1169

Answers (2)

Tobias
Tobias

Reputation: 672

You're either looking at a native image (only imports ntdll), you've bound the imports, or you are delay-loading everything. Or you're using a viewer that doesn't handle PE32+, which lacks a field in the optional header.

Edit: I re-read the question. If you look at the timestamp in the import table entry it is probably not zero, indicating bound imports.

Upvotes: 0

Martin Rosenau
Martin Rosenau

Reputation: 18523

I was writing some tool that parses .EXE files and I've seen such .EXE files, too.

The reason why such files exist is hinted in the Microsoft documentation that you have linked:

The RVA of the import lookup table. ... (The name "Characteristics" is used in Winnt.h, but no longer describes this field.)

For me, the sentence in brackets and the words "no longer" mean that older Windows versions used the "RVA of the import lookup table" field for storing different kind of information and therefore .EXE files written for these Windows versions had no import lookup table.

And because newer Windows versions should be able to run old executable files, recent Windows versions still seem to accept executable files which use that field for other information.

And on the other side some linkers or compilers still seem to fill this field with zero because Windows still accepts a value of zero here.

However, as far as I understand correctly, only 32-bit versions of Windows used this field for storing different kind of information. If this is true, only 32-bit .EXE files (written for older Windows versions) with this field set to zero should be valid.

This means that Microsoft may disable the support for 64-bit .EXE files that have this field set to zero in the future. And this means that a 64-bit linker or compiler setting this field to zero is buggy.

Upvotes: 1

Related Questions