Crack in France
par pifoman

 
 

Ce cours est un reflet fidèle du cours intégré au crack de ma création de FlashGet 1.65 fr.

 

INFOS SUR LE CRACK

 

Nom du prog

FlashGet 1.65

Editeur

http://www.amazesoft.com/

Téléchargeable

http://www.flashget.com/fgf165.exe

Date du progMardi 7 juin 2005
Date du crackMardi 19 juillet 2005
Réalisé parPifoman
Url sitehttp://pifoman.free.fr/pif.php
Url redirectionhttp://www.geocities.com/mitonnes/pif.htm

 

COMMENTAIRES SUR LE PROGRAMME

 

      FlashGet est spécialement conçu pour gérer deux des plus gros problèmes survenant lorsque vous téléchargez des fichiers : la vitesse et la gestion des fichiers téléchargés. FlashGet est capable de diviser des fichiers téléchargés en sections, de télécharger chaque section simultanément pour un accroissement de la vitesse de téléchargement. Ces caractéristiques, couplées avec des fonctions de gestion puissantes et faciles à utiliser, vous aideront à contrôler vos téléchargements.

 

LIMITATIONS

 

   1 - Bannière publicitaire permanente dans la fenêtre principale.
   2 - Unregistered dans Aide -> A propos de FlashGet.
   3 - Sous-menu Aide -> formulaire d'achat à retirer une fois enregistré.

 

LES OUTILS

 

w32dasm 8.9
Pour désassembler le progamme (transformation en langage d'assemblage)
Pour trouver les string data references nécessaires pour élaborer le crack.

WinHex 10.2
Pour éditer l'exécutable et modifier certains octets dans le but de la cracker.
On cherche l'offset impliqué en regardant la barre de statut de w32dasm 8.9.
On utilise ce même offset dans WinHex pour effectuer physiquement la modification.

Resource Hacker 3.4.0.79
Pour voir et modifier les ressources d'une application
(menus, icônes , bitmaps, curseurs, raccourcis claviers, boîtes de dialogue)
 

 

ASSEMBLEUR

 

Offset
Déplacement depuis le début de la zone de code d'un programme.

EB
  Code hexadécimal correspondant en assembleur à un saut inconditionnel (jmp).
      On saute tout le temps vers l'adresse écrite sous forme hexadécimale qui suit le EB

90
 Code hexadécimal qui se traduit en assembleur par "ne rien faire" (= nop = No OPeration). 

 

LE CRACK

 

Détail des modifications flashget.exe
(méthode de cracking n°1 et 2)

OctetAdresseOffsetOriginalCrackéEffet
1

0041E0E0

1E0E0

8BC3Enregistrement au nom inscrit dans la base de registre

2

00464FFB

64FFB

48

00

Suppression du menu help -> Ordering Information.

3

00464FFD

64FFD

94

95

Suppression du menu help -> Ordering Information.

 

Détail des modifications flashget.exe
(méthode de cracking n°3)

OctetAdresseOffsetOriginalCrackéEffet
1

0041E2EB

1E2EB

5FEBSaut vers la zone de code qui déclare le serial valide.

2

0041E2EC

1E2EC

5E

13

Saut vers la zone de code qui déclare le serial valide.

 

ANALYSE  DU  PROGRAMME

 

      flashget.exe

 

      Aujourd'hui on s'attaque à un logiciel très connu dans le monde des gestionnaires de téléchargement.

      Comme d'habitude lorsque l'on commence le craquage d'un programme on commence par le désassembler et ensuite le débugguer pour y repérer les failles qui nous serviront à élaborer par la suite le crack. Le désassembleur / débuggueur que j'ai l'habitude d'utiliser et dont on va se servir c'est w32dasm. Cette introduction faite nous pouvons commencer.

      On ouvre flashget.exe dans le désassembleur w32dasm par la commande Disassembler -> Open File to disassemble -> flashget.exe. Après quelques instants le listing de désassemblage s'affiche dans w32dasm.

       Avant de commencer notre étude du programme nous allons mettre systématiquement le logiciel en version anglaise (afficher -> language -> english). Cela présente en effet de nombreux avantages puisque le logiciel comme beaucoup d'autres a été conçu en langue anglaise (menus, interfaces, boîte de dialogue). La version française n'est qu'une traduction du code écrit en anglais.

       Par ailleurs dans ce cours j'expose 2 méthodes de cracking différentes qui aboutissent au même résultat : patcher la variable qui permet de lancer le logiciel en mode enregistré. J'en ai ajouté une troisième et dernière (différente des 2 premières) qui consiste à craquer le routine qui vérifie la validité du serial stocké en base de registre.

 

 

        1/ Les variables d'enregistrement
 

             a/ Tentative d'enregistrement

       Si vous lancez le logiciel vous voyez apparaître dans le dernier menu (le menu help) l'élément "Remove Banner...". En cliquant dessus une fenêtre d'enregistrement apparaît avec 3 champs "Name", "E-Mail" et "Registration Code". Mettons les valeurs suivantes

       "Name" = Pifoman
       "E-Mail" = pifoman@yahoo.com
       "Registration Code"  = 123456

       Appuyez ensuite sur le bouton OK. Une fenêtre apparaît ensuite en affichant "Thank you for registering FlashGet. Please restart the program. If you have typed your registration data correctly, the banners will be removed.". Cela signifie en français que le programme a besoin d'être redémarré pour prendre en compte les modications et que si les informations d'enregistrement sont correctes la bannière qui apparaît en haut de la fenêtre de FlashGet disparaîtra.

       Notons le message et allons dans w32dasm pour voir où est appelé ce message. Faîtes CTRL S pour vous placer au début de la zone de code de FlashGet puis Search -> Find Text -> Thank you for registering FlashGet. Vous arrivez alors à un seul endroit.

 

:0041DF5C745Cje 0041DFBA
:0041DF5E8B8C242C010000mov ecx, dword ptr [esp+0000012C]
:0041DF6551push ecx
 
* Possible StringData Ref from Data Obj ->"RegName"
 
:0041DF6668A8F55200push 0052F5A8
 
* Possible StringData Ref from Data Obj ->"General"
 
:0041DF6B68A8D15200push 0052D1A8
:0041DF708BCEmov ecx, esi
:0041DF72E80D310C00call 004E1084
...
 
* Possible StringData Ref from Data Obj ->"RegPass"
 
:0041DF8168A0F55200push 0052F5A0
 
* Possible StringData Ref from Data Obj ->"General"
 
:0041DF8668A8D15200push 0052D1A8
:0041DF8BE8F4300C00call 004E1084
...
 
* Possible StringData Ref from Data Obj ->"RegDisp"
 
:0041DF9A6898F55200push 0052F598
 
* Possible StringData Ref from Data Obj ->"General"
 
:0041DF9F68A8D15200push 0052D1A8
:0041DFA4E8DB300C00call 004E1084
:0041DFA96AFFpush FFFFFFFF
:0041DFAB6A30push 00000030
 
* Possible Reference to String Resource ID=61314: "Thank you for registering FlashGet. Please restart the prog"
 
:0041DFAD6882EF0000push 0000EF82
:0041DFB2E839140000call 0041F3F0
:0041DFB783C40Cadd esp, 0000000C
 
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0041DF51(C), :0041DF5C(C)
 
:0041DFBA8D4C2408lea ecx, dword ptr [esp+08]

 

       Le message "Thank you for registering FlashGet. Please restart the program. If you have typed your registration data correctly, the banners will be removed." est donc appelé en 0041DFAD. Si vous remontez dans le code vous voyez 3 appels à des chaînes RegName, RegPass et RegDisp suivis à chaque fois d'un appel à General. 3 ça ne vous rappelle rien ? Il y avait 3 champs dans la fenêtre d'enregistrement ! Le problème maintenant est de savoir la correspondance entre ces 3 variables qui seront intégrées au registre et les champs de la boîte d'enregistrement.

 

              b/ Localiser les variables d'enregistrement dans le registre.

       La question se pose alors comment retouver ces 4 informations (RegName, RegPass, RegDisp et General) dans le registre ; informations qui seront examinées par flashget.exe pour savoir s'il doit démarrer en mode enregistré ou non. Pour cela il suffit d'utiliser un petit utilitaire gratuit qui s'appelle Regmon.exe (Regmon = Registry monitoring -> en français surveillance du registre). Il est disponible an anglais sur http://www.sysinternals.com . Il est très petit (seulement 188 ko pour la version 6.06).

      Comment allons nous l'utiliser ? En fait c'est assez simple. Je suppose d'abord que flashget.exe est toujours ouvert et que vous êtes à nouveau dans la boîte d'enregistrement de flashget.exe avec les 3 valeurs suivantes remplies

      "Name" = Pifoman
       "E-Mail" = pifoman@yahoo.com
       "Registration Code"  = 123456

      Ensuite vous lancez Regmon.exe et comme on veut surveiller l'activité du processus flashget.exe avec le registre vous tapez flashget.exe dans la case include puis OK.Vous cliquez ensuite sur le bouton OK de la boîte d'enregistrement et dès que le message "Thank you for registering FlashGet. Please restart the program. If you have typed your registration data correctly, the banners will be removed." apparaît faîtes File -> Save As ... -> Regmon.LOG dans Regmon.exe. Ouvrez ensuite Regmon.LOG. Vous voyez apparaître les informations recherchées.

8   2.27 flashget.exe:2796 SetValue HKCU\software\JetCar\JetCar\General\RegName SUCCESS "pifoman@yahoo.com"
17 2.27 flashget.exe:2796 SetValue HKCU\software\JetCar\JetCar\General\RegPass   SUCCESS "123456"
26 2.27 flashget.exe:2796 SetValue HKCU\software\JetCar\JetCar\General\RegDisp   SUCCESS "Pifoman"

     On en déduit que FlashGet sauvegarde dans le registre nos 3 champs d'enregistrement sous la clé General qui se trouve dans le chemin HKEY_CURRENT_USER\software\JetCar\JetCar.

       RegName =  pifoman@yahoo.com
       RegPass   = 123456
       RegDisp   = Pifoman

     Les variables d'enregistrement sont donc RegName, RegPass, RegDisp.

 

 

        2/ Méthode de cracking n°1

 

             Elle consiste à trouver et forcer la variable d'enregistrement en étudiant le menu Help -> About FlashGet...

              a/ Localiser dans w32dasm le message d'évaluation du menu "A propos de".

     En parcourant les menus de flashget.exe on voit le menu Help -> About FlashGet... qui nous affiche une fenêtre à l'intérieur de laquelle on peut lire : This copy of FlashGet is licensed to : Unregistered. Juste en dessous de cette phrase on lit Our thanks to:. Ce que l'on va faire maintenant c'est voir où le programme fait sa vérification d'enregistrement parcequ'il nous affiche Unregistered. On va pour cela dans le listing de désassemblage de flashget.exe et on cherche la chaîne Our thanks to:.On arrive à cet endroit

 

* Possible StringData Ref from Data Obj ->"Our thanks to:"
 
:0041A2F068CCED5200push 0052EDCC
...
 
* Possible Reference to Dialog: DialogID_0064, CONTROL_ID:04B9, ""
 
...
:0041A36D8BF8mov edi, eax
:0041A36F8BCFmov ecx, edi
:0041A371E86A3D0000call 0041E0E0
:0041A37685C0test eax, eax
:0041A3780F84EE000000je 0041A46C
:0041A37E8D542414lea edx, dword ptr [esp+14]
:0041A3828BCFmov ecx, edi
:0041A38452push edx
:0041A385E846AF0000call 004252D0
...
:0041A3A68B44240Cmov eax, dword ptr [esp+0C]
:0041A3AA8B48F8mov ecx, dword ptr [eax-08]
:0041A3AD85C9test ecx, ecx
:0041A3AF7412je 0041A3C3
...
 
* Possible Reference to Dialog: DialogID_0064, CONTROL_ID:04AE, "Unregistered"
 
:0041A3B268AE040000push 000004AE
:0041A3B78BCEmov ecx, esi
:0041A3B9E8B9E40B00call 004D8877
:0041A3BEE9A9000000jmp 0041A46C
 
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041A3AF(C)
 
:0041A3C38D4C240Clea ecx, dword ptr [esp+0C]
...
 
* Possible StringData Ref from Data Obj ->"Software\Microsoft\Windows\CurrentVersion"
 
:0041A3CC68A0ED5200push 0052EDA0
...
:0041A3EA7E0Ejle 0041A3FA
 
* Possible StringData Ref from Data Obj ->"Software\Microsoft\Windows NT\CurrentVersion"
 
:0041A3EC6870ED5200push 0052ED70
...
 
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041A3EA(C)
 
:0041A3FA6802000080push 80000002
...
 
* Possible StringData Ref from Data Obj ->"RegisteredOwner"
 
:0041A4296860ED5200push 0052ED60
...
 
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0041A378(C), :0041A3BE(U)
 
:0041A46C8D4C240Clea ecx, dword ptr [esp+0C]
...
:0041A490C3ret

 

              b/ Débugging avant l'affichage du message d'évaluation du menu "A propos de".

     On va maintenant débugguer flashget.exe à partir de l'adresse 0041A2F0 (adresse du premier byte de Our thanks to:) pour localiser la variable dans le code de flashget.exe qui est impliquée dans l'enregistrement de flashget.exe. Pour cela on commence par charger le programme en mémoire par la commande CTRL L de w32dasm. Ensuite on lance le programme via le debugger avec F9. On pose alors un breakpoint sur l'adresse 0041A2F0 qui appelle le Our thanks to: (SHIFT F12 -> 0041A2F0 -> OK -> F2) et direction le menu Help -> About FlashGet. A ce moment là w32dasm resurgit. Il a breaké (s'est arrêté) sur l'adresse 0041A2F0 (vous avez entendu un bing). Faîtes ensuite des F8 successifs (F8 = exécution ligne de code par ligne de code du programme sans entrer dans les calls mais en les exécutant quand même). Vous arrivez ici

 

:0041A36F8BCFmov ecx, edi
:0041A371E86A3D0000call 0041E0E0
:0041A37685C0test eax, eax
:0041A3780F84EE000000je 0041A46C
...
 
* Possible StringData Ref from Data Obj ->"RegisteredOwner"
 
:0041A4296860ED5200push 0052ED60
 
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0041A378(C), :0041A3BE(U)
 
:0041A46C8D4C240Clea ecx, dword ptr [esp+0C]

 

     Si vous faîtes F8 arrivé en 0041A378 vous constatez que le programme saute par dessus le RegisteredOwner appelé en 0041A429. Nous on veut s'enregistrer donc il nous faut absolument annuler ce saut en 0041A378. Comment faire ? En 0041A376 flashget.exe fait un test eax, eax qui équivaut à un and eax, eax. Si eax est différent de 00000000 le test rend un résultat non nul ce qui implique que le je 0041A46C (jump if equal to zéro dans le dernier test) ne saute pas (on n'a pas obtenu zéro). Il faut donc sorti du call 0041E0E0 en 0041A371 que eax soit différent de 00000000.Voyons ce qui se passe à l'adresse 0041E0E0 (faîtes F7 dès que vous êtes arrivé avec le debugger sur l'adresse 0041A371).

 

* Referenced by a CALL at Addresses:
|:0041A371 , :00425306 , :0042700F , :0042728D , :0042CFB4
|:00451F64 , :00462AEA , :00464FA0 , :004703EC , :00475DD8
 
:0041E0E08B8184020000mov eax, dword ptr [ecx+00000284]
:0041E0E6C3ret

 

     Vous arrivez en 0041E0E0. Notez la valeur de eax en haut à gauche dans la grande fenêtre du debugger (celle qui s'était ouverte quand vous aviez fait CTRL L dans w32dasm). Vous voyez eax = 0053C9a0. Ensuite si vous faîtes F8 le contenu sur 4 bytes (c'est le dword ptr) de l'adresse ecx + 00000284 est mis dans le registre eax (eax passe alors à 00000000).Et bien il suffit de teminer prématurément l'exécution du call 0041E0E0 en mettant un ret en 0041E0E0. Comme ça eax gardera la valeur non nulle qu'il avait avant de passer dans le call 0041E0E0.

 

             c/ Vérifications des conséquences provoquées par le patch.

     Avant d'effectuer physiquement la modification il faut s'assurer que notre patch ne perturbe pas l'exécution du programme (par exemple un crash). En effet on a modifié l'instruction en 0041E0E0. Le problème c'est que cette instruction est appelée par 10 adresses au total qui sont 0041A371 (celle de notre patch), 00425306, 0042700F, 0042728D, 0042CFB4, 00451F64, 00462AEA, 00464FA0, 004703EC, 00475DD8. On va en vérifier une (les autres on supposera que c'est OK en lançant le programme modifié et en constatant qu'il ne crashe pas et qu'il fait ce qu'on attend de lui c'est à dire démarrer en mode enregistré). Laquelle choisir ? Réponse : 00425306. Pourquoi ? Pour la raison suivante. Le menu "A propos de" de flashget.exe fait appel à cette adresse (voir le listing du paragraphe 2-a) :

     :0041A385   E846AF0000          call 004252D0

     Pour vous en convaincre terminez la session de debugging courante par CTRL T puis relancez en une par CTRL L puis posez un bp sur l'adresse 0041A378 (SHIFT F12 -> 0041A378 -> OK -> F2). En 0041A378 on saute par dessus le RegisteredOwner (cf paragraphe 2-b). Faîtes F9 puis allez dans le menu Help -> About FlashGet... de flashget.exe. w32dasm apparaît arrêté sur l'adresse 0041A378.

 

:0041A371E86A3D0000call 0041E0E0
:0041A37685C0test eax, eax
:0041A3780F84EE000000je 0041A46C
:0041A37E8D542414lea edx, dword ptr [esp+14]
:0041A3828BCFmov ecx, edi
:0041A38452push edx
:0041A385E846AF0000call 004252D0

 

      On va annuler le saut en 0041A378 pour pouvoir atteindre ensuite l'adresse 0041A385. Pour cela cliquez sur le bouton Modify Data dans la grande fenêtre du debugger en bas à gauche puis dans la fenêtre qui s'ouvre cliquez sur le 1 en dessous de la lettre Z en haut puis cliquez sur les boutons Modify puis Close. Faîtes ensuite des F8 pour arriver en 0041A385. Une fois sur cette adresse descendez dans le call 004252D0 en appuyant sur F7.

 

* Referenced by a CALL at Address:
|:0041A385
 
:004252D06AFFpush FFFFFFFF
...
:004252E8A180A15300mov eax, dword ptr [0053A180]
...
:00425306E8D58DFFFFcall 0041E0E0
:0042530B85C0test eax, eax
:0042530D7479je 00425388
:0042530F6898C95300push 0053C998
 
* Possible StringData Ref from Data Obj ->"RegDisp"
 
:004253146898F55200push 0052F598
:004253198D4C2414lea ecx, dword ptr [esp+14]
 
* Possible StringData Ref from Data Obj ->"General"
 
:0042531D68A8D15200push 0052D1A8
...
:0042534F7537jne 00425388
:004253516898C95300push 0053C998
 
* Possible StringData Ref from Data Obj ->"RegName"
 
:0042535668A8F55200push 0052F5A8
:0042535B8D442414lea eax, dword ptr [esp+14]
 
* Possible StringData Ref from Data Obj ->"General"
 
:0042535F68A8D15200push 0052D1A8
 
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0042530D(C), :0042534F(C)
 
...
:004253BCC20400ret 0004

 

      En 0042530B le programme refait un test eax, eax après avoir appelé notre fameux call 0041E0E0. On voit que si le call 0041E0E0 n'a pas été modifié on a encore une remise à zéro de eax (il valait 0053a194 avant de passer sur le call 0041E0E0). Cela provoque encore un saut par dessus une instruction intéressante : le push 0052F598 en 00425314 qui est chargée de récupérer la chaîne RegDisp = "Pifoman" dans le registre pour l'afficher ensuite à la place du Unregistered dans le menu Help -> About FlashGet... de flashget.exe.

      On a donc bien la confirmation encore une fois qu'il faut empêcher la remise à zéro de eax dans le call 0041E0E0.
 

      Remarque : si le programme avait sauté le RegDisp il aurait à la place de Unregistered dans le menu Help -> About FlashGet... de flashget.exe mis la valeur de RegisteredOwner qui se trouve dans la clef HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion. En effet si vous reprenez le listing du paragraphe 2-a en 0041A3AD vous voyez que le programme teste la valeur de ecx qui est la longueur du RegDisp lu en base de registre. Si la lecture du RegDisp n'a pu être faîte ecx = 00000000 et le programme saute vers la lecture de la clef ci-dessus.

 

             d/ Enregistrement de la modification

       -> Dans le code du programme

       Ce que nous allons faire c'est annuler physiquement ma mise à zéro de eax en 0041E0E0. Pour cela on ouvre une copie vierge de flashget.exe dans winhex et on remplace par la commande ALT G -> 1E0E0 (1E0E0 c'est l'offset donné dans w32dasm dans la barre de statut de w32dasm quand vous sélectionnez l'adresse 0041E0E0) le code hexadécimal suivant en blanc et rouge (le blanc c'est ce qui est effectivement à changer) :

 

      :0041E0E0   8B8184020000                      mov eax, dword ptr [ecx+00000284]
      :0041E0E6   C3                                          ret
      :0041E0E7   90                                           nop
      :0041E0E8   90                                           nop
      :0041E0E9   90                                           nop
      :0041E0EA   90                                           nop
      :0041E0EB   90                                           nop
      remplacé par
      :0041E0E0   C3                                           ret
      :0041E0E1   8184020000C39090909090   add dword ptr [edx+eax-6F3D0000], 90909090 

       Le fait de mettre C3 sans changer le code qui le suit est ici sans influence sur l'exécution du programme grâce aux nop d'origine qui suivent le C3 à partir de l'adresse 0041E0E7. En effet si vous modifiez l'offset 1E0E0 dans une copie de flashget.exe en y mettant C3, que vous enregistrer la modification et que vous désassemblez cette copie modifiée dans w32dasm vous voyez dans les 2 listings de désassemblage (flashget.exe non modifié et flashget.exe modifié) que la prochaine ligne de code est située en 0041E0F0 :

      :0041E0F0 6AFF              push FFFFFFFF

       -> Dans le registre de windows

        Cela est effectué par le crack qui met à jour le contenu de la valeur RegDisp présente sous la clé HKEY_CURRENT_USER\software\JetCar\JetCar\General (c'est la commande /nom=pifoman dans la zone de texte du crack).Vous pouvez faire manuellement cette opération (une fois le programme patché) en adaptant ce code qui doit être collé dans un fichier texte nommé enregistrer_flashget.reg :

         REGEDIT4

        [HKEY_CURRENT_USER\software\JetCar\JetCar\General]
        "RegName" =  pifoman@yahoo.com
        "RegPass"   =  123456
        "RegDisp"   =   Pifoman

 

 

        3/ Méthode de cracking n°2

 

             Elle consiste à trouver l'endroit où est retiré le menu Help -> Remove Banner... lors de l'enregistrement.

              a/ Etude des menus avec Resource Hacker.

     Comme on peut le vérifier en appliquant la méthode de cracking n°1 le menu  Help -> Remove Banner... disparaît quand on est enregistré. Logique ! On ne peut pas proposer de retirer la bannière publicitaire (Remove Banner...) à un utilisateur enregistré. On va donc chercher l'endroit où le programme retire ce menu.

     Pour étudier les menus de flashget.exe j'ai choisi l'éditeur de resources Resource Hacker. Ouvrons flashget.exe dans Resource Hacker. A gauche vous avez une structure arborescente qui liste les différents composants de l'application : vous avez de haut en bas les avis, les cursors, les bitmaps, les icons, les menus, les dialogs, la string table, les accelerators, les cursors groups, les icons groups, le version info et une ressource numérotée 241. On va descendre dans le chemin Menu -> 128 -> 1033. Pourquoi ? Parceque si vous cliquez sur ce 1033 une mini fenêtre contenant les menus de flashget.exe apparaît. Si elle n'apparaît pas cliquez sur le bouton Monter en haut dans la partie droite de Resource Hacker. Déroulez ensuite l'ascenseur à droite au maximum pour retrouver le menu HELP.Voici ce que vous devez trouver.

     POPUP "Sea&rch"
     {
          MENUITEM "&MP3\tF10", 32919
          MENUITEM "&Software", 32920
          MENUITEM "&Game", 32921
          MENUITEM "&File", 32922
          MENUITEM "&WWW", 32923
     }

     POPUP "&Help"
     {
          MENUITEM "User &Manual", 32823
          MENUITEM SEPARATOR
          MENUITEM "&Register...", 32916
          MENUITEM "&Remove Banner...", 32846
          MENUITEM "&Ordering Information", 32917
          MENUITEM SEPARATOR
          MENUITEM "&Check for a new version", 32858
          MENUITEM "&About FlashGet...", 57664
          MENUITEM "&Goto FlashGet Home Page ->", 32796
          MENUITEM "&FAQ in Internet", 32914
          MENUITEM "&User Manual in Internet", 32915
     }

 

     Comment interpréter ce code.Le mot-clef POPUP déclare l'existence d'un menu de nom HELP.Le & devant le HELP c'est pour le raccourci clavier (dans flashget.exe les touches ALT et h pressées en même temps déroule le menu help). Chaque élément du menu est précédé du mot-clef MENUITEM puis suivi du nom qui sera affiché dans flashget.exe et enfin d'un identifiant). Le mot-clef SEPARATOR trace une ligne horizontale ente 2 éléments sucessifs du menu (par exemple User &Manual et &Register...).

     Dans le menu HELP on voit tout de suite que l'élement &Register... existe mais n'est jamais affiché (mode enregistré ou non). C'est sûrement un reste d'un précédent flashget qui a été gardé pour conserver la compatibilité ascendante entre les versions sucessives de flashget. Par ailleurs le menu Sea&rch existe aussi mais n'est jamais affiché (mode enregistré ou non). Pourquoi ? Parceque le service internet de recherche de http://www.amazesoft.com/ n'est plus implémenté. Si vous réactivez ce menu (je vous monterais comment faire plus bas) flashget.exe lancera une requête sur un serveur web sans rien donner comme résultat (à part des signes cabalistiques incompréhensibles).

 

              b/ Trouver l'endroit où est appelé l'élément de menu Remove Banner...

     L'élément de menu qui nous intéresse c'est le MENUITEM "&Remove Banner...", 32846. En hexadécimal 32846 donne 804E (démarrer -> exécuter -> calc -> 32846 -> clic sur le bouton hex). Revenons à flashget.exe désassemblé dans w32dasm et cherchons où est appelé cet élement de menu par CTRL S ; Search -> Find Text -> 0000804E -> OK.

 

:00464F9C8B4C2414mov ecx, dword ptr [esp+14]
:00464FA0E83B91FBFFcall 0041E0E0
:00464FA585C0test eax, eax
:00464FA77453je 00464FFC
...
 
* Reference To: USER32.GetMenu, Ord:011Ch
 
:00464FADFF1524265000Call dword ptr [00502624]
...
 
* Possible Reference to Dialog: DialogID_00CA, CONTROL_ID:0007, "&No"
 
:00464FBC6A07push 00000007
:00464FBE50push eax
:00464FBFFFD5call ebp
...
 
* Reference To: USER32.DeleteMenu, Ord:0087h
 
:00464FD08B3D54265000mov edi, dword ptr [00502654]
:00464FD66A00push 00000000
 
* Possible Reference to String Resource ID=32846: "Register FlashGet to remove the banner."
 
:00464FD8684E800000push 0000804E
:00464FDD51push ecx
:00464FDEFFD7call edi
...
 
* Possible Reference to String Resource ID=32916: "Register your flashget."
 
:00464FE56894800000push 00008094
:00464FEA52push edx
:00464FEBFFD7call edi
...
:00464FFAEB48jmp 00465044
 
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00464FA7(C)
 
 
* Possible Reference to String Resource ID=32916: "Register your flashget."
 
:00464FFCBE94800000mov esi, 00008094
:00465001E8DAF1FAFFcall 004141E0
:004650066683B86E03000001cmp word ptr [eax+0000036E], 0001
:0046500E7505jne 00465015
 
* Possible Reference to String Resource ID=32846: "Register FlashGet to remove the banner."
 
:00465010BE4E800000mov esi, 0000804E
 
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0046500E(C)
 
:004650158B4B1Cmov ecx, dword ptr [ebx+1C]
...
 
* Reference To: USER32.GetMenu, Ord:011Ch
 
:00465019FF1524265000Call dword ptr [00502624]
...
 
* Possible Reference to Dialog: DialogID_00CA, CONTROL_ID:0007, "&No"
 
:004650286A07push 00000007
:0046502A52push edx
:0046502BFFD5call ebp
...
:0046503A6A00push 00000000
:0046503C56push esi
:0046503D50push eax
 
* Reference To: USER32.DeleteMenu, Ord:0087h
 
:0046503EFF1554265000Call dword ptr [00502654]
 
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00464FCB(C), :00464FFA(U), :00465035(C)
 
:004650448B4B1Cmov ecx, dword ptr [ebx+1C]
:0046504751push ecx
 
* Reference To: USER32.GetMenu, Ord:011Ch
 
:00465048FF1524265000Call dword ptr [00502624]
...
:004650576800040000push 00000400
 
* Possible Reference to Dialog: DialogID_00CA, CONTROL_ID:0006, "&Yes"
 
:0046505C6A06push 00000006
:0046505E52push edx
 
* Reference To: USER32.RemoveMenu, Ord:0204h
 
:0046505FFF1508275000Call dword ptr [00502708]
...
:00465077C3ret

 

     La routine de masquage de l'élément de menu &Remove Banner... est longue mais je ne peux pas la simplifier plus au risque de vous égarer. Si vous démarrez une session de debugging avec CTRL L puis que posez un breakpoint sur l'adresse 00464FA7 après notre fameux call 0041E0E0 (qui teste l'enregistrement de flashget) et que vous faîtes F9 le débugger va s'arrêter sur l'adresse 00464FA7. Après une série de F8 jusqu'au ret en 00465077 voici le détail de ce qui se passe.

     00464FA7 : saut vers 00464FFC.
     00464FFC : on met l'identifiant de l'élément de menu &Register... dans esi. 8094h = 32916d.
     0046500E : on saute la mise dans esi de l'identifiant 804E (l'élément de menu &Remove Banner...). 804Eh = 32846.
     00465019 : on appelle l'API USER32.GetMenu.
     0046502B : on appelle l'API USER32.GetSubMenu.
     0046503C : on passe l'identifiant esi = 00008094 à l'API USER32.DeleteMenu.
     0046503E : on appelle l'API USER32.DeleteMenu et on efface l'élément &Register... du menu help.
     00465048 : on appelle l'API USER32.GetMenu.
     0046505C : on passe le menu numéro 6 à l'API USER32.RemoveMenu correspondant au menu caché Search.
     0046505F : on appelle USER32.RemoveMenu et on supprime le menu Search.

 

     Conclusion : on supprime l'élement de menu &Register... mais pas le &Remove Banner....Si on annule le saut en 00464FA7 (équivaut à patcher le call 0041E0E0 comme précédemment en empêchant la remise à zéro de eax) voici ce qui se passe :

 

     00464FA7 : on ne saute pas vers 00464FFC.
     00464FAD : on appelle l'API USER32.GetMenu.
     00464FBF : on appelle l'API USER32.GetSubMenu.
     00464FD0 : on passe dans edi l'adresse du début de la fonction DeleteMenu de C:\windows\system32\user32.dll.
     00464FD8 : on empile l'identifiant 804E (l'élément de menu &Remove Banner...). 804Eh = 32846.
     00464FDE : on appelle l'API USER32.DeleteMenu et on supprime l'élément de menu &Remove Banner...
     00464FE5 : on empile l'identifiant 8094 (l'élément de menu &Remove Banner...). 8094h = 32916d.
     00464FEB : on appelle l'API USER32.DeleteMenu on efface l'élément &Register... du menu help.
     00464FFA : on saute vers 00465044.
     00465048 : on appelle l'API USER32.GetMenu.
     0046505C : on passe le menu numéro 6 à l'API USER32.RemoveMenu correspondant au menu caché Search.
     0046505F : on appelle USER32.RemoveMenu et on supprime le menu Search.

 

     Conclusion : on supprime les élements de menu &Remove Banner... et &Register....C'est ce qu'on voulait.

 

             c/ Enregistrement de la modification

     C'est exactement pareil que dans le paragraphe 2-d.

 

 

        4/ Patchs supplémentaires des méthodes de cracking n°1 et 2

 

     -> Le patch inutile

     Chose promise chose dûe. Je vous avais promis de faire réapparaître le menu caché Search de flashget.exe. Je ne l'afficherais pas dans mon crack car le service de recherche comme je l'ai dit précédemment chez http://www.amazesoft.com/ n'est plus implémenté. J'expose juste la démarche à suivre pour réaliser ce tour de passe-passe. Vous avez remarqué (cf paragraphe 3-b) que dans les 2 cas (mode enregistré ou mode non enregistré) on appelle en 0046505F l'API USER32.RemoveMenu pour supprimer le menu numéro 6 (c'est le numéro correspondant au menu Search). Eh bien pour faire réapparaître ce menu il suffit d'annuler l'appel à cette fonction. Par exemple on peut remplacer à l'offset 65044 dans winhex le code hexadécimal suivant en rouge :

 

     :00465044   8B4B1C            mov ecx, dword ptr [ebx+1C]
       remplacé par
     :00465044   EB23                 jmp 00465069
     :00465046   90                      nop

 

     -> Le patch utile

     Une fois enregistré vous voyez le menu help -> Ordering Information (en français Aide -> Formulaire d'achat). Ca fait un peu désordre sachant qu'on est enregistré et que l'on a normalement déja payé une licence. On ne va pas quand même en payer une une deuxième fois :(! Bon voici ce qu'on va faire c'est effacer cet élément de menu en utilisant ce qu'on a fait auparavant. Comme on est enregistré on ne saute pas en 00464FA7. Souvenez vous en mode non enregistré on invoquait  l'API USER32.DeleteMenu en 0046503E. L'identifiant de &Ordering Information (cf Resource Hacker) c'est 32917 <=> 8095 en hexadécimal. Eh bien il suffit de remplacer à l'offset 64FFA dans winhex le code hexadécimal suivant en blanc et rouge (le blanc c'est ce qui est effectivement à changer) :

 

     :00464FFA   EB48                   jmp 00465044
     :00464FFC   BE94800000       mov esi, 00008094
 
      remplacé par
     :00464FFA   EB00                   jmp 00464FFC
     :00464FFC   BE95800000       mov esi, 00008095

 

 

        5/ Méthode de cracking n°3

 

             Elle consiste à forcer la procédure qui vérifie la validité du serial stocké en base de registre.

             a/ Pose des breakpoints

       On sait que c'est la valeur du paramètre RegPass de la clé HKEY_CURRENT_USER\software\JetCar\JetCar\General qui est vérifiée au démarrage par flashget.exe pour savoir s'il doit démarrer en mode enregistré ou non. Ce qu'on va faire c'est d'abord lancer une nouvelle session de debugging dans w32dasm (flashget.exe a été au préalable désassemblé dedans) avec la commande CTRL L de w32dasm. Puis faîtes CTRL S et Search -> Find Text -> RegPass -> F2. Alternez les F3 (occurence suivante) avec les F2. Vous avez mis alors 2 breakpoints. Un sur l'adresse 0041DF81 et un sur l'adresse 0041E156. On démarre le débugging avec F9 et on break ici

 

* Possible StringData Ref from Data Obj ->"RegPass"
 
:0041E15668A0F55200push 0052F5A0
:0041E15B8D4C241Clea ecx, dword ptr [esp+1C]
 
* Possible StringData Ref from Data Obj ->"General"
 
:0041E15F68A8D15200push 0052D1A8
...
:0041E1BB8379F805cmp dword ptr [ecx-08], 00000005
:0041E1BF0F8E26010000jle 0041E2EB
 
* Possible StringData Ref from Data Obj ->"@"
 
:0041E1C568C4F55200push 0052F5C4
:0041E1CA8BCEmov ecx, esi
:0041E1CCE855260B00call 004D0826
:0041E1D185C0test eax, eax
:0041E1D30F8C12010000jl 0041E2EB
 
* Possible StringData Ref from Data Obj ->"."
 
:0041E1D968C0F55200push 0052F5C0
:0041E1E0E841260B00call 004D0826
:0041E1E585C0test eax, eax
:0041E1E70F8CFE000000jl 0041E2EB
...
:0041E1FB8B5500mov edx, dword ptr [ebp+00]
:0041E1FE8B42F8mov eax, dword ptr [edx-08]
:0041E20183F82Ccmp eax, 0000002C
:0041E2040F85E1000000jne 0041E2EB
 
* Possible StringData Ref from Data Obj ->"fgc-"
 
:0041E20A68B8F55200push 0052F5B8
:0041E20F8BCDmov ecx, ebp
:0041E211E810260B00call 004D0826
:0041E21685C0test eax, eax
:0041E2187506jne 0041E220
:0041E21A895C2410mov dword ptr [esp+10], ebx
:0041E21EEB18jmp 0041E238
 
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041E218(C)
 
 
* Possible StringData Ref from Data Obj ->"fgf-"
 
:0041E22068B0F55200push 0052F5B0
:0041E2258BCDmov ecx, ebp
:0041E227E8FA250B00call 004D0826
:0041E22C85C0test eax, eax
:0041E22E0F85B7000000jne 0041E2EB
 
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041E21E(U)
 
...
:0041E24833F6xor esi, esi
 
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041E2DD(U)
 
:0041E24A8B07mov eax, dword ptr [edi]
...
:0041E2D746inc esi
:0041E2D883FE03cmp esi, 00000003
:0041E2DB7D23jge 0041E300
:0041E2DDE968FFFFFFjmp 0041E24A
...
 
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0041E197(C), :0041E1A5(C), :0041E1BF(C), :0041E1D3(C), :0041E1E7(C)
:0041E204(C), :0041E22E(C)
 
:0041E2EB5Fpop edi
:0041E2EC5Epop esi
...
:0041E2FFC3ret
 
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041E2DB(C)
 
:0041E3006AFFpush FFFFFFFF
...
:0041E3106A01push 00000001
:0041E31250push eax
 
* Possible StringData Ref from Data Obj ->"General"
 
:0041E31368A8D15200push 0052D1A8
:0041E318E807CE0C00call 004EB124
...
:0041E335C3ret

 

       J'ai retiré la routine de vérification du serial du listing qui est entre les adresses 0041E248 et 0041E2DD. J'ai juste gardé les tests de validité qui font que le serial (contenu de la variable RegPass) sera toujours bon sorti de la boucle de vérification.

       0041E1CC : on vérifie que pifoman@yahoo.com contient un @ sinon on saute vers la sortie en 0041E2EB.
       0041E1E0   : on vérifie que pifoman@yahoo.com contient un . sinon on saute vers la sortie en 0041E2EB.
       0041E201   : on compare la longueur de la valeur de RegPass à 2C = 44 en décimal.Si différente on sort -> 0041E2EB.
       0041E22E   : si RegPass ne commence pas par fgc- ou fgf- on saute vers la sortie en 0041E2EB.
       0041E248   : on initialise le compteur de boucle esi à 00000000.
       0041E2D7  : on augmente de 1 le compteur de boucle.
       0041E2DB : si on a fait 3 tours de boucle on saute vers la sortie 0041E300 qui déclare que RegPass est un serial valide.
       0041E2DD : on boucle sur 0041E24A pour lire la suite de la valeur RegPass (qui est le serial).
 

 

             b/ Le patch de la routine de vérification du serial

       On a l'embarras du choix. Voici une solution parmi d'autres. Elle consite à sauter vers la bonne sortie 0041E300 depuis 0041E2EB. Cela fonctionne quelque soit les caratères contenus dans RegPass (RegPass peut même être vide).

       Ouvrons une copie vierge de flashget.exe dans winhex et remplaçons par la commande ALT G -> 1E2EB (1E2EB c'est l'offset donné dans w32dasm dans la barre de statut quand vous sélectionnez l'adresse 0041E2EB) le code hexadécimal suivant en rouge :

 

      :0041E2EB    5F               pop edi
      :0041E2EC    5E               pop esi
      remplacé par
      :0041E2EB    EB13           jmp 0041e300

 

       Enregistrons et lançons le programme modifié. On est enregistré. Vous remarquez que l'on a pas besoin de remplir les champs du menu help -> Remove Banner... ni de modifier les 3 valeurs du registre (RegName, RegPass, RegDisp) car on est directement enregistré avec ce patch.

 

 

CONCLUSION

 

      Dans ce cours vous avez appris dans un premier temps à localiser les variables d'enregistrement du programme flashget.exe en exploitant un message d'erreur dans w32dasm et en utilisant l'utilitaire Regmon. Par la suite je vous ai présenté 2 méthodes pour craquer FlashGet à partir de 2 analyses différentes conduisant au même résultat : l'enregistrement du logiciel à votre nom.

      La première méthode consiste à étudier le menu Aide -> "A propos de". Il s'agit en particulier de retouver l'endroit dans w32dasm où le programme appelle le message Our thanks to: .C'est en effet à la suite de cette expression que le nom du propriétaire du logiciel est affiché. Unregistered par défaut ou une autre valeur notamment celle de la variable RegDisp stockée dans le registre lors de la tentative d'enregistrement par le menu aide -> "Remove Banner".

      La seconde méthode consiste quant à elle à chercher l'endroit dans w32dasm où est appelé l'élément de menu "Remove Banner...". En effet ce dernier n'apparaît pas dans la version enregistrée du programme. Pour mener à bien notre analyse on a récupéré l'identifiant de cet élément de menu via l'éditeur de ressources nommé Resource Hacker puis cherché dans w32dasm cet identifiant sous forme hexadécimale. Nous sommes tombé comme dans la première méthode sur la variable d'enregistrement qui permettait le retrait de "Remove Banner...".

       Dans une 4 ième partie je vous ai montré 2 endroits où l'on peut patcher (un pour faire réapparaître le menu caché Search et un pour retirer le menu help -> Ordering Information qui reste malgré l'enregistrement).

       Enfin dans une 5 ième partie je vous expose la technique pour craquer la procédure qui teste la validité du serial entré.

 

Bonne nuit à tous.
Et à bientôt pour de nouveaux cours.
Pifoman

 



pifoman




Nombre de visites depuis le 20/07/2005