Name/ Lucifer48 #/ IAG8X35Y (normal registration) Name/ Lucifer48 #/ 2FF1GEAE (lite registration) Programme : Cool Edit 95 PlateForme : Windows 95 Date : 24 aout 1998, 13h44 Protection : registration via serial number Fichier : cool95.exe Outils : Soft-ice v3.2 Ou ça? : http://www.syntrillium.com Temps passé: Quelques dizaines de minutes + la rédaction Cours : 16 Matos : Bloc-notes en 800*600 Après trois semaines d'inactivité, je persiste et je signe ce seizième tutorial avec Cool Edit. C'est une protection plutôt originale, qui utilise le xor et l'addition: c'est à dire qu'on croit trouver le bon serial en mémoire, alors on l'essaye mais en réessayant c'est un autre serial qui apparaît car le serial calculé dépend à la fois du nom entré et du serial number. ============================= 1. ENCORE UN MOIS DE VACANCES (youpi!) ============================= Je lance le soft, click sur "Register Now", remplie de la façon suivante: Registered User's Name: Lucifer48 Registration Number: 36157800 Je préalablement posé un BPX HMEMCPY. Click sur OK, F5, F11, quelques pressions sur F12 (huit je crois). Je suis ici: XXXX:0040B232 68F3030000 PUSH 000003F3 XXXX:0040B237 56 PUSH ESI XXXX:0040B238 FFD7 CALL EDI ; On sort de là (EDI = [USER32!GetDlgItemTextA] ) XXXX:0040B23A 385C241C CMP [ESP+1C],BL ; BL=0, la case "Registration Number" est vide? XXXX:0040B23E 0F84FB000000 JZ 0040B33F ; si oui, bye bye XXXX:0040B244 8B0D0C1A4600 MOV ECX,[00461A0C]; ECX=6F6F6669 soit "oofi" XXXX:0040B24A B80C1A4600 MOV EAX,00461A0C ; pointe sur "iffobari" XXXX:0040B24F 8D542414 LEA EDX,[ESP+14] ; pointe 8 octets avant notre serial XXXX:0040B253 895C2460 MOV [ESP+60],EBX XXXX:0040B257 8B4004 MOV EAX,[EAX+04] ;EAX=69726162 soit "irab" XXXX:0040B25A 895C2464 MOV [ESP+64],EBX XXXX:0040B25E 890A MOV [EDX],ECX ;ecrit "ifoo" XXXX:0040B260 894204 MOV [EDX+04],EAX ;ecrit "bari" Pour moi j'ai en mémoire: 013F:005DF578 | 69 66 6F 6F 62 61 72 69 33 36 31 35 37 38 30 30 | iffobari36157800 Nos huis premiers octets vont subir quelques modifications... XXXX:0040B2A5 8A440414 MOV AL,[EAX+ESP+14] XXXX:0040B2A9 32440C3C XOR AL,[EAX+ESP+3C] ;xor avec une à une les lettres de mon nom XXXX:0040B2AD 8D4C243C LEA ECX,[ESP+3C] XXXX:0040B2B1 00443C14 ADD [EDI+ESP+14],AL XXXX:0040B2B5 51 PUSH ECX XXXX:0040B2B6 FFD5 CALL EBP ;= CALL [KERNEL32!lstrlen] (soit 9 pour moi) XXXX:0040B2B8 0FBFCB MOVSX ECX,BX XXXX:0040B2BB 3BC1 CMP EAX,ECX ;"Lucifer48" = 9 chars, soit 9 boucles XXXX:0040B2BD 7FC0 JG 0040B27F XXXX:0040B2BF 6633C0 XOR AX,AX XXXX:0040B2C2 EB04 JMP 0040B2C8 Pour bien comprendre l'action de la boucle, je vais prendre mon nom en exmple: 62 ('b') XOR 4C ('L') = 2E + 69 ('i') = 97 61 ('a') XOR 75 ('u') = 14 + 66 ('f') = 7A 72 ('r') XOR 63 ('c') = 11 + 6F ('o') = 80 69 ('i') XOR 69 ('i') = 00 + 6F ('o') = 6F 97 XOR 66 ('f') = F1 + 62 ('b') = 53 7A XOR 65 ('e') = 1F + 61 ('a') = 80 80 XOR 72 ('r') = F2 + 72 ('r') = 64 6F XOR 34 ('4') = 5B + 69 ('i') = C4 53 XOR 38 ('8') = 6B + 97 = 02 (vous comprenez les cycles de 4) Donc en mémoire en a la chose suivante: 013F:005DF578 | 02 7A 80 6F 53 80 64 C4 33 36 31 35 37 38 30 30 | .z.oS.d.36157800 Une autre boucle arrive maintenant (il manque un peu le début): XXXX:0040B30F 8A443C14 MOV AL,[EDI+ESP+14] ;lit 1 à 1, les 8 premiers octets (02,7A,...) XXXX:0040B313 8A543C1C MOV DL,[EDI+ESP+1C] ;lit 1 à 1, mon serial (33,36,...) XXXX:0040B317 8D1CBF LEA EBX,[EDI*4+EDI] ;EBX=indice de boucle*5 XXXX:0040B31A 03C2 ADD EAX,EDX ;02+33, 7A+36, ... XXXX:0040B31C 8D149B LEA EDX,[EBX*4+EBX] ;EDX=indice de boucle*25 (25_d = 1A_h) XXXX:0040B31F 03D7 ADD EDX,EDI ;EDX=indice de boucle*26 XXXX:0040B321 BB1A000000 MOV EBX,0000001A XXXX:0040B326 8D8410F7000000 LEA EAX,[EDX+EAX+000000F7] XXXX:0040B32D 99 CDQ XXXX:0040B32E F7FB IDIV EBX XXXX:0040B330 80C241 ADD DL,41 XXXX:0040B333 6683F908 CMP CX,08 ;huit boucles XXXX:0040B337 88543C2C MOV [EDI+ESP+2C],DL ;écrit le résultat juste en dessous du serial XXXX:0040B33B 7CC9 JL 0040B306 XXXX:0040B33D EB0B JMP 0040B34A Là encore, en prenant mon exmemple c'est simple à comprendre: (02+33)=35 + (0*1A)=00 + F7 = 12C reste de la division par 1A = 0E +41=4F ('O') (7A+36)=B0 + (1*1A)=1A + F7 = 1C1 reste de la division par 1A = 07 +41=48 ('H') (80+31)=B1 + (2*1A)=34 + F7 = 1DC reste de la division par 1A = 08 +41=49 ('I') (6F+35)=A4 + (3*1A)=4E + F7 = 1E9 reste de la division par 1A = 15 +41=56 ('V') (53+37)=8A + (4*1A)=68 + F7 = 1E9 reste de la division par 1A = 15 +41=56 ('V') (80+38)=B8 + (5*1A)=82 + F7 = 231 reste de la division par 1A = 0F +41=50 ('P') (64+30)=94 + (6*1A)=9C + F7 = 227 reste de la division par 1A = 05 +41=46 ('F') (C4+30)=F4 + (7*1A)=B6 + F7 = 2A1 reste de la division par 1A = 17 +41=58 ('X') On remarque que chaque caractère est indépendant (ça nous arrange bien!) Pour moi je trouve donc OHIVVPFX XXXX:0040B34E 8D4C243C LEA ECX,[ESP+3C] XXXX:0040B352 C644243400 MOV BYTE PTR [ESP+34],00 XXXX:0040B357 50 PUSH EAX ;pointe vers OHIVVPFX XXXX:0040B358 51 PUSH ECX ;pointe vers Lucifer48 XXXX:0040B359 E832F5FFFF CALL 0040A890 ;big call de comparaison XXXX:0040B35E 668944241A MOV [ESP+1A],AX XXXX:0040B363 83C408 ADD ESP,08 XXXX:0040B366 6685C0 TEST AX,AX ;si AX=0, alors mauvais serial XXXX:0040B369 0F842D040000 JZ 0040B79C ;si on saute: bad guy Pour obtenir un bon serial il faut que AX soit non nul. Le call 0040A890 est ENORME, il construit de nouveaux passwords à l'aide de mon nom et va, tout à la fin de la routine comparer avec OHIVVPFX. On trace, on trace, on passe les boucles et voilà le passage intéressant: XXXX:0040ADCD 8B9424EC000000 MOV EDX,[ESP+000000EC] XXXX:0040ADD4 8D442414 LEA EAX,[ESP+14] XXXX:0040ADD8 52 PUSH EDX ;pointe vers OHIVVPFX XXXX:0040ADD9 8B35FCB54600 MOV ESI,[KERNEL32!lstrcmpi] XXXX:0040ADDF 50 PUSH EAX XXXX:0040ADE0 EFD6 CALL ESI ;=CALL [KERNEL32!lstrcmpi] XXXX:0040ADE2 85C0 TEST EAX,EAX ;renvoit FFFFFFFF si les str sont <> XXXX:0040ADE4 7519 JNZ 0040ADFF XXXX:0040ADE6 66B80300 MOV AX,0003 Il y a, à la fin de ce call 0040A890, cinq comparaisons semblables à celle ci, avec pour valeurs respectives de AX: 0003 / 0003 / 0001 / 0003 / 0002. * Avec AX=0003, on obtient un message d'erreur: "You have entered an invalid number. Please register Cool Edit directly with Syntrillium if you want upgrades and support!" (c'est programmes des passwords pour les versions antérieures) * Avec AX=0002, on obtient le message: "You are now registered Cool Edit Lite. Press OK to restart the Lite version of Cool Edit." * Avec AX=0001, aucun message mais on est bien enregistré. Pour moi "OHIVVPFX" est comparé respectivement avec HHUILFJF, NFGADXPX, KSEYCKKM, HTKRYSCO et NXDRLCWS. En ce qui nous concerne, il va falloir trouver un bon serial pour KSEYCKKM et NXDRLCWS (pour le fun). =============== 2. UNE SOLUTION =============== Avec ce qui précède, ça ne pose aucun problème. Soit x l'octet à trouver (les calculs qui suivent sont en hexa) 1/ Basic Registration ($50), il faut trouver: KSEYCKKM ( 4B 53 45 59 43 4B 4B 4D ) -- (02 + x + F7) MOD 1A = 0A +41=4B ('K') donc x=49 ('I') (7A + x + 111) MOD 1A = 12 +41=53 ('S') donc x=41 ('A') (80 + x + 12B) MOD 1A = 04 +41=45 ('E') donc x=47 ('G') (6F + x + 145) MOD 1A = 18 +41=59 ('Y') donc x=38 ('8') (53 + x + 15F) MOD 1A = 02 +41=43 ('C') donc x=58 ('X') (80 + x + 179) MOD 1A = 0A +41=4B ('K') donc x=33 ('3') (64 + x + 193) MOD 1A = 0A +41=4B ('K') donc x=35 ('5') (C4 + x + 1AD) MOD 1A = 0C +41=4D ('M') donc x=59 ('Y') J'essaye IAG8X35Y, ça marche! 2/ Lite Version ($25), il faut trouver: NXDRLCWS ( 4E 58 44 52 4C 43 57 53 ) -- (02 + x + F7) MOD 1A = 0D +41=4E ('N') donc x=32 ('2') (7A + x + 111) MOD 1A = 17 +41=58 ('X') donc x=46 ('F') (80 + x + 12B) MOD 1A = 03 +41=44 ('D') donc x=46 ('F') (6F + x + 145) MOD 1A = 11 +41=52 ('R') donc x=31 ('1') (53 + x + 15F) MOD 1A = 0B +41=4C ('L') donc x=47 ('G') (80 + x + 179) MOD 1A = 02 +41=43 ('C') donc x=45 ('E') (64 + x + 193) MOD 1A = 16 +41=57 ('W') donc x=41 ('A') (C4 + x + 1AD) MOD 1A = 12 +41=53 ('S') donc x=45 ('E') J'essaye 2FF1GEAE, ça marche! Voilà, ainsi s'achève ce tutorial. A la prochaine, crackez bien d'ici là...