Dynamic Import Resolution
Au lieu d'une table d'imports normale, le programme résout les API à l'exécution via LoadLibrary et GetProcAddress sur des chaînes chiffrées, laissant l'IAT statique quasi vide et l'analyste aveugle.
La résolution dynamique d'imports cache les API qu'un programme utilise en refusant
de les déclarer dans l'Import Address Table (IAT). À l'exécution, le code appelle
LoadLibraryA pour obtenir un handle de module et GetProcAddress pour rechercher
chaque fonction par son nom, en utilisant des chaînes déchiffrées ou reconstruites
sur la pile. L'IAT statique ne liste alors que quelques fonctions de chargement, si
bien qu'un triage rapide ne révèle presque rien du comportement du malware. Cette
technique est distincte du hachage d'API, qui résout les fonctions par un hachage
de leur nom plutôt que par le nom en clair.
Fonctionnement
Le programme ne référence jamais l'API cible directement. Il construit le nom de la
DLL et de la fonction (souvent déchiffré ou assemblé octet par octet pour déjouer la
recherche de chaînes), résout l'adresse et l'appelle. L'IAT ne contient que
LoadLibraryA et GetProcAddress.
// static IAT shows nothing useful; everything is resolved at runtime
char dll[] = decrypt("kernel32.dll");
char name[] = decrypt("VirtualAlloc"); // also built on the stack
HMODULE h = LoadLibraryA(dll);
FARPROC fn = GetProcAddress(h, name); // <-- real API recovered here
void *mem = ((PFN_VirtualAlloc)fn)(0, len, MEM_COMMIT, PAGE_RWX);Détection & contournement
- Statique — Dans IDA/Ghidra, la vue des imports est quasi vide à l'exception de
LoadLibraryA/GetProcAddress. Les appels passent par des pointeurs en registre (call rax) plutôt que par des thunks nommés, et l'on voit des stubs de déchiffrement ou de construction de chaînes sur la pile alimenter les appels de chargement. Les références croisées depuisGetProcAddresscartographient les sites de résolution. - Dynamique — Posez des points d'arrêt de journalisation conditionnels sur
LoadLibraryAetGetProcAddress, journalisez le nom demandé (argument) et l'adresse retournée (rax/eax), et vous obtenez immédiatement la liste complète des API résolues et l'emplacement de chaque pointeur. L'Interceptor de Frida ou API Monitor capturent la même correspondance sans scripter de points d'arrêt. - Patch / simplification — Annotez chaque pointeur résolu avec le vrai nom d'API dans le désassembleur, puis dumpez le processus et reconstruisez une IAT correcte afin que le listing devienne lisible et ré-exécutable.
- Outils — Points d'arrêt de journalisation conditionnels de x64dbg, Scylla ou ImpRec pour la reconstruction d'IAT sur un dump, l'Interceptor de Frida pour le hooking à chaud, et API Monitor.