• Cours appronfondie n°1

    1/ Les logiciels utiles pour ce cours

    -> Le programme à craquer     :  Start Clean v1.2
    -> Un désassembleur             :  W32dasm 8.93
    -> Un éditeur hexa décimal     :  Winhex 10.2

     

    2/ Techniques de récupération d'un sérial valide pour Start Clean v1.2

    Je poursuis et complète les précisions de smeita du cours n°2. En effet comme il le souligne l'affichage de la boîte de dialogue "Incorrect code" n'est que la conséquence d'une vérification du numéro de série qui a eu lieu avant l'affichage de la boîte (le programme fait son calcul pour vérifier si le "code" entré correspond bien au "code" attendu à partir du "name" entré dans la boîte de saisie "Entrer Registration info").

    Comment savoir où cette vérification est faite ? Il suffit pour cela de remonter dans le code en regardant le listing de désassemblage (on fait toujours comme ça) :

     

    <script type="text/javascript">document.write("")</script>

     

    Sur cette photo d'écran (celle du dessus) vous voyez que le je 004027C1 trouvé auparavant dans le cours n°2  est précédé d'un call 00401150. En général tout ce qui est vérification de numéro de série est effectué dans un call qui précède un test (ou un comp = comparaison) et qui est suivi d'un saut conditionnel (ici je 004027C1).

    Si on entre (on dit encore descendre) dans le call en sélectionant la ligne et en faisant flèche droite dans W32dasm on arrive à l'adresse 00401150 qui quelques lignes plus bas est suivie du listing de désassemblage trouvé dans le cours n°1  (vous avez la fonction lstrcmpA qui compare les chaînes entrées dans le champ "code" de la boîte d'enregistrement avec le code réel calculé par le programme et qui est suivie d'un saut vers une zone où on n'est pas enregistré jne 00401271)

     

    <script type="text/javascript">document.write("")</script>

     

    Concusion : le call 00401150 est bien la routine (sous-programme) de vérification.

    Poussons plus loin notre analyse en déboguant Start Clean. Je parle déboguage (debugging en anglais) car en effet W32dasm contient un débugger en plus d'un désassembleur. Un débugger ça sert à faire tourner un programme ligne de code par ligne de code. Par exemple sur la photo du dessus une ligne de code c'est push 00401271 à l'adresse 004011EB autrement dit c'est du code en assembleur.

    Pour charger le débugger faites CTRL L dans W32dasm (Start Clean doit être ouvert dans W32dasm). Là 2 fenêtres s'ouvent en plus de la fenêtre initiale (une grande et une petite) : ce sont des fenêtres pour le debugging. Dans la petite cochez les 5 options (Enabled Documented API Details,Enabled Undocumented API Details,Enabled Local Function Details,Stop auto on API, Step Into "rep" instruction Bypass).

    Ensuite on va mettre un point d'arrêt (breakpoint en anglais; en abrégé bp) sur la ligne de code que l'on soupçonne d'être incriminée dans le contrôle de la validité des données saisies dans la boîte d'enregistrement. Pour cela

       -> On sélectionne la ligne d'adresse 00402799 (Shift F12 -> 00402799 si vous n'êtes pas dessus) :

        :00402799 E8B2E9FFFF              call 00401150

       -> Poser le breakpoint sur cette ligne en appuyant sur la touche F2

       -> Démarrer le debugging de Start Clean en appuyant sur la touche F9

       -> Start Clean se lance dans une nouvelle fenêtre.

       -> Dans Start Clean cliquez sur le bouton register et saisissez pour dans le champ name pifoman et dans le champ code 123456 et appuyer sur le bouton OK.

       -> A ce moment là la fenêtre principale de W32dasm se met au premier plan et vous voyez la ligne sur laquelle vous avez mis un breakpoint colorée en vert. W32dasm s'est arrêté (on dit aussi a breaké) sur le bp d'adresse 00402799 que vous avez posé en faisant un bing (si vous avez les enceintes branchées). Cela signifie que l'éxécution du programme une fois entré le "name" et le "code" passe sur la ligne de code d'adresse 00402799.

       -> Nous on va voir ce qui se passe dans le call. Pour cela on fait F7 (ça correspond au bouton step into dans la petite fenêtre du debugger). Step into signifie pas à pas à l'intérieur (du call).

       -> Ensuite on appuie plusieur fois sur F8 (step over) pour exécuter les instructions une par une sans entrer dans les call mais en les exécutant quant même.

    Qu'est ce qu'on voit ensuite

       -> Le programme fait appel au registre * Possible StringData Ref from Data Obj ->"SoftwareStart CleanConfiguration" et continue

       -> Le programme arrive en sur l'API * Reference To: USER32.GetDlgItemTextA, Ord:00EDh et passe sur
            :004011B3 FFD6                    call esi

       -> Là une fenêtre s'ouvre

       -> Cliquez sur le bouton Get API result. Vous voyez alors la valeur "pifoman" entrée précédemment dans le champ "name"

     

    <script type="text/javascript">document.write("")</script>

     

       -> Cliquez sur le bouton Close
       -> Appuyer plusieurs fois sur F8 une nouvelle fenêtre s'ouvre.Vous voyez alors la valeur "123456" entrée précédemment dans le champ "code" qui a été transférée à la méthode (fonction) GetDlgItemTextA en cliquant sur le bouton Get API result

     

    <script type="text/javascript">document.write("")</script>

     

       -> Cliquez sur le bouton Close
       -> Appuyer plusieurs fois sur F8
       -> Une autre fenêtre dans laquelle vous voyez le nom "pifoman" apparaît.On continue
       -> Une deuxième fenêtre s'ouvre en faisant F8 sur la ligne suivante
           :004011E3 FF1520924000            Call dword ptr [00409220

     

    <script type="text/javascript">document.write("")</script>
     

    Je crois que vous avez compris dans cette fenêtre vous voyez votre numéro de série entré dans le champ "code" qui est 123456 et le fameux vrai numéro de série calculé par le programme qui est 1598-15026-2421-469. Ces 2 chaînes de caractères sont passées en argument à la fonction lstrcmp (strcmp = string comparaison <=> comparaison de chaînes de caractères). En argument 1 de cette fonction c'est 1598-15026-2421-469 et en argument 2 c'est 123456. Vous n'avez pas besoin de faire Get API result ici vous pouvez cliquer sur le bouton close.

    La question que vous pourriez me poser c'est comment ces 2 paramètres (ou encore arguments) sont passés à la fonction lstrcmp ? Eh bien la réponse est dans le code asm. Regardons le listing suivant.

    <script type="text/javascript">document.write("")</script>

     

    Vous voyez au dessus de la ligne  :004011E3  FF1520924000  Call dword ptr [00409220] et un push eax suivi d'un push 00406030.
    Ce qu'il faut savoir c'est qu'en assembleur le passage de paramètres à une routine (symbolisée par un call) se fait en empilant dans la zone de pile du programme (instruction push  = empiler) les arguments qui vont ensuite êtres utilisés par le call (ici le call appelle la fonction lstrcmp). L'empilage se fait donc avant d'exécuter le call. Le premier élément empilé est le registre eax et ensuite l'adresse 00406030.

    Petite précision supplémentaire : si au cours du programme par exemple arrivé à l'adresse 004011E3 vous voulez savoir ce q'il y a dans l'adresse 00406030 à cause du push 00406030 vous pouvez le faire en cliquant sur "user Addr" dans la grande fenêtre (user addr = user address = adresse entrée par l'utilisateur) du debugger et taper 00406030 -> entrée -> clic sur le bouton UA1

     

    <script type="text/javascript">document.write("")</script>

     

    NB : comment décrypter ce qui est affiché dans cette fenêtre ? Eh bien si on prend par exemple la ligne surlignée en bleu on voit que le contenu de l'adresse 00406030 ce qui se note [00406030] (ça s'écrit pareil dans les lignes de code en assembleur) est un octet (byte en anglais) dont la valeur hexadécimale est 31 correspondant au caractère ascii 1 (utilisez la charmap dans démarrer->exécuter->charmap si vous n'êtes pas convaincu pour la conversion de caractères). De même la valeur à l'adresse 00406031 est 35 en hexadécimal soit 5 en ascii (c'est le format ascii qui est utile). Et ainsi de suite (39<=>9,38<=>8,2d<=>-,31<=>1 ...).

     

    Conclusion : Vous êtes capable maintenant de récupérer un numéro de série (serial) d'un programme sans difficultés. La seule difficulté c'est de savoir dans quelle adresse est située le serial c'est à dire localiser l'endroit où est située la comparaison entre votre serial et le vrai serial (celui calculé par le programme).

     

    3/ Création du 1 ier crack

    Ce qui serait intéressant pour craquer la protection qui se situe au niveau de la fonction lstrcmp c'est de passer en paramètre de la fonction lstrcmp en argument 1 non plus le vrai serial 1598-15026-2421-469 calculé par Start Clean mais notre serial 123456 comme ça le programme va comparer 2 chaînes identiques 123456 et 123456 et rendre vrai à tous les coups dans le test qui suit. Pour ça il faut donc transformer

          
           :004011DD 50                          push eax
           :004011DE 6830604000            push 00406030
           en
           :004011DD 50                          push eax
           :004011DE 50                          push eax
           :004011DF 90                          nop
           :004011E0 90                          nop
           :004011E1 90                          nop
           :004011E2 90                          nop


       -> Vous sélectionnez la ligne d'adresse 004011DE et vous relevez l'offset correspondant à cette adresse dans la barre de statut de w32dasm (là où c'est marqué @offset) soit 5DE

       -> Vous ouvrez une copie de start Clean dans winhex
       -> Vous faites ALT G (aller à la position) -> 5DE
       -> Vous remplacez les octets 68 30 60 40 00 par 50 90 90 90 90
       -> CTRL S pour sauver (enlever la protection en écriture sur le fichier par clic droit-> propriétés si winhex refuse d'enregistrer).
       -> Lancez Start clean et saisissez n'importe quoi dans les champs name et code
       -> Relancez Start clean et vous êtes enregistré. Chouette !

    On peut aussi allez faire un tour dans le registre (démarrer->exécuter->regedit) et ouvrez en déroulant l'arbre à gauche la clef
    HKEY_CURRENT_USERSoftwareStart CleanConfiguration

    Vous retrouvez dans cette clé le code calculé par le programme sous le nom "code" et votre nom sous le nom "name". Comment est-ce que je sais que c'est cette clé qu"il fallait aller voir. Eh bien le programme avant de calculer le bon code est passé sur la ligne de code à l'adresse 00401170

     * Possible StringData Ref from Data Obj ->"SoftwareStart CleanConfiguration

     

    4/ Création du 2 ième crack

    Vous pouvez par exemple pour éviter de vous fatiguer à coder un crack en C++ (voir cours suivant) ou en pascal,  faire un fichier .reg. Celui-ci va se charger de mettre à jour le registre de windows à l'endroit où Start Clean regarde au lancement pour voir si on est enregistré ou non (c'est la clé SoftwareStart CleanConfiguration). Il suffira alors de double cliquer sur le fichier .reg pour faire la mise à jour du registre une fois le fichier crée. Le contenu du fichier que vous allez appeler par exemple crack_startclean.reg est le suivant (faites un copier/coller dans notepad : un fichier .reg est un fichier texte) :

    REGEDIT4

    [HKEY_CURRENT_USERSoftwareStart CleanConfiguration]
    "Name"="pifoman"
    "Code"="1598-15026-2421-469"

     

    5/ Création du keygen

    But : forcer l'affichage du serial par le programme

    Quand vous faites OK dans la boîte d'enregistrement après avoir entré comme nom pifoman et comme code 123456 le programme vous affiche "Incorrect code". Nous on va demander cette fois-ci au programme au lieu de nous afficher ce message "Incorrect code" de nous afficher à la place le bon serial : celui qu'il a calculé. Si si c'est possible ! Pour ça il suffit de connaître l'endroit où le programme affiche la fenêtre d'erreur.

       -> Faite une recherche de l'expression Incorrect code avec Search->Find Text.
       -> Vous trouvez une seule occurrence : l'adresse 004027C5 comme on le voit dans la photo suivante

     

    <script type="text/javascript">document.write("")</script>

     

    On va maintenant utiliser ce qu'on sait déja. Le serial est situé à l'adresse 00406030 car si vous vous souvenez on avait à l'adresse 004011DE un push 00406030 (avant d'entrer dans la fameuse fonction lstrcmp qui comparait notre serial au serial attendu). Maintenant en regardant la photo du dessus on voit que le message d'erreur est passé à la methode MessageBoxA en mettant 2 paramètre sur le pile (push 004063AC et push esi)=> ce sont les variables passées en paramètre de la fonction MessageBoxA. Eh bien voila on a tout ce qu'il faut. Il nous suffit de passer à la place de l'adresse 004063AC qui contient le Incorrect code l'adresse 00406030 qui contient le vrai serial et le tour est joué. On va donc remplacer

       -> :004027C5 68AC634000              push 004063AC
       par
       -> :004027C5 6830604000              push 00406030

    On va pour ça on va dans winhex à l'offset 1BC5 obtenu en sélectionnant la ligne d'adresse 004027C5 et en regardant la barre de statut de W32dasm. Ensuite par ALT G -> 1BC5 dans winhex on effectue la modification du code en remplaçant le code hexédécimal en rouge par sa nouvelle valeur 6830604000.

    On redémarre le programme et on saisit pifoman / 123456 comme valeurs pour les champs name et code. On fait Ok et là le programme nous donne gentiment le serial qu'on a plus qu'à recopier à la place de 123456 dans le champ code de la boîte d'enregistrement.

     

    <script type="text/javascript">document.write("")</script>

     

     

    Voila la protection du programme est complètement élucidée. Nous l'avons craquée de 2 manières différentes:
       -> une qui valide n'importe quel code d'enregistrement
       -> l'autre qui affiche le serial en toute lettre à la place du message d'erreur.

     

    Ce cours est à mon avis très formateur sur le debugging et l'utilisation de w32dasm. Vous pourrez reproduire la même analyse dans beaucoup de programmes dans le but de craquer leur protection par serial.

     


  • Commentaires

    Aucun commentaire pour le moment

    Suivre le flux RSS des commentaires


    Ajouter un commentaire

    Nom / Pseudo :

    E-mail (facultatif) :

    Site Web (facultatif) :

    Commentaire :