I am attempting to understand the PE File Format and I have come across an unexpected value in the IMAGE_THUNK_DATA Array.

Here are the file details:
MD5: d82d3e003eb5c728d584e22ce7f36fbf
File Name: ChromeSetup.exe Link: hxxps://www[.]google[.]com/chrome/thank-you.html?platform=win64&statcb=1&installdataindex=empty&defaultbrowser=0

(After some testing, I found out that the hash changes but the issue is the same.)

The issue I'm facing is that in one of the DLLs that is present, the IMAGE_THUNK_DATA structure contains an additional DWORD that is out-of-bounds. Here's the attached screenshot:

Out-of-Bounds DWORD:

That first block i.e. (48fe 0100), resolves perfectly to "SHGetFolderPathW". But that second block (a8020080) is out of bounds - adjusting for endian format, we get 0x800002a8 - but the file itself is present up till 0x14DE2A (verified via 010 Editor and xxd). The third block signifies the end of the IMAGE_THUNK_DATA array so no issues there.

I've checked using 010 Editor and it shows "SHGetFolderPathW" as the only function imported from SHELL32.dll. I'd greatly appreciate some help understanding why that second block is present if no function name resolves to that address, which is out-of-bounds by itself?

  • 3
    Iirc the msb (0x80000000) indicates pure import by ordinal and no name look up import by ordinal stuff
    – blabb
    May 4, 2023 at 13:05
  • @blabb, looks like you are correct. In an old MSDN article, the setting of the high-bit is indicative of how the value is to be interpreted - either as an ordinal or a RVA. In this case, the value 0x800002A8 has the high-bit set so it is to be interpreted as an ordinal. The last 31-bits, when converted to decimal, give 680. May 4, 2023 at 14:45
  • 1
    This would mean that the executable is stating to the loader that the first function ("SHGetFolderPathW") is to be loaded by name but the second one is to be loaded by ordinal (680) right? This leads me to another question - are ordinals set in stone or do they change as well? May 4, 2023 at 14:45
  • Why should anything be set in granite you give a ordinal either it returns back an address to the function that matches the ordinal pass or returns error. Today 680 maybe shwhatever tommorow it can be shsomeother doesnt matter does it?
    – blabb
    May 5, 2023 at 4:21

1 Answer 1


As I commented if the Most significant Bit (31 for x86 or 63 for x64)
is set then the import is done by ordinal and no name lookup is done.

the msdn article by matt pietrek is still gold but if you need a latest reference

ordinals can change be added be removed or be converted to name lookup

in an x64 win 10 machine using dumpbin from vs i can see shell32 export ordinal number 680 is the function IsUserAnAdmin()

dumpbin /exports c:\Windows\System32\shell32.dll | grep -iE "ordinal hint| 680"
    ordinal hint RVA      name
        680   57 002752A0 IsUserAnAdmin

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.