Skip to content
Anti-analyseadvanced

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.

c
#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/CreateProcessW avec les drapeaux de création DEBUG_PROCESS/DEBUG_ONLY_THIS_PROCESS, WaitForDebugEvent et ContinueDebugEvent. Sous Linux, cherchez ptrace avec PTRACE_TRACEME/PTRACE_ATTACH près d'un fork/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!DebugActiveProcess et kernel32!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 drapeau DEBUG_PROCESS de CreateProcess. Vous pouvez aussi terminer ou détacher le processus gardien pour libérer la place de débogage. Sous Linux, NOP l'appel ptrace(PTRACE_TRACEME) ou utilisez LD_PRELOAD pour neutraliser ptrace.
  • Outils — Process Hacker/Process Explorer pour repérer le gardien ; x64dbg avec un point d'arrêt sur DebugActiveProcess/CreateProcessW ; ScyllaHide ; sous Linux, un stub ptrace via LD_PRELOAD ou un catch syscall ptrace dans gdb.
Votes

Commentaires(0)