IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Discussion :

Protection anti-debugger


Sujet :

Windows

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    48
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 48
    Points : 59
    Points
    59
    Par défaut Protection anti-debugger
    Bonjour à tous

    Je suis entrain de créer un petit programme actuellement et je souhaiterai le protéger un peu contre le debogage, j'ai déjà une ou deux solutions, hors j'ai vu sur msdn une api CheckRemoteDebuggerPresent, je connaissais déjà IsDebuggerPresent que je sais utiliser, malheureusement pour la première, ce n'est pas le cas, c'est pas très clair sur msdn

    J'aimerai si possible qu'une âme charitable m'aide à comprendre comment CheckRemoteDebuggerPresent peut être employé dans un programme pour que si la présence d'un debugger est détecté pendant l'utilisation, cela provoque l'arrêt du binaire

    Merci d'avance, d'ailleur si vous avez des techniques anti debugging à me faire partager, je suis preneur 8)

  2. #2
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 753
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 753
    Points : 10 704
    Points
    10 704
    Billets dans le blog
    3
    Par défaut
    C'est dispo qu'à partir de WinXP SP1... donc:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #define _WIN32_WINNT 0x0501
    #include <windows.h>
    et puis:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
        BOOL present;
        if &#40; !CheckRemoteDebuggerPresent&#40;
            GetCurrentProcess&#40;&#41;,
            &present &#41; &#41;
        &#123;
            cout << "Echec de la fonction\n";
        &#125;
        else
        &#123;
            cout << "Debugger &#58; ";
            cout << &#40; &#40; present &#41; ? &#40; "oui\n" &#41; &#58; &#40; "non\n" &#41; &#41;;
        &#125;

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    48
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 48
    Points : 59
    Points
    59
    Par défaut
    Merci sympa

    C'est beaucoups plus clair maintenant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define _WIN32_WINNT 0x0501
    Voilà pourquoi je n'y arrive pas

    Merci en tout cas, j'avais trouvé un peu de docs sur le sujet, mais comme tout était en anglais cette subtilité m'avais échappée

    Merci beaucoups, pour ton aide

    voici le code fonctionnel, je l'ai testé avec un debugger il marche très bien


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #define _WIN32_WINNT 0x0501
    #include <windows.h>
    #include <iostream>
    
    using namespace std;
    int main&#40;&#41;
    &#123;
        BOOL present;
        if &#40; !CheckRemoteDebuggerPresent&#40; GetCurrentProcess&#40;&#41;,&present &#41;&#41;
        &#123;
             cout << "Echec de la fonction\n";
             &#125;
             else
             &#123;
                  cout << "Debugger &#58; "; 
                  cout << &#40; &#40; present &#41; ? &#40; "oui\n" &#41; &#58; &#40; "non\n" &#41; &#41;; 
                  
                  &#125;
                  system&#40;"PAUSE"&#41;;
                  return 0;
                  &#125;
    Cet API est très bien, car elle n'est pas sensible, aux anti-protections, qui detècte IsDebuggerPresent, par contre elle est visible dans l'appel aux API, en essayant de cacher les appels dans le debugger ça peut faire une protection intéréssante

  4. #4
    Membre habitué Avatar de Crisanar
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    162
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2004
    Messages : 162
    Points : 137
    Points
    137
    Par défaut
    Je ne sais pas comment fonctionne CheckRemoteDebuggerPresent mais je sais que IsDebuggerPresent est très facile à berner!
    Utiliser seulement une API pour protéger n'est pas une protection très efficace ni vouée à tenir en echec un cracker très longtemps, même si elle est 'masquée'.

  5. #5
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 753
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 753
    Points : 10 704
    Points
    10 704
    Billets dans le blog
    3
    Par défaut
    Note que ton programme ne fonctionnera pas sous un ordi XP simple ou inférieur. Faudrait peut être mieux envisager une liaison dynamique via GetProcAddress( GetModuleHandle( "kernel32.dll" ), "CheckRemoteDebuggerPresent" ), ce qui au passage masquera un peu l'utilisation de cette fonction (disparition de la table d'import).

  6. #6
    mat.M
    Invité(e)
    Par défaut
    Et si je debbuge ton programme avec wdisasm32 ?
    Tu vas arriver à le protéger ton programme ?

  7. #7
    Rédacteur
    Avatar de Neitsa
    Homme Profil pro
    Chercheur sécurité informatique
    Inscrit en
    Octobre 2003
    Messages
    1 041
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur sécurité informatique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 041
    Points : 1 956
    Points
    1 956
    Par défaut
    Et si je debbuge ton programme avec wdisasm32 ?
    Tu vas arriver à le protéger ton programme ?
    wdisasm32=Windasm32 ? D'après le nom j'en conclu qu'il s'agit d'un désassembleur.

    Or, il ne faut pas confondre Debuggeur et désassembleur. Le premier contrôle l'execution d'un programme au runtime (à l'exécution) et est le plus souvent pourvu d'un module de désassemblage.

    Le deuxième ne permet qu'une analyse dite de "dead listing", qui ne permet qu'une vue du code assembleur, tel qu'il se présente dans l'exécutable sous forme statique.

    Les protections type IsDebuggerPresent ne permettent qu'une protection au Runtime.

    Les protections en statiques se font sous forme de compression ou d'ajout de junk code (intructions assembleur inopérante rendant l'analyse du désassembleur fausse) ou par l'ajout d'une surcouche avec une VM [Machine Virtuelle] ou encore par des procédés de cryptage plus ou moins complexes. Toutes ces techniques statiques sont combinables entre elles.

    Finalement, la plupart des programmes de protections du commerce mais aussi les malwares (virus, worms, trojans, etc.) combinent les formes de protections à la fois contre une attaque statique mais aussi contre une attaque à l'exécution.

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    48
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 48
    Points : 59
    Points
    59
    Par défaut
    Cette api n'est qu'une idée de protection, mais n'est pas pas une solution miracle, elle n'est pas détectée par les plugins d'olly, je l'ai testé, par contre elle est facilement repérable

    Le fait qu'elle ne soit compatible qu'a partir de xp1, limite son utilisation

    Merci de tes conseils Aurelien.Regat-Barrel, je me renseigne sur les techniques qui existent, ce qui me permet de manipuler pour certaines l'api windows que je ne connais pas beaucoup

    J'ai lu quelques textes sur le sujet, malheureuseusement peu existent en français, ce qui est dommage, mais c'est mieux que rien

    A mon sens, il n'existe pas de protections inataquable, mais leur complexitées peuvent empecher pas mal de personnes d'attaquer le binaire

    Citation Envoyé par Mat.M
    Et si je debbuge ton programme avec wdisasm32 ?
    Tu vas arriver à le protéger ton programme ?
    Le but est effectivement que tu n'y arrives pas tout en sachant que c'est possible, tout dépends de ton niveau de connaissances, notament en assembleur

    Il existe un débugger s'appelant W32dasm, qui ce fait un peu vieux, mais peu toujours servir, seulement sur des protections complexe comme celle qu'évoque Neitsa, je doute qu'il puisse être efficace, malgré tout beaucoups de techniques que j'ai eu l'occasion de lire, concerne principalement Softice

    J'ai lu justement qu'en changeant les caractéristiques de la section contenant l'entrypoint avec un editeur de PE, cela pouvait empecher W32dasm de faire son bouleau

  9. #9
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 753
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 753
    Points : 10 704
    Points
    10 704
    Billets dans le blog
    3
    Par défaut
    Créer une protection robuste, c'est un boulot de spécialiste, ça demande beaucoup de compétences et d'efforts : ça coute cher.
    Il vaut voir ce que ça rapporte par rapport au coût. La plupart du temps une protection qui résiste quelques minutes découragera les petits pirates du dimanche. Si tu veux résister aux spécialistes, faut te mettre à leur niveau...
    Bidouiller le PE, ça peut aussi rendre ton exe douteux auprès des antivirus. Faut pas oublier qu'à chaque fois c'est l'utilisateur honnête qui est lésé, donc personnelement je te conseille la prudence dans tes choix, ton exe aura vite fait de planter sous un autre OS, de déclencher des alertes au virus, etc...
    Dans les techniques "propres" mais efficaces, il me semble qu'il y en a une à base des SEH de Windows. Tu places ton code sensible dans un handler SEH, et déclenche une exception fatale dans ton exe. Ton handler est alors exécuté, mais dans le débugger (celui de W32dasm en tous cas), l'exception est catchée par ce dernier et du coup on peut pas tracer dans le code sensible... Mais bon, j'y connais presque rien, c'est peut être des bêtises. Mais si ce n'est pas le cas, ça doit facilement être implémentable avec les mot-clés spécifique SEH de VC++ (__try...__except...)
    Pour W32dasm, une simple compression avec aspack / upx complique les choses, pour le pirate du dimanche toujours...

  10. #10
    Membre habitué Avatar de Crisanar
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    162
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2004
    Messages : 162
    Points : 137
    Points
    137
    Par défaut
    Citation Envoyé par Aurelien.Regat-Barrel
    Dans les techniques "propres" mais efficaces, il me semble qu'il y en a une à base des SEH de Windows. Tu places ton code sensible dans un handler SEH, et déclenche une exception fatale dans ton exe. Ton handler est alors exécuté, mais dans le débugger (celui de W32dasm en tous cas), l'exception est catchée par ce dernier et du coup on peut pas tracer dans le code sensible... Mais bon, j'y connais presque rien, c'est peut être des bêtises. Mais si ce n'est pas le cas, ça doit facilement être implémentable avec les mot-clés spécifique SEH de VC++ (__try...__except...)
    Effectivement c'est une possibilité, mais avec des debuggers comme OllyDbg, il est facile de le configurer afin de ne pas se laisser piéger par ce type de tricks (Je n'ai jamais utilisé Win32Dasm en tant que debugger -de toute façon il a fait son temps )
    J'ai souvenir, sans jamais avoir testé, qu'il est même possible, en déclenchant une exception, de modifier les registres de debug et d'empecher un tracing ou qqch du style.
    Mais Neitsa saura certainement mieux répondre que moi à cette question...

  11. #11
    Membre confirmé
    Profil pro
    Freelance
    Inscrit en
    Avril 2003
    Messages
    393
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Freelance

    Informations forums :
    Inscription : Avril 2003
    Messages : 393
    Points : 492
    Points
    492
    Par défaut
    On pourrait en écrire une tartine sur le sujet. Le mieux serait d'aller voir les forums FR appropriés de reverse engineering.
    Pour ca, demandez à Neitsa, je suis certain qu'il en a en tete

  12. #12
    Rédacteur
    Avatar de Neitsa
    Homme Profil pro
    Chercheur sécurité informatique
    Inscrit en
    Octobre 2003
    Messages
    1 041
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur sécurité informatique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 041
    Points : 1 956
    Points
    1 956
    Par défaut
    Hello,

    Dans les techniques "propres" mais efficaces, il me semble qu'il y en a une à base des SEH de Windows.
    C'est une technique assez employée mais qui, de part ce fait, est devenue facilement contrable... L'API Windows permet de le faire sans problème, et la plupart des debuggers offre cette possibilité (comme le disait Crisanar, OllyDBG offre cette dernière).

    Dans la boucle de debugging, quand on opére la gestion de l'exception déclenché par le programme (il faudra prévoir tout les cas) il suffit de faire ceci (ici, seule la gestion d'une exception de division par zéro est présente):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    DEBUG_EVENT DebugEv;
    DWORD dwContinueStatus = DBG_CONTINUE; 
     
    for&#40;;;&#41; 
    &#123; 
        WaitForDebugEvent&#40;&DebugEv, INFINITE&#41;; 
     
        switch &#40;DebugEv.dwDebugEventCode&#41; 
        &#123; 
            case EXCEPTION_DEBUG_EVENT&#58; 
      
                switch&#40;DebugEv.u.Exception.ExceptionRecord.ExceptionCode&#41;
                &#123; 
                    case EXCEPTION_INT_DIVIDE_BY_ZERO 
                    // le programme débuggé à fait une division par zéro
                    // on choisi de lui laissé traiter lui même l'exception. 
                    dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED;
                        break;
    
    &#91;...cut...&#93;
    
    ContinueDebugEvent&#40;DebugEv.dwProcessId, 
                       DebugEv.dwThreadId, 
                       dwContinueStatus&#41;;
     
    &#125;
    Ici la gestion est simple, on pourrait faire plus compliqué : récupérer un pointeur sur le code du SEH, désassembler le SEH est regarder si le traitement ou non du SEH s'impose (on peut alors passer le bon code pour "dwContinueStatus").

    J'ai souvenir, sans jamais avoir testé, qu'il est même possible, en déclenchant une exception, de modifier les registres de debug et d'empecher un tracing ou qqch du style.
    En effet un programme peut effacer lui-même les Drx (debug registers ; registres hardware de debugging) de son propre CONTEXT (cf. structure CONTEXT de Get/SetThreadContext). La structure CONTEXT est directement atteignable au travers du SEH.

    Mais le problème reste le même, le SEH peut être ou non pris en charge par le debuggeur, le mieux est encore d'alterner des SEH qui ne font rien de spécial, et des SEH qui vont s'occuper de tester si l'on est effectivement débuggé.

    Pour un "anti-tracing" (empêcher un débugger de tracer le code de son application) on peut manipuler le registre EFLAGS (toujours dans un SEH) en mettant le drapeau TF (trap flag) à 1 dans un SEH. Le trap flag une fois armé déclenche une exception de type "trap" et les debuggeurs sont incapables de continuer à tracer...

    Le mieux est encore de coupler tout ca avec des méthodes anti-analyse (junk code, VM, crypto) + une détection de breakpoint (en cherchant l'opcode 0xCC qui correspond à une INT3) + un CRC pour vérifier l'intégrité de son propre code : on commence à tenir une protection qui tient la route

    L'effacement des Drx par la structure CONTEXT n'est valable qu'en Ring3, les débuggeurs Ring0 y sont insensibles du fait qu'ils utilisent directement les debug Registers (forme mnémonique Asm : mov Drx, xxxxxxx).

    On pourrait en écrire une tartine sur le sujet
    Oui protéger des applications est un vrai boulot à plein temps

    En fait, peut importe le nombre et la difficulté des protections, si un programme reste exécutable, il y a forcément matière et possibilité à le "déprotéger". La seule chose qu'il faille retenir est le facteur temps : plus un programme est long à débugger et à analyser, plus l'attaquant à des chances d'abandonner... Il faut donc multiplier les protections en "couches" (layers) et ne pas hésiter à forcer la dose d'obfuscation.

    Plus ca va prendre de temps et mieux c'est

Discussions similaires

  1. protection anti leech
    Par erazor7c6 dans le forum Sécurité
    Réponses: 2
    Dernier message: 29/07/2010, 16h32
  2. Protection anti-aspirateurs de site
    Par krys420 dans le forum Apache
    Réponses: 3
    Dernier message: 11/12/2009, 11h36
  3. Protection anti-triche pour un jeu
    Par TocTocKiéLà? dans le forum Développement 2D, 3D et Jeux
    Réponses: 28
    Dernier message: 05/09/2007, 23h54

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo