
Unhooking della sezione .text di ntdll tramite API nativa. A differenza di altri unhooker, questo non lascia due ntdll caricate. Supporto x86/x64/wow64.
unhooking corretto della sezione .text di ntdll tramite API native. Supporta x86/x64/wow64.
Il programma attraversa il PEB per individuare l'indirizzo di base di ntdll.dll e analizza manualmente la tabella degli export del PE per risolvere le funzioni NT API senza toccare la Import Address Table. Poi usa NtOpenFile per aprire la copia pulita di ntdll.dll dal disco, crea un oggetto sezione con NtCreateSection e la mappa nel processo con NtMapViewOfSection per ottenere una sorgente di unhook senza caricare davvero una seconda dll tramite LoadLibrary. La sezione .text hookata viene modificata in PAGE_EXECUTE_READWRITE tramite NtProtectVirtualMemory, il .text pulito viene copiato sopra quello hookato con una memcpy personalizzata, e la protezione viene poi ripristinata ai flag originali. Dopo una verifica byte per byte che l'unhook abbia funzionato, la copia pulita viene smappata correttamente con NtUnmapViewOfSection, così non rimane una seconda ntdll caricata in memoria.
La maggior parte del codice di unhook pubblico è letteralmente copiato e incollato dalla stessa fonte spazzatura (come l'esempio di ired.team e praticamente quasi ogni unhooker open source su github) e ha problemi enormi che lo rendono inutile contro qualsiasi EDR serio. Usano VirtualProtect invece delle API native, il che vanifica l'intero scopo perché stai chiamando funzioni hookate per unhookare funzioni; impostano permessi RWX sulla sezione .text, che è un IOC enorme che gli EDR flaggano immediatamente, e non smappano davvero la copia pulita perché CloseHandle su un mapping di sezione non libera la memoria. Serve UnmapViewOfFile o NtUnmapViewOfSection, ma tutti dimenticano questa parte, quindi lasciano due copie di ntdll caricate nel processo, che è praticamente un enorme cartello al neon che dice "sono malware". Provano anche a usare FreeLibrary sulla ntdll principale, che non funziona nemmeno e causa leak di handle; inoltre cambiano la protezione in RWX due volte inutilmente, quando una volta basta se la ripristini correttamente.
Questa implementazione corregge i bug comuni del codice di unhook pubblico usando API native ovunque (NtOpenFile, NtCreateSection, NtMapViewOfSection, NtProtectVirtualMemory), smappando correttamente la copia pulita con NtUnmapViewOfSection per evitare di lasciare due copie di ntdll caricate, non usando FreeLibrary sulla ntdll principale e verificando il successo tramite confronto della memoria. Tuttavia NON evita gli IOC fondamentali che gli EDR moderni rilevano. Usare NtOpenFile su C:\Windows\System32\ntdll.dll è un IOC che viene loggato, NtCreateSection con SEC_IMAGE che punta a ntdll.dll viene tracciato via ETW, modificare la protezione della memoria sulla sezione .text di ntdll è una bandiera rossa enorme anche con le API native, e scrivere nel .text è rilevabile tramite callback di scrittura in memoria. Questa tecnica è ben nota e gli EDR moderni come CrowdStrike e SentinelOne hanno firme per l'intero pattern. Gli EDR avanzati come Microsoft Defender for Endpoint ed Elastic non usano più nemmeno gli hook in usermode, poiché si affidano a callback del kernel e telemetria ETW, quindi l'unhook non fa letteralmente nulla contro di loro. Funziona contro EDR di base che usano solo hook inline e prodotti di sicurezza più vecchi, ma fallisce contro qualsiasi cosa con componenti in kernel-mode o analisi comportamentale. Alternative migliori includono le syscall dirette, dove non chiami mai funzioni hookate in primo luogo, heaven's gate per l'attraversamento del confine wow64, l'estrazione manuale delle syscall dal .text di ntdll a runtime, o semplicemente evitare del tutto le API sospette, dato che l'unhook nel 2024/2025 è generalmente una tecnica morta contro EDR aziendali seri.
Funziona su processi nativi x64, processi nativi x86 e processi wow64 (x86 su Windows x64). Rileva automaticamente wow64 e usa la directory di sistema corretta (System32 vs SysWOW64), così non devi pensarci.
Viene toccata solo la sezione .text di ntdll.dll, perché è lì che vive tutto il codice effettivo delle funzioni e dove gli EDR posizionano gli hook come hook di funzione inline (istruzioni jmp nei prologhi delle funzioni). Le altre sezioni come .data e .rdata vengono lasciate stare perché non c'è motivo di toccarle e creerebbe solo più IOC senza alcun beneficio.
cl /EHsc /std:c++17 main.cpp /Fe:unhook.exe
o qualsiasi altra cosa, qualsiasi compilatore C++ moderno funziona. Richiede windows.h e winternl.h.
l'accesso non autorizzato ai sistemi informatici è illegale. usalo su sistemi che possiedi o su cui hai l'autorizzazione a testare. la prigione federale è reale.
Il codice usa la macro CONTAINING_RECORD per attraversare correttamente le liste LDR, accede al PEB tramite i registri di segmento (gs su x64, fs su x86), fa una ricerca hardcoded della sezione .text tramite confronto dei nomi, che potrebbe essere più elegante ma vabbè funziona, gestisce gli errori tramite i codici NTSTATUS e la macro NT_SUCCESS, e avvolge le operazioni di memoria in try/except SEH per sicurezza. Se non sai leggere il C++ e capire i dettagli interni del formato PE, probabilmente non dovresti usarlo comunque.