IAT hook je další z celé řady hooků používaných ať už těmi „zlými“ (autory malware, rootkitů aj.) nebo těmi „hodnými“ (antiviroví vývojáři, gamehackeři, případně běžní vyvojáři).

Jeho cílem je, jak název napovídá, zahookovat adresy funkcí v tabulce importovaných funkcí modulu. Jinými slovy, jedná se o funkce, které jsou fyzicky přítomny v jiných modulech (např. v DLL knihovnách), než ze kterého jsou volány.

Jak tedy bude celý kód fungovat? Nejprve si musíme najít v paměťovém prostoru modulu tabulku importovaných funkcí (Import Address Table), v ní nasledně dohledáme adresu funkce, kterou chceme zahookovat a přepíšeme ji na adresu naší funkce, jež bude zpracovávat volaní místo originální funkce. Jak je tedy vidno, princip je podobný EAT hooku.

#include <windows.h>
#include <stdio.h>
 
// function datatype definition
typedef void (WINAPI *oldexitprocess)(UINT uExitCode);
 
// variable for keeping of original ExitProcess address
oldexitprocess OldExitProcess = NULL;
 
 
void WINAPI NewFunc(UINT uExitCode);
 
int IatHook(HMODULE hModule, LPCSTR lpProcName, VOID *NewAddress, VOID **OldAddress){
  PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)hModule;
  PIMAGE_NT_HEADERS pNtHdrs;
  PIMAGE_IMPORT_DESCRIPTOR pImportDescript;
  PIMAGE_THUNK_DATA pThunkData;
  PDWORD pAddress = NULL;
  DWORD i = 0, dwOldProtect;
 
  // is this PE file?
  if(pDosHdr->e_magic != 0x5A4D)
    return 0;
 
  // calculate PE Virtual Address
  pNtHdrs = (PIMAGE_NT_HEADERS)((DWORD)(pDosHdr->e_lfanew) + (DWORD)hModule);
 
  // is this NT Headers?
  if(pNtHdrs->Signature != 0x00004550)
    return 0;
 
  // calculate pointer at IMAGE_IMPORT_DESCRIPTOR
  pImportDescript = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)(pNtHdrs->OptionalHeader.DataDirectory[1].VirtualAddress) +
                                               (DWORD)hModule);
 
  // FirstThunk is Relative Virtual Address to Import Address Table
  // if bound this IAT has actual addresses
  while(pImportDescript->FirstThunk){
    pThunkData = (PIMAGE_THUNK_DATA)((DWORD)(pImportDescript->OriginalFirstThunk) +
                                     (DWORD)hModule);
    while(pThunkData->u1.Function){
      // is this function that we are looking for?
      if(lstrcmpA((char *)((DWORD)(pThunkData->u1.AddressOfData) + (DWORD)hModule + 2), lpProcName) == 0){
        // get address of function in IAT
        pAddress = (PDWORD)((DWORD)(pImportDescript->FirstThunk) + 
                            (DWORD)hModule) + 
                            i;
 
        // set READWRITE privileges for memory region
        if(VirtualProtect((VOID *)pAddress, sizeof(DWORD), PAGE_READWRITE, &dwOldProtect) == 0)
          return 0;
 
        // save old function address
        *OldAddress = (VOID *)(*pAddress);
 
        // overwrite function address in IAT with new address
        *((PDWORD)pAddress) = (DWORD)NewAddress;
 
        // restore memory privileges
        if(VirtualProtect((VOID *)pAddress, sizeof(DWORD), dwOldProtect, &dwOldProtect) == 0)
          return 0;
 
        return 1;
      }
     i++;
      pThunkData++;
    }
    pImportDescript++;
  }
 
  return 0;
}
 
 
void WINAPI NewFunc(UINT uExitCode){
  MessageBoxA(NULL, "This Win API function isn't original ExitProcess.", "ExitProcess hooked", NULL);
  OldExitProcess(uExitCode);
}
 
int main(){
  IatHook(GetModuleHandle(0),"ExitProcess", (VOID *)&NewFunc, (VOID **)&OldExitProcess);
  printf("Function ExitProcess was hooked. Press any key..\n");
  getchar();
 
  ExitProcess(0);
}