D'apres PEiD, le programme est packé
avec FSG:
L'option "Trace real entry blockwise" de OllyDbg permet de trouver
assez vite l'OEP...
Ensuite dump et reconstruction de l'IAT...
seg001:00413831 loc_0_413831:
seg001:00413831
dec byte ptr [esi]
seg001:00413833
jz near ptr dword_0_402D71
; OEP
seg001:00413839
push esi
seg001:0041383A
seg001:0041383A loc_0_41383A:
seg001:0041383A
push ebp
seg001:0041383B
call dword ptr [ebx+4]
seg001:0041383E
stosd
seg001:0041383F
jmp short loc_0_413821
seg001:0041383F start
endp
1-Entée
Tenter des bpx sur GetDlgItemText ou GetWindowTextA ne mene
a rien ( il utilse WM_GETTEXT)... mais une recherche de la
chaine "Invalid user data." nous conduit:
seg000:00403991
mov ebx, offset aInvalidUserData
seg000:00403996
mov esi, offset Serial
seg000:0040399B
push esi
; lParam
seg000:0040399C
push 41h
; wParam
seg000:0040399E
push 0Dh
; Msg
seg000:004039A0
push 3EAh
; nIDDlgItem
seg000:004039A5
push [ebp+hDlg] ; hDlg
seg000:004039A8
call SendDlgItemMessageA
seg000:004039AD
cmp eax, 40h
seg000:004039B0
jnz short End
seg000:004039B2
mov edi, offset Name
seg000:004039B7
push edi
; lParam
seg000:004039B8
push 41h
; wParam
seg000:004039BA
push 0Dh
; Msg
seg000:004039BC
push 3E9h
; nIDDlgItem
seg000:004039C1
push [ebp+hDlg] ; hDlg
seg000:004039C4
call SendDlgItemMessageA
seg000:004039C9
cmp eax, 5
seg000:004039CC
jl short End
Donc, la longueur du Serial = 40h et celle du Nom doit etre superieur
à 4
Ensuite le Nom est utilisé pour creer une clef de 256 bits (
pour simplifier je l'appelle NameKey ).
seg000:004039CE
push edi
seg000:004039CF
push eax
; Name length
seg000:004039D0
push edi
; Name
seg000:004039D1
call GenSubKey
... et les lettres composant le serial sont remplacé par leur
valeur numerique, ie '0' -> 0, '1' ->1, ..., 'F' -> F
( le serial doit etre composé uniquement de [0-9] et [A-F]
)
seg000:004039D6
push esi
seg000:004039D7
push esi
; serial
seg000:004039D8
call AsciiToHex
seg000:004039DD
jb End
2- Serial
Puis NameKey et une constante ( MagicKey ) sont utilisés pour
modifier le Serial et creer ModifiedSerial:
seg000:004039E2 Loop:
seg000:004039E2
push esi
; NameKey
seg000:004039E3
push offset MagicKey ; a constant
seg000:004039E8
push edi
; Serial
seg000:004039E9
call GenereKey
seg000:004039EE
add esi, 10h
seg000:004039F1
add edi, 10h
seg000:004039F4
dec ecx
seg000:004039F5
jnz short Loop
seg000:00403A45 GenereKey proc
near
seg000:00403A45
seg000:00403A45 Name
= dword ptr 8
seg000:00403A45 MagicKey
= dword ptr 0Ch
seg000:00403A45 Serial
= dword ptr 10h
seg000:00403A45
seg000:00403A45
push ebp
seg000:00403A46
mov ebp, esp
seg000:00403A48
pusha
seg000:00403A49
mov esi, [ebp+Serial]
seg000:00403A4C
mov edi, [ebp+Name]
seg000:00403A4F
xor eax, eax
seg000:00403A51
mov ecx, 80h
seg000:00403A56
seg000:00403A56 LoopGenKey:
seg000:00403A56
shl dword ptr [edi+0Ch], 1
seg000:00403A59
rcl dword ptr [edi+8], 1
seg000:00403A5C
rcl dword ptr [edi+4], 1
seg000:00403A5F
rcl dword ptr [edi], 1
seg000:00403A61
setb al
seg000:00403A64
or [edi+0Ch], eax
seg000:00403A67
push esi
seg000:00403A68
push [ebp+MagicKey]
seg000:00403A6B
call [off_0_403A79 + eax*4]
seg000:00403A72
loop LoopGenKey
seg000:00403A74
popa
seg000:00403A75
leave
seg000:00403A76
retn 0Ch
seg000:00403A76 GenereKey endp
seg000:00403A79 off_0_403A79 dd offset Cas1
seg000:00403A7D
dd offset Cas2
Si le bit se situant le plus a gauche de NameKey est 0 GenereKey appelle
Cas1 sinon il appelle Cas2...
seg000:00403B87 Cas1
proc near
seg000:00403B87
seg000:00403B87 MagicKey
= dword ptr 8
seg000:00403B87 Serial
= dword ptr 0Ch
seg000:00403B87
seg000:00403B87
push ebp
seg000:00403B88
mov ebp, esp
seg000:00403B8A
pusha
seg000:00403B8B
xor ecx, ecx
seg000:00403B8D
push ecx
seg000:00403B8E
push ecx
seg000:00403B8F
push ecx
seg000:00403B90
push ecx
seg000:00403B91
mov esi, [ebp+MagicKey]
seg000:00403B94
mov edi, [ebp+Serial]
seg000:00403B97
mov edx, 80h
seg000:00403B9C
seg000:00403B9C LoopCase1:
seg000:00403B9C
shr dword ptr [edi], 1
seg000:00403B9E
rcr dword ptr [edi+4], 1
seg000:00403BA1
rcr dword ptr [edi+8], 1
seg000:00403BA4
rcr dword ptr [edi+0Ch], 1
seg000:00403BA7
jnb short loc_0_403BB7
seg000:00403BA9
seg000:00403BA9 Loop64_C1:
seg000:00403BA9
mov eax, [ecx+esi]
seg000:00403BAC
xor [esp+ecx], eax
seg000:00403BAF
add ecx, 4
seg000:00403BB2
and ecx, 0Fh
seg000:00403BB5
jnz short Loop64_C1
seg000:00403BB7
seg000:00403BB7 loc_0_403BB7:
seg000:00403BB7
add esi, 10h
seg000:00403BBA
dec edx
seg000:00403BBB
jnz short LoopCase1
seg000:00403BBD
cld
seg000:00403BBE
pop eax
seg000:00403BBF
stosd
seg000:00403BC0
pop eax
seg000:00403BC1
stosd
seg000:00403BC2
pop eax
seg000:00403BC3
stosd
seg000:00403BC4
pop eax
seg000:00403BC5
stosd
seg000:00403BC6
popa
seg000:00403BC7
leave
seg000:00403BC8
retn 8
seg000:00403BC8 Cas1
endp
seg000:00403BC8
Si on veut pouvoir trouver un Serial valide, il faut qu'on soit capable
de calculer la valeur du Serial a partir de la valeur de ModifiedSerial.
On remarque que si "Y1 = Cas1(Serial1)" et "Y2 = Cas1(Serial2)"
alors "Y2 xor Y1 = Cas1(Serial2 xor Serial1)"
Or toutes les valeurs peuvent etre considerées comme une suite
de bit BnBn-1...B1B0, or :
BnBn-1...B1B0 = 000...001*B0 xor 000...010*B1 xor ...
xor 010...000*B(n-1) xor 100...000*Bn
donc Cas1(BnBn-1...B1B0 ) = Cas1(000...001)*B0 xor Cas1(000...010)*B1
xor ... xor Cas1(010...000)*B(n-1) xor Cas1(100...000)*Bn
Donc AnAn-1...A1A0 = Cas1(BnBn-1...B1B0 ) = BnBn-1...B1B0
*M avec M la matrice:
|
B0 |
B1 |
... |
Bn-1 |
Bn |
|
|
|
|
\/ |
\/ |
\/ |
\/ |
\/ |
|
|
|
( |
Cas1(B0 )n |
Cas1(B1 )n |
... |
Cas1(Bn-1 )n |
Cas1(Bn )n |
) |
> |
An |
( |
Cas1(B0 )n-1 |
Cas1(B1 )n-1 |
... |
Cas1(Bn-1 )n-1 |
Cas1(Bn )n-1 |
) |
> |
An-1 |
( |
... |
... |
... |
... |
... |
) |
> |
... |
( |
Cas1(B0 )1 |
Cas1(B1 )1 |
... |
Cas1(Bn-1 )1 |
Cas1(Bn )1 |
) |
> |
A1 |
( |
Cas1(B0 )0 |
Cas1(B1 )0 |
... |
Cas1(Bn-1 )0 |
Cas1(Bn )0 |
) |
> |
A0 |
Un effectuant des xor entre les differentes colonnes on peut facilement
s'arranger pour mettre M sous la forme d'une matrice triangulaire superieur
:
|
B? xor ... xor B? |
B? xor ... xor B? |
... |
B? xor ... xor B? |
B? xor ... xor B? |
|
|
|
|
\/ |
\/ |
\/ |
\/ |
\/ |
|
|
|
( |
1 |
Cas1(B1 )n |
... |
Cas1(Bn-1 )n |
Cas1(Bn )n |
) |
> |
An |
( |
0 |
1 |
... |
Cas1(Bn-1 )n-1 |
Cas1(Bn )n-1 |
) |
> |
An-1 |
( |
... |
... |
... |
... |
... |
) |
> |
... |
( |
0 |
0 |
... |
1 |
Cas1(Bn )1 |
) |
> |
A1 |
( |
0 |
0 |
... |
0 |
1 |
) |
> |
A0 |
Une fois sous cette forme il est assez simple de detreminer les colonnes
sur les quelles effectuer des xor pour que:
AnAn-1...A1A0 = ModifiedSerial...
|
|
|
... |
|
B? xor ... xor B? |
|
|
|
|
\/ |
\/ |
\/ |
\/ |
\/ |
|
|
|
( |
1 |
Cas1(B1 )n |
... |
Cas1(Bn-1 )n |
(ModifiedSerial)n |
) |
> |
An |
( |
0 |
1 |
... |
Cas1(Bn-1 )n-1 |
(ModifiedSerial)n-1 |
) |
> |
An-1 |
( |
... |
... |
... |
... |
... |
) |
> |
... |
( |
0 |
0 |
... |
1 |
(ModifiedSerial)1 |
) |
> |
A1 |
( |
0 |
0 |
... |
0 |
(ModifiedSerial)0 |
) |
> |
A0 |
Donc Cas1(B? xor ... xor B?) = ModifiedSerial... autrement dit B? xor
... xor B? = Serial
seg000:00403BCB Cas2
proc near
seg000:00403BCB
seg000:00403BCB var_2C
= dword ptr -2Ch
seg000:00403BCB var_28
= dword ptr -28h
seg000:00403BCB var_24
= dword ptr -24h
seg000:00403BCB MagicKey
= dword ptr 8
seg000:00403BCB Serial
= dword ptr 0Ch
seg000:00403BCB
seg000:00403BCB
push ebp
seg000:00403BCC
mov ebp, esp
seg000:00403BCE
pusha
seg000:00403BCF
xor ecx, ecx
seg000:00403BD1
push ecx
seg000:00403BD2
push ecx
seg000:00403BD3
push ecx
seg000:00403BD4
push ecx
seg000:00403BD5
mov esi, [ebp+MagicKey]
seg000:00403BD8
mov edi, [ebp+Serial]
seg000:00403BDB
cld
seg000:00403BDC
mov edx, 80h
seg000:00403BE1
seg000:00403BE1 LoopCase2:
seg000:00403BE1
xor ebx, ebx
seg000:00403BE3
seg000:00403BE3 Loop64_C2:
seg000:00403BE3
lodsd
seg000:00403BE4
and eax, [ecx+edi]
seg000:00403BE7
call NumEax
seg000:00403BEC
add ecx, 4
seg000:00403BEF
and ecx, 0Fh
seg000:00403BF2
jnz short Loop64_C2
seg000:00403BF4
shr ebx, 1
seg000:00403BF6
rcl [esp+30h+var_24], 1
seg000:00403BFA
rcl [esp+30h+var_28], 1
seg000:00403BFE
rcl [esp+30h+var_2C], 1
seg000:00403C02
rcl dword ptr [esp], 1
seg000:00403C05
dec edx
seg000:00403C06
jnz short LoopCase2
seg000:00403C08
pop eax
seg000:00403C09
stosd
seg000:00403C0A
pop eax
seg000:00403C0B
stosd
seg000:00403C0C
pop eax
seg000:00403C0D
stosd
seg000:00403C0E
pop eax
seg000:00403C0F
stosd
seg000:00403C10
popa
seg000:00403C11
leave
seg000:00403C12
retn 8
seg000:00403C12 Cas2
endp
Ici aussi,il suffit d'utiliser la matrice N :
|
B0 |
B1 |
... |
Bn-1 |
Bn |
|
|
|
|
\/ |
\/ |
\/ |
\/ |
\/ |
|
|
|
( |
Cas2(B0 )n |
Cas2(B1 )n |
... |
Cas2(Bn-1 )n |
Cas2(Bn )n |
) |
> |
An |
( |
Cas2(B0 )n-1 |
Cas2(B1 )n-1 |
... |
Cas2(Bn-1 )n-1 |
Cas2(Bn )n-1 |
) |
> |
An-1 |
( |
... |
... |
... |
... |
... |
) |
> |
... |
( |
Cas2(B0 )1 |
Cas2(B1 )1 |
... |
Cas2(Bn-1 )1 |
Cas2(Bn )1 |
) |
> |
A1 |
( |
Cas2(B0 )0 |
Cas2(B1 )0 |
... |
Cas2(Bn-1 )0 |
Cas2(Bn )0 |
) |
> |
A0 |
... pour determiner le Serial a partir de ModifiedSerial:
Donc pour recupere le Serial a partir ModifiedSerial il faut utiliser
la matrice M si le bit le plus a droite de NameKey est a 0, ou la matrice
N si il est a 1.
3 - Verification
Ensuite le 128 premiers bits de ModifiedSerial sont verifiés:
seg000:004039FD
push esi
; ModifiedSerial
seg000:004039FE
push edi
; NameKey
seg000:004039FF
call vTEA
seg000:00403A04
jb short Fin
seg000:00403A81 vTEA
proc near
seg000:00403A81
seg000:00403A81 TEA1_A
= dword ptr -28h
seg000:00403A81 TEA1_B
= dword ptr -24h
seg000:00403A81 TEA2_A
= dword ptr -20h
seg000:00403A81 TEA2_B
= dword ptr -1Ch
seg000:00403A81 var_18
= byte ptr -18h
seg000:00403A81 arg_0
= dword ptr 8
seg000:00403A81 arg_4
= dword ptr 0Ch
seg000:00403A81
seg000:00403A81
push ebp
seg000:00403A82
mov ebp, esp
seg000:00403A84
pusha
seg000:00403A85
mov esi, [ebp+arg_4]
seg000:00403A88
mov edi, [ebp+arg_0]
seg000:00403A8B
mov ecx, 2
seg000:00403A90
seg000:00403A90 LoopTEA_Encode:
seg000:00403A90
sub esp, 8
seg000:00403A93
push esp
; Buffer
seg000:00403A94
push edi
; Key
seg000:00403A95
push esi
; Data
seg000:00403A96
call vTEA_Encode
seg000:00403A9B
xchg esi, edi
seg000:00403A9D
loop LoopTEA_Encode
seg000:00403A9F
mov eax, [esp+28h+TEA1_A]
seg000:00403AA2
xor eax, [esp+28h+TEA2_A]
seg000:00403AA6
jnz short Invalid
seg000:00403AA8
mov eax, [esp+28h+TEA1_B]
seg000:00403AAC
sub eax, [esp+28h+TEA2_B]
seg000:00403AB0
jnz short Invalid
seg000:00403AB2
mov ecx, 4
seg000:00403AB7
repe cmpsd
seg000:00403AB9
jecxz short Invalid
seg000:00403ABB
clc
seg000:00403ABC
seg000:00403ABC loc_0_403ABC:
seg000:00403ABC
lea esp, [esp+10h]
seg000:00403AC0
popa
seg000:00403AC1
leave
seg000:00403AC2
retn 8
Donc pour que la premiers partie du ModifiedSerial soit considerée
comme valide il faut que vTEA_Encode(ModifiedSerial_P1,NameKey)
== vTEA_Encode(NameKey,ModifiedSerial_P1)
ModifiedSeria_P1l != NameKey
Analysons le fonctionnement de vTEA_Encode:
seg000:00403B17 vTEA_Encode proc near
seg000:00403B17
seg000:00403B17 InternalKey4 = dword ptr -34h
seg000:00403B17 InternalKey2 = dword ptr -30h
seg000:00403B17 InternalKey1 = dword ptr -2Ch
seg000:00403B17 InternalKey0 = dword ptr -28h
seg000:00403B17 ptrData
= dword ptr 8
seg000:00403B17 ptrKey
= dword ptr 0Ch
seg000:00403B17 Buffer
= dword ptr 10h
seg000:00403B17
seg000:00403B17
push ebp
seg000:00403B18
mov ebp, esp
seg000:00403B1A
pusha
seg000:00403B1B
cld
seg000:00403B1C
mov esi, [ebp+ptrKey]
seg000:00403B1F
mov ebx, [ebp+ptrData]
seg000:00403B22
push [ebp+Buffer]
seg000:00403B25
lodsd
seg000:00403B26
push eax
seg000:00403B27
lodsd
seg000:00403B28
push eax
seg000:00403B29
lodsd
seg000:00403B2A
push eax
seg000:00403B2B
lodsd
seg000:00403B2C
push eax
seg000:00403B2D
xor edx, edx
seg000:00403B2F
mov esi, [ebx]
seg000:00403B31
mov edi, [ebx+4]
seg000:00403B34
mov ebp, 20h
seg000:00403B39
seg000:00403B39 LoopTEA:
seg000:00403B39
add edx, 9E3779B9h
seg000:00403B3F
mov eax, edi
seg000:00403B41
mov ecx, eax
seg000:00403B43
mov ebx, edi
seg000:00403B45
rol eax, 4
seg000:00403B48
ror ebx, 5
seg000:00403B4B
add eax, [esp+34h+InternalKey0]
seg000:00403B4F
add ebx, [esp+34h+InternalKey1]
seg000:00403B53
add ecx, edx
seg000:00403B55
xor ecx, eax
seg000:00403B57
xor ecx, ebx
seg000:00403B59
add esi, ecx
seg000:00403B5B
mov eax, esi
seg000:00403B5D
mov ebx, esi
seg000:00403B5F
mov ecx, esi
seg000:00403B61
shl eax, 4
seg000:00403B64
shr ebx, 5
seg000:00403B67
add eax, [esp+34h+InternalKey2]
seg000:00403B6B
add ebx, [esp+34h+InternalKey4]
seg000:00403B6E
add ecx, edx
seg000:00403B70
xor ecx, eax
seg000:00403B72
xor ecx, ebx
seg000:00403B74
add edi, ecx
seg000:00403B76
dec ebp
seg000:00403B77
jnz short LoopTEA
seg000:00403B79
add esp, 10h
seg000:00403B7C
pop ebx
seg000:00403B7D
mov [ebx], esi
seg000:00403B7F
mov [ebx+4], edi
seg000:00403B82
popa
seg000:00403B83
leave
seg000:00403B84
retn 0Ch
seg000:00403B84 vTEA_Encode endp
Donc vTEA_Encode calcule:
void code(long* v, long* k) {
unsigned long y=v[0],z=v[1], sum=0, /* set up */
delta=0x9e3779b9, n=32 ;
/* a key schedule constant */
while (n-->0) {
/* basic cycle start */
sum += delta ;
y += (ROL4(z)+k[0]) xor ( y+sum)
xor ( ROL5(z)+k[1]) ;
z += (SHL4(y)+k[2]) xor ( y+sum)
xor ( SHR5(y)+k[3]) ;
}
v[0]=y ; v[1]=z ; } |
Donc si on remplace k[2] et k[3] par ( k[2] xor 2^31 ) et ( k[3]
xor 2^31 ) le resultat sera le meme bien que les clefs soient differentes
( si vous en doutez, faites une table de verité pour vous en convaincre
;))
Le fait que le TEA ( cette routine est tres proche de celle du TEA)
permette l'utilisation de clefs "equivalentes" est decrit plus precisement
dans "Key-Schedule Cryptanalysis of IDEA, G-DES, GOST, SAFER, and
Triple-DES"
Donc [ModifiedSerial ] == [ NameKey ],
[ModifiedSerial +4
] == [ NameKey + 4 ],
[ModifiedSerial +8
] == [ NameKey + 8] xor 2^31,
[ModifiedSerial +
12 ] == [ NameKey +12] xor 2^31
Puis les 128 derniers bits du ModifiedSerial sont verifiés:
seg000:00403A0C
push esi
; Serial p2
seg000:00403A0D
push edi
; Name
seg000:00403A0E
push esi
; Serial p2
seg000:00403A0F
call CheckSerialP2
seg000:00403A14
dec dword ptr [esi+0Ch]
seg000:00403A17
xor ecx, ecx
seg000:00403A19
seg000:00403A19 CheckSerial:
seg000:00403A19
mov eax, [ecx+esi]
seg000:00403A1C
test eax, eax
seg000:00403A1E
jnz short Fin
seg000:00403A20
add ecx, 4
seg000:00403A23
and ecx, 0Fh
seg000:00403A26
jnz short CheckSerial
Donc le resultat de CheckSerialP2 doit etre egal a 1...
seg000:00403CAC CheckSerialP2 proc near
seg000:00403CAC
seg000:00403CAC Serial_
= dword ptr 8
seg000:00403CAC Name_P2
= dword ptr 0Ch
seg000:00403CAC Serial
= dword ptr 10h
seg000:00403CAC
seg000:00403CAC
push ebp
seg000:00403CAD
mov ebp, esp
seg000:00403CAF
pusha
seg000:00403CB0
sub esp, 20h
seg000:00403CB3
mov ecx, 4
seg000:00403CB8
mov edi, esp
seg000:00403CBA
mov esi, [ebp+Serial_]
seg000:00403CBD
cld
seg000:00403CBE
repe movsd
seg000:00403CC0
mov ecx, 4
seg000:00403CC5
mov ebx, edi
seg000:00403CC7
mov esi, [ebp+Name_P2]
seg000:00403CCA
repe movsd
seg000:00403CCC
xor eax, eax
seg000:00403CCE
mov ecx, 4
seg000:00403CD3
mov edi, [ebp+Serial]
seg000:00403CD6
repe stosd
seg000:00403CD8
sub edi, 10h
seg000:00403CDB
mov ecx, 80h
seg000:00403CE0
clc
seg000:00403CE1
seg000:00403CE1 Loop:
seg000:00403CE1
mov eax, 3
seg000:00403CE6
seg000:00403CE6 _Loop1:
seg000:00403CE6
rcl dword ptr [edi+eax*4], 1
seg000:00403CE9
dec eax
seg000:00403CEA
jns short _Loop1
seg000:00403CEC
mov eax, 3
seg000:00403CF1
jnb short _Loop2
seg000:00403CF3
xor dword ptr [edi+0Ch], 87h
seg000:00403CFA
seg000:00403CFA _Loop2:
seg000:00403CFA
seg000:00403CFA
rcl dword ptr [esp+eax*4], 1
seg000:00403CFD
dec eax
seg000:00403CFE
jns short _Loop2
seg000:00403D00
jnb short Next
seg000:00403D02
mov eax, 3
seg000:00403D07
seg000:00403D07 _Loop3:
seg000:00403D07
mov edx, [ebx+eax*4]
seg000:00403D0A
xor [edi+eax*4], edx
seg000:00403D0D
dec eax
seg000:00403D0E
jns short _Loop3
seg000:00403D10
seg000:00403D10 Next:
seg000:00403D10
loop Loop
seg000:00403D12
add esp, 20h
seg000:00403D15
popa
seg000:00403D16
leave
seg000:00403D17
retn 0Ch
seg000:00403D17 CheckSerialP2 endp
Ici aussi l'utilisation d'une matrice L :
|
B0 |
B1 |
... |
Bn-1 |
Bn |
|
|
|
|
\/ |
\/ |
\/ |
\/ |
\/ |
|
|
|
( |
CheckSerialP2(B0 )n |
CheckSerialP2(B1 )n |
... |
CheckSerialP2(Bn-1 )n |
CheckSerialP2(Bn )n |
) |
> |
An |
( |
CheckSerialP2(B0 )n-1 |
CheckSerialP2B1 )n-1 |
... |
CheckSerialP2(Bn-1 )n-1 |
CheckSerialP2(Bn )n-1 |
) |
> |
An-1 |
( |
... |
... |
... |
... |
... |
) |
> |
... |
( |
CheckSerialP2(B0 )1 |
CheckSerialP2(B1 )1 |
... |
CheckSerialP2(Bn-1 )1 |
CheckSerialP2(Bn )1 |
) |
> |
A1 |
( |
CheckSerialP2(B0 )0 |
CheckSerialP2(B1 )0 |
... |
CheckSerialP2(Bn-1 )0 |
CheckSerialP2(Bn )0 |
) |
> |
A0 |
... permet de determiner quelle valeur de ModifiedSerial_P2 verifie
CheckSerialP2(ModifiedSerial_P2) == 1
Une fois ModifiedSerial_P1 et ModifiedSerial_P2 obtenus il suffit d'appliquer
l'algo, precedement decrit, qui permet de calculer la valeur du Serial
a partir de celle de ModifiedSerial
Name |
Amenesia |
Serial |
93180C843E7004FA4F749AB6E82A9E883A4C2C6FBBDF8921927E9ACBC6C885E1 |
Si vous trouvez une erreur ou avez une question : tchernozium@yahoo.fr
|
|