Members of kernel32.lib
are not normal object files but special placeholders. From the PE/COFF spec:
Traditional import libraries, that is, libraries that describe the exports from one image for use by another, typically follow the layout described in section 7, “Archive (Library) File Format.” The primary difference is that import library members contain pseudo-object files instead of real ones, in which each member includes the section contributions that are required to build the import tables that are described in section 6.4, “The .idata Section.” The linker generates this archive while building the exporting application.
The section contributions for an import can be inferred from a small set of information. The linker can either generate the complete, verbose information into the import library for each member at the time of the library’s creation or write only the canonical information to the library and let the application that later uses it generate the necessary data on the fly.
[...] a short import library is written as follows:
Archive member header Import header Null-terminated import name string Null-terminated DLL name string
This is sufficient information to accurately reconstruct the entire contents of the member at the time of its use.
In kernel32.lib
on my machine, __imp_ExitProcess
is mentioned in the first and second linker members (symbol list) and point to the specific pseudo-object describing the import:
Archive member name at 8: /
50107C36 time/date Thu Jul 26 01:07:34 2012
uid
gid
0 mode
106CA size
correct header end
2515 public symbols
[...]
3C874 ExitProcess
3C874 __imp_ExitProcess
[...]
Archive member name at 3C874: KERNEL32.dll/
50107639 time/date Thu Jul 26 00:42:01 2012
uid
gid
0 mode
2D size
correct header end
Version : 0
Machine : 8664 (x64)
TimeDateStamp: 50107639 Thu Jul 26 00:42:01 2012
SizeOfData : 00000019
DLL name : KERNEL32.dll
Symbol name : ExitProcess
Type : code
Name type : name
Hint : 371
Name : ExitProcess
So, as you can see, the data in .lib explicitly says that it refers to an import name ExitProcess
from the DLL KERNEL32.dll
. The linker can use this to build necessary metadata in the import section.
Now, the above only discussed how the __imp_ExitProcess
symbol is resolved. I'm not 100% sure but I think if a symbol (e.g. ExitProcess
) has been resolved to such an import stub, and it does not start with __imp_
, then the linker has to generate a jump stub (for code symbols), or an indirect access (for data accesses) to the IAT slot.