About Box - PatchDéfi Main Rouge Février 2000
proposé par Christal
PC Screen Tools version 1.00
* Referenced by a (U)nconditional
or (C)onditional Jump at Address:
|:00402C98(C)-->
Dépend d'un saut conditionnel en :00402C98
|
*
Reference To: MFC42.Ordinal:0C14, Ord:0C14h
|
:00402CD9 E842380000
Call 00406520
* Possible StringData Ref from Data Obj ->">>> Unregistered <<<"
-
:00402C8A
E8211D0000
call 004049B0 --> Fct de vérification
:00402C8F
85C0
test eax, eax --> EAX = 0 ?
*
Possible Reference to Dialog: DialogID_0064, CONTROL_ID:03F7, ""
|
:00402C91
68F7030000
push 000003F7
:00402C96
8BCE
mov ecx, esi
:00402C98
743F
je 00402CD9 --> Dépend
de EAX
-
*
Possible StringData Ref from Data Obj ->"RegName"
|
:004049DA
68B4A24000
push 0040A2B4
*
Possible StringData Ref from Data Obj ->"SOFTWARE\PC Screen Tools"
|
:004049DF
6870A24000
push 0040A270
:004049E4
6802000080
push 80000002
:004049E9
C744242400000000 mov [esp+24],
00000000
:004049F1
33FF
xor edi, edi
:004049F3
E8C8040000
call 00404EC0 --> Va rechercher la valeur
de RegName dans
--- La base de registre.
...
*
Possible StringData Ref from Data Obj ->"RegCompany"
|
:00404A01
68A8A24000
push 0040A2A8 --> ...de RegCompany
...
:00404A25 56 push esi --> Adresse de la valeur de RegNo ?!? ( on va le supposer )
*
Possible StringData Ref from Data Obj ->"RegNo"
|
:00404A26
68A0A24000
push 0040A2A0 --> ...et de RegNo
-
*
Possible StringData Ref from Data Obj ->"CheckRegistrationNumber"
|
:00404A50
68BCA24000
push 0040A2BC
:00404A55
50
push eax
*
Reference To: KERNEL32.GetProcAddress, Ord:0116h
|
:00404A56
FF1510B64000
Call dword ptr [0040B610] --> Récupère
l'adresse de la Fct
--- CheckRegistrationNumber
:00404A5C
EB04
jmp 00404A62
-
:00404A62
56
push esi --> Adresse de la valeur de RegNo
?!? ( on va le supposer )
:00404A63
FFD0
call eax --> Call CheckRegistrationNumber
:00404A65
83C404
add esp, 00000004
:00404A68
85C0
test eax, eax
:00404A6A
7409
je 00404A75 --> Si EAX = 0 --> RegNo invalide
:00404A6C
C6461F00
mov [esi+1F], 00
:00404A70
BF01000000
mov edi, 00000001
*
Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004049FA(C),
:00404A1B(C), :00404A3C(C), :00404A6A(C)
|
:00404A75
8D4C2408
lea ecx, dword ptr [esp+08]
:00404A79
C7442414FFFFFFFF mov [esp+14],
FFFFFFFF
:00404A81
E82A040000
call 00404EB0
-->
:00404EB0 C701808B4000
mov dword ptr [ecx], 00408B80
:00404EB6 C3
ret
:00404A86
8B4C240C
mov ecx, dword ptr [esp+0C]
:00404A8A
8BC7
mov eax, edi
:00404A8C
5F
pop edi
:00404A8D
64890D00000000 mov
dword ptr fs:[00000000], ecx
:00404A94
5E
pop esi
:00404A95
83C410
add esp, 00000010
:00404A98
C20C00
ret 000C
Disassembly of File: magdll.dll
...
:10001402
B801000000
mov eax, 00000001
:10001407
A31C200010
mov dword ptr [1000201C], eax
:1000140C
5B
pop ebx
:1000140D
83C408
add esp, 00000008
:10001410
C3
ret --> Fin de la Fct avec EAX = 1 --> Bon
RegNo !
*
Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:10001149(C),
:10001152(C), :1000115B(C), :10001164(C), :1000116D(C)
|:10001178(C),
:10001180(C), :1000118B(C), :10001193(C), :1000119E(C)
|:100011A6(C),
:100011B1(C), :100011B9(C), :100011C4(C), :100011CC(C)
|:100011D8(C),
:100011E1(C), :100011ED(C), :100011F6(C), :10001201(C)
|:10001209(C),
:10001212(C), :1000121C(C), :10001226(C), :10001230(C)
|:100012AA(C),
:100012C2(C), :10001326(C), :1000133E(C), :10001392(C)
|:100013A3(C),
:100013EE(C), :10001400(C)
|
:10001411
33C0
xor eax, eax
:10001413
5B
pop ebx
:10001414
83C408
add esp, 00000008
:10001417
C3
ret --> Fin de la Fct avec EAX = 0 --> RegNo
invalide !
Conclusion :
Il suffit de mettre un JMP 10001402 ( EBEF ) en :10001411.
Recherche
du RegNo - KeyGen
:10001130
8B4C2404
mov ecx, dword ptr [esp+04] --> ECX = adresse
de RegNo
:10001134
C7051C20001000000000 mov dword ptr [1000201C], 00000000
:1000113E
83EC08
sub esp, 00000008 --> Réserve 8 bytes
sur la pile
:10001141
B02D
mov al, 2D --> "-"
:10001143
8A5104
mov dl, byte ptr [RegNo+04]
:10001146
3AD0
cmp dl, al --> [RegNo+04] = "-"
:10001148
53
push ebx
:10001149
0F85C2020000
jne 10001411
:1000114F
384107
cmp byte ptr [RegNo+07], al --> Idem pour
ceux-ci
:10001158
38410B
cmp byte ptr [RegNo+0B], al
:10001161
38410D
cmp byte ptr [RegNo+0D], al
:1000116A
38411C
cmp byte ptr [RegNo+1C], al
:10001173
8A410F
mov al, byte ptr [RegNo+0F]
:10001176
3C30
cmp al, 30
:10001178
0F8C93020000
jl 10001411 --> [RegNo+0F] >= "0"
:1000117E
3C46
cmp al, 46
:10001180
0F8F8B020000
jg 10001411 --> [RegNo+0F] <= "F"
:10001186
8A4110
mov al, byte ptr [RegNo+10] --> Vérifie
pour ceux-ci aussi
:10001199
8A4111
mov al, byte ptr [RegNo+11]
:100011AC
8A4112
mov al, byte ptr [RegNo+12]
:100011BF
8A4115
mov al, byte ptr [RegNo+15]
:100011D2
8A5916
mov bl, byte ptr [RegNo+16]
:100011E7
8A5117
mov dl, byte ptr [RegNo+17]
:100011FC
8A4119
mov al, byte ptr [RegNo+19]
:1000120F
803953
cmp byte ptr [RegNo+0], 53 --> "S"
:10001218
80790154
cmp byte ptr [RegNo+01], 54 --> "T"
:10001222
80790231
cmp byte ptr [RegNo+02], 31 --> "1"
:1000122C
80790330
cmp byte ptr [RegNo+03], 30 --> "0"
:10001236
02C2
add al, dl --> al = [RegNo+19] + [RegNo+17]
:10001238
8A5115
mov dl, byte ptr [RegNo+15]
:1000123B
02C3
add al, bl --> al = al + [RegNo+16]
:1000123D
8A5912
mov bl, byte ptr [RegNo+12]
:10001240
02C2
add al, dl --> al = al + [RegNo+15]
:10001242
8A5111
mov dl, byte ptr [RegNo+11]
:10001245
02C3
add al, bl --> al = al + [RegNo+12]
:10001247
8A5910
mov bl, byte ptr [RegNo+10]
:1000124A
02C2
add al, dl --> al = al + [RegNo+11]
:1000124C
8A510F
mov dl, byte ptr [RegNo+0F]
:1000124F
02C3
add al, bl --> al = al + [RegNo+10]
:10001251
8A5908
mov bl, byte ptr [RegNo+08]
:10001254
02C2
add al, dl --> al = al + [RegNo+0F]
:10001256
8A5105
mov dl, byte ptr [RegNo+05]
:10001259
88542410
mov byte ptr [esp+10], dl
:1000125D
8A510C
mov dl, byte ptr [RegNo+0C]
-->
Format de RegNo = ST10-??-???-?-??????????????-
-->
al = [19]+[17]+[16]+[15]+[12]+[11]+[10]+[0F]
:10001260
3453
xor al, 53
:10001262
32C2
xor al, dl --> xor al, [RegNo+0C]
:10001264
8A542410
mov dl, byte ptr [esp+10]
:10001268
32C3
xor al, bl --> xor al, [RegNo+08]
:1000126A
32C2
xor al, dl --> xor al, [RegNo+05]
:1000126C
3465
xor al, 65
--> al = al xor 53 xor [0C] xor [08] xor [05] xor 65
:1000126E
8AD0
mov dl, al
:10001270
C0EA04
shr dl, 04
:10001273
80C230
add dl, 30
:10001276
80FA39
cmp dl, 39
:10001279
88542404
mov byte ptr [esp+04], dl
:1000127D
7607
jbe 10001286
:1000127F
80C207
add dl, 07
:10001282
88542404
mov byte ptr [esp+04], dl
-->
dl = ( al shr 04 ) + 30
-->
SI dl > "9" ALORS dl = dl + 7
-->
[esp+04] = dl
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000127D(C)
|
:10001286
240F
and al, 0F
:10001288
0430
add al, 30
:1000128A
3C39
cmp al, 39
:1000128C
88442408
mov byte ptr [esp+08], al
:10001290
7606
jbe 10001298
:10001292
0407
add al, 07
:10001294
88442408
mov byte ptr [esp+08], al
-->
al = ( al and 0F ) + 30
-->
SI al > "9" ALORS al = al + 7
-->
[esp+08] = al
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10001290(C)
|
:10001298
8A4113
mov al, byte ptr [RegNo+13]
:1000129B
8B542404
mov edx, dword ptr [esp+04] --> edx = dl +
???
:1000129F
0FBEC0
movsx eax, al --> eax = 00000000 + [RegNo+13]
:100012A2
81E2FF000000
and edx, 000000FF --> edx = dl
:100012A8
3BC2
cmp eax, edx --> eax = edx ?
:100012AA
0F8561010000
jne 10001411 --> Sinon RegNo invalide
--> SI [13] != dl ALORS RegNo invalide
:100012B0
8A4114
mov al, byte ptr [RegNo+14]
:100012B3
8B542408
mov edx, dword ptr [esp+08]
:100012B7
0FBEC0
movsx eax, al
:100012BA
81E2FF000000
and edx, 000000FF
:100012C0
3BC2
cmp eax, edx
:100012C2
0F8549010000
jne 10001411
--> SI [14] != al ALORS RegNo invalide
:100012C8
8A510A
mov dl, byte ptr [RegNo+0A]
:100012CB
8A4109
mov al, byte ptr [RegNo+09]
:100012CE
80C253
add dl, 53
:100012D1
80F254
xor dl, 54
:100012D4
80F231
xor dl, 31
:100012D7
80F230
xor dl, 30
:100012DA
32D3
xor dl, bl
:100012DC
8A5913
mov bl, byte ptr [RegNo+13]
:100012DF
32C2
xor al, dl
:100012E1
8A5114
mov dl, byte ptr [RegNo+14]
:100012E4
32C2
xor al, dl
:100012E6
32C3
xor al, bl
:100012E8
3418
xor al, 18
:100012EA
8AD0
mov dl, al
:100012EC
C0EA04
shr dl, 04
:100012EF
80C230
add dl, 30
:100012F2
80FA39
cmp dl, 39
:100012F5
88542404
mov byte ptr [esp+04], dl
:100012F9
7607
jbe 10001302
:100012FB
80C207
add dl, 07
:100012FE
88542404
mov byte ptr [esp+04], dl
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100012F9(C)
|
:10001302
240F
and al, 0F
:10001304
0430
add al, 30
:10001306
3C39
cmp al, 39
:10001308
88442408
mov byte ptr [esp+08], al
:1000130C
7606
jbe 10001314
:1000130E
0407
add al, 07
:10001310
88442408
mov byte ptr [esp+08], al
-->
dl = ( [0A] + 53 ) xor 54 xor 31 xor 30 xor [08]
-->
bl = [13]
-->
al = [09] xor dl
-->
dl = [14]
-->
al = al xor [14] xor [13] xor 18
-->
dl = ( al shr 4 ) + 30
-->
SI dl > "9" ALORS dl = dl + 7
-->
[esp+04] = dl
-->
al = al and 0F + 30
-->
SI al > "9" ALORS al = al + 7
-->
[esp+08] = al
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000130C(C)
|
:10001314
8A411A
mov al, byte ptr [RegNo+1A]
:10001317
8B542404
mov edx, dword ptr [esp+04]
:1000131B
0FBEC0
movsx eax, al
:1000131E
81E2FF000000
and edx, 000000FF
:10001324
3BC2
cmp eax, edx
:10001326
0F85E5000000
jne 10001411
:1000132C
8A591B
mov bl, byte ptr [ecx+1B]
:1000132F
8B542408
mov edx, dword ptr [esp+08]
:10001333
0FBEC3
movsx eax, bl
:10001336
81E2FF000000
and edx, 000000FF
:1000133C
3BC2
cmp eax, edx
:1000133E
0F85CD000000
jne 10001411
-->
SI [1A] != dl ALORS faux RegNo
-->
SI [1B] != al ALORS faux RegNo
:10001344
8A4106
mov al, byte ptr [RegNo+06]
:10001347
8A5114
mov dl, byte ptr [RegNo+14]
:1000134A
32C2
xor al, dl
:1000134C
8A5113
mov dl, byte ptr [RegNo+13]
:1000134F
32C2
xor al, dl
:10001351
8A542410
mov dl, byte ptr [RegNo+10]
:10001355
32C2
xor al, dl
:10001357
34AB
xor al, AB
:10001359
8AD0
mov dl, al
:1000135B
C0EA04
shr dl, 04
:1000135E
80C230
add dl, 30
:10001361
80FA39
cmp dl, 39
:10001364
88542404
mov byte ptr [esp+04], dl
:10001368
7607
jbe 10001371
:1000136A
80C207
add dl, 07
:1000136D
88542404
mov byte ptr [esp+04], dl
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10001368(C)
|
:10001371
240F
and al, 0F
:10001373
0430
add al, 30
:10001375
3C39
cmp al, 39
:10001377
88442408
mov byte ptr [esp+08], al
:1000137B
7606
jbe 10001383
:1000137D
0407
add al, 07
:1000137F
88442408
mov byte ptr [esp+08], al
-->
al = [06] xor [14] xor [13] xor [10] xor AB
-->
dl = ( al shr 4 ) + 30
-->
SI dl > "9" ALORS dl = dl + 7
-->
[esp+04] = dl
-->
al = al and 0F + 30
-->
SI al > "9" ALORS al = al + 7
-->
[esp+08] = al
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000137B(C)
|
:10001383
0FBE510E
movsx edx, byte ptr [RegNo+0E]
:10001387
8B442404
mov eax, dword ptr [esp+04]
:1000138B
25FF000000
and eax, 000000FF
:10001390
3BD0
cmp edx, eax
:10001392
757D
jne 10001411
:10001394
0FBE5118
movsx edx, byte ptr [RegNo+18]
:10001398
8B442408
mov eax, dword ptr [esp+08]
:1000139C
25FF000000
and eax, 000000FF
:100013A1
3BD0
cmp edx, eax
:100013A3
756C
jne 10001411
-->
SI [0E] != dl ALORS faux RegNo
-->
SI [18] != al ALORS faux RegNo
:100013A5
8A411A
mov al, byte ptr [ecx+1A]
:100013A8
8A510C
mov dl, byte ptr [ecx+0C]
:100013AB
32D8
xor bl, al
:100013AD
32DA
xor bl, dl
:100013AF
80F363
xor bl, 63
:100013B2
8AD3
mov dl, bl
:100013B4
8AC2
mov al, dl
:100013B6
C0E804
shr al, 04
:100013B9
0430
add al, 30
:100013BB
3C39
cmp al, 39
:100013BD
88442404
mov byte ptr [esp+04], al
:100013C1
7606
jbe 100013C9
:100013C3
0407
add al, 07
:100013C5
88442404
mov byte ptr [esp+04], al
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100013C1(C)
|
:100013C9
80E20F
and dl, 0F
:100013CC
80C230
add dl, 30
:100013CF
80FA39
cmp dl, 39
:100013D2
88542408
mov byte ptr [esp+08], dl
:100013D6
7607
jbe 100013DF
:100013D8
80C207
add dl, 07
:100013DB
88542408
mov byte ptr [esp+08], dl
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100013D6(C)
|
:100013DF
0FBE511D
movsx edx, byte ptr [ecx+1D]
:100013E3
8B442404
mov eax, dword ptr [esp+04]
:100013E7
25FF000000
and eax, 000000FF
:100013EC
3BD0
cmp edx, eax
:100013EE
7521
jne 10001411
:100013F0
0FBE491E
movsx ecx, byte ptr [ecx+1E]
:100013F4
8B542408
mov edx, dword ptr [esp+08]
:100013F8
81E2FF000000
and edx, 000000FF
:100013FE
3BCA
cmp ecx, edx
:10001400
750F
jne 10001411
-->
bl = [1B] xor [1A] xor [0C] xor 63
-->
dl = bl
-->
al = ( bl shr 4 ) + 30
-->
SI al > "9" ALORS al = al + 7
-->
[esp+04] = al
-->
dl = ( dl and 0F ) + 30
-->
SI dl > "9" ALORS dl = dl + 7
-->
[esp+08] = dl
-->
SI [1D] != al ALORS faux RegNo
-->
SI [1E] != dl ALORS faux RegNo
:10001402
B801000000
mov eax, 00000001
:10001407
A31C200010
mov dword ptr [1000201C], eax
:1000140C
5B
pop ebx
:1000140D
83C408
add esp, 00000008
:10001410
C3
ret --> Fin de la Fct avec EAX = 1 --> Bon RegNo !
*
Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:10001149(C),
:10001152(C), :1000115B(C), :10001164(C), :1000116D(C)
|:10001178(C),
:10001180(C), :1000118B(C), :10001193(C), :1000119E(C)
|:100011A6(C),
:100011B1(C), :100011B9(C), :100011C4(C), :100011CC(C)
|:100011D8(C),
:100011E1(C), :100011ED(C), :100011F6(C), :10001201(C)
|:10001209(C),
:10001212(C), :1000121C(C), :10001226(C), :10001230(C)
|:100012AA(C),
:100012C2(C), :10001326(C), :1000133E(C), :10001392(C)
|:100013A3(C),
:100013EE(C), :10001400(C)
|
:10001411
33C0
xor eax, eax
:10001413
5B
pop ebx
:10001414
83C408
add esp, 00000008
:10001417
C3
ret --> Fin de la Fct avec EAX = 0 --> Faux RegNo !
Conclusion :
-->
Forme du RegNo :
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Avec :
-->
dl = ( [ ( [19]+[17]+[16]+[15]+[12]+[11]+[10]+[0F] ) xor 53 xor [0C] xor
[08] xor [05] xor 65 ] shr 04 ) + 30
-->
SI dl > "9" ALORS dl = dl + 7
-->
al = ( [ ( [19]+[17]+[16]+[15]+[12]+[11]+[10]+[0F] ) xor 53 xor [0C] xor
[08] xor [05] xor 65 ] and 0F ) + 30
-->
SI al > "9" ALORS al = al + 7
-->
[13] = dl
-->
[14] = al
-->
dl = ( [ ( [09] xor [ ( [0A]+ 53 ) xor 54 xor 31 xor 30 xor [08] ] ) xor
[14] xor [13] xor 18 ] shr 04 ) + 30
-->
SI dl > "9" ALORS dl = dl + 7
-->
al = ( [ ( [09] xor [ ( [0A]+ 53 ) xor 54 xor 31 xor 30 xor [08] ] ) xor
[14] xor [13] xor 18 ] and 0F ) + 30
-->
SI al > "9" ALORS al = al + 7
-->
[1A] = dl
-->
[1B] = al
-->
dl = ( [ [06] xor [14] xor [13] xor [10] xor AB ] shr 04 ) + 30
-->
SI dl > "9" ALORS dl = dl + 7
-->
al = ( [ [06] xor [14] xor [13] xor [10] xor AB ] and 0F ) + 30
-->
SI al > "9" ALORS al = al + 7
-->
[0E] = dl
-->
[18] = al
-->
al = ( [ [1B] xor [1A] xor [0C] xor 63 ] shr 04 ) + 30
-->
SI al > "9" ALORS al = al + 7
-->
dl = ( [ [1B] xor [1A] xor [0C] xor 63 ] and 0F ) + 30
-->
SI dl > "9" ALORS dl = dl + 7
-->
[1D] = al
-->
[1E] = dl
Donc,
si [19]=[17]=[16]=[15]=[12]=[11]=[10]=[0F]= 30 =[0C]=[08]=[05] ; Rem :
30 = "0"
Alors
[19]+[17]+[16]+[15]+[12]+[11]+[10]+[0F] = 80
et [ ( 80 xor 53 xor 30 xor 30 xor 30 xor 65 shr 04 ) + 30 ] = 38 <
39 --> [13] = "8"
et [ ( 80 xor 53 xor 30 xor 30 xor 30 xor 65 and 0F ) + 30 ] = 36 <
39 --> [14] = "6"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Si
[09]=[0A]=30
Alors
( [ ( 30 xor [ ( 30 + 53 ) xor 54 xor 31 xor 30 xor 30 ] ) xor 36 xor 38
xor 18 ] shr 04 ) + 30 = 3C > 39
--> 3C + 7 = 43 --> [1A] = "C"
et ( [ ( 30 xor [ ( 30 + 53 ) xor 54 xor 31 xor 30 xor 30 ] ) xor 36 xor
38 xor 18 ] and 0F ) + 30 = 30 < 39
--> [1B] = "0"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Si
[06]= 30
Alors
[ ( [ 30 xor 36 xor 38 xor 30 xor AB ] shr 04 ) + 30 ] = 3A > 39 --> 3A
+ 7 = 41 --> [0E] = "A"
et [ ( [ 30 xor 36 xor 38 xor 30 xor AB ] and 0F ) + 30 ] = 35 < 39
--> [18] = "5"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
C | 0 |
|
Alors
[ ( [ 30 xor 43 xor 30 xor 63 ] shr 04 ) + 30 ] = 32 --> [1D] = "2"
et [ ( [ 30 xor 43 xor 30 xor 63 ] and 0F ) + 30 ] = 30 --> [1E] = "0"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
--> Donc le RegNo ne dépend ni du Nom, ni de la Companie. Un des RegNos valides est : ST10-00-000-0-A00008600050C0-20
Rem : Les deux méthodes écrites ci-dessus ont été uniquement réalisée avec WDasm, je n'ai à aucun moment utilisé de debugger... j'avoue qu'il faut un certain feeling, il faut "sentir le code" comme disait +ORC... et une bonne connaissance de l'ASM n'est pas inutile !
Reverse
Engineering - 1
Christal voulait qu'on fasse un KeyGen incrusté dans le proggy, je n'en voit pas vraiment l'utilité vu que le serial ne dépend pas du nom ni de la companie comme vu plus haut. Il faudrait, pour ne pas avoir toujours le même RegNo, créer une fonction pseudo-aléatoire du Nom et de la companie mais qui n'a aucun intérêt à mon humble avis.
Pour les modifications des ressources, j'utilise Borland Resource Workshop v4.5.
Une première méthode :Je lance BRW, j'ouvre pcst.exe et dans la liste des DIALOG, je double-clcik sur 132 ( = 84 hexa ) qui est la dialogbox de l'enregistrement ( Aperçu sur la droite ). Je suis donc en mode Edition. Je click du bouton droit sur le Static "Registration", Style... et je décoche Visible dans Attributes. Je fais de même pour l'Edit correspondant. Si vous ne voulez pas faire plus, vous pouvez rajouter dans le paramètre Caption dans Style... de l'Edit, le RegNo que nous avons trouvé. Ainsi il ne faut même pas injecter le RegNo valide dans l'Edit, ce sera déjà fait !
Vu que c'est un proggy écrit en C++ ( si je ne me trompe pas ?!? ), il utilise une bibliothèque propriétaire : MFC42.DLL. Il n'y a donc pas de BPX sur les Fcts API courantes comme DialogBoxParamA, etc... Il va donc falloir improviser. J'avais plein d'idée pour cette partie, mais je patauge un peu à cause de cette DLL. Bon, le temps que je réfléchisse, je vous laisse avec une autre façon de Patcher ce proggy.
1
Heure après le démarrage de Windows ?!? - Patch
Un minimum de culture générale ( ok, c'est pas vraiment ça, mais ça fait partie des incontournables ), la Fct API qui renvoit le temps écoulé depuis le démarrage de Windows, c'est GetTickCount.
The GetTickCount function
retrieves the number of milliseconds that have elapsed since Windows was
started.
DWORD GetTickCount(VOID)
Parameters
This function has no
parameters.
Return Values
If the function succeeds,
the return value is the number of milliseconds that have elapsed since
Windows was started.
Donc le programme affichera son Nag si 60*60*1000 milliseconde sont passées, soit 3600000 = 36EE80 hexa millisecondes.
*
Reference To: KERNEL32.GetTickCount, Ord:0145h
|
:00403CA5 FF150CB64000
Call dword ptr [0040B60C]
:00403CAB 3D80EE3600
cmp eax, 0036EE80 --> 1 Heure ?
:00403CB0 7643
jbe 00403CF5
--> Si c'est < ou =, on continue normallement. On modifie donc le JBE en un JMP inconditionnel ( EB43 ). Il n'y a plus de limitation !
Reverse
Engineering - 2
Ca y est, j'ai une idée, je vais hooker la fonction GetProcAddress, ainsi, si on demande la fonction CheckRegistrationNumber, je renvois l'adresse d'une fonction qui renvoit toujours 1 dans EAX. C'est plus intéressant que de mettre un
MOV EAX, 00000001
RET
En
:10001110, adresse de CheckRegistrationNumber pour qu'il renvoit toujours
1.
ou en :004049B0,
adresse de la procédure de verification incluse dans pcst.exe
Rem : La modification en ces 2 adresses est cependant fonctionnelle mais inintéressante !
Pour faire cela, je vais devoir modifier l'IAT ( Import Addresse Table ). Pour pas avoir de Page Fault ou de BSOD, il faut authorizer l'écriture sur cette partie du proggy en mémoire. Ensuite il faut dévier l'Entrypoint pour qu'il pointe sur la procédure qui modifiera l'IAT et redonner la main aux programme.
Grâce
au PE Editor de ProcDump, je récupère l'adresse de l'Import
Table : RVA : 0000B000 Size : 0000008C
Donc
l'IAT fait partie de cette section-ci :
Object04: .idata RVA: 0000B000 Offset: 00008200 Size: 00001000 Flags: C0000040
Flage
: C0000040 = IMAGE_SCN_MEM_WRITE --> On peut écrire dessus !
or IMAGE_SCN_MEM_READ
or IMAGE_SCN_CNT_INITIALIZED_DATA
Je ne dois donc rien modifier de ce côtè là. Recherchons l'adresse de GetProcAddress dans l'IAT :
:00404A56 FF1510B64000 Call dword ptr [0040B610]
On peut maintenant insérer notre fonction vers la fin de la section .text, où il y a des 000000000 à la volée :
//********************
Program Entry Point ********
:004070B5 50
push eax
:004070B6 A110B64000
mov eax, dword ptr [0040B610]
:004070BB C70510B64000EC704000
mov dword ptr [0040B610], 004070EC --> Modifie l'IAT
:004070C5 A3D0704000
mov dword ptr [004070D0], eax --> Sauve l'adresse
original
:004070CA 58
pop eax
:004070CB E920F8FFFF
jmp 004068F0 --> Jump à l'EP original
:004070D0 00000000
BYTE 4 DUP(0) --> 4
bytes de réservé pour sauver
l'adresse de GetProcAddress
:004070D4 436865636B526567697374726174696F6E4E756D62657200
-->
"CheckRegistrationNumber",0
:004070EC 00000000
BYTE 4 DUP(0) --> Adresse de la fct qui va gérer
GetProcAddress
Là j'ai déjà modifié l'EntryPoint qui valait 000068F0 par 000070B5 pour qu'il pointe sur notre fonction.
Maintenant je dois écrire la fct qui sera appelée lors d'un CALL GetProcAddress. Cette fct doit vérifier le nom de la fct dont on veut l'adresse et si celle-ci est CheckRegistrationNumber, renvoyer l'adresse d'une fonction qui renvoit toujours 1 dans EAX.
FARPROC GetProcAddress(
HMODULE
hModule, // handle to DLL module
LPCSTR
lpProcName // name of function
);
Donc le nom de la fonction sera en [esp+08], on utilisera l'instruction ASM : REPNE CMPSB qui compare le contenu de DS:[EDI] avec celui de DS:[ESI], ECX fois. Il va donc faloire récupérer la taille du nom de la fct, mettre cette valeur dans ECX, mettre [ESP+08] dans ESI et 004070D4 dans EDI pour ensuite lancer la comparaison :
:000064EC 8B442408
mov eax, [esp+08] --> eax = Adresse du nom de la
fct
:000064F0 57
push edi
:004070F1 56
push esi
:004070F2 51
push ecx
:004070F3 B917000000
mov ecx, 00000017 --> longueur de "Check..."
:004070F8 8BF0
mov esi, eax --> esi = Adresse du nom de la fct
*
Possible StringData Ref from Code Obj ->"CheckRegistrationNumber"
|
:004070FA BFD4704000
mov edi, 004070D4 --> Adresse de "Check..."
:004070FF F2A6
repnz cmpsb --> Compare les 2 strings
:00407101 59
pop ecx
:00407102 5E
pop esi
:00407103 5F
pop edi
:00407104 7406
je 0040710C --> Si c'est les mêmes on saute
:00407106 FF25D0704000
jmp dword ptr [004070D0] --> Sinon on donne la main
à GetProcAddress
* Referenced by a (U)nconditional
or (C)onditional Jump at Address:
|:00407104(C)
|
:0040710C B818714000
mov eax, 00407118 --> Met l'adresse de la fonction
qui renvoit tjrs 1 dans EAX
:00407111 83C40C
add esp, 0000000C --> Rétablit la pile
:00407114 FF6424F4
jmp [esp-0C] --> RET
:00407118 33C0
xor eax, eax --> Renvoit toujours 1 dans EAX
:0040711A 40
inc eax
:0040711B C3
ret
Evidemment, cette méthode ne sert à rien ici, mais mon but était de vous montrer le principe.. j'aurais pu aussi, par exemple, hooker la fct GetTickCount et lui faire renvoyer à tout moment une valeur en dessous des 3600000 millisecondes. Cette méthode est très très éfficace pour les logiciel en démonstration qui ne possède pas de boite d'enregistrement et dont la limitation est un TimeLimit. A ce moment là, on hook la procédure GetSystemTime ou GetLocalTime pour qu'elle renvoit toujours une date comprise dans la période d'essai. Dans l'exemple ci-dessus, j'appelle la fct original que si mon critère est vérifié, mais vous pouvez aussi faire l'inverse, appeller la fct, puis modifier les données renvoyées par celle-ci... A vous de voir la meilleurs solution.
Reverse
Engineering - 3
Bon, ici on va partir sur une toute autre idée, je vais modifier la AboutBox en lui rajoutant un bouton qui affichera une MessageBox avec "Cracked by TeeJi". Maintenant que je sais mon but, il faut que je trouve la procédure de gestion de la DialogBox. Un indice, on peut voir des pages WEB en clickant sur les bouton, donc il y a un appel à la fct WinExec. Reguardons les différentes occurences :
* Possible StringData
Ref from Data Obj ->" http://mikkoaj.hypermart.net"
|
:00402DB6 BF90A14000
mov edi, 0040A190
* Reference To: KERNEL32.WinExec,
Ord:026Fh
|
:00402DEB FF1500B64000
Call dword ptr [0040B600]
* Possible StringData
Ref from Data Obj ->" http://mikkoaj.hypermart.net/register.html"
|
:00402E96 BFC8A14000
mov edi, 0040A1C8
* Reference To: KERNEL32.WinExec,
Ord:026Fh
|
:00402ECB FF1500B64000
Call dword ptr [0040B600]
* Possible StringData
Ref from Data Obj ->" http://mikkoaj.hypermart.net/register.html"
|
:00404C46 BFC8A14000
mov edi, 0040A1C8
* Reference To: KERNEL32.WinExec,
Ord:026Fh
|
:00404C7B FF1500B64000
Call dword ptr [0040B600]
* Possible StringData
Ref from Data Obj ->" http://mikkoaj.hypermart.net/register.html"
|
:00406256 BFC8A14000
mov edi, 0040A1C8
* Reference To: KERNEL32.WinExec,
Ord:026Fh
|
:0040628B FF1500B64000
Call dword ptr [0040B600]
Vu
que le seul endroit dans le programme qui permet d'aller sur http://mikkoaj.hypermart.net
c'est l'AboutBox, on peut en conclure que les adresses :00402DB6, :00402DEB,
:00402E96 et :00402ECB font partie de la procédure de gestion. (
On oublie les autres pour le moment )
Malheureusement,
je m'aperçois qu'il y a en fait 2 fonctions différente (en
voyageant autour des adresses en question)
:00402D5F 90
nop
:00402D60 6AFF
push FFFFFFFF
:00402D62 68AB6C4000
push 00406CAB
...
:00402E2E 5B
pop ebx
:00402E2F 81C410010000
add esp, 00000110
:00402E35 C3
ret
Qui gère le bouton : [Goto Homepage : http://mikkoaj.hypermart.net], et
:00402E3F 90
nop
:00402E40 6AFF
push FFFFFFFF
:00402E42 68CB6C4000
push 00406CCB
...
:00402F0E 5B
pop ebx
:00402F0F 81C410010000
add esp, 00000110
:00402F15 C3
ret
Qui gère le bouton : [Register online, get your registration code !]
En tracant à l'aide de Softice ( par exemple ), on voit que ces 2 fcts sont appelées par MFC42.DLL qui gère en fait la DialogBox. Vu qu'il n'y a pas de Call Reference, je me dis qu'il y a une Adresse Table qui contient les adresses des différentes fonctions. Voici ce que je trouve en recherchant 00402D60 et 00402E40 :
.00408310: 0C 00
00 00-2C 65 40 00-00 00 00 00-00 00 00 00
.00408320: 00
00 00 00-00 00 00 00-00 00 00 00-00 00 00 00
.00408330: 80
4B 40 00-38 83 40 00-11 01 00 00-00 00 00 00
.00408340: 0B
04 00 00-0B 04 00 00-0C 00 00 00-60 2D 40 00
.00408350: 11
01 00 00-00 00 00 00-0C 04 00 00-0C 04 00 00
.00408360: 0C
00 00 00-40 2E 40 00-18 00 00 00-00 00 00
00
.00408370: 00
00 00 00-00 00 00 00-0E 00 00 00-30 2C 40 00
.00408380: 00
00 00 00-00 00 00 00-00 00 00 00-00 00 00 00
.00408390: 00
00 00 00-00 00 00 00-B6 65 40 00-70 24 40 00
Analysons un peu tout cela :
.00408330: 00404B80
00408338 --> [00404B80] = mov eax, [00040B710] ret
--> eax = 8000108A
.00408338: 00000111
00000000 0000040B 0000040B 0000000C 00402D60 -->
WM_COMMAND = 111
.00408350: 00000111
00000000 0000040C 0000040C 0000000C 00402E40
.00408368:
00000018 00000000 00000000 00000000 0000000E 00402C30-->
WM_SHOWWINDOW = 18
Avec BRW, on va récupérer l'ID des deux bouton :
Dialog ID = 100
= 64 hexa
[Goto homepage...
] : ID = 1035 = 40B hexa
[Register online....
] : ID = 1036 = 40C hexa
Quand
on appuie sur un bouton, WMsg = 111 et lParam = wParam = ID.
Donc
le format de la table donne quelquechose de ce genre ci :
???????? MsgTable
WMessage ????????
wParam lParam ???????? WinProc
...
WMessage ????????
wParam lParam ???????? WinProc
00000000 00000000
00000000 00000000 00000000 00000000
Donc MFC42 va créer la DialogBox, puis à chaque fois qu'il recevra un WMsg, il reguardera si il se trouve dans la table, si c'est le cas, il exécutera la WinProc correspondante, sinon DefWindowProc sera exécuter ( je suppose ).
Rem : Je me suis permis d'appeler les procédure exécutée lors d'un Msg une WinProc, je m'excuse si celà choque qqn, mais je n'allais pas en donner un autre, j'espère que vous comprendrai ainsi !
Vu que la table semble commencer en .00408330, j'ai recherché cette valeur et j'ai trouvé une et une seule occurence :
.00402D50: B8 30 83 40-00 C3 90 90-90 90 90 90-90 90 90 90 hmm, ca ressemble à du code :
.00402D50: B830834000
mov eax,000408330 ;" @â0"
.00402D55: C3
retn
Toujours pas de Call ou Jump référence, je recherche 00402D50 :
.00408430: 0040654A
00406544 0040653E 00000000
.00408440: 00406502
00404B60 004011E0 00401200
.00408450: 004011E0
004064FC 00406430 0040642A
.00408460: 00406424
0040641E 00406418 00406412
.00408470: 00402D50
0040640C 00406406 00406400
.00408480: 004063FA
004063F4 004063EE 004063E8
.00408490: 004063E2
004063DC 004063D6 004063D0
.004084A0: 004064F6
004064F0 004063C4 004063BE
...
Le début de la table semble être en 408440, je recherche à nouveau :
* Referenced by a CALL
at Addresses:
|:00403FD1
, :0040458C
|
:00402BF0 56
push esi
:00402BF1 6A00
push 00000000
:00402BF3 8BF1
mov esi, ecx
*
Possible Reference to Dialog: DialogID_0064
|
:00402BF5 6A64
push 00000064
*
Reference To: MFC42.Ordinal:0144, Ord:0144h
|
:00402BF7 E80C390000
Call 00406508
:00402BFC C70640844000
mov dword ptr [esi], 00408440
:00402C02 8BC6
mov eax, esi
:00402C04 5E
pop esi
:00402C05 C3
ret
Plein de choses intéressantes ici. Tout d'abord la référence à la DialogBox 64h = 100 ! C'est notre AboutBox. De plus, cette fct est appelée par 2 Call, ce qui semble logique, soit par le menu, soit par la barre d'outil. On pourrait donc penser que la Table d'Adresses en 00408440 contient toutes les addresses utilisées par la AboutBox.
:00403FD1 E81AECFFFF
call 00402BF0
:00403FD6 8DBECC000000
lea edi, dword ptr [esi+000000CC]
:00403FDC 8D4C240C
lea ecx, dword ptr [esp+0C]
:00403FE0 57
push edi
:00403FE1 C784248000000000000000
mov dword ptr [esp+00000080], 00000000
:00403FEC E8AF0B0000
call 00404BA0
:00403FF1 8D5E44
lea ebx, dword ptr [esi+44]
:00403FF4 8D4C240C
lea ecx, dword ptr [esp+0C]
:00403FF8 53
push ebx
:00403FF9 E892E3FFFF
call 00402390
:00403FFE 8D4C240C
lea ecx, dword ptr [esp+0C]
:00404002 C786C800000000000000
mov dword ptr [esi+000000C8], 00000000
:0040400C C70300000000
mov dword ptr [ebx], 00000000
*
Reference To: MFC42.Ordinal:09D2, Ord:09D2h
|
:00404012 E8A9240000
Call 004064C0
Il semblerait que MFC42.Ordinal:09D2 soit en fait l'équivalent de DialogBoxParamA.
Maintenant que je sais tout cela, je vais attaquer le Reverse proprement dis. Vu qu'il n'y a pas de place pour rajouter la gestion du bouton que nous allons rajouter, il va falloir déplacer la MsgTable ( et peut-être aussi son header ).
.00408330: 00404B80
00408338 --> Header
.00408338: 00000111
00000000 0000040B 0000040B 0000000C 00402D60 -->
MsgTable
.00408350: 00000111
00000000 0000040C 0000040C 0000000C 00402E40 ---
.00408368:
00000018 00000000 00000000 00000000 0000000E 00402C30
---
Cette partie du code se trouve dans la section .rdata :
Object02: .rdata RVA: 00008000 Offset: 00006600 Size: 00001600 Flags: 40000040
On a besoin de 8 Bytes pour le Header ( Si on doit le déplacer ) et de 24*4 = 96 Bytes pour les Msgs. Donc en tout 104 Bytes soit 68 hexa Bytes = 26 DWord.
.00409590: 00 00
00 00-00 00 00 00-00 00 00 00-00 00 00 00 --> Cette
partie de code ne semble
.004095A0: 00
00 00 00-00 00 00 00-00 00 00 00-00 00 00 00 ---
pas utilisée ( vérifiée avec un BPR )
.004095B0: 00
00 00 00-00 00 00 00-00 00 00 00-00 00 00 00
.004095C0: 00
00 00 00-00 00 00 00-00 00 00 00-00 00 00 00
.004095D0: 00
00 00 00-00 00 00 00-00 00 00 00-00 00 00 00
.004095E0: 00
00 00 00-00 00 00 00-00 00 00 00-00 00 00 00
.004095F0: 00
00 00 00-00 00 00 00-00 00 00 00-00 00 00 00
.00409590: 80 4B
40 00-98 95 40 00-11 01 00 00-00 00 00 00
.004095A0: 0B
04 00 00-0B 04 00 00-0C 00 00 00-60 2D 40 00
.004095B0: 11
01 00 00-00 00 00 00-0C 04 00 00-0C 04 00 00
.004095C0: 0C
00 00 00-40 2E 40 00-18 00 00 00-00 00 00 00
.004095D0: 00
00 00 00-00 00 00 00-0E 00 00 00-30 2C 40 00
.004095E0: 11
01 00 00-00 00 00 00-0D 04 00 00-0D 04 00 00 -->
040D hexa = 1037 = ID du nouveau bouton
.004095F0:
0C 00 00 00-?? ?? ?? ??-00 00 00 00-00 00 00 00 -->
?? c'est l'adresse de la WinProc
Je vais rapidement expliquer comment j'ai rajouté le bouton. Dans BRW, j'ouvre pcst.exe, je double-click sur la DIALOG 100. Je suis en mode édition, je click sur l'icône avec un bouton [OK] qui se trouvre dans la boite Tools. Je dessine le bouton à côté des autres bouton. Je double-click sur le bouton créé, dans Caption je met Crack Infos, Control ID je met 1037 ( = 40D hexa ) et je click [OK]. Dans le menu Control, je click sur Check for duplicate ids... je click sur [OK] et il me dit No duplicate control ids found. [Ok], et je sauve le projet. ( Si vous ne comprenez pas, exercez-vous avec Notepad.exe à rajouter, enlever ou modifier les menus, les dialog, etc.. )
Maintenant nous allons modifier en :00408334 l'adresse de la MsgTable par la nouvelle adresse : 00409598. On peut aussi ecraser avec des 00 l'ancienne MsgTable. On lanse PC Screen, About, on click sur un bouton et plus rien ce passe !. C'est pas grave, nous devons aussi déplacer le Header ( ce que j'avais déjà fait ) et modifier l'instruction en :00402D50 par
:00402D50 mov eax,000409590
Il
faut maintenant écrire notre WinProc correspondant à notre
bouton. Je rappelle qu'il doit simplement afficher une MessageBox avec
"Cracked by TeeJi" à l'intérieur.
Vu
que MessageBoxA n'est pas dans L'IAT, il va falloir récupérer
son adresse grâce à la fct GetProcAddress. ( Il ne faut pas
charger préalablement User32.DLL car elle l'est déjà.
Effectivement, il y a des fonction de cette dll qui sont dans l'IAT ).
Recherchons l'adresse de GetProcAddress :
:004026E5 8B2D10B64000 mov ebp, dword ptr [0040B610] --> Adresse de GetProcAddress dans l'IAT
Les paramètre à donner sont :
HMODULE hModule,
// handle to DLL module -->
Puis celui-là !
LPCSTR lpProcName
// name of function --> D'abord pusher
celui-ci
On utilise GetModuleHandleA pour récupérer l'handle de la DLL User32.dll. Cet fct nécessiste un paramètre :
*
Reference To: KERNEL32.GetModuleHandleA, Ord:00FEh
|
:00406A3A FF1504B64000
Call dword ptr [0040B604] --> L'adresse de GetModuleHandleA
dans l'IAT
LPCTSTR lpModuleName // address of module name to return handle for
On va déjà écrire toutes les strings qui nous seront utiles :
00407120: 4D
65 73 73-61 67 65 42-6F 78 41 00-55 73 65 72 MessageBoxA User
00407130: 33
32 00 00-43 72 61 63-6B 65 64 20-62 79 20 54 32 Cracked by
T
00407140: 65
65 4A 69-00 43 72 61-63 6B 20 49-6E 66 6F 73 eeJi Crack Infos
00407150: 00
00 00 00-00 00 00 00-00 00 00 00-00 00 00
00
Maintenant, on écris la WinProc :
:00407151 90
nop
:00407152 90
nop
:00407153 90
nop --> Pour une question d'alignement
:00407154 6660
pusha
*
Possible StringData Ref from Code Obj ->"User32"
|
:00407156 682C714000
push 0040712C
*
Reference To: KERNEL32.GetModuleHandleA, Ord:00FEh
|
:0040715B FF1504B64000
Call dword ptr [0040B604]
*
Possible StringData Ref from Code Obj ->"MessageBoxA"
|
:00407161 6820714000
push 00407120
:00407166 50
push eax --> eax contient l'handle de User32.dll
*
Reference To: KERNEL32.GetProcAddress, Ord:0116h
|
:00407167 FF1510B64000
Call dword ptr [0040B610]
:0040716D 6A00
push 00000000 --> Style de MessageBox
*
Possible StringData Ref from Code Obj ->"Crack Infos"
|
:0040716F 6845714000
push 00407145 --> Title
*
Possible StringData Ref from Code Obj ->"Cracked by TeeJi"
|
:00407174 6834714000
push 00407134 --> Text
:00407179 6A00
push 00000000 --> Handle
:0040717B FFD0
call eax --> call MessageBoxA
:0040717D 6661
popa
:0040717F 33C0
xor eax, eax --> Tout c'est bien passé
:00407181 C3
ret
On peut à présent terminer la MsgTable :
.004095F0: 0C 00 00 00-54 71 40 00-00 00 00 00-00 00 00 00 --> 00407154 c'est l'adresse de la WinProc
Voilà ce qui termine ce 3ème Mini-Reverse. C'est encore totalement inutile, en fait, faut dire que je ne comprends même pas l'utilité de ce programme alors je vois pas pourquoi j'essayerais de l'améliorer d'une manière ou d'une autre. Cependant, si vous avez bien compris toutes les étapes de ce cours, vous savez à présent modifier n'importe quelle DialogBox d'un programme écris en C++ ( j'en suis toujours pas sûre que c'est du C++ mais bon, ça utilise MFC42.DLL en tout cas. )
Greetz
Amicalement,
TeeJi