Hmm.. c'est pas très gentil de se faire traiter de t4pz ^^
Vous pouvez trouver le pack.zip ici, merci a Fyuw de irc.worldnet #carib0u pour le chall.
On va commencer par scanner le crackme avec protectionID:
Scanning -> C:\Documents and Settings\Xylitol\Bureau\foome {part I}.exe
File Type : Exe, Size : 11264 (02C00h) Byte(s)
[!] File appears to have no protection or is using an unknown protection
On peut remarquer ici que le KeygenMe ne possède aucune protection anti-reversing particulière, ce qui va nous faire gagner un peu de temps au final.
Chargeons le KeygenMe dans OllyDbg, et puis on va regarder les strings:
Click Droit " Search For / All Referenced Text String"
004012A3 SUB ESP,8 (Initial CPU selection)
00401324 MOV DWORD PTR [...] ASCII "OLLYDBG.EXE"
0040132E MOV DWORD PTR [...] ASCII "idag.exe"
00401338 MOV DWORD PTR [...] ASCII "windbg.exe"
00401403 MOV DWORD PTR [...] ASCII "U sUck"
0040140B MOV DWORD PTR [...] ASCII "t4pZ"
00401431 MOV DWORD PTR [...] ASCII " [ foome part I by fyuw]",LF,LF,"Login : "
00401447 MOV DWORD PTR [...] ASCII "%s"
00401466 MOV DWORD PTR [...] ASCII "Need more 5 char..."
00401494 MOV DWORD PTR [...] ASCII "Need less 10 char..."
004014AF MOV DWORD PTR [...] ASCII "pwd : "
004014C5 MOV DWORD PTR [...] ASCII "%d"
0040151A MOV DWORD PTR [...] ASCII "Iz N0t da g00d password"
00401522 MOV DWORD PTR [...] ASCII "t4pZ"
0040154D MOV DWORD PTR [...] ASCII "U win.. make a keygen"
00401555 MOV DWORD PTR [...] ASCII "t4pZ"
004017DB MOV DWORD PTR [...] ASCII "w32_sharedptr->size == sizeof(W32_EH_SHARED)"
004017E7 MOV EAX,foome_[...] ASCII "../../gcc-3.4.5/gcc/config/i386/w32-shared-ptr.c"
004017F9 MOV DWORD PTR [...] ASCII "GetAtomNameA (atom, s, sizeof(s)) != 0"
00401805 MOV ECX,foome_[...] ASCII "../../gcc-3.4.5/gcc/config/i386/w32-shared-ptr.c"
Les premiers strings indiquent des signes d'anti-débogues:
OLLYDBG.EXE
idag.exe
windbg.exe
Cliquons dessus et vérifions:

Le programme vérifie dans la liste des processus pour voir s’il y a un des trois noms chargé en mémoire, si un des trois est trouvé, le foome s'auto ferme. Placez des nops ou renommez le fichier OLLYDBG.EXE par autre chose et voilà.
Maintenant retournons dans les string data references et double cliquons sur la ligne qui contient le string "Iz N0t da g00d password"
Remontons un petit peu et plaçons un point d'arrêt (breakpoint) en 0040150A:
0040150A |. 3985 B4FEFFFF CMP [LOCAL.83],EAX
Tapons un nom puis un faux sérial, on valide puis le programme break, regardons dans le dump
EAX=00002A75 "<- 10869"
Stack SS:[0022FE2C]=00007A69 "<- 31337"
Le bon sérial et stocké dans EAX... on a sérialfishé le truc.
Maintenant analysons la routine de génération de sérial valide, celle-ci se situe juste au-dessus de notre breakpoint, et commence après l'appel de la fonction scanf.
La routine de génération.
Entrons dans les détails pour chaque instruction:
004014D1 |. 0FBE9D 8AFEFFFF MOVSX EBX,BYTE PTR SS:[EBP-176] |Prend la 3e Lettre du Login que l'on place dans EBX
004014D8 |. 8D85 88FEFFFF LEA EAX,DWORD PTR SS:[EBP-178] |Insère le Contenue du Login dans EAX
004014DE |. 890424 MOV DWORD PTR SS:[ESP],EAX |Aucune utilité particulière pour la Génération du sérial
004014E1 |. E8 0E060000 CALL strlens |Strlen() renvoi la Longueur du Login Entré (Xylitol : 7)
004014E6 |. 89C2 MOV EDX,EAX |Déplace le contenu de EAX dans EDX
004014E8 |. 89D0 MOV EAX,EDX |Déplace le contenu de EDX dans EAX
004014EA |. 01C0 ADD EAX,EAX |EAX = EAX * 2 (Xylitol : 7*2). Soit 7h + 7h = Eh
004014EC |. 01D0 ADD EAX,EDX |EAX = EAX + EDX (EDX = 7h)
004014EE |. C1E0 09 SHL EAX,9 |Décalage dans EAX de 9 Rangs vers la Gauche
004014F1 |. 01D0 ADD EAX,EDX |Additionne EDX à EAX
004014F3 |. 01C3 ADD EBX,EAX |Additionne EAX à EBX
004014F5 |. 8B85 A0FEFFFF MOV EAX,DWORD PTR SS:[EBP-160] |EAX = "windbg.exe"
004014FB |. 890424 MOV DWORD PTR SS:[ESP],EAX |Aucune utilité dans l'algorithme, paramètre pour l'API Strlen
004014FE |. E8 F1050000 CALL |EAX = A (en hexa, 10 en decimale), EDX est écrasé, et ECX = "windbg.exe"
00401503 |. 29C3 SUB EBX,EAX |Soustrait EAX à EBX
00401505 |. 89D8 MOV EAX,EBX |Déplace le contenue de EBX dans EAX
00401507 |. 83C0 0C ADD EAX,0C |Additionne 0C à EAX
0040150A |. 3985 B4FEFFFF CMP DWORD PTR SS:[EBP-14C],EAX |Compare le Vrai sérial au Sérial Entré par l'Utilisateur
N'oubliez pas qu'en ASM, chaque calcul effectué, est effectué en héxadécimal !!
À présent que l'on connait la routine principale du keygenMe, nous allons pouvoir reprogrammer celle-ci et en faire un Keygen fonctionnel et valide.
Sophocle a programmé un keygen en Python et 0vercl0k en C. Je ne souhaitais pas coder un Keygen en utilisant un langage qui avait déjà été utilisé, et par conséquent, j'ai opté pour l'ASM de Windows, à savoir MASM.
Par soucis de clairvoyance, je n'insère ici que la fonction de génération du sérial valide.
MOV EDX,EAX
MOV EAX,EDX
ADD EAX,EAX
ADD EAX,EDX
SHL EAX,9
ADD EAX,EDX
ADD EBX,EAX
PUSHAD ;Sauvegarde tous les registres.
MOV ECX, EDX ;Insère la Longueur du Login dans ECX.
XOR EDX, EDX ;Compteur pour la Longueur de la chaîne.
LEA ESI, szName ;On pointe la Chaîne à analyser.
JMP Strlen
Char_Traite:
MOV EBX, EAX ;On met le caractère contenue dans AL dans BX
JMP Continue ;On continue sur la routine du Keygen
Strlen:
CMP EDX,3 ;Compare si EDX vaut 3 (3e Char)
JE Char_Traite ;Si c'est le cas, on JMP sur la Fonction Char_Traite
LODSB ;Charge dans AL le caractère courant et pointe le suivant.
OR EAX, EAX ;On test si c'est la fin de la chaîne.
JZ Continue ;Si c'est le cas, on sort de la routine.
INC EDX ;On rajoute un caractère de plus dans la chaîne.
JMP Strlen ;Saute sur le caractère suivant de la chaîne.
Continue:
POPAD ;Restaure tous les registres
ADD EBX, ECX
MOV EAX,0Ah
SUB EBX,EAX
MOV EAX,EBX
ADD EAX,0Ch
Au final, un algorithme respecté et fonctionnel, sur un keygen assez rudimentaire, mais qui permet de bien s'initier au Reversing.
Et on va se quitter sur une petite screen réjouissante:

Xylitol le 27 Novembre 2008.