PE Header Erasure (Anti-Dump)
Après le chargement, le stub met à zéro l'en-tête PE en mémoire ou corrompt SizeOfImage, si bien que les dumpers mémoire qui s'appuient sur l'en-tête échouent, forçant l'analyste à reconstruire l'en-tête avant de pouvoir analyser un dump.
La plupart des dumpers mémoire localisent un module en lisant son en-tête PE en mémoire : les signatures MZ/PE, l'en-tête optionnel et la table des sections indiquent à l'outil où commence l'image, sa taille et comment disposer les sections. L'effacement de l'en-tête PE attaque cette hypothèse. Une fois que Windows a mappé et relocalisé l'image, le stub écrase l'en-tête — en mettant à zéro la signature MZ/PE et la table des sections, ou simplement en corrompant SizeOfImage — si bien qu'un dumper qui recherche des en-têtes ne trouve rien, ou calcule une taille d'image erronée et produit un dump tronqué et inanalysable.
Fonctionnement
Le chargeur n'a besoin de l'en-tête que jusqu'à ce que l'image soit mappée ; ensuite il le détruit sur place :
// after the loader has mapped + relocated the image at 'base'
IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER *)base;
IMAGE_NT_HEADERS *nt = (IMAGE_NT_HEADERS *)((BYTE *)base + dos->e_lfanew);
// option A: nuke the signatures so scanners can't find the module
RtlZeroMemory(base, nt->OptionalHeader.SizeOfHeaders);
// option B: leave the header but lie about the size
nt->OptionalHeader.SizeOfImage = 0x1000; // dumper grabs one page onlyL'exécution se poursuit normalement car l'OS ne consulte plus l'en-tête, mais tout outil qui le relit voit des données corrompues.
Détection & contournement
- Static — Sans objet par définition : l'effacement a lieu à l'exécution. Sur le disque, le fichier possède toujours un en-tête ; l'astuce ne se manifeste qu'en mémoire.
- Dynamic — Dans le débogueur, inspectez la page de base du module : une première page mise à zéro (pas de
MZ) ou unSizeOfImagebien plus petit que la région mappée est la signature. Comparez l'étendue réelle du module chargé (depuis la carte mémoire / le VAD) à la taille déclarée par l'en-tête pour repérer la corruption. Posez un point d'arrêt sur les écritures deRtlZeroMemory/memsetvisant la base de l'image pour saisir l'effacement en cours. - Rebuild — Reconstruisez l'en-tête à partir d'une copie propre du même fichier sur le disque (l'en-tête de fichier y est intact), ou laissez pe-sieve le reconstruire : pe-sieve parcourt la mémoire du processus, récupère les limites des sections et écrit un en-tête valide pour le dump. Sinon, dumpez chaque section selon ses limites mémoire réelles et assemblez un PE neuf dans PE-bear, en corrigeant
SizeOfImage, la table des sections et le point d'entrée à la main. - Tools — pe-sieve (reconstruction automatique de l'en-tête et dump), Scylla (dump d'image avec reconstruction de l'en-tête), PE-bear (réparation manuelle de l'en-tête/des sections) et la carte mémoire du débogueur pour trouver les limites réelles de l'image.