Skip to content

IAT Destruction & Rebuild

Les packers effacent ou redirigent la table des adresses d'import et résolvent les API via un thunk personnalisé à l'exécution, si bien qu'un dump statique n'a aucun import exploitable et doit être reconstruit avant analyse.

L'Import Address Table (IAT) est le tableau de pointeurs de fonctions que le chargeur Windows remplit pour qu'un programme puisse appeler kernel32!CreateFileW et consorts. Les packers détruisent cette visibilité : une fois le code d'origine décompacté, soit ils mettent l'IAT à zéro et re-résolvent chaque API à la demande, soit ils font pointer chaque entrée de l'IAT vers un thunk résolveur personnalisé qui ne recherche la vraie fonction qu'au moment de l'appel. Un dump mémoire pris au point d'entrée d'origine contient donc le bon code mais une table d'imports cassée et illisible, et le dump ne se chargera ni ne s'analysera correctement tant que les imports ne sont pas reconstruits.

Fonctionnement

Chaque site d'appel est redirigé via un stub qui masque la cible réelle. Un schéma courant stocke un identifiant d'API obfusqué et le résout paresseusement :

asm
; original:  call dword ptr [IAT_CreateFileW]
; packed:    call resolver_thunk_0042

resolver_thunk_0042:
    push  0xA1B2C3D4         ; obfuscated (dll-hash << 16 | api-hash)
    call  resolve_api        ; walk PEB -> module list -> export table
    jmp   eax                ; tail-jump into the resolved API

resolve_api:                 ; returns the real function address in eax
    ; ... hash each export name, compare, return match ...
    ret

Comme l'entrée de l'IAT contient désormais un pointeur dans la mémoire propre au packer (ou zéro), les outils qui lisent le répertoire d'imports sur le disque ne voient rien d'exploitable.

Détection & contournement

  • Static — Le répertoire d'imports est minuscule, vide ou pointe en dehors de toute section nommée. PE-bear affiche un onglet imports quasi vide et une RVA d'IAT qui tombe dans une région à forte entropie. Un motif call/jmp eax répété précédé d'un push <constante> est l'empreinte du thunk résolveur.
  • Dynamic — Exécutez jusqu'à l'OEP (astuce ESP, ou point d'arrêt après le tail jump qui sort du stub), puis dumpez l'image du processus pendant qu'elle est entièrement décompactée. Tracez un appel au résolveur pour confirmer si les entrées sont remplies sur place ou remplacées par des thunks ; posez un point d'arrêt dans resolve_api pour énumérer les API demandées.
  • Rebuild — Pointez Scylla (ou ImpREC) sur le processus en cours, fixez l'OEP, et lancez IAT Autosearch puis Get Imports. Scylla parcourt l'IAT, résout chaque pointeur en module!export et écrit une table d'imports neuve dans le dump (Fix Dump). Pour les IAT redirigées par thunk, laissez le résolveur s'exécuter une fois par entrée pour que les pointeurs soient concrets, puis lancez l'autosearch ; sinon, tracez le résolveur pour mapper chaque thunk à son API manuellement.
  • Tools — x64dbg avec le plugin Scylla (dump à l'OEP + reconstruction de l'IAT), ImpREC (autosearch historique et réparation de thunks) et PE-bear (inspection et validation du répertoire d'imports reconstruit).
Votes

Commentaires(0)