Trouver un serial pour Gesbank 2.10a (Visual Basic 3)

 Introduction:

Gesbank est un utilitaire qui sert a faire ses comptes.
Si on utilise Filemon en le lançant on s'aperçois qu'il utlise VBRUN300.DLL il s'agit donc d'un programme ecrit en Visual Basic 3 , il va donc falloir utliser une methode differente que celle utilise habituellement pour cracker ce programme.

Outils necessaires:

- Le prog Gesbank 2.10a dispo sur le site de ATP-Team (section Exercices)
- Un decompilateur pour visual basic 3 , j'ai utiliser personellement Dodi's VB Discompiler ,disponible sur le site de Mammon par exemple.
- Qbasic : fournie dans le cdrom de win95 ou win98 (D:\TOOLS\OLDMSDOS\)

Decompilation:

Apres avoir recuperer un decompilateur vb3 si vous n'en n'aviez pas , il faut decompiler le prog , avec Dodi la marche a suivre est la suivante:
- Lancer Dodi's VB Discompiler
- File/Open puis Gesbank2.exe puis selectionner un repertoire ou sera extrait toutes les parties du prog.
- Ensuite vous risquer d'avoir un message d'erreur a propos de shape3d.vxd , cliquer sur ignorer , puis sur ok , normalement vous voyer defiler des nom de fichier.
- Aller dans le repertoire que vous avez choisi precedament et vous avez alors tout plein de fichier qui corresponde a chaque partie du programme.
- En cherchant un peu on voit que la section d'enregistrement est dans le fichier Nomlic.bas.

Comprehension du programme:

Voici ce qu'on obtient (raccourci , j'ai juste garder ce qui etait interressant):
-----------------------------------------------------------------------------
   .............
   Screen.MousePointer = c001E
 
   l0028 = "Désolé." & gv00E0
   l0028 = l0028 & "Ce n'est pas le bon code (ou saisie non conforme)."
message qui indique que vous n'avez pas entrer le bon code donc 10028 = bad code !

For l002C = False To 1
      txtSaisie(l002C).Text = Trim(txtSaisie(l002C).Text)
      If  txtSaisie(l002C).Text = "" Then Exit For
   Next l002C
   If  l002C <= 1 Then
      Screen.MousePointer = False
      MsgBox "Saisie obligatoire.", 64, gc00BE
      txtSaisie(l002C).SetFocus
      Exit Sub
   End If
test si quelque chose a ete entre si non => affiche saise obligatoire

   l0038 = InStr(txtSaisie(1).Text, "-")
En utlisant l'aide Qbasic on trouve que la commande Instr sert a mettre dans une variable la position ou se trouve un caractere dans une chaine donc dans le cas present le programme met dans la variable 10038 la place du premier tiret qui se trouve dans txtSaisie(1).Text qui est surement par deduction le code entre.

   If  l0038 = False Or l0038 < 3 Or l0038 = Len(txtSaisie(1).Text) Then
Teste si 10038 est egal a False (donc 0) , si il ce trouve a moins de trois caractere ou si il est en derniere position , si c'est le cas alors => erreur (bad code!)

      Screen.MousePointer = False
      Beep
      MsgBox l0028, 16, gc00BE
      Unload frmNomLicence
      Exit Sub
   End If
Le prog arrive ici si les conditions precedentes sont fausse

   l003C = Left(txtSaisie(1).Text, l0038 - 1)
Left sert a mettre dans une variable un nombre donne de caractere qui se trouve dans une chaine en partant de la gauche.
Donc ici le programme met dans 1003C les caracteres du debut jusqu'au tiret (10038-1)

   l0040 = InStr(l0038 + 1, txtSaisie(1).Text, "-")
Le programme met dans 10040 la position du prochain tiret.

   If  l0040 = False Or l0040 = Len(txtSaisie(1).Text) Then
Si il n'y a plus de tiret ou si il sagit du dernier caractere => erreur
      Screen.MousePointer = False
      Beep
      MsgBox l0028, 16, gc00BE
      Unload frmNomLicence
      Exit Sub
   End If

l0044 = Mid(txtSaisie(1).Text, l0038 + 1, l0040 - (l0038 + 1))
Mid sert a mettre dans une variable une partie d'une chaine de caractere , Mid (chaine , depart , nb_de_caractere )
Donc prenont par exemple la cle suivante : ABC-DEFGHIJK-MNO , le programme met alors dans 10044 "DEFGHIJK"
(Mid(chaine, 3+1 , 13 - (3+1)))

   If  Len(l0044) <> 14 Or Mid(l0044, 7, 7) <> "BP30742" Then
Len met dans une variable le nombre de caractere d'une chaine , donc le programme teste si la longueur de "DEFGHIJK" est different de 14 ou si du 7e caractere de 10044 et pour les 7 suivant la chaine correspond a "BP30742" si ce n'est pas le cas => erreur.
Donc nous savons maintenant que la chaine doit etre de cette forme : ABC-DEFGHIBP30742J-KLM par exemple.

      Screen.MousePointer = False
      Beep
      MsgBox l0028, 16, gc00BE
      Unload frmNomLicence
      Exit Sub
   End If

   l0048 = Mid(txtSaisie(1).Text, l0040 + 1)
Met dans 10048 "KLM" pour notre exemple

   For l002C = 1 To Len(l0048)
      If  Asc(Mid(l0048, l002C, 1)) < 48 Or Asc(Mid(l0048, l002C, 1)) > 57 Then Exit For
   Next l002C
Asc retourne dans une variable le premier code ascii d'une chaine de caractere.Le programme ici fait une boucle le nombre de fois qu'il y a de caracteres dans 10048 donc 3 fois dans notre exemple , en testant si le caractere qui se trouve dans 10048 a la position 1002C a pour code ascii un nombre compris entre 48(code ascii de 0) et 57(code ascii de 9)  si ce n'est pas le cas => sort de la boucle sinon continue.
Donc en fait il verifie si "KLM" sont des chiffres.

   If  l002C <= Len(l0048) Then
Verifie si toute les caracteres sont passer dans le teste est donc si toute les caracteres sont des chiffres, si ce n'est pas le cas => erreur
Nous savon maintenant que le code doit etre de la forme : ABC-DEFGHIBP30742J-123

      Screen.MousePointer = False
      Beep
      MsgBox l0028, 16, gc00BE
      Unload frmNomLicence
      Exit Sub
   End If

   l004C& = False
Met 0 dans 1004c

   For l002C = 1 To Len(txtSaisie(False).Text)
      l004C& = l004C& + Asc(Mid(txtSaisie(False).Text, l002C, 1))
   Next l002C
Fait une boucle en additionnant tout les code ascii de txtSaisie(False).Text qui doit etre surement notre Nom.
Prenons Bendi :
B = 66    e = 101    n = 110  d = 100   i = 105
66+101+110+100+105= 482
1004c = 482

   l004E& = False
Met 0 dans 1004e

   For l002C = 1 To 6
      l004E& = l004E& + Val(Mid(l0044, l002C, 1))
   Next l002C
Val sert a convertir un caractere numerique en sont equivalent numerique (????) si a$="10" et b=val(a$) alors b=10 OK ? Non , c'est pas grave !!
En fait le programme additionne tous les nombre dans 10044 de la position 1 a 6.
Donc dans notre exmple 1004e serait egal a 0 car il n'y a aucun chiffre dans "DEFGHI"

   l0050& = False
Met 0 dans 10050

   For l002C = 1 To Len(gc00BE)
      l0050& = l0050& + Asc(Mid(gc00BE, l002C, 1))
   Next l002C
Fait la somme des caracteres ascii de gc00BE. Mais qu'est ce que c'est que gc00BE en regardant on s'aperçois qu'on le trouve a chaque foit que la messagebox de code faux est appelle , en cherchant de la doc sur visualbasic , j'ai trouve que la commande messagebox doit appelle de la façon suivante : messagebox  message , type_de_boite , titre , il sagit donc du titre on regarde le titre qui apparait quand on rentre un mauvais code :"GesBank".
Somme = 71+101+115+66+97+110+107=667
10050 = 667

   If  l004C& + l004E& + l0050& <> Val(l003C) Then
Val(1003c) est en fait la valeur contenue dans "ABC" donc 0 dans notre exemple.
Additionne 1004C + 1004E + 10050 , si le resultat est different de "ABC" => erreur
482+667+1004C =ABC
482+667=1149
Faisont un compte rond !
si 1004C=11 alors ABC = 1160
Comment faire 11 avec la somme des chiffres des "DEFGHI" ben , "222221" par exemple !!
Notre exemple est maintenant : 1160-222221BF30742J-123

      Screen.MousePointer = False
      Beep
      MsgBox l0028, 16, gc00BE
      Unload frmNomLicence
      Exit Sub
   End If

   l0052 = Len(txtSaisie(False).Text)
10052 = taille de Name (5 pour Bendi )

   If  l0052 > 26 Then l0052 = l0052 - 26
Si tu comprends pas ca c'est grave !

   If  Right(l0044, 1) <> Chr(l0052 + 64) Then
Right sert a la meme chose que left sauf qui part de droite (nonnnn??)
Donc le programme teste si la lettre de droite de "222221BP30742J" donc J est le meme caractere qui pour code ascii 10052+64 donc dans notre cas 5+64=69 Chr(69)=E

      Screen.MousePointer = False
      Beep
      MsgBox l0028, 16, gc00BE
      Unload frmNomLicence
      Exit Sub
   End If

   l0056& = l004C& Mod l0052
Mod divise deux nombre est met le reste dans la variable utilise donc ici le programme fait 482/5 ce qui en utilisant Qbasic donne 2.

   If  l0056& <> Val(l0048) Then
Si 10056 different de "123" dans notre exemple alors => erreur , donc je vous laisse le plaisir de trouver le bon code en remplacant le valeur de 10048 par celle de 10056 ,...
     Screen.MousePointer = False
      Beep
      MsgBox l0028, 16, gc00BE
      Unload frmNomLicence
      Exit Sub
   End If
   gv0148.M080F = txtSaisie(False).Text
   .......................
   .......................
   gv00D8 = ""
   For l006E = 4 To 5
      MDI1.smnuAssist(l006E).Visible = False
   Next l006E
   MDI1.Caption = gc00BE & " " & gc00C4
   Screen.MousePointer = False
   MsgBox "Merci de votre confiance envers le shareware", 64, gc00BE
   Unload frmNomLicence
   Exit Sub
  ..........................
Plus rien, c'est fini il ne rest plus qu'a essaye le code est BINGO ! il fonctionne ! Bon pour ceux qui aurez rencontrer un probleme voici un petit supplement gratuit !
-----------------------------------------------------------------------------

Allons plus loin...

Allons plus loin,... temps qu'on a Qbasic sous la main, faisons une traduction de la verif en faisant un petit copier-coller plus quelque changement ainsi si vous avez du mal a trouver votre code vous pourez tracer la verif pour voir ce qui ne va pas (si!si! QBasic a une fonction de deboguage !!)
Voici ce que ça donne :
-----------------------------------------Verif.bas----------------------------------
CLS
PRINT "Verification de l'enregistrement de GesBank"
PRINT "ecrit pour QBasic par Bendi"
PRINT ""
INPUT "Nom:"; name$
INPUT "Code:"; serial$
gc00be$ = "GesBank"
a10038 = INSTR(serial$, "-")
IF a10038 = 0 OR a10038 < 3 OR a10038 = LEN(serial$) THEN
GOTO nag
END IF
a1003c$ = LEFT$(serial$, a10038 - 1)
a10040 = INSTR(a10038 + 1, serial$, "-")
IF a10040 = 0 OR a10040 = LEN(serial$) THEN
GOTO nag
END IF
a10044$ = MID$(serial$, a10038 + 1, a10040 - (a10038 + 1))
IF LEN(a10044$) <> 14 OR MID$(a10044$, 7, 7) <> "BP30742" THEN
GOTO nag
END IF
a10048$ = MID$(serial$, a10040 + 1)
FOR a1002c = 1 TO LEN(a10048$)
IF ASC(MID$(a10048$, a1002c, 1)) < 48 OR ASC(MID$(a10048$, a1002c, 1)) > 57 THEN EXIT FOR
NEXT a1002c
IF a1002c <= LEN(a10048$) THEN
GOTO nag
END IF
a1004c = 0
FOR a1002c = 1 TO LEN(name$)
 a1004c = a1004c + ASC(MID$(name$, a1002c, 1))
NEXT a1002c
a1004e = 0
FOR a1002c = 1 TO 6
 a1004e = a1004e + VAL(MID$(a10044$, a1002c, 1))
NEXT a1002c
a10050 = 0
FOR a1002c = 1 TO LEN(gc00be$)
 a10050 = a10050 + ASC(MID$(gc00be$, a1002c, 1))
NEXT a1002c
IF a1004c + a1004e + a10050 <> VAL(a1003c$) THEN
GOTO nag
END IF
a10052 = LEN(name$)
IF a10052 > 26 THEN a10052 = a10052 - 26
IF RIGHT$(a10044$, 1) <> CHR$(a10052 + 64) THEN
GOTO nag
END IF
a10056 = a1004c MOD a10052
IF a10056 <> VAL(a10048$) THEN
GOTO nag
END IF
PRINT "Bravo !! vous venez de cracker GesBank..:)"
GOTO fin:
nag:
PRINT "Mauvais code !!"
fin:
-----------------------------------------Verif.bas----------------------------------

Petite Keygen vite fait !!

Bon , aller .. temps qu'on y est , on va faire une petite Keygen vite fait !!! Et deviner en quel language ...... QBasic !!! Bon je sais ,c'est nul !, mais c'est tellement simple !! puis pour un programme ecrit en basic rien ne vaut une keygen ecrit en basic ! Mais si vous savez programmer en assembleur ou C vous aurez vite fait de la traduire .

Bon aller, voila ce ca donne :

-----------------------------------------keygen.bas----------------------------------
CLS
PRINT "KeyGen pour Gesgank 2.10a"
PRINT "ecrit pour Qbasic par Bendi"
' affiche le titre
PRINT ""
' et la demande de nom
INPUT "Nom:"; name$
PRINT "code:"

gencode:

rand:
RANDOMIZE TIMER                                   ' routine qui
a = RND * 1000000                                       ' sort un nombre
nbr = INT(a)                                                   ' aleatoire de
IF a < 100000 THEN                                     ' 0 a 999999  (6 chiffres)
GOTO rand
END IF

som1 = 0                                                        ' routine qui
FOR X = 1 TO LEN(name$)                         ' calcul la somme des
 som1 = som1 + ASC(MID$(name$, X, 1))   ' caractere
NEXT X                                                          ' du nom

nbr$ = STR$(nbr)                                            ' transforme le nombre aleatoire
                                                                        ' en string$ (ex: 123 devient "123")

som2 = 0                                                        ' routine qui
FOR X = 1 TO 7                                              ' calcul la somme des
 som2 = som2 + VAL(MID$(nbr$, X, 1))        ' chiffres
NEXT X                                                          ' du nombre aleatoire

code1 = som1 + som2 + 667                           ' additionne les 2 sommes precedentes
                                                                        ' et met le resultat dans code1

code1$ = STR$(code1)                                    ' transforme code1 en string$

code2$ = CHR$(LEN(name$) + 64)                ' additionne la valeur du caractere
                                                                        ' a 64 et met le caractere dans code2$
code3 = som1 MOD LEN(name$)                 ' divise som1 par la taille de name
                                                                        ' et met le reste dans code3

code3$ = STR$(code3)                                ' transforme code3 en string$

code$ = code1$ + "-" + LTRIM$(nbr$) + "BP30742" + code2$ + "-" + LTRIM$(code3$)

' ajoute les chaines code1$ , code2$ et code3$ avec le nombre aleatoire
' la cle et des tirets

LOCATE 4, 6: PRINT code$                ' affiche le code

PRINT "Nouveau code ? O/N"              ' demande pour un nouveau code
                                                               ' avec un nouveau nombre aleatoire
nkey:                                                       ' ..
a$ = INKEY$                                         ' ....
IF a$ = "o" THEN GOTO gencode ELSE IF a$ = "n" GOTO fin ELSE GOTO nkey
fin:
-----------------------------------------keygen.bas----------------------------------

Et voila, c'est simple ! Normal , on a la verif juste au dessus, il y a juste a faire l'operation inverse !

...the end...

Voila c'est fini , j'espere vous avoir appris quelque trucs en ce qui concerne le crack des programmes Visual Basic , en fait le plus simple dans le cas ou le programme peut etre decompiler, est de le decompiler puis de le traduire en QBasic , enfin c'est ma methode !

a bientot ..
Bendi