#/ A48B9C29BC0 (pour obtenir "registered for: Reg.-Nr. 10") #/ A48B9C29BCD (pour obtenir "registered for: Reg.-Nr. 1D") #/ A48B9C29BC (pour obtenir "registered for: Reg.-Nr. 0C") #/ A48B9C29VC (pour obtenir "registered for: Reg.-Nr. DC") #/ A48B9C29V (pour obtenir "registered for: Reg.-Nr. 129V") #/ A48B9C29B (pour obtenir "registered for: Reg.-Nr. 129B") Programme : Dr. Hardware v2.0e PlateForme : Windows 3.1 / 95 Date : 30 aout 1998, 21h49 Protection : registration via serial number Fichier : drhard.exe Outils : Soft-ice v3.2 (THE debugger) Ou ça? : http://ourworld.compuserve.com/homepages/pgsoft PcTeam - CD pro 37 (juillet/aout) Temps passé: Une petite heure + la rédaction (autant dire toute la nuit...) Cours : 17 Matos : Bloc-notes en 800*600 Voilà un logiciel pas trop mal, puisqu'il permet d'évaluer son hardware et c'est plutôt bien fait (on peut par exemple consulter directement la RAM du CMOS). Une énorme déception tout de même, pcteam nous a founit sur le CD une version préhistorique (pas tant que ça quand même), de plus elle est en 16 bits. J'aime pas beacoup les programmes 16 bits, car on doit toujours se trimballer les segments, genre es:di, ds:si, es:ax,... c'est chiant à taper... et puis lorsque que l'on recherche des données (nom,serial,...), on ne les trouve jamais, car c'est jamais le bon segment; souvent les conversions en héxa sont divisées en deux registres... en 32 bits, c'est plus simple. Menu Service / Unlock... Je pose le breakpoint habituel (HMEMCPY) Un message nous dit: "Note: service will be locked after 4 invalid inputs!" Je remplis, la case et click sur OK. F11, quelques pressions de F12 XXXX:5BC8 9A06107707 CALL USER!GETWINDOWTEXT ; On sort d'ici XXXX:5BCD 833EBC0103 CMP WORD PTR [01BC],03 ; En mettant l'octet à 0, on peut XXXX:5BD2 7E0C JLE 5BE0 ; essayer plus de 4 fois... XXXX:5BD4 6A01 PUSH 01 XXXX:5BD6 6A01 PUSH 01 XXXX:5BD8 66FF36238F PUSH DWORD PTR [8F23] XXXX:5BDD E9F200 JMP 5CD2 XXXX:5BE0 1E PUSH DS XXXX:5BE1 685A30 PUSH 305A ; En DS:305A, y'a notre password XXXX:5BE4 666A00 PUSH 00 XXXX:5BE7 666A00 PUSH 00 XXXX:5BEA 9A561BC719 CALL 19C7:1B56 ; La validité du serial se passe ICI XXXX:5BEF 83C40C ADD SP,0C XXXX:5BF2 8946A4 MOV [BP-5C],AX ; sauvegarde le résultat du call XXXX:5BF5 3D0100 CMP AX,0001 ; Si AX=1 alors le serial est bon XXXX:5BF8 751A JNZ 5C14 ; Si on saute: bad guy! En XXXX:5C14 et au delà, le programme élabore la message-box ("Invalid code. Try up to X times again", ou X={0,1,2,3} ) donc le CALL 19C7:1B56 est l'unique call à tracer. A noter que le nombre de password invalides est incrit dans le fichier DRINTERN.DAT (pour moi après installation, le fichier contient: 30.08.1998.3334.0 (soit 17 octets) et après un mauvais serial, le contenu devient 30.08.1998.3334.1 C'est pas très important, mais c'était juste pour dire qu'après avoir entré un bon serial, celui-ci est stocké dans ce même fichier. Exporons plutôt ce CALL 19C7:1B56 (souvenez vous qu'à la fin de la routine on doit avoir AX=1) XXXX:1B89 8A46CE MOV AL,[BP-32] ; Lit le premier caractère du serial XXXX:1B8C 04F0 ADD AL,F0 ; +F0 XXXX:1B8E 8846CE MOV [BP-32],AL ; Sauvegarde le résultat XXXX:1B91 16 PUSH SS XXXX:1B92 8D46CE LEA AX,[BP-32] XXXX:1B95 50 PUSH AX ; En SS:AX y'a notre serial XXXX:1B96 9AD2803719 CALL 1937:80D2 ; Ce call va revenir plusieurs fois XXXX:1B9B 83C404 ADD SP,04 XXXX:1B9E 8946F0 MOV [BP-10],AX ; Sauvegarde de la 1ère valeur héxadécimale XXXX:1BA1 0BC0 OR AX,AX XXXX:1BA3 0F849601 JZ 1D3D ; S'il y a saut: bad serial (sortie avec AX=FFFF) Petie precision sur le CALL 1937:80D2. Il convertit la valeur en SS:AX (notre serial) en héxadécimal (resultat renvoyé dans AX), seulement il vérifie que chaque caractère est <$40 et >$2F (ça doit donc être un chiffre). De plus le +F0 nous impose une contrainte: le premier caractère du serial doit avoir une valeur comprise entre $40 et $49 (soit @,A,B,C,D,E,F,G,H,I). Pour l'instant A484848 est un serial possible (mais c'est pas encore fini). continuons: XXXX:1BA7 8A46D1 MOV AL,[BP-2F] ; Lit le quatrième caractère XXXX:1BAA 04EF ADD AL,EF ; +EF XXXX:1BAC 8846D1 MOV [BP-2F],AL ; Sauvegarde le résultat XXXX:1BAF 16 PUSH SS XXXX:1BB0 8D46D1 LEA AX,[BP-2F] XXXX:1BB3 50 PUSH AX ; En SS:AX y'a notre serial +3 XXXX:1BB4 9AD2803719 CALL 1937:80D2 ; Conversion en héxa XXXX:1BB9 83C404 ADD SP,04 XXXX:1BBC 8946EE MOV [BP-12],AX ; Sauvegarde de la 2ème valeur héxadécimale XXXX:1BBF 0BC0 OR AX,AX XXXX:1BC1 0F847801 JZ 1D3D ; S'il y a saut: bad serial (sortie avec AX=FFFF) Seconde contrainte: le quatrième caractère doit être compris entre $41 et $4A (soit A,B,C,D,E,F,G,H,I,J). Donc A48A33 est un password possible, ce qui signifie que la 1ère valeur héxadécimale sera la obligatoirement la conversion des 3 premiers chiffres. XXXX:1BC5 8A46D3 MOV AL,[BP-2D] ; Lit le sixième caractère XXXX:1BC8 04EE ADD AL,EE ; +EE XXXX:1BCA 8846D3 MOV [BP-2D],AL ; Sauvegarde le résultat XXXX:1BCD 16 PUSH SS XXXX:1BCE 8D46D3 LEA AX,[BP-2D] XXXX:1BD1 50 PUSH AX ; En SS:AX y'a notre serial +5 XXXX:1BD2 9AD2803719 CALL 1937:80D2 ; Conversion en héxa XXXX:1BD7 83C404 ADD SP,04 XXXX:1BDA 8946EC MOV [BP-14],AX ; Sauvegarde de la 3ème valeur héxadécimale XXXX:1BDD 0BC0 OR AX,AX XXXX:1BDF 0F845A01 JZ 1D3D ; S'il y a saut: bad serial (sortie avec AX=FFFF) Troisième contrainte: le sixième caractère doit être compris entre $42 et $4B (soit B,C,D,E,F,G,H,I,J,K). Donc A48A3B12 est un password possible, donc la 2ème valeur héxa est la conversion des caractèrres 4 et 5. XXXX:1BE3 8B46F0 MOV AX,[BP-10] ; 1ère valeur héxa XXXX:1BE6 2B46EE SUB AX,[BP-12] ; 1ère valeur héxa - 2ème valeur héxa XXXX:1BE9 3B46EC CMP AX,[BP-14] ; = 3ème valeur héxa ? XXXX:1BEC 0F854D01 JNZ 1D3D ; S'il y a saut: bad serial (sortie avec AX=FFFF) Exemple: je prend comme serial A48B9C135 A -> 1 ce qui fait 148_d = 94_h B -> 1 ce qui fait 19_d = 13_h C -> 1 ce qui fait 1135_d = 46F_h Or 94_h - 13_h <> 46F_h donc ce serial est incorrect. Mais A48B9C29 convient. Etant donné que le programme va lire un 9ème caractère, je vais prendre A48B9C29X (il y a aussi possiblité de lire le 8ème caractère si la 3ème valeur héxa est <=$63... je vous laisse aller voir le code). XXXX:1C0B 8B46EE MOV AX,[BP-12] ; 2ème valeur héxa forcément compris entre 0 et 99_d XXXX:1C0E BB0A00 MOV BC,000A XXXX:1C11 99 CWD XXXX:1C12 F7FB IDIV BX XXXX:1C14 5A POP DX ; ressort (pour moi) le 9ème caractère 'X' XXXX:1C15 2BD0 SUB DX,AX XXXX:1C17 83FA43 CMP DX,43 XXXX:1C1A 745E JZ 1C7A Avec le serial A48B9C29D j'essaye, c'est OK, DX=43 est j'obtiens un message d'erreur: "You need a new key!" (c'est probablement un serial pour les versions antérieures). Un peu plus loin, on a: XXXX:1C37 8B46EE MOV AX,[BP-12] ; 2ème valeur héxa forcément compris entre 0 et 99_d XXXX:1C3A BB0A00 MOV BC,000A XXXX:1C3D 99 CWD XXXX:1C3E F7FB IDIV BX XXXX:1C40 5A POP DX ; ressort (pour moi) le 9ème caractère 'X' XXXX:1C41 03D0 ADD DX,AX XXXX:1C43 83FA57 CMP DX,57 XXXX:1C46 7432 JZ 1C7A J'essaye le serial A48B9C29V je recois le message "Online registration successfull". En bas à gauche, il y a inscrit "registered for: Reg.-Nr. 129V" Je quitte et je relance et j'ai une erreur: "Invalid file format: Reinstall the program." Je remet 30.08.1998.3334.0 dans drintern.dat et je continue. XXXX:1C63 8B46EE MOV AX,[BP-12] ; Seconde valeur héxa XXXX:1C66 BB0A00 MOV BX,000A XXXX:1C69 99 CWD ; convertion d'un Word en Dword (DX+AX) XXXX:1C6A F7FB IDIV BX XXXX:1C6C 5A POP DX ; ressort (pour moi) le 9ème caractère 'X' XXXX:1C6D 2BD0 SUB DX,AX XXXX:1C6F 83FA41 CMP DX,41 XXXX:1C72 7406 JZ 1C7A J'essaye avec A48B9C29B, et j'ai encore le message "Online registration successfull". En bas à gauche, il y a inscrit "registered for: Reg.-Nr. 129B" Je requitte le programme, je relance et paf, encore "Invalid file format: Reinstall the program." Il y a un problème, mon serial est trop court... (on a lu des trucs en mémoire, là ou il n'y avait rien). Je re-remet 30.08.1998.3334.0 dans le fichier drintern.dat et je continue vers XXXX:1C7A Ensuite le programme utilise le caractère 10 (addition de +ED) et calcule une nouvelle valeur héxa avec le call 1937:80D2. Par exemple pour le serial A48B9C29VE48, E devient 2 et renvoit (après le call 1937:80D2) AX=00F8 (=248_d). (C->0 ; D->1 ; E->2 ; F->3 ; G->4 ; H->5 ; I->6 ; J->7 ; K->8 ; L->9) En prenant le password: A48B9C29VE484849 (remarque: 2484849_d = 25EA71_h) Tout un tas AND/OR/SHR/SHL avant.. ... XXXX:1D21 268A07 MOV AL,ES:[BX] ; lit (avec l'exemple ci-dessous: EA) XXXX:1D24 C1E806 SHR AX,06 ; AX=013B XXXX:1D27 250300 AND AX,0003 ; AX=0003 XXXX:1D2A 8B5EFA MOV BX,[BP-06] XXXX:1D2D 268B17 MOV DX,ES:[BX] ; lit (avec l'exemple ci-dessous: EA70) XXXX:1D30 C1EA04 SHR DX,04 ; DX=0EA7 XXXX:1D33 82E21F AND DX,1F ; DX=0007 XXXX:1D36 83E203 AND DX,03 ; DX=0003 XXXX:1D39 3BC2 CMP AX,DX ; si ax<>dx, on affiche le programme reffuse de XXXX:1D3B 7406 JZ 1D43 ; démarrer (avec A48B9C29VE484849 ça marche) XXXX:1D3D B8FFFF MOV AX,FFFF XXXX:1D40 E9E300 JMP 1E26 Un bon serial est donc: A48B9C29VE484848 ou bien A48B9C29VE484849, A48B9C29VE484850, A48B9C29VE484851 marche aussi... (idem pour +A48B9C29VE484848 ou -A48B9C29VE484848 ) Bref y'en a plein... Avec le serial A48B9C29VE484849 on a: "registered for: Reg.-Nr. 3484849", là encore c'est parfaitement logique au lieu d'avoir 2484849... Remarque: j'ai réessayé ultérieurement les deux serials A48B9C29V et A48B9C29B, ils ont parfaitement marché (en effet le 10ème caractère étant 00, c'est logique que ça aille, mais cette octet est-il toujours nul??? moi, je pense que oui). Etant donné la minable protection, qui m'a faite bien chier, je ne ferais pas de key-generator: j'ai le flemme... C'est pas compliqué: just do it. A la prochaine peut être...