- Dùng PEiD kiểm tra biết chương trình không bị PACK và biết chương trìnhđược viết
bằng Borland Delphi 6.0 - 7.0
- Chạy thử chương trình với User và Fake Serial ta nhận được "NAG" . Tuy nhiên, ta
không thể tìm thấy chuỗi này trong quá trình tìm kiếm . Nhưng ta nhận thấy chương trình
có khoảng thời gian dừng trước khi xuất hiện NAG . Ta truy đến hàm kernel32.Sleep . Ta
tìm được hàm này tại địa chỉ :
004937D3 |. E8 0CBBF7FF |CALL <JMP.&kernel32.Sleep> ; \Sleep
- Dò ngược lên trên và đặt BreakPoint tại lệnh CALL đầu tiên của FUNCTIONnày :
004937C7 |. E8 F44FFEFF CALL DUMeter.004787C0 ; <== Set
BreakPoint here
II – Cracking :
- Load chương trình lên, chạy chương trình với User và Fake Serial, chương trình dừng
lại tại điểm đặt BP . Trace xuống chút :
00493848 |. E8 1764FCFF CALL DUMeter.00459C64 ; <==
LenS
0049384D |. 837D E4 00 CMP [LOCAL.7],0 ; <==
Must be input
00493851 |. 74 14 JE SHORT DUMeter.00493867
00493853 |. 8D55 E0 LEA EDX,[LOCAL.8]
00493856 |. 8B83 74030000 MOV EAX,DWORD PTR DS:[EBX+374]
0049385C |. E8 0364FCFF CALL DUMeter.00459C64 ; <==
LenU
00493861 |. 837D E0 00 CMP [LOCAL.8],0 ; <==
Must be input
00493865 |. 75 33 JNZ SHORT DUMeter.0049389A
- Trace tiếp ta đến :
0049399D |. E8 9AD1FFFF CALL DUMeter.00490B3C ; <== Trace
Into
=== Trace Into ===
00490B78 |. FF16 CALL DWORD PTR DS:[ESI] ; <== Trace Into
=== Trace Into ===
0049DD11 . 8BF0 MOV ESI,EAX ; <==
U
0049DD13 . 8BD6 MOV EDX,ESI ; <==
U
0049DD15 . B8 D0DD4900 MOV
EAX,DUMeter.0049DDD0 ; ASCII "D3"
0049DD1A . 59 POP ECX ; <==
Fake Serial
0049DD1B . E8 16FEFEFF CALL DUMeter.0048DB36 ; <==
Encrypt & Compare
=== Trace Into ===
=== Trace Into ===
- Tiếp tục Trace Into ta đến quá trình mã hoá chính :
0048DB6A |. E8 2DFDFFFF CALL DUMeter.0048D89C ; <== LenS
0048DB6F |. 83F8 18 CMP EAX,18 ; <== LenS
must be 24 charts
0048DB72 |. 74 07 JE SHORT DUMeter.0048DB7B ; <==
Continue check
0048DB74 |. 33C0 XOR EAX,EAX
0048DB76 |. E9 C5000000 JMP DUMeter.0048DC40
0048DB7B |> 803E 61 CMP BYTE PTR DS:[ESI],61
0048DB7E |. 7C 08 JL SHORT DUMeter.0048DB88
0048DB80 |. 803E 7A CMP BYTE PTR DS:[ESI],7A
0048DB83 |. 7F 03 JG SHORT DUMeter.0048DB88
0048DB85 |. 8006 E0 ADD BYTE PTR DS:[ESI],0E0
0048DB88 |> 803E 20 CMP BYTE PTR DS:[ESI],20
0048DB8B |. 74 15 JE SHORT DUMeter.0048DBA2
0048DB8D |. 8A16 MOV DL,BYTE PTR DS:[ESI] ; <== U[0]
0048DB8F |. 3A13 CMP DL,BYTE PTR DS:[EBX] ; <== if (
U[0] == "D" )
0048DB91 |. 75 08 JNZ SHORT DUMeter.0048DB9B ; <==
Continue check
0048DB93 |. 8A4E 01 MOV CL,BYTE PTR DS:[ESI+1] ; <== U[1]
0048DB96 |. 3A4B 01 CMP CL,BYTE PTR DS:[EBX+1] ; <== if (
U[1] == "3" )
0048DB99 |. 7E 07 JLE SHORT DUMeter.0048DBA2 ; <==
Continue check
- Trace tiếp ta đến quá trình phân cách chuỗi Serial nhập thành 4 đoạn .
Đoạn thứ nhất gồm 3 ký tự U[3][4][5]
Đoạ
n thứ hai gồm 8 ký tự U[7][8][9][10][11][12][13][14]
Đoạn thứ 3 cũng gồm 8 ký tự U[16][17][18][19][20][21][22][23]
Đoạn cuối cùng gồm 16 ký
tự U[0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15]
0048DBA2 |> \8D53 03 LEA EDX,DWORD PTR DS:[EBX+3]
0048DBA5 |. 8D45 F4 LEA EAX,[LOCAL.3]
0048DBA8 |. B9 03000000 MOV ECX,3 ; <== 3
charts
0048DBAD |. E8 14FDFFFF CALL DUMeter.0048D8C6 ; <== SecI
0048DBB2 |. C645 F7 00 MOV BYTE PTR SS:[EBP-9],0
0048DBB6 |. 8D53 07 LEA EDX,DWORD PTR DS:[EBX+7]
0048DBB9 |. 8D45 E8 LEA EAX,[LOCAL.6]
0048DBBC |. B9 08000000 MOV ECX,8 ; <== 8
charts
0048DBC1 |. E8 00FDFFFF CALL DUMeter.0048D8C6 ; <== SecII
0048DBC6 |. C645 F0 00 MOV BYTE PTR SS:[EBP-10],0
0048DBCA |. 8D53 10 LEA EDX,DWORD PTR DS:[EBX+10]
0048DBCD |. 8D45 DC LEA EAX,[LOCAL.9]
0048DBD0 |. B9 08000000 MOV ECX,8 ; <== 8
charts
0048DBD5 |. E8 ECFCFFFF CALL DUMeter.0048D8C6 ; <== SecIII
0048DBDA |. C645 E4 00 MOV BYTE PTR SS:[EBP-1C],0
0048DBDE |. 8D45 C8 LEA EAX,[LOCAL.14]
0048DBE1 |. B9 10000000 MOV ECX,10 ; <== 16
charts
0048DBE6 |. 8BD3 MOV EDX,EBX
0048DBE8 |. E8 D9FCFFFF CALL DUMeter.0048D8C6 ; <== SecIV
- Đầu tiên chương trình sẽ mã hoá chuỗi U nhập . Tuy nhiên, trước khi tiến hành quá
trình mã hoá chương trình sẽ chuyển đổi các ký tự của chuỗi U nhập sang dạng
UpperCase và loại bỏ các ký tự đặc biệt :
0048DBFF |. E8 81FDFFFF CALL DUMeter.0048D985 ; <==
Encrypt U : ValueU
=== Encrypt U ===
0048D98C |> /C1E2 04 /SHL EDX,4 ; <== ValueU =
ValueU * 0x10
0048D98F |. |0FBE08 |MOVSX ECX,BYTE PTR DS:[EAX] ; <== U[i]
0048D992 |. |03D1 |ADD EDX,ECX ; <== ValueU =
ValueU + U[i]
0048D994 |. |8BCA |MOV ECX,EDX ; <== Temp =
ValueU
0048D996 |. |81E1 000000F0 |AND ECX,F0000000 ; <== Temp = Temp
and 0xF0000000
0048D99C |. |85C9 |TEST ECX,ECX ; <== if ( ECX !=
0x0 )
0048D99E |. |74 0B |JE SHORT DUMeter.0048D9AB ; <== then
0048D9A0 |. |C1E9 18 |SHR ECX,18 ; <== Temp = Temp
/ 0x1000000
0048D9A3 |. |33D1 |XOR EDX,ECX ; <== Value = Value
xor Temp
0048D9A5 |. |81E2 FFFFFF0F |AND EDX,0FFFFFFF ; <== ValueU =
ValueU & 0xFFFFFFF
0048D9AB |> |40 |INC EAX ; <== i++
0048D9AC |> |8038 00 CMP BYTE PTR DS:[EAX],0 ; <== while ( i <
LenU )
0048D9AF |.^\75 DB \JNZ SHORT DUMeter.0048D98C ; <== continue
Loop
=== Encrypt U ===
- Kế đó là mã hoá SecI . Đoạn mã hoá này cho ta biết được rằng các ký tự của SecI phải
là một trong các ký tự của chuỗi mặc định
"ABCDEFGHIJKLMNOPQRSTUVWXYZ987654" :
0048DC06 |. 8D45 F4 LEA EAX,[LOCAL.3] ; <== SecI
0048DC09 |. E8 01FEFFFF CALL DUMeter.0048DA0F ; <==
Encrypt SecI : ValueI
=== Encrypt SecI ===
0048DA19 |. E8 7EFEFFFF CALL DUMeter.0048D89C ; <==
LenSecI
0048DA1E |. 83F8 03 CMP EAX,3 ; <== Must
be 3 charts
0048DA21 |. 73 04 JNB SHORT DUMeter.0048DA27
0048DA23 |. 33C0 XOR EAX,EAX
0048DA25 |. EB 39 JMP SHORT DUMeter.0048DA60
0048DA27 |> BA 0C174F00 MOV
EDX,DUMeter.004F170C ; ASCII
"ABCDEFGHIJKLMNOPQRSTUVWXYZ987654"
0048DA2C |. 8A03 MOV AL,BYTE PTR DS:[EBX] ; <==
SecI[0]
0048DA2E |. E8 82FFFFFF CALL DUMeter.0048D9B5 ; <==
Location in DefaultString
0048DA33 |. 8BF0 MOV ESI,EAX ; <== LocI
0048DA35 |. 4E DEC ESI ; <== LocI
0048DA36 |. BA 0C174F00 MOV
EDX,DUMeter.004F170C ; ASCII
"ABCDEFGHIJKLMNOPQRSTUVWXYZ987654"
0048DA3B |. 8A43 01 MOV AL,BYTE PTR DS:[EBX+1] ; <==
SecI[1]
0048DA3E |. E8 72FFFFFF CALL DUMeter.0048D9B5 ; <==
Location in DefaultString
0048DA43 |. 8BF8 MOV EDI,EAX ; <== LocII
0048DA45 |. 4F DEC EDI ; <== LocII
0048DA46 |. BA 0C174F00 MOV
EDX,DUMeter.004F170C ; ASCII
"ABCDEFGHIJKLMNOPQRSTUVWXYZ987654"
0048DA4B |. 8A43 02 MOV AL,BYTE PTR DS:[EBX+2] ; <==
SecI[2]
0048DA4E |. E8 62FFFFFF CALL DUMeter.0048D9B5 ; <==
Location in DefaultString
0048DA53 |. 48 DEC EAX ; <== LocIII-
-
0048DA54 |. C1E7 05 SHL EDI,5 ; <== ValueI
= LocII * 0x20
0048DA57 |. 0BF7 OR ESI,EDI ; <== Value
= Value or LocI
0048DA59 |. C1E0 0A SHL EAX,0A ; <== LocIII
= LocIII * 0x400
0048DA5C |. 0BF0 OR ESI,EAX ; <== Value
= Value or LocIII
0048DA5E |. 8BC6 MOV EAX,ESI ; <== Value
=== Encrypt SecI ===
- Tiếp đến là quá trình chuyển đổi SecII từ chuỗi sang dạng HEX Value tương ứng ( Ví
dụ SecII : “123AB” được chuyển sang thành giá trị ValueII = 0x123AB ) . Như vậy, các
ký tự của SecII phải nằm trong khoảng các ký tự sau “123456789ABCDEF” :
0048DC10 |. 8D45 E8 LEA EAX,[LOCAL.6] ; <== SecII
0048DC13 |. E8 7CFEFFFF CALL DUMeter.0048DA94 ; <== Convert to
HEX value : ValueII
- Tiếp đó là quá trình kiểm tra đầ
u tiên :
0048DC1A |. 3BF3 CMP ESI,EBX ; <== if ( ValueU
== ValueII )
0048DC1C 74 04 JE SHORT DUMeter.0048DC22 ; <== Continue
check
- Tương tự như quá trình mã hoá SecII, SecIII cũng giống như vậy :
0048DC22 |> \8D45 DC LEA EAX,[LOCAL.9] ; <== SecIII
0048DC25 |. E8 6AFEFFFF CALL DUMeter.0048DA94 ; <== Convert to
HEX value : ValueIII
- Qúa trình mã hoá SecIV dựa trên thuật toán CRC32 :
0048DC2C |. 8D45 C8 LEA EAX,[LOCAL.14] ; <== SecIV
0048DC2F |. E8 1EFDFFFF CALL DUMeter.0048D952 ; <== CRC32
Encrypt
=== CRC32 Encrypt ===