Name/ Serial/ F609843Z3A40 Serial/ F6Y9843Z3A4Y Serial/ VQ42358F7ZYY Serial/ VQ42358F7Z00 Serial/ GSB28BAE2C03 Serial/ GSB28BAE2CY3 Programme : Transmac v3.1 PlateForme : Windows 95 Date : 20-21 juillet 1998 Fichier : Transmac.exe Outils : Soft-ice v3.2 Ou ça? : PcTEAM CD PRO N°37 (juillet/aout 98) Temps passé: Deux jours (-DODO -TELE -REPAS -WARCRAFT2), je l'ai NIQUE! Cours : 14 Matos : Bloc-notes en 800*600 ================ 1. PROBLEMATIQUE ================ Name/ Lucifer48 #/ 361578009900 (j'ai utilisé comme d'habitude BPX HMEMCPY) XXXX:0040A655 56 PUSH ESI XXXX:0040A656 E82A010000 CALL 0040A785 ;<----- Tout ce fait ici XXXX:0040A65B 59 POP ECX XXXX:0040A65C 6A01 PUSH 01 XXXX:0040A65E 53 PUSH EBX XXXX:0040A65F FF15F8344300 CALL [USER!EndDialog] Voilà pour notre premier point de repère. Ce call est ultra-important est donc on ne peut donc le passer sans y jeter un coup d'oeil averti. Dans le call CALL 0040A785: ... XXXX:0040A7B6 806415EC0 AND BYTE PRT [EDX+EBP-14],00 ;edx=0000000C XXXX:0040A7BB 8D45EC LEA EAX,[EBP-14] ;pointe vers notre serial XXXX:0040A7BE 50 PUSH EAX XXXX:0040A7BF E86C810000 CALL 00412930 ;calcule la taille de notre serial XXXX:0040A7C4 83F80C CMP EAX,0C ;la taille doit être de 12 chr. XXXX:0040A7C8 7510 JNZ 0040A7DA ;si c'est pas égal, on dégage XXXX:0040A7CA 8D45EC LEA EAX,[EBP-14] XXXX:0040A7CD 50 PUSH EAX ;pointe toujours vers notre serial XXXX:0040A7CE 68005A4200 PUSH 00425A00 ;zone mémoire très importante (*) XXXX:0040A7D3 E804000000 CALL 0040A7DC ;CALL TRES TRES TRES IMPORTANT XXXX:0040A7D8 59 POP ECX XXXX:0040A7D9 59 POP ECX XXXX:0040A7DA C9 LEAVE XXXX:0040A7DB C3 RET (*) Cette zone mémoire est très importante car c'est la que le programme inscrit son checksum. Emplacement: 'A 'B 'C 'D 'E 'F 'G ******************** XXXX:00425A10 00 00 00 00 42 9A 2B 43 BB 62 CB 00 00 00 00 00 ....B.+C.b...... XXXX:00425A20 4C 75 63 69 66 67 72 34 38 00 00 00 00 00 00 00 Lucifer48....... Ces 7 octets caractérisent le serial après quelques calculs. Je vous le dis tout de suite il va faloir trouver: A5 xx 46 zz xx yy 52 xx correspond a un octet calculé à l'aide du serial, c'est à dire que xx peut être quelconque. (ça fait plus que 5 octets à trouver) yy doit être compris entre 90 et 9F zz doit être compris entre 13 et FF ou 00 Maintenant il est temps d'aller faire un tour dans le CALL 0040A7DC. J'ai décidé de prendre mon serial afin de donner un exemple. Acrrochez vous... XXXX:0040A7DE 8B7C240 MOV EDI,[ESP+10] ;pointe vers le serial XXXX:0040A7E2 8A07 MOV AL,[EDI] ;Charge le caractère *1* (pour moi 33) XXXX:0040A7E4 47 INC EDI ;caractère suivant XXXX:0040A7E6 E8E7000000 CALL 0040A8D2 ;en gros si c'est un chiffre AL=AL-30h XXXX:0040A7EB 8B742410 MOV ESI,[ESP+10] ;notre zone mémoire importante XXXX:0040A7EF 59 POP ECX XXXX:0040A7F0 83C60A ADD ESI,0A XXXX:0040A7F3 88460A MOV [ESI+0A],AL ;écrit à l'emplacement 'A XXXX:0040A7F6 8A07 MOV AL,[EDI] ;Charge le caractère *2* (pour moi 36) XXXX:0040A7F8 50 PUSH EAX XXXX:0040A7F9 47 INC EDI ;caractère suivant XXXX:0040A7FA E8D3000000 CALL 0040A8D2 ;en gros si c'est un chiffre AL=AL-30h XXXX:0040A7FF 59 POP ECX XXXX:0040A800 8AC8 MOV CL,AL ; CL=AL=06 XXXX:0040A802 C1E803 SHR EAX,03 ; EAX=0 XXXX:0040A805 C0E105 SHL CL,05 ; CL=C0 XXXX:0040A808 084E0A OR [ESI+0A],CL ;écrit à l'emplacement 'A (C0 OR 03 = C3) XXXX:0040A80B 2403 AND AL,03 ; étant donné que EAX=0... XXXX:0040A80D 88460B MOV [ESI+0B],AL ;écrit à l'emplacement 'B XXXX:0040A810 8A07 MOV AL,[EDI] ;Charge le caractère *3* (pour moi 31) XXXX:0040A812 50 PUSH EAX XXXX:0040A813 47 INC EDI ;caractère suivant XXXX:0040A814 E8B9000000 CALL 0040A8D2 ;en gros si c'est un chiffre AL=AL-30h XXXX:0040A819 C0E004 SHL AL,04 ;*16 (+ un 0) SHL 1,04 =10 XXXX:0040A81C 88460F MOV [ESI+0F],AL ;écrit à l'emplacement 'F XXXX:0040A81F 8A07 MOV AL,[EDI] ;Charge le caractère *4* (pour moi 35) XXXX:0040A821 59 POP ECX XXXX:0040A822 47 INC EDI XXXX:0040A823 50 PUSH EAX XXXX:0040A824 E8A9000000 CALL 0040A8D2 ;en gros si c'est un chiffre AL=AL-30h XXXX:0040A829 C0E002 SHL AL,02 ;AL=14 XXXX:0040A82C 08460B OR [ESI+0B],AL ;écrit à l'emplacement 'B XXXX:0040A82F 8A07 MOV AL,[EDI] ;Charge le caractère *5* (pour moi 37) XXXX:0040A831 59 POP ECX XXXX:0040A832 47 INC EDI ;caractère suivant XXXX:0040A833 50 PUSH EAX XXXX:0040A834 E899000000 CALL 0040A8D2 ;en gros si c'est un chiffre AL=AL-30h XXXX:0040A839 59 POP ECX XXXX:0040A83A 8AC8 MOV CL,AX ; CL=AL=07 XXXX:0040A83C D1E8 SHR EAX,1 ; EAX=3 XXXX:0040A83E C0E107 SHL CL,07 ; CL=80 XXXX:0040A841 084E0B OR [ESI+0B],CL ;écrit à l'emplacement 'B XXXX:0040A844 240F AND AL,0F ; AL=03 XXXX:0040A846 88460C MOV [ESI+0C],AL ;écrit à l'emplacement 'C XXXX:0040A849 8A07 MOV AL,[EDI] ;Charge le caractère *6* (pour moi 38) XXXX:0040A84B 50 PUSH EAX XXXX:0040A84C 47 INC EDI XXXX:0040A84D E880000000 CALL 0040A8D2 ;en gros si c'est un chiffre AL=AL-30h XXXX:0040A852 08460F OR [ESI+0F],AL ;écrit à l'emplacement 'F (08 OR 10 = 18) XXXX:0040A855 8A07 MOV AL,[EDI] ;Charge le caractère *7* (pour moi 30) XXXX:0040A857 59 POP ECX XXXX:0040A858 47 INC EDI XXXX:0040A859 50 PUSH EAX XXXX:0040A85A E873000000 CALL 0040A8D2 ;en gros si c'est un chiffre AL=AL-30h XXXX:0040A860 8AC8 MOV CL,AL ; AL=CL=00 XXXX:0040A862 C1E804 SHR EAX,04 ; EAX=0 XXXX:0040A865 C0E104 SHL CL,04 ; CL=0 XXXX:0040A868 084E0C OR [ESI+0C],CL ;écrit à l'emplacement 'C (00 OR 03 = 03) XXXX:0040A86B 2401 AND AL,01 ;AL=0 XXXX:0040A86D 88460D MOV [ESI+0D],AL ;écrit à l'emplacement 'D XXXX:0040A870 8A07 MOV AL,[EDI] ;Charge le caractère *8* (pour moi 30) XXXX:0040A872 50 PUSH EAX XXXX:0040A873 47 INC EDI ;caractère suivant XXXX:0040A874 E859000000 CALL 0040A8D2 ;en gros si c'est un chiffre AL=AL-30h XXXX:0040A879 D0E0 SHL AL,1 ;AL=0 XXXX:0040A87B 08460D OR [ESI+0D],AL ;écrit à l'emplacement 'D XXXX:0040A87E 8A07 MOV AL,[EDI] ;Charge le caractère *9* (pour moi 39) XXXX:0040A880 59 POP ECX XXXX:0040A881 47 INC EDI ;caractère suivant XXXX:0040A882 50 PUSH EAX XXXX:0040A883 E84A000000 CALL 0040A8D2 ;en gros si c'est un chiffre AL=AL-30h XXXX:0040A888 C0E004 SHL AL,04 ;AL=90 XXXX:0040A88B 884610 MOV [ESI+10],AL ;écrit à l'emplacement 'G (90) XXXX:0040A88E 8A07 MOV AL,[EDI] ;Charge le caractère *10* (pour moi 39) XXXX:0040A890 59 POP ECX XXXX:0040A891 47 INC EDI ;caractère suivant XXXX:0040A892 50 PUSH EAX XXXX:0040A893 E83A000000 CALL 0040A8D2 ;en gros si c'est un chiffre AL=AL-30h XXXX:0040A898 59 POP ECX XXXX:0040A899 8AC8 MOV CL,AL ; CL=AL=09 XXXX:0040A89B C1E802 SHR EAX,02 ; EAX=2 XXXX:0040A89E C0E106 SHL CL,06 ; CL=40 XXXX:0040A8A1 084E0D OR [ESI+0D],CL ; écrit à l'emplacement 'D (00 OR 40 = 40) XXXX:0040A8A4 2407 AND AL,07 ; AL=2 XXXX:0040A8A6 88460E MOV [ESI+0E],AL ; écrit à l'emplacement 'E XXXX:0040A8A9 FF37 PUSH DWORD PTR [EDI] XXXX:0040A8AB E822000000 CALL 0040A8D2 ;Attention: résultat à partir du chr *11* XXXX:0040A8B0 084610 OR [ESI+10],AL ;écrit à l'emplacement 'G (90 OR 00 = 90) XXXX:0040A8B3 59 POP ECX XXXX:0040A8B4 FF7701 PUSH DWORD PTR [EDI+01] XXXX:0040A8B7 E816000000 CALL 0040A8D2 ;Attention: résultat à partir du chr *12* XXXX:0040A8BC 59 POP ECX XXXX:0040A8BD C0E003 SHL AL,03 XXXX:0040A8C0 08460E OR [ESI+0E],AL ;écrit à l'emplacement 'E (00 OR 02 = 02) XXXX:0040A8C3 6A07 PUSH 07 XXXX:0040A8C5 56 PUSH ESI XXXX:0040A8C6 E848000000 CALL 0040A913 ;CALL TRES IMPORTANT (c'est le dernier) ... XXXX:0040A8D1 C3 RET ;fin de la routine (ouf!) On récapitule: 'A 'B 'C 'D 'E 'F 'G Initialement : -- -- -- -- -- -- -- en XXXX:0040A7E2 : 03 -- -- -- -- -- -- (MOV à l'emplacement 'A) en XXXX:0040A808 : C3 -- -- -- -- -- -- ( OR à l'emplacement 'A) en XXXX:0040A80D : C3 00 -- -- -- -- -- (MOV à l'emplacement 'B) en XXXX:0040A81C : C3 00 -- -- -- 10 -- (MOV à l'emplacement 'F) en XXXX:0040A82C : C3 14 -- -- -- 10 -- ( OR à l'emplacement 'B) en XXXX:0040A841 : C3 94 -- -- -- 10 -- ( OR à l'emplacement 'B) en XXXX:0040A846 : C3 94 03 -- -- 10 -- (MOV à l'emplacement 'C) en XXXX:0040A852 : C3 94 03 -- -- 18 -- ( OR à l'emplacement 'F) en XXXX:0040A868 : C3 94 03 -- -- 18 -- ( OR à l'emplacement 'C) en XXXX:0040A86D : C3 94 03 00 -- 18 -- (MOV à l'emplacement 'D) en XXXX:0040A87B : C3 94 03 00 -- 18 -- ( OR à l'emplacement 'D) en XXXX:0040A88B : C3 94 03 00 -- 18 90 (MOV à l'emplacement 'G) en XXXX:0040A8A1 : C3 94 03 40 -- 18 90 ( OR à l'emplacement 'D) en XXXX:0040A8A6 : C3 94 03 40 02 18 90 (MOV à l'emplacement 'E) en XXXX:0040A8B0 : C3 94 03 40 02 18 90 ( OR à l'emplacement 'G) en XXXX:0040A8C3 : C3 94 03 40 02 18 90 ( OR à l'emplacement 'E) Tout irais au mieux dans le meilleur des mondes s'il ne restait pas ce CALL 0040A913 qui va encore transformer nos 7 précieux octets. Allons donc dans ce CALL 0040A913 que l'on décomposera en 2 parties (2 boucles). Let's rock XXXX:0040A92B 8D0C3B LEA ECX,[EDI+EBX] XXXX:0040A92E 895D08 MOV [EBP+08],EBX --->:0040A931 0FB651FF MOVZX EDX,BYTE PTR [ECX-01] ;lit l'un des 7 octets XXXX:0040A935 0FB7C6 MOVZX EAX,SI ;initialement ESI=55AA XXXX:0040A938 03F2 ADD ESI,EDX ;additionne l'un des 7 octets XXXX:0040A93A 69F645290000 IMUL ESI,ESI,00002945 XXXX:0040A940 C1E808 SHR EAX,08 ;décalage d'un octet vers la droite XXXX:0040A943 33C2 XOR EAX,EDX XXXX:0040A945 81EEA7460000 SUB ESI,000046A7 XXXX:0040A94B 8841FF MOV [ECX-01],AL ;écrit le résultat XXXX:0040A94F FF4D08 DEC DWORD PTR [EBP+08] ;indice de boucle -1 XXXX:0040A952 75DD JNZ 0040A931 ;si c'est non nul: on repart Cette boucle modifie octet par octet notre zone mémoire en commençant par l'octet le plus à droite (va de l'emplacement 'G à l'emplacement 'A) ESI fait office de checksum de telle manière que l'octet précédent (il détermine la valeur du xor en eax) joue un role dans le résultat de l'octet en cours. Ne connaissant ni le résultat à fournir ni le résultat à obtenir on passe notre chemin. --->:0040A95F 0FB60C3E MOVZX ECX,BYTE PTR [EDI+ESI] ;ecx = l'un des 7 octets XXXX:0040A963 0FB7C2 MOVZX EAX,DX XXXX:0040A966 C1E808 SHR EAX,08 ;décalage d'un octet vers la droite XXXX:0040A969 33C1 XOR EAX,ECX XXXX:0040A96B 03CA ADD ECX,EDX XXXX:0040A96D 69C9E95E0000 IMUL ECX,ECX,00005EE9 XXXX:0040A973 BA71390000 MOV EDX,00003971 ;EDX initial vaut 0000A5A5 XXXX:0040A978 88043E MOV [EDI+ESI],AL ;écrit le résultat XXXX:0040A97B 2BD1 SUB EDX,ECX XXXX:0040A97D 46 INC ESI XXXX:0040A97E 3BF3 CMP ESI,EBX ;EBX=7 XXXX:0040A980 7CDD JL 0040A95F ... XXXX:0040A986 C3 RET ;fin de la routine Cette boucle modifie octet par octet (de l'emplacement 'A à l'emplacement 'G cette fois ci) EDX fait office de checksum pour que l'octet précédent joue un rôle dans le valeur de l'octet en cours et ainsi de suite. Heureusement cette fois nous connaissons le résultat final à obtenir. Reprenons avec mes valeurs: Avec le call 0040A7DC on obtient: C3 94 03 40 02 18 90 Avec la 1ère boucle on obtient: E7 A6 1C 2A 4C 58 C5 Avec la 2ème boucle on obtient: 42 9A 2B 43 BB 62 CB Résultat à obtenir: A5 xx 46 zz xx yy 52 (xx compris entre 00 et FF) (yy compris entre 90 et 9F) (zz compris entre 13 et FF ou 00) Remarque: les valeurs précédentes sont inclusives, i.e 'zz' peut être égal à 13) PS: pour savoir les valeurs à obtenir, il faut tracer un peu, passer le USER / KERNEL32!_FreqAsm et c'est le PREMIER call (call 0040B7F3 en XXXX:0040BAAA) qui arrive. La routine de test est ici. ========================= 2. RECHERCHE DE SOLUTIONS ========================= Notre première tâââche c'est d'obtenir le résultat intermédiaire (résultat issu de la 1ère boucle). On sait que la 2ème boucle va de gauche à droite. Sachant que A5 XOR E7 = 42 et que l'on doit obtenir A5... on doit donc avoir 00 Début des 7 octets à l'issu de la 1ère boucle 00 -- -- -- -- -- -- Soit XXh notre dexième indice: il faut que: ( 00003971 - ( ( (XX XOR E0) + C296E044 ) * 00005EE9 ) ) = xxxxXXxx h (avec XX=46) et ainsi de suite... après il restera à faire la même chose avec la boucle1 mais avec le résultat trouvé pour la boucle2. Comme j'ai pas envie de supputer pendant 3 heures. Le turbo pascal va m'aider. Ci-joint avec un fichier transmac.pas qui génère les 7 bons octets. Quelques solutions: 01 46 AA 40 E1 6B 3B # ED F4 5F 6C 02 B4 60 11 12 54 E0 BB C9 DA # 4D 31 02 DE 03 97 C0 E8 C2 6A 0E 63 63 79 # B1 B4 32 7D 03 B6 A0 0B 58 D0 B2 B1 01 18 # 39 CA C7 EF 03 4F B0 02 AB 65 C4 5A F4 C7 # 28 9C 2C 4A 00 6D A0 EC 2B 23 AD 55 90 66 # 5F 8B 81 1E 06 45 70 0C F1 2F E8 9A 34 05 # 38 87 F5 E8 AA BB 01 D0 F8 64 E2 0E BC A3 # 39 86 60 E9 F0 78 63 C7 7D F7 71 A6 43 42 # EC 93 3D DD 4D 24 C4 8F EA 8F 48 57 A0 E1 # DA 3E 54 B3 12 84 25 FB 68 0D 53 91 D7 FA # 26 F9 DD 8C DB 20 86 31 FA 4A 98 8D 35 99 # 28 92 9D 93 31 C4 E7 C2 B4 1F BF CF 93 38 # etc. J'en essaye un: je stocke les octets en mémoire, j'exécute le call 0040A913, je regarde les modifications, c'est bon ça marche. Nous somme venus à bout de ce fichu call, reste maintenant un dernier obstacle et ce sera fini. J'ai oublié de dire que le programme accepte aussi les lettres (heureusement; et que 41 ('A') renvoit $0A et ainsi de suite jusqu'a $1F. (entre autres: un 'Y' vaut un '0' ; un 'Z' vaut un 'O') Jetez-y un coup d'oeil quand même (CALL 0040A8D2). Trouvons maintenant un bon serial: ------- ESSAI 1 ------- Je choisis la suite: 90 0B A4 1C 1B BB 20 * caractère 1 = 47 (pour faire $10, emplacement 'A) * caractère 2 = 53 (pour faire $80 OR $10 =$90,emplacement 'A) (* c'est bon pour 'A *) (fait $3 à l'emplacement 'B) * caractère 3 = 42 (pour faire $B0, emplacement 'F) * caractère 4 = 32 (pour faire $08 OR $03 = $0B, emplacement 'B) (* c'est bon pour 'B *) * caractère 5 = 38 (pour faire $00 OR $0B = $0B, emplacement 'B) (fait $04 à l'emplacement 'C) * caractère 6 = 42 (pour faire $B0 OR $0B = $BB, emplacement 'F) (* c'est bon pour 'F *) * caractère 7 = 41 (pour faire $A0 OR $04 = $A4, emplacement 'C) (* c'est bon pour 'C *) (fait $00 à l'emplacement 'D) * caractère 8 = 45 (pour faire $1C, emplacement 'D) (* c'est bon pour 'D *) * caractère 9 = 32 (pour faire $20, emplacement 'G) (* c'est bon pour 'G *) * caractère 10 = 43 (pour faire $3, emplacement 'E) * caractère 11 = 30 * caractère 12 = 33 (pour faire $18 OR $03, emplacement 'E) (* c'est bon pour 'E *) Serial/ GSB28BAE2C03 Serial/ GSB28BAE2CY3 ------- ESSAI 2 ------- Je choisis la suite: CF 24 34 B0 02 04 34 * caractère 1 = 46 (pour faire $F ,emplacement 'A) * caractère 2 = 36 (pour faire $C0 OR $0F = $CF, emplacement 'A) (* c'est bon pour 'A *) (fait $0 à l'emplacement 'B) * caractère 3 = 30 (fait $0 à l'emplacement 'F) * caractère 4 = 39 (pour faire $24 OR $00 = $24, emplacement 'B) (* c'est bon pour 'B *) * caractère 5 = 38 (pour faire $00 OR $24 = $24, emplacement 'B) (fait $4 à l'emplacement 'C) * caractère 6 = 34 (pour faire $04, emplacement 'F) (* c'est bon pour 'F *) * caractère 7 = 33 (pour faire $04 OR $30 = $34, emplacement 'C) (* c'est bon pour 'C *) (fait $00 à l'emplacement 'D) * caractère 8 = 4F (fait $00 OR $30 à l'emplacement 'D) * caractère 9 = 33 (pour faire $30, emplacement 'G) * caractère 10 = 41 (pour faire $80 OR $30) (* c'est bon pour 'D *) (pour faire $02) (* c'est bon pour 'E *) * caractère 11 = 34 (pour faire $04 OR $30, emplacement 'G) (* c'est bon pour 'G *) * caractère 12 = 30 (pour faire $00) Serial/ F609843Z3A40 Serial/ F6Y9843Z3A4Y ------- ESSAI 3 ------- Je choisis la suite: 5F 8B 81 1E 06 45 70 * caractère 1 = 56 (en 'A: $1F) * caractère 2 = 51 (en 'A: $1F OR $40) (* OK pour 'A *) (en 'B: $03) * caractère 3 = 34 (en 'F: $40) * caractère 4 = 32 (en 'B: $08 OR $03) * caractère 5 = 33 (en 'B: $0B OR $80) (* OK pour 'B *) (en 'C: $01) * caractère 6 = 35 (en 'F: $40 OR $05) (* OK pour 'F *) * caractère 7 = 38 (en 'C: $80 OR $01) (* OK pour 'C *) (en 'D: $00) * caractère 8 = 46 ($00 OR $1E) (* OK pour 'D *) * caractère 9 = 37 ($70) (* OK pour 'G *) * caractère 10 = 4F ($06) (* OK pour 'E *) * caractère 11 et 12 = 30 (pour faire des 0) Serial/ VQ42358F7ZYY Serial/ VQ42358F7Z00 J'espère que ma disposition n'est pas trop confuse. ================ 3. DERNIERS MOTS ================ On essaye un serial, la "GRANT OF LICENSE" devient "GRANT OF SINGLE USER LICENSE" on click sur About..."TransMac v3.1 (32bit/registered)" Cool! A noter que cette protection ne se sert absolument pas du nom donc vous pouvez y mettre n'importe quoi. En fin de compte cette protection n'est pas si difficile, car il existe des dizaines et des dizaines de bons serials, évidemment on ne cracke pas ce programme en 3 minutes (à part les mecs de chez PhozenCrew... c'est surtout sur ça que misent les programmeurs du soft: le découragement des crackers les moins chevronés). Mais il n'en deumeure pas moins qu'il est ultra-facile de modifier l'exe avec un éditeur hexa pour cracker (sans aucun danger) TransMac. Perso, lorsque les sharewares sont protégés via des serials, je préfère les trouver plutôt que de cracker à coup de HexWorkshop. Moralité: il ne faut JAMAIS être impréssionné: "Ce qu'un homme peut faire (sur PC), un autre peut le défaire avec Soft-ice". LUCIFER48, 22h17