Reputation: 927
The PE format specification states that
All image files that import symbols, including virtually all executable (EXE) files, have an .idata section.
But I've notices that while it's true for debug builds, It's not true for release builds (at least when compiling with VS2010).
Visual Studio merges the IAT & Import Directory (and some other directories as well) together with the read-only data into .rdata section (I guess this is done to save space and load time).
It's easy enough to determine the location and size of both IAT & Import Directory (reading the directories information), But I couldn't find a way to determine where the actual data (read-only initialized data) starts and ends.
So, Is there any way to get that information out of the PE header?
Thanks
Upvotes: 0
Views: 960
Reputation: 8166
But I've notices that while it's true for debug builds, It's not true for release builds (at least when compiling with VS2010).
Different Microsoft linker versions produce different PE files. For example, on an up-to-date Win 8.1 Update 1 (x64) system, most system (from system32 / syswow64) PE files have an .idata section (the [Major|Minor]LinkerVersion field from the optional header report a 11.0 linker version, so that is the VS2012 linker).
But you're right, some older linkers produce merged sections.
Visual Studio merges the IAT & Import Directory (and some other directories as well) together with the read-only data into .rdata section (I guess this is done to save space and load time).
Once again this depends on the linker version. Older linker versions have the habit of merging the import directory and IAT into the code (.text) section, as the code section is read only by default. I have an old version of comctl32.ocx (in SysWOW64) in my system that exhibits this behavior (linker is reported to be v3.10 ...).
It's easy enough to determine the location and size of both IAT & Import Directory (reading the directories information), But I couldn't find a way to determine where the actual data (read-only initialized data) starts and ends.
So, Is there any way to get that information out of the PE header?
I suppose here that by 'actual data', you mean read-only data used by the code section.
No, not precisely. As you mentionned, nothing from the PE header directly references the read-only data that are usually used by the code. So you must fallback on heuristics, knowing you wont achieve a 100% certainty on read-only data discovery.
In case where the Import directory and the IAT are merged with read-only data, one possibility could be to subtract the size and addresses of both import directory and IAT: everything that is not part of the import would then be read-only data (you have the total raw-size of the section in the section headers).
Firstly, this doesn't mean that read-only data will be contiguous: the IAT is usually located at the start of the section and sometimes the import directory is pushed somewhere else, with read-only data (used by the code, for example) everywhere around.
Secondly, you can't really know if other read-only data will be placed inside the section by the linker (except if those data are referenced by one or more data directories), as the linker has the right to merge sections that have exactly the same attributes (usually something alongIMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA
).
Upvotes: 1