PC Screen Tool
Défi de la Main Rouge
Mars 2000
Petit Essai de Reverse Engineering
by Christal
|
Beaucoup semble regretter que le sérial généré ne le
soit pas sur la base du Name ou de la Company, entrés dans les deux premiers champs de la boite d'enregistrement.
0000 3501 5F00 0000 0000 5200 6500 6700 ..5._.....R.e.g. > coordonnées D.Box 6900 7300 7400 6500 7200 2000 5000 4300 i.s.t.e.r. .P.C. 2000 5300 6300 7200 6500 6500 6E00 2000 .S.c.r.e.e.n. . 5400 6F00 6F00 6C00 7300 0000 0800 4D00 T.o.o.l.s.....M. 5300 2000 5300 6100 6E00 7300 2000 5300 S. .S.a.n.s. .S. 6500 7200 6900 6600 0000 0000 0100 0150 e.r.i.f........P 0000 0000 6300 3400 3200 0E00 0100 FFFF ....c.4.2....... > coordonnées [OK]+ ID 8000 4F00 4B00 0000 0000 0000 0000 0150 ..O.K..........P 0000 0000 9B00 3400 3200 0E00 0200 FFFF ......4.2....... > coordonnées [cancel]+ ID 8000 4300 6100 6E00 6300 6500 6C00 0000 ..C.a.n.c.e.l... 0000 0000 0000 0250 0000 0000 0A00 0A00 .......P........ > coordonnée Name 1400 0800 FFFF FFFF 8200 4E00 6100 6D00 ..........N.a.m. > static -1 6500 0000 0000 0000 0000 0250 0000 0000 e..........P.... 0A00 1800 3200 0800 FFFF FFFF 8200 4300 ....2.........C. 3000 6D00 7000 6100 6E00 7900 2000 2000 0.m.p.a.n.y. . . 2000 2000 0000 0000 0000 0250 0000 0000 . ........P.... 0A00 2700 4100 0800 FFFF FFFF 8200 5200 ..'.A.........R. 6500 6700 6900 7300 7400 7200 6100 7400 e.g.i.s.t.r.a.t. 6900 6F00 6E00 2000 4E00 7500 6D00 6200 i.o.n. .N.u.m.b. 6500 7200 0000 0000 8000 8150 0000 0000 e.r........P.... > fin des "static" 6400 0700 C400 0C00 F703 FFFF 8100 0000 d............... > 1015 control + coord 0000 0000 8000 8150 0000 0000 6400 1500 d............... > coordonnées 2ème champ C400 0C00 F803 FFFF 8100 0000 0000 0000 .......P....d... > 1016 control_ID 8000 8150 0000 0000 6400 2200 C400 0C00 ...............P > coordonnées 3ème champ FB03 FFFF 8100 0000 0000 0000 0000 0150 ...............P > 1019 control_ID (Vous aurez remarqué que les caractéristiques de chacun des scripts
de champs se finissent par FFFF, ce qui est un bon point de repère...) * Possible Reference to Dialog: DialogID_0084
|
:00404B48 6884000000 push 00000084 > pousse l'identificateur (ID) de la DialogBox sur la pile
* Reference To: MFC42.Ordinal:0144, Ord:0144h
|
:00404B4D E8B6190000 Call 00406508
:00404B52 C706A88A4000 mov dword ptr [esi], 00408AA8
:00404B58 8BC6 mov eax, esi
:00404B5A 5E pop esi
:00404B5B C20400 ret 0004
DialogID_0084, # of Controls=010, Caption:"Register PC Screen Tools", ClassName:"" 001 - ControlID:0001, Control Class:"BUTTON" Control Text:"OK" 002 - ControlID:0002, Control Class:"BUTTON" Control Text:"Cancel" 003 - ControlID:FFFF, Control Class:"STATIC" Control Text:"Name" 004 - ControlID:FFFF, Control Class:"STATIC" Control Text:Company " 005 - ControlID:FFFF, Control Class:"STATIC" Control Text:"Registration Number" 006 - ControlID:03F7, Control Class:"EDIT" Control Text:"" 007 - ControlID:03F8, Control Class:"EDIT" Control Text:"" 008 - ControlID:03FB, Control Class:"EDIT" Control Text:"" 009 - ControlID:040B, Control Class:"BUTTON" Control Text:"Give me a Serial Number" 010 - ControlID:FFFF, Control Class:"STATIC" Control Text:"" L'identificateur du champ "Registration Number" est 03FBh (1019d). * Possible Reference to Dialog: DialogID_0084, CONTROL_ID:03FB, ""
|
:00404D3C 68FB030000 push 000003FB > pousse l'identificateur du Champ
> "Registration Number" sur la pile
:00404D41 8BCE mov ecx, esi
et cette routine se trouve placée un peu au dessus de: * Possible StringData Ref from Data Obj ->"Registration successful !"
|
:00404DAB 68FCA24000 push 0040A2FC
:00404DB0 8D4C240C lea ecx, dword ptr [esp+0C]
:00404DB4 E8E7D5FFFF call 004023A0
Glop! Glop! Entre les deux il y a peut être notre champ de saisie du sérial... :00404D54 E8D91A0000 Call 00406832 :00404D59 8D942470020000 lea edx, dword ptr [esp+00000270] > Name :00404D60 8D842470010000 lea eax, dword ptr [esp+00000170] > Company :00404D67 52 push edx :00404D68 8D8C24F4010000 lea ecx, dword ptr [esp+000001F4] > Sérial Au retour du call, vous trouvez les TROIS saisies de champs, joliment complétés
par les informations entrées dans les formulaires de saisie... Name Virt Size Virt Offset Raw Size Raw Offset Characteristics .text 000060B5 00001000 00006200 00000400 60000020 .rdata 000014A0 00008000 00001600 00006600 40000040 .data 00000818 0000A000 00000600 00007C00 C0000040 .idata 00000F3E 0000B000 00001000 00008200 C0000040 .rsrc 00003D04 0000C000 00003E00 00009200 40000040 La Virtual size de la section est 00003D04, ce qui veut dire que la mémoire
qui sera allouée pour cette section sera de 00003D04 bytes. Le Virtual Offset de la section est de 0000C000,
additionné à l'Image base qui vaut 00400000, ça nous donne une adresse virtuelle de 0000C000
+ 00400000 = 0040C000. :0040FD20 60 PUSHAD > sauve l'état des registres
:0040FD21 90 NOP
:0040FD22 BF05000000 MOV EDI,00000005 > prépare un pointeur à 5
:0040FD27 BA00FD4000 MOV EDX,0040FD00 > charge l'adresse de l'image du sérial
:0040FD2C 8BF0 MOV ESI,EAX > place le Name dans ESI
> (j'aurai besoin de AL plus tard)
Comme il me fallait un registre qui gère les caractères sur 8 bits, j’ai opté pour utiliser AL, Si ne gérant qu'au minimum des Words sur 16 bits. :0040FD2E 03FA ADD EDI,EDX > Ajoute le pointeur à l'adresse du sérial
> EDI va pointer sur 0040FD005 (après ST10-)
:0040FD30 803F00 CMP BYTE PTR [EDI],00 > fin de l'image du sérial?
> celui ci se terminant par NULL
:0040FD33 7440 JZ 0040FD75 > Goto Fin
:0040FD35 803F2D CMP BYTE PTR [EDI],2D > le caractère suivant est-il un (-)?
:0040FD38 7438 JZ 0040FD72 > Goto Suite
:0040FD3A 8A01 MOV AL,[ECX] > 1 caractère de Name dans AL
:0040FD3C 3C00 CMP AL,00 > est-ce le dernier?
:0040FD3E 7417 JZ 0040FD57 > si oui, Goto Suite1
:0040FD40 3C30 CMP AL,30 > caractère inférieur à "0"?
:0040FD42 7C10 JL 0040FD54 > Goto Caractère_suivant
> (JL saute si plus petit que…)
:0040FD44 3C46 CMP AL,46 > caractère inférieure à "F"
:0040FD46 7E0A JLE 0040FD52 > Goto Caractère_suivant
:0040FD48 3C61 CMP AL,61 > caractère inférieur à "a"
:0040FD4A 7C08 JL 0040FD54 > Goto Caractère_suivant
:0040FD4C 3C66 CMP AL,66 > caractère supérieur à "f"
:0040FD4E 7F04 JG 0040FD54 > Goto Caractère_suivant
> (JG saute si plus grand que…)
:0040FD50 2C20 SUB AL,20 > transforme caractère en majuscule
:0040FD52 8807 MOV [EDI],AL > place caractère dans image
Caractère_suivant (1er champ):
:0040FD54 41 INC ECX > incrémente Name
:0040FD55 EB1B JMP 0040FD72 > boucle
Suite1:
:0040FD57 8A06 MOV AL,[ESI] > caractère de Company dans AL
:0040FD59 3C00 CMP AL,00 > est ce le dernier?
:0040FD5B 7415 JZ 0040FD72 > si oui, Goto Fin
:0040FD5D 3C30 CMP AL,30 > caractère inférieur à 0?
:0040FD5F 7C10 JL 0040FD71 > Goto Caractère_suivant
:0040FD61 3C46 CMP AL,46 > caractère inférieur à "F"?
:0040FD63 7E0A JLE 0040FD6F > Goto OK_Champ2
:0040FD65 3C61 CMP AL,61 > caractère inférieur à "a"?
:0040FD67 7C08 JL 0040FD71 > Goto Caractère_suivant
:0040FD69 3C66 CMP AL,66 > caractère supérieur à "f"?
:0040FD6B 7F04 JG 0040FD71 > Goto Caractère_suivant
:0040FD6D 2C20 SUB AL,20 > transforme AL en majuscule
OK_Champ2:
:0040FD6F 8807 MOV [EDI],AL > place caractère dans image
Caractère_suivant (2er champ):
:0040FD71 46 INC ESI > incrémente Company
Suite:
:0040FD72 47 INC EDI > incrémente Boucle
:0040FD73 EBBB JMP 0040FD30 > boucle
Fin:
:0040FD75 E94A040000 JMP 004101C4 > vers générateur du sérial
:0040FD7A 0000 ADD [EAX],AL > espace disponible
:0040FD7C 0000 ADD [EAX],AL > espace disponible
Cette routine n'est pas très optimisée, mais elle fonctionne, et c'est
malgré tout le principal... Name : Christal Company : Hello, les gars Vont donner : ST10-C0-000-0-A000E000000E000-A0
Ch ris t al Hello, les g ars
Il est bien sur possible de modifier l'image pour avoir autre chose que des 0... Il va falloir maintenant utiliser cette base pour générer un sérial
valable. .Pcst 00000000 00010000 00001000 0000D000 C0000040 Je vais rajouter une section de 0x1000 bytes à la suite des autres. :10001130 8B4C2404 mov ecx, dword ptr [esp+04] Au début de la routine de contrôle dans la DLL, ECX reçoit le
sérial à valider. Il va falloir faire de même, passer notre image dans ECX, puis « retourner
» deux trois petites choses, et finalement virer les contrôles de validité. :10001279 88542404 mov byte ptr [esp+04], dl > Place dl dans le tampon de contrôle :1000127D 7607 jbe 10001286 > SI dl > "9" :1000127F 80C207 add dl, 07 > alors dl = dl + 7 :10001282 88542404 mov byte ptr [esp+04], dl > et change la valeur dans ESP+04 la modification envisagée va permettre de placer « dl » directement dans l’image du sérial final placé dans ECX, et chaque mov byte ptr [esp+04], dl, vont devenir des : :00410225 885113 MOV [ECX+13],DL > place DL dans l'image du sérial à la 20ème place
:00410228 90 NOP > pour garder le même nombre d’octets et ne pas
> avoir à modifier les sauts conditionnels.
Après cela, il faut encore supprimer les tests de comparaisons : :10001298 8A4113 mov al, byte ptr [ECX+13] > 20ème caractère du sérial entré :1000129B 8B542404 mov edx, dword ptr [esp+04] > récupère la valeur de DL dans [ESP+4] :1000129F 0FBEC0 movsx eax, al > place AL dans EAX :100012A2 81E2FF000000 and edx, 000000FF > DL dans EDX :100012A8 3BC2 cmp eax, edx > les compare :100012AA 0F8561010000 jne 10001411 > et dégage si pas Glop ! Il y en a 5. Tous peuvent disparaître sans problème. Il est bien sur
possible de les nopper, mais pour faire plus clean, le plus simple est de les sélectionner dans l’éditeur
hexa, et de les supprimer. Il n’y a pas d’incidence sur le reste de la routine, sauts compris. 0137:004101C4 B900FD4000 MOV ECX,0040FD00 et après génération du bon sérial : 0137:0041037E 61 POPAD 0137:0041037F BA00FD4000 MOV EDX,0040FD00 0137:00410384 E9E349FFFF JMP 00404D6C Restaurer les registre :00404D54 E8D91A0000 Call 00406832 :00404D59 8D842470010000 lea eax, dword ptr [esp+00000170] > Company :00404D60 8D8C24F0010000 lea ecx, dword ptr [esp+000001F0] > Name :00404D67 E9B4AF0000 jmp 0040FD20 > Go to patch :00404D6C 52(ad de retour) push edx > pousse le sérial « amélioré » :00404D6D 50 push eax > la company :00404D6E 51 push ecx > le Name :00404D6F 90 nop > équilibrage :00404D70 90 nop > (on aurait pu choisir INC EAX DEC EAX…) :00404D71 8D4C2410 lea ecx, dword ptr [esp+10] > continue... Voici le sérial que j'ai obtenu: ST10-C0-000-0-A00E0E0000D0BB-53 Il resterait encore bien d’autres choses à faire. Dans son tut, TeeJi propose
une solution pour faire apparaître une message box en cliquant sur un des boutons de la boite de Dialogue
"About"... * Possible StringData Ref from Data Obj ->"Registration successful !"
|
:00404DAB 68FCA24000 push 0040A2FC > et Voilà !
:00404DB0 8D4C240C lea ecx, dword ptr [esp+0C]
:00404DB4 E8E7D5FFFF call 004023A0 > affichage MessageBox
Et il ne reste qu’à modifier le Push 0040A2FC par un Push 0040FD00, et le tour est joué : :00404DAB 6800FD4000 PUSH 0040FD00 :00404DB0 8D4C240C LEA ECX,[ESP+0C] :00404DB4 E8E7D5FFFF CALL 004023A0 Pas utile, mais joli... |
Bonne journée
Christal