import address table (IAT)

This is a discussion on import address table (IAT) within the C++ Programming forums, part of the General Programming Boards category; Hello everyone, 1. After my study, the address of IAT of an executable is known at compile/link time, other than ...

  1. #1
    Registered User
    Join Date
    May 2006
    Posts
    1,579

    import address table (IAT)

    Hello everyone,


    1.

    After my study, the address of IAT of an executable is known at compile/link time, other than known at load/runtime, right?

    I have this confusion because if an EXE needs to link with an import library, some of the instructions in the import library contains pointers to the address to the IAT entries of the EXE (right?) which needs to be fixed-up during load time. So, if IAT address is not known at compile/link time, import library will not be able to contain pointers to the address of IAT.

    2.

    IAT address of an EXE is some default address which has the same values for all EXE?


    thanks in advance,
    George

  2. #2
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,246
    The address table in an exe or DLL always assumes some base address (0x400000 If I remember correctly). The address values of a DLL are modified by an offset when the library is loaded. This offset is just the difference between 0x400000 and whatever address the DLL was actually loaded to.

    So at compile time, the only known address is the base address of 0x400000. It is up to the application loader to get the real addresses at runtime.

  3. #3
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Thanks bithub,


    It is good to know the address of IAT itself is known at compile/link time, and before load/runtime.

    Quote Originally Posted by bithub View Post
    The address table in an exe or DLL always assumes some base address (0x400000 If I remember correctly). The address values of a DLL are modified by an offset when the library is loaded. This offset is just the difference between 0x400000 and whatever address the DLL was actually loaded to.

    So at compile time, the only known address is the base address of 0x400000. It is up to the application loader to get the real addresses at runtime.

    regards,
    George

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    First of all, there is potentially more than one import address table in an executable file (both .EXE's and .DLL's count as executable here), as there would be one table PER DLL that is used by the executable. [These may well be in ONE long list, but the loader must know about each DLL being loaded and what functions are being used from each DLL].

    As to where in the executable this is, that's up to the linker. The compiler only knows that it needs to produce a stub for DLL-imports, nothing about where or how this gets put together to call the actual DLL.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,059
    The PE format uses RVAs (Relative Virtual Address). It is the value you need to add to the base address to get the linear address. The base address is the address the PE image is loaded to, and may vary from one invocation to the next.

    For example, suppose an executable file is loaded to address 0x400000 and execution starts at RVA 0x1560. The effective execution start will then be at the address 0x401560. If the executable were loaded to 0x100000, the execution start would be 0x101560.

    It becomes more complicated when the parts of the PE file (the sections) are not necessarily aligned the same way the loaded image is. For example, the sections of the file are often aligned to 512-byte-borders, but the loaded image may be aligned to 4096-byte-borders. So, to find a piece of information such as the IAT table in a PE-file for a specific RVA, you must calculate the offsets as if the file were loaded, but skip according to the file offsets.

    When a compiler finds a call to a function that is in a DLL, it will, in the very simplist sense, not know anything about the DLL function and simply output a normal call-instruction to that symbol, the address of which the linker will have to fix, like it does for any type of external symbol. The linker uses an import library to look up from which DLL which symbol is imported, and produces stubs for all the imported symbols, each of which consists of a jump instruction; the stubs are the actual call targets. These jump instructions will actually jump to an address that is acquired from the import address table. In more advanced applications (when "__declspec(dllimport)" is used), the compiler knows the function is imported, and outputs a call to the address that's in the import address table, bypassing the jump.

    Here is a link to a simple example for reading the IAT.
    Last edited by BobS0327; 02-19-2008 at 10:39 AM.

  6. #6
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Thanks Mats,


    1.

    I think you are wrong in below comments. The thunk is produced by linker, not compiler. Here is the related link from Microsoft. Any comments?

    http://support.microsoft.com/kb/132044/en-us

    --------------------
    the linker generates a thunk for which it does know the address.
    --------------------

    Quote Originally Posted by matsp View Post
    As to where in the executable this is, that's up to the linker. The compiler only knows that it needs to produce a stub for DLL-imports, nothing about where or how this gets put together to call the actual DLL.

    --
    Mats
    2.

    It is good to learn from you that the address of IAT is known by linker at link time/phase, and not in the load phase.


    regards,
    George


    Thanks BobS0327,


    From your comprehensive reply, I think maybe it is the reason that the address of DLL is not easily determined during link time, and only could be determined during load time, so that both linker and import library could not decide the addresses of DLL exported functions and they just point to the IAT entry.

    We have to use loader to fill-in the actual address of DLL exported functions during load time? Right?

    Quote Originally Posted by BobS0327 View Post
    The PE format uses RVAs (Relative Virtual Address). It is the value you need to add to the base address to get the linear address. The base address is the address the PE image is loaded to, and may vary from one invocation to the next.

    For example, suppose an executable file is loaded to address 0x400000 and execution starts at RVA 0x1560. The effective execution start will then be at the address 0x401560. If the executable were loaded to 0x100000, the execution start would be 0x101560.

    It becomes more complicated when the parts of the PE file (the sections) are not necessarily aligned the same way the loaded image is. For example, the sections of the file are often aligned to 512-byte-borders, but the loaded image may be aligned to 4096-byte-borders. So, to find a piece of information such as the IAT table in a PE-file for a specific RVA, you must calculate the offsets as if the file were loaded, but skip according to the file offsets.

    When a compiler finds a call to a function that is in a DLL, it will, in the very simplist sense, not know anything about the DLL function and simply output a normal call-instruction to that symbol, the address of which the linker will have to fix, like it does for any type of external symbol. The linker uses an import library to look up from which DLL which symbol is imported, and produces stubs for all the imported symbols, each of which consists of a jump instruction; the stubs are the actual call targets. These jump instructions will actually jump to an address that is acquired from the import address table. In more advanced applications (when "__declspec(dllimport)" is used), the compiler knows the function is imported, and outputs a call to the address that's in the import address table, bypassing the jump.

    Here is a link to a simple example for reading the IAT.

    regards,
    George

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. What does this do (Windows API)?
    By EVOEx in forum Windows Programming
    Replies: 4
    Last Post: 12-19-2008, 09:48 AM
  2. Writing array, to file
    By zootreeves in forum C Programming
    Replies: 9
    Last Post: 09-08-2007, 05:06 PM
  3. I thought pointers were pointers...
    By keira in forum C Programming
    Replies: 19
    Last Post: 08-15-2007, 11:48 PM
  4. DX - CreateDevice - D3DERR_INVALIDCALL
    By Tonto in forum Game Programming
    Replies: 3
    Last Post: 12-01-2006, 06:17 PM
  5. Im so lost at . .
    By hermit in forum C Programming
    Replies: 18
    Last Post: 05-15-2002, 01:26 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21