The Reko decompiler crashes while trying to load the PE delay import directory of a particular binary I'm looking at. For 32-bit executables, the PE spec states that the directory consists of a sequence of records where offset 4 contains:
[the] RVA of the name of the DLL to be loaded. The name resides in the read-only data section of the image (
szName
)
When I use dumpbin to look at the image, I see that the PE header
185000 [ 2C6] RVA [size] of Delay Import
And the .didata
section's raw data is:
00585000: 00 00 00 00 90 51 58 00 00 00 00 00 A0 50 58 00 .....QX......PX.
00585010: B4 50 58 00 C8 50 58 00 DC 50 58 00 00 00 00 00 �PX.�PX.�PX.....
(etc)
Notice that at 00585004, the szName
field has what looks to me a virtual address (00585190) and not a RVA (which would have been 00185190). Still, dumpbin manages to interpret this as:
USER32.DLL
00000000 Characteristics
00000000 Address of HMODULE
005850A0 Import Address Table
005850B4 Import Name Table
005850C8 Bound Import Name Table
005850DC Unload Import Name Table
0 time date stamp
where it follows the 00585190 to find the string USER32.DLL
.
So how should the entries in the Delay Import Directory be interpreted? Should a PE loader first attempt to read the szName
field as an RVA, and only when it discovers that it isn't a valid RVA, attempt to read it as VA?
Note that for small EXE files, which get loaded at address 0x0040000, the range of valid RVA's will be [0x00000000..MAX_RVA)
while the range of valid virtual addresses will be [0x00400000..MAX_RVA + 0x00400000]
, so RVA's and VA's could theoretically be distinguished by looking at their numerical values. But once the binary size exceeds 0x00400000 bytes (4194304 bytes) these ranges overlap and you can't tell the difference anymore.
Update: Interestingly, many PE viewers and editors crash or go off the rails on this binary. Dumpbin, IDA, and -- most significantly -- the Windows loader don't crash. Wonder what algorithm they are using to avoid dying on this binary?