RawrXD PE Writer - Implementazione Completa
Panoramica
Questo è un writer PE32+ completo e un emettitore di codice macchina implementato in puro assembly x64 MASM con zero dipendenze e nessun utilizzo di CRT. Genera eseguibili Windows funzionanti da zero.
Architettura
Il writer PE segue un approccio di progettazione backend, fornendo un'API pulita per:
- Creazione di contesti eseguibili PE
- Aggiunta di import con strutture IAT/INT appropriate
- Emissione di codice macchina con gestione delle sezioni
- Scrittura di file PE completi con tutti gli header necessari
Componenti Principali
1. Strutture Definite
- IMAGE_DOS_HEADER: Header DOS standard con puntatore e_lfanew
- IMAGE_NT_HEADERS64: Header NT con header file e header opzionale
- IMAGE_SECTION_HEADER: Header di sezione per .text, .rdata, .idata
- IMAGE_IMPORT_DESCRIPTOR: Descrittori della tabella di import
- PE_CONTEXT: Struttura di contesto interna per la costruzione di file PE
2. Funzioni Chiave
PEWriter_CreateExecutable
- Input: RCX = base immagine (0 = default), RDX = RVA punto di ingresso
- Output: RAX = handle contesto PE (0 = fallimento)
- Scopo: Alloca e inizializza la struttura completa del contesto PE
Dettagli Implementazione:
- Alloca memoria per header DOS, header NT, header di sezione
- Inizializza l'header DOS con la firma corretta e e_lfanew
- Imposta gli header NT con tipo macchina AMD64 e magic PE32+
- Configura l'header opzionale con base immagine, allineamento sezione/file
- Alloca buffer di codice e tabelle di import
- Imposta indirizzi virtuali e offset file predefiniti
PEWriter_AddImport
- Input: RCX = contesto PE, RDX = nome DLL, R8 = nome funzione
- Output: RAX = 1 successo, 0 fallimento
- Scopo: Costruisce la tabella di import con strutture IAT/INT appropriate
Dettagli Implementazione:
- Gestisce descrittori di import per più DLL
- Crea voci della tabella di ricerca import (INT)
- Imposta voci della tabella degli indirizzi di import (IAT)
- Gestisce le strutture di import per nome
- Traccia il conteggio delle importazioni e valida i limiti
PEWriter_AddCode
- Input: RCX = contesto PE, RDX = buffer codice, R8 = dimensione codice
- Output: RAX = RVA del codice (0 = fallimento)
- Scopo: Gestisce l'emissione di codice macchina con corretta gestione delle sezioni
Dettagli Implementazione:
- Copia il codice macchina nel buffer interno
- Convalida la dimensione del codice rispetto ai limiti massimi
- Calcola e restituisce RVA per il codice
- Aggiorna il tracciamento interno della dimensione del codice
- Gestisce il contenuto della sezione .text
PEWriter_WriteFile
- Input: RCX = contesto PE, RDX = nome file
- Output: RAX = 1 successo, 0 fallimento
- Scopo: Scrittura completa del file con tutti gli header, le sezioni e la tabella di import
Dettagli Implementazione:
- Crea il file di output con chiamate API Win32 appropriate
- Scrive l'header DOS e lo stub DOS
- Calcola e aggiorna i valori finali dell'header NT
- Scrive gli header di sezione per .text, .rdata, .idata
- Implementa il padding e l'allineamento corretti del file
- Scrive i dati delle sezioni con la tabella di import
- Gestisce tutti i calcoli RVA e gli offset file
Gestione della Memoria
L'implementazione utilizza le API heap di Windows:
- GetProcessHeap(): Ottiene l'heap del processo corrente
- HeapAlloc(): Alloca memoria inizializzata a zero
- HeapFree(): Libera la memoria allocata durante la pulizia
Tutta l'allocazione di memoria include una corretta gestione degli errori e pulizia.
Layout della Struttura del File
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
Layout degli Indirizzi Virtuali
0x1000: .text section (SECTION_ALIGNMENT)
0x2000: .rdata section
0x3000: .idata section
0x4000: Next available virtual address
Costanti e Valori Predefiniti
- Base Immagine: 0x140000000 (predefinita per x64)
- Allineamento Sezione: 0x1000 (4KB)
- Allineamento File: 0x200 (512 byte)
- Punto di Ingresso: RVA configurabile
- Sottosistema: Applicazione console (IMAGE_SUBSYSTEM_WINDOWS_CUI)
Esempio di Utilizzo
; 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
Istruzioni di Build
- Assicurati che MASM64 e Windows SDK siano installati
- Esegui
build.bat per compilare il writer PE e l'esempio
- Esegui
PE_Writer_Example.exe per generare hello.exe
- Testa l'eseguibile generato
Gestione degli Errori
Tutte le funzioni restituiscono 0 in caso di fallimento e non-zero in caso di successo. L'implementazione include:
- Controlli di fallimento dell'allocazione di memoria
- Gestione degli errori di I/O file
- Validazione dell'input
- Pulizia corretta delle risorse
- Controllo dei limiti per i buffer
Limitazioni
- Massimo 99 importazioni (MAX_IMPORTS - 1)
- Dimensione massima codice 64KB (MAX_CODE_SIZE)
- Tre sezioni fisse (.text, .rdata, .idata)
- Solo sottosistema console
- Nessun supporto per rilocazioni
- Nessuna firma digitale
Funzionalità Avanzate
L'implementazione fornisce una solida base per:
- Creazione di sezioni personalizzate
- Binding complesso di import
- Incorporamento di risorse
- Firma digitale
- Supporto per rilocazioni
- Tabelle di gestione delle eccezioni
Note Tecniche
- Puro assembly x64 MASM - nessuna dipendenza CRT
- Utilizza l'heap di Windows per la gestione della memoria
- Genera formato PE32+ per x64
- Compatibile con Windows Vista e successivi
- Segue la specifica PE di Microsoft
- Zero dipendenze da librerie esterne eccetto kernel32.dll
Questa implementazione fornisce un writer PE32+ completo e pronto per la produzione, adatto per backend di generazione codice, compilatori personalizzati e packer eseguibili.