This is going to be a relatively long blog post, but I feel it may be useful since not much information is given on about how to find the IAT (Import Address Table) and EAT (Export Address Table) with WinDbg. There is some useful articles and blog posts on the subject, but I would like to add my own explanations and bring all the information together into one blog post. I’ll start with a description of the purpose of the tables and their general structure.
The IAT is simply a array of pointers which are loaded by the Image Loader. The IAT is used primarily as form of a lookup table, which is used to call function present in other library modules (.DLLs). Since the executable module will not the the know memory addresses of the libraries and it’s stored functions, it brings the in the purpose of the IAT. The IAT slots will be written with memory addresses by the linker.
The IAT is part of a larger data structure called the _IMAGE_IMPORT_DESCRIPTOR, which also contains another lookup table called the INT (Import Name Table), which is identical to the IAT.
The OriginalFirstThunk points to the Import Name Table and the FirstThunk points to the Import Address Table. We can find these in WinDbg, but it may take a little detective work to do so. We need to find the base address of the current image (executable module) and the address of the Import Directory, which is simple with the use of the !dh extension.
Using the dd command to dump the memory addresses of the Import Directory, we can see the relevant members mentioned earlier.
000220e8 is the address of the OriginalFirstThunk and the 00022330 is the address of the FirstThunk. Again, using the dd command we can dump these addresses using WinDbg.
The addresses shown are for the INT, and by using the dc command on one of the selected offsets with the base address, you will be able to view the name of the function. The current example didn’t produce much, since the program I was using was a very small program with one or two libraries.
We can display similar information with the FirstThunk, and I personally prefer using the FirstThunk since we can use the ln command with the address to find the exact function, which will be displayed cleanly with WinDbg.
Using the ln command, we can see the similar function name which was roughly shown with the INT:
We can use the !dh extension to load the PE Header Sections for a desired module, and then view the address of the IAT.
As mentioned before, since the IAT is a array of pointers, we can use the dps command to dump pointers with symbol information if provided.
This is only a small subset of the IAT, you can adjust the number of functions dumped by changing the dps parameters.
Now, we need to explore the EAT which is going to be a little more difficult to explore using WinDbg than the IAT. The EAT works in the same way as the IAT, apart from the library will be exporting the functions to the image executable, in which the program will import into the IAT.
We need to investigate the Export Directory which is a IMAGE_EXPORT_DIRECTORY data structure, used in the following format:
The AddressOfFunctions is the field which we are most interested in since this is the EAT. It also contains the RVAs (Relative Virtual Address) of the exported functions to be used by the PE Loader.
The AddressOfNames and AddressOfNameOrdinals are loaded alongside each other, to provide a linkage between the address of the function and the name of the function. The AddressOfNames is a pointer to a array of function names, and the AddressOfNameOrdinals is a pointer to a array used to index into the AddressOfFunctions to obtain the addresses for the function names.
Going back to the Export Directory and WinDbg, we can dump the Export Directory using similar methods as before.
I’ve highlighted the important addresses from the IMAGE_EXPORT_DIRECTORY (Export Directory) structure. The 00051dc is the AddressOfFunctions, the AddressOfNames is the 000b672c and the 000b7c7c is the AddressOfNameOrdinals.
Using the dd command to dump the AddressOfFunctions array, and then using the da command to dump each element of the array, we can see which functions are stored there.
Now we can use the da command to dump the exported function.
We could repeat this process for every exported function, but that would take a considerable amount of time, and there are easier methods than using WinDbg.
PeStudio can also be used to find the addresses of the IAT and EAT, and if these tables contain any functions. It also includes the size of the table.
Under the Imported Symbols, we can view the functions imported by the image executable, and if they potentially have a malicious intent. I’ve only shown the kernel32 based functions, since that was the library we were investigating using WinDbg.
We can view similar information with Dependency Walker, and selecting the desired library.
The columns are explained here.
In the future, I’ll look into the other PE Header Sections and look at IAT Hooking.
Additional Reading and References: