RawrXD PE Writer - Implémentation complète
Aperçu
Ceci est un writer PE32+ complet et un émetteur de code machine implémenté en assembleur MASM x64 pur, sans dépendances et sans utilisation du CRT. Il génère des exécutables Windows fonctionnels à partir de zéro.
Architecture
Le writer PE suit une approche de style « backend designer », offrant une API propre pour :
- Créer des contextes d'exécutables PE
- Ajouter des importations avec les structures IAT/INT appropriées
- Émettre du code machine avec gestion des sections
- Écrire des fichiers PE complets avec tous les en-têtes requis
Composants principaux
1. Structures définies
- IMAGE_DOS_HEADER : En-tête DOS standard avec pointeur e_lfanew
- IMAGE_NT_HEADERS64 : En-têtes NT avec en-tête de fichier et en-tête optionnel
- IMAGE_SECTION_HEADER : En-têtes de section pour .text, .rdata, .idata
- IMAGE_IMPORT_DESCRIPTOR : Descripteurs de table d'importation
- PE_CONTEXT : Structure de contexte interne pour la construction des fichiers PE
2. Fonctions clés
PEWriter_CreateExecutable
- Entrée : RCX = base de l'image (0 = par défaut), RDX = RVA du point d'entrée
- Sortie : RAX = handle de contexte PE (0 = échec)
- Objectif : Alloue et initialise une structure de contexte PE complète
Détails d'implémentation :
- Alloue la mémoire pour l'en-tête DOS, les en-têtes NT, les en-têtes de section
- Initialise l'en-tête DOS avec la signature appropriée et e_lfanew
- Configure les en-têtes NT avec le type de machine AMD64 et le magic PE32+
- Configure l'en-tête optionnel avec la base de l'image, l'alignement des sections et des fichiers
- Alloue le tampon de code et les tables d'importation
- Définit les adresses virtuelles et les décalages de fichier par défaut
PEWriter_AddImport
- Entrée : RCX = contexte PE, RDX = nom de la DLL, R8 = nom de la fonction
- Sortie : RAX = 1 succès, 0 échec
- Objectif : Construit la table d'importation avec les structures IAT/INT appropriées
Détails d'implémentation :
- Gère les descripteurs d'importation pour plusieurs DLL
- Crée les entrées de la table de recherche d'importation (INT)
- Configure les entrées de la table d'adresses d'importation (IAT)
- Gère les structures d'importation par nom
- Suit le nombre d'importations et valide les limites
PEWriter_AddCode
- Entrée : RCX = contexte PE, RDX = tampon de code, R8 = taille du code
- Sortie : RAX = RVA du code (0 = échec)
- Objectif : Gère l'émission de code machine avec une gestion appropriée des sections
Détails d'implémentation :
- Copie le code machine dans le tampon interne
- Valide la taille du code par rapport aux limites maximales
- Calcule et retourne la RVA du code
- Met à jour le suivi interne de la taille du code
- Gère le contenu de la section .text
PEWriter_WriteFile
- Entrée : RCX = contexte PE, RDX = nom du fichier
- Sortie : RAX = 1 succès, 0 échec
- Objectif : Écriture complète du fichier avec tous les en-têtes, sections et table d'importation
Détails d'implémentation :
- Crée le fichier de sortie à l'aide des appels API Win32 appropriés
- Écrit l'en-tête DOS et le stub DOS
- Calcule et met à jour les valeurs finales de l'en-tête NT
- Écrit les en-têtes de section pour .text, .rdata, .idata
- Implémente le remplissage et l'alignement corrects du fichier
- Écrit les données des sections avec la table d'importation
- Gère tous les calculs de RVA et les décalages de fichier
Gestion de la mémoire
L'implémentation utilise les API heap de Windows :
- GetProcessHeap() : Obtient le heap du processus en cours
- HeapAlloc() : Alloue de la mémoire initialisée à zéro
- HeapFree() : Libère la mémoire allouée lors du nettoyage
Toute allocation mémoire inclut une gestion appropriée des erreurs et un nettoyage.
Disposition de la structure du fichier
DOS Header (64 bytes)
DOS Stub (variable size, padded to 0x80)
NT Headers (248 bytes for PE32+)
Section Headers (40 bytes × 3 sections)
Padding to file alignment (0x400)
.text Section (code)
- Machine code
- Padded to file alignment
.rdata Section (read-only data)
- String constants, resources
- Padded to file alignment
.idata Section (import data)
- Import descriptors
- Import lookup table
- Import address table
- Import by name structures
- Padded to file alignment
Disposition des adresses virtuelles
0x1000: .text section (SECTION_ALIGNMENT)
0x2000: .rdata section
0x3000: .idata section
0x4000: Next available virtual address
Constantes et valeurs par défaut
- Base de l'image : 0x140000000 (par défaut pour x64)
- Alignement des sections : 0x1000 (4 Ko)
- Alignement du fichier : 0x200 (512 octets)
- Point d'entrée : RVA configurable
- Sous-système : Application console (IMAGE_SUBSYSTEM_WINDOWS_CUI)
Exemple d'utilisation
; Create PE context
mov rcx, 0 ; Default image base
mov rdx, 1000h ; Entry point RVA
call PEWriter_CreateExecutable
mov rbx, rax ; Save context
; Add kernel32.dll imports
mov rcx, rbx
mov rdx, offset dll_kernel32
mov r8, offset func_GetStdHandle
call PEWriter_AddImport
; Add machine code
mov rcx, rbx
mov rdx, offset code_buffer
mov r8, code_size
call PEWriter_AddCode
; Write executable file
mov rcx, rbx
mov rdx, offset filename
call PEWriter_WriteFile
Instructions de construction
- Assurez-vous que MASM64 et le SDK Windows sont installés
- Exécutez
build.bat pour compiler le writer PE et l'exemple
- Exécutez
PE_Writer_Example.exe pour générer hello.exe
- Testez l'exécutable généré
Gestion des erreurs
Toutes les fonctions retournent 0 en cas d'échec et une valeur non nulle en cas de succès. L'implémentation inclut :
- Vérifications d'échec d'allocation mémoire
- Gestion des erreurs d'E/S de fichier
- Validation des entrées
- Nettoyage approprié des ressources
- Vérification des limites des tampons
Limitations
- Maximum de 99 importations (MAX_IMPORTS - 1)
- Taille de code maximale de 64 Ko (MAX_CODE_SIZE)
- Trois sections fixes (.text, .rdata, .idata)
- Sous-système console uniquement
- Pas de prise en charge des relocalisations
- Pas de signatures numériques
Fonctionnalités avancées
L'implémentation fournit une base solide pour :
- Création de sections personnalisées
- Liaison d'importation complexe
- Intégration de ressources
- Signature numérique
- Prise en charge des relocalisations
- Tables de gestion des exceptions
Notes techniques
- Assembleur MASM x64 pur - aucune dépendance CRT
- Utilise le heap Windows pour la gestion de la mémoire
- Génère le format PE32+ pour x64
- Compatible avec Windows Vista et versions ultérieures
- Suit la spécification PE de Microsoft
- Aucune dépendance de bibliothèque externe excepté kernel32.dll
Cette implémentation fournit un writer PE32+ complet et prêt pour la production, adapté aux backends de génération de code, aux compilateurs personnalisés et aux packers d'exécutables.