Reading the IAT to infer malware behaviour before execution — suspicious API patterns, what a stripped IAT means, and how to use PEStudio to map capabilities from imports alone.
⚡ Quick Bite · 40s
The Import Address Table as the best window into malware behavior — how Windows populates dependencies, spotting suspicious process injection APIs, and understanding dynamic API resolution.
Watch this 40-second summary before diving into the full article. Sign in to earn 5 leaderboard points.
The Import Address Table (IAT) lists the external functions from Windows DLLs that the program calls. When Windows loads a PE file, it resolves the addresses of all imported functions and writes them into the IAT. The program then calls these functions through the IAT entries.
Examining the IAT reveals a great deal about a binary's intended behaviour without running it. Every imported function is a capability declaration.
Open any PE file in PEStudio. Navigate to the Imports tab. For each imported DLL, you see the function names. PEStudio automatically flags known suspicious functions in red.
Look for:
wininet.dll, ws2_32.dll)kernel32.dll with injection APIs)advapi32.dll with Reg* functions)crypt32.dll, bcrypt.dll)| Imported Function(s) | Behavioural Indication |
|---|---|
CreateFileA/W, WriteFile, DeleteFileA/W | File manipulation. Dropping payloads or deleting evidence. |
RegOpenKeyExA/W, RegSetValueExA/W | Registry modification. Establishing persistence via Run key. |
VirtualAlloc, VirtualProtect | Memory allocation with custom permissions. Strong indicator of shellcode injection or runtime unpacking. |
CreateRemoteThread, WriteProcessMemory | Code injection into another process. |
OpenProcess with PROCESS_ALL_ACCESS | Targeting another process for injection or hollowing. |
InternetOpenA, HttpSendRequestA | HTTP communication. Likely contacting a C2 server. |
URLDownloadToFileA | Single-call downloader pattern. Downloads payload from URL. |
GetAsyncKeyState, SetWindowsHookExA | Keyboard monitoring. Keylogger behaviour. |
IsDebuggerPresent, CheckRemoteDebuggerPresent | Anti-debugging checks. |
CreateProcessA/W | Process creation. May spawn cmd.exe or powershell.exe. |
FindResource, LoadResource, LockResource | Extracts embedded payload from PE resources. Dropper pattern. |
CryptEncrypt, CryptGenKey | Cryptographic operations. May indicate ransomware. |
A binary whose import table contains only LoadLibraryA and GetProcAddress is resolving its real imports at runtime to hide them from static analysis.
Normal binary IAT:
kernel32.dll: CreateFileA, WriteFile, VirtualAlloc, CreateProcessA...
wininet.dll: InternetOpenA, HttpOpenRequestA, HttpSendRequestA...
advapi32.dll: RegOpenKeyExA, RegSetValueExA...
Packed/obfuscated binary IAT:
kernel32.dll: LoadLibraryA, GetProcAddress
The malware uses LoadLibraryA to load any DLL at runtime and GetProcAddress to resolve any function by name — leaving nothing visible to static analysis. This is characteristic of packed or manually-mapped executables.
Next action when you see a stripped IAT: check entropy, check section names, run DIE. The binary is almost certainly packed — unpack it before proceeding.
Some malware resolves imports without calling LoadLibraryA at all. It computes a hash of each API name and walks the export table of loaded DLLs to find a matching hash. No import table entry is created.
; API hashing loop (simplified)
hash_loop:
mov eax, [esi] ; load current export name
call compute_hash ; compute custom hash of name
cmp eax, 0xDEADBEEF ; compare to target hash
je found ; if match, use this function address
add esi, 4 ; next export
jmp hash_loop
The hardcoded hash values (0xDEADBEEF in this example) are the only trace of the intended API call. Finding these in a disassembler requires computing the hash function in reverse — or running the sample and breaking when the hash matches.
Rather than manually reading every import, run Capa (Mandiant) on the binary:
capa suspicious.exe
Capa maps code patterns to behavioural capabilities and MITRE ATT&CK techniques:
+------------------------------------------------------+
| CAPABILITY | NAMESPACE |
+------------------------------------------------------+
| delete shadow copies | impact |
| query registry | discovery |
| communicate via HTTP | c2 |
| capture keystrokes | collection |
+------------------------------------------------------+
Capa reads more than just the IAT — it analyses code patterns and recognises capability implementations even when imports are stripped.
1. Open in PEStudio → check Imports tab
2. If IAT is stripped (only LoadLibrary + GetProcAddress):
→ check entropy → confirm packing → unpack first
3. If IAT is visible:
→ flag suspicious API groups from the table above
→ run Capa for behavioural capability summary
→ note APIs as predicted IOCs before dynamic analysis
4. Compare predicted behaviour against dynamic analysis results
Predicted behaviour from the IAT becomes a hypothesis. Dynamic analysis confirms or refutes it.
Sign in to mark this article as read and track your progress.