3. Routine de check du serial.

Résumons le fonctionnement du keygenme. Tout d'abord, au lancement du binaire, 3 octets sont générés de façon pseudo-aléatoire et sont stockés en 405103, 405104 et 405105. Puis, l'utilisateur actionne les boutons de la coloquinthe dans un certain ordre. Ceci a pour effet à chaque clic de stocker un octet dans une table située en 4050FF. Une fois que le user a réalisé une combinaison de 4 clics, le binaire vérifie la validité de la séquence en utilisant une TABLE DE VERIFICATION. Plutôt que d'entrer dans de longues explications, voici en images le déroulement de la vérification du serial :

Un cadre se déplace sur les deux tables situées en 4050FF et 405103. La routine va donc vérifier sur la valeur indiquée par la petite flèche noire du cadre mobile est égale à la valeur correspondante dans la table. Pour ce faire, la valeur récupérée dans la première table (4050FF) représente la colonne d'une TABLE DE VERIFICATION tandis que la seconde valeur situé dans la seconde table (405103) représente la ligne de cette même table de vérification. Si on prend la valeur en 4050FF, nous avons 0 qui indique donc la colonne 0 de la TABLE DE VERIFICATION. EN 405103, nous avons 2 qui indique la ligne 2 de cette même TABLE. La valeur située en (0;2) dans la TABLE est le nombre 2. La valeur indiquée par la flèche noire du cadre mobile doit donc valoir 2 également.Dans mon exemple, tout est correct sauf la dernière valeur (le dernier bouton activé). Notez également que la première valeur n'est pas testée ici mais nous allons voir qu'elle peut toujours être égale à 0.

En réalité, vous imaginez bien que le check du serial n'est pas présenté de façon aussi explicite. Il y a ce qu'on appelle un "fake" dans la routine, c'est-à-dire un élément ajouté à la routine pour rendre les choses plus complexes à analyser. Cela dit, il ne sert à rien et nous verrons que nous n'en avons pas besoin pour coder le keygen.

Voici le début de la routine de vérification. ESI représente le décalage de notre cadre.

004016B3  CMP BYTE PTR DS:[ESI+4050FF],0
004016BA  JNZ SHORT esoquynt.004016FF
004016BC  CMP BYTE PTR DS:[ESI+405100],1
004016C3  JNZ SHORT esoquynt.004016FF
004016C5  CMP BYTE PTR DS:[ESI+405103],1
004016CC  JNZ SHORT esoquynt.004016F5
004016CE  OR ESI,ESI
004016D0  JNZ SHORT esoquynt.004016DC
004016D2  PUSH 1337C0DE
004016D7  JMP esoquynt.00401C90
004016DC  CMP ESI,1
004016DF  JNZ SHORT esoquynt.004016EB
004016E1  PUSH 111347
004016E6  JMP esoquynt.00401C90
004016EB  PUSH 0F1237
004016F0  JMP esoquynt.00401C90
004016F5  PUSH 0BADB07
004016FA  JMP esoquynt.00401C90

La routine commence par 3 comparaisons. Regardez la TABLE DE VERIFICATION et vous allez comprendre que ces séquences de comparaisons reviennent à tester la table. Si la comparaison réussit, une valeur est poussée sur la pile. Si la comparaison échoue, BADB07h est poussé. Quoiqu'il arrive, on se moque de savoir quelle valeur est poussée, il faut que 3 comparaisons successives réussissent.

A la fin de la routine de check, nous pouvons voir ceci :

00401C9A  POP EAX
00401C9B  POP EBX
00401C9C  POP ECX
00401C9D  ADD EAX,EBX
00401C9F  ADD EAX,ECX
00401CA1  CMP EAX,1357E65C
00401CA6  JNZ SHORT esoquynt.00401CC5
00401CA8  PUSH DWORD PTR DS:[40547B]
00401CAE  PUSH 0
00401CB0  PUSH 172
00401CB5  PUSH 208
00401CBA  PUSH DWORD PTR DS:[405368]
00401CC0  CALL SendDlgItemMessageA
00401CC5  RETN

Les valeurs poussées sur la pile sont dépilées et ajoutées les unes aux autres. Si par malheur l'une d'elle vaut BADB07h, ceci signifie que l'une des comparaisons s'est mal passé et donc la somme ne sera pas égale à la valeur attendue 1357E65C. Si le test réussit, un message est envoyé à la fenêtre pour afficher le petit logo de la victoire.

Vous voyez donc que les valeurs poussées n'ont aucun intérêt et font double emploi avec les comparaisons. Il s'agit donc d'un fake !

Page suivante

Valid XHTML 1.0 Strict

Valid CSS!