Self-Debugging
Le malware lance un enfant qui débogue le parent (ou inversement) afin que la règle d'un seul débogueur par processus verrouille complètement le débogueur de l'analyste hors du processus protégé.
Windows n'autorise qu'un seul débogueur attaché à un processus à la fois. Le malware en abuse en se déboguant lui-même : il lance un processus enfant qui appelle DebugActiveProcess sur le parent (ou crée l'enfant avec le drapeau DEBUG_PROCESS pour que le parent débogue l'enfant). Une fois cette relation d'auto-débogage établie, un analyste ne peut plus attacher son propre débogueur — la place est prise — et le processus gardien peut aussi gérer les exceptions que l'analyste verrait autrement.
C'est une technique avancée car les deux processus sont mutuellement dépendants : tuer le mauvais ou s'attacher au mauvais moment casse l'astuce, ce qui est précisément le levier dont a besoin l'analyste.
Fonctionnement
Le parent lance un assistant qui s'attache en tant que débogueur. Tant qu'il est attaché, l'assistant occupe l'unique place de débogage.
#include <windows.h>
// Guardian process: attach to the protected parent so nobody else can.
void GuardParent(DWORD dwParentPid)
{
if (DebugActiveProcess(dwParentPid)) {
DEBUG_EVENT ev;
for (;;) {
WaitForDebugEvent(&ev, INFINITE);
// swallow events; an external debugger can't attach now
ContinueDebugEvent(ev.dwProcessId, ev.dwThreadId, DBG_CONTINUE);
}
}
}Sous Linux, l'équivalent est un fork() où l'enfant appelle immédiatement ptrace(PTRACE_TRACEME, ...) (ou le parent appelle PTRACE_ATTACH sur l'enfant) ; comme un processus ne peut avoir qu'un seul traceur, le gdb/strace de l'analyste est verrouillé avec « Operation not permitted ».
Détection & contournement
- Statique — Recherchez dans IDA/Ghidra
DebugActiveProcess,CreateProcess/CreateProcessWavec les drapeaux de créationDEBUG_PROCESS/DEBUG_ONLY_THIS_PROCESS,WaitForDebugEventetContinueDebugEvent. Sous Linux, cherchezptraceavecPTRACE_TRACEME/PTRACE_ATTACHprès d'unfork/clone. - Dynamique — Identifiez la paire de processus dans Process Hacker/Process Explorer (cherchez un parent/enfant tous deux vivants, l'un déboguant l'autre). Posez un point d'arrêt sur
kernel32!DebugActiveProcessetkernel32!CreateProcessW; inspectez les drapeaux de création et le PID cible pour cartographier la relation. - Patch / contournement — Attachez votre débogueur avant que l'auto-débogage ne commence (posez un point d'arrêt sur l'EP/TLS et avancez jusqu'à l'appel
DebugActiveProcess), puis patchez-le pour qu'il échoue (forcez return 0 / NOP l'appel) ou retirez le drapeauDEBUG_PROCESSdeCreateProcess. Vous pouvez aussi terminer ou détacher le processus gardien pour libérer la place de débogage. Sous Linux, NOP l'appelptrace(PTRACE_TRACEME)ou utilisezLD_PRELOADpour neutraliserptrace. - Outils — Process Hacker/Process Explorer pour repérer le gardien ; x64dbg avec un point d'arrêt sur
DebugActiveProcess/CreateProcessW; ScyllaHide ; sous Linux, un stubptraceviaLD_PRELOADou uncatch syscall ptracedansgdb.