0
votes

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://docs.microsoft.com/en-us/windows/desktop/debug/pe-format#the-idata-section) does not cover this kind of .idata section.

2
It is technically possible, imports can be defined by name or by ordinal (a simple number). You don't need a lookup table when ordinals are used. It is unusual, but you can't show us your import statements anymore and said nothing about the linker. Best not to dwell on this. - Hans Passant
To clearify things: This is not an "import by name" versus "import by ordinal issue". Each entry in the "Import Lookup Table" and the "Import Address Table" can be a pointer to a name or an ordinal (depending whether the last bit is set). My problem is: there should be two tables with identical values (according to MS docs) but only the "Import Address Table" is there. - Christian Ammann
I suspect you're mistaken or CFF Explorer is showing you bad data. There should be three entries in the Import Directory Table, one for USER32.DLL, one for KERNEL32.DLL and an empty one with all zero values marking the end of the table. Each of these three entries will have its own "Import Lookup Table RVA" and "Import Address Table RVA" values. - Ross Ridge

2 Answers

1
votes

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.

0
votes

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.