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 (
When I use dumpbin to look at the image, I see that the PE header
185000 [ 2C6] RVA [size] of Delay Import
.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
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?