|Informative Information for the Uninformed|
The Import Address Table (IAT) of a PE image is used to store the absolute virtual addresses of functions that are imported from external PE images. When a PE image is mapped into virtual memory, the dynamic loader (in kernel-mode, this is ntoskrnl) takes care of populating the contents of the PE image's IAT based on the actual virtual address locations of dependent functions8. The compiler, in turn, generates code that uses an indirect call instruction to invoke imported functions. Each imported function has a function pointer slot in the IAT. In this fashion, PE images do not need to have any preconceived knowledge of where dependent PE images are going to be mapped in virtual memory. Instead, this knowledge can be postponed until a runtime determination is made.
The fundamental step involved in hooking an IAT entry really just boils down to changing a function pointer. What distinguishes an IAT hook from other types of function pointer hooks is the context in which the overwritten function pointer is called through. Since each PE image has their own IAT, any hook that is made to a given IAT will implicitly only affect the associated PE image. For example, consider a situation where both foo.sys and bar.sys import ExAllocatePoolWithTag. If the IAT entry for ExAllocatePoolWithTag is hooked in foo.sys, only those calls made from within foo.sys to ExAllocatePoolWithTag will be affected. Calls made to the same function from within bar.sys will be unaffected. This type of limitation can actually be a good thing, depending on the underlying motivations for a given backdoor.
Category: Type I; may legitimately be modified, but should point to expected values.
Origin: The origin of the first IAT hook is unclear. In January, 2000, Silvio described hooking via the ELF PLT which is, in some aspects, functionally equivalent to the IAT in PE images.
Capabilities: Kernel-mode code execution
Considerations: Assuming the calling restrictions of an IAT hook are acceptable for a given backdoor, there are no additional considerations that need to be made.
Covertness: It is possible for modern tools to detect IAT hooks by analyzing the contents of the IAT of each PE image loaded in kernel-mode. To detect discrepancies, a tool need only check to see if the virtual address associated with each function in the IAT is indeed the same virtual address as exported by the PE image that contains a dependent function.