Nếu đúng thì giá trị trả về sẽ là khác 0 và chuyển đến thông báo đúng... >>>> Thực chất của quá trình này có thể nói như sau : chuỗi S nhập nếu là toàn số thì không có gì xảy ra vì ESI
Trang 1Posted by: moonbaby Jan 4 2004, 07:11 AM
QUOTE
Homepage : http://crackme.de
CrackMe : vcrkme02.zip (vcrkme02.exe )
Coder : [v0!d] ( Microsoft Visual C++ 6.0 )
Type : Serial
Packed : N / A
Crack Tool : OllyDbg 1.09d
Unpack Tool : N / A
Request : Correct Serial
Rule : N/A
Note : N/A
>>>>>>>> Đặt BreakPoint tại hai điểm sau :
QUOTE
00401169 FF15 A4404000 CALL DWORD PTR
DS:[<&USER32.GetDlgItemTe>; \GetDlgItemTextA
>>>>>>>> Trace tiếp ta đến đây :
QUOTE
Sau khi trace qua lệnh CALL trên thì chuỗi này sẽ được thay bằng
Trang 2chính chuỗi S nhập
0040116F 68 30504000 PUSH
vcrkme02.00405030 ; ASCII "Enter your code here"
0040116F 68 30504000 PUSH
vcrkme02.00405030 ; ASCII "1234567890123456"
Qua đoạn lệnh này ta nhận thấy đoạn mã này không bao gồm quá trình kiểm tra và xử lý là chỉ có quá trình so sánh giá trị trả về cho EAX, như vậy lệnh CALL sẽ bao hàm một qúa trình so sánh vào xử
lý Nếu đúng thì giá trị trả về sẽ là khác 0 và chuyển đến thông báo đúng
00401174 E8 87FEFFFF CALL vcrkme02.00401000
00401179 83C4 04 ADD ESP,4
0040117C A3 A0564000 MOV DWORD PTR DS:[4056A0],EAX
00401181 85C0 TEST EAX,EAX < === So sánh EAX với 00h
00401183 74 37 JE SHORT vcrkme02.004011BC < === Nếu bằng 00h thì nhảy đến Nag sai
>>>>>>>> Trace thẳng vào trong để xem xét quá trình mã hoá
QUOTE
00401174 E8 87FEFFFF CALL vcrkme02.00401000
>>>>>>>> Sau khi trace vào trong lệnh CALL trên ta đến đây :
Trang 3QUOTE
00401000 /$ 53 PUSH EBX < === Ta đến đây
00401001 | 55 PUSH EBP
00401002 | 8B6C24 0C MOV EBP,DWORD PTR SS:[ESP+C] <
=== S nhập lưu vào EBP
00401006 | 56 PUSH ESI
00401007 | 57 PUSH EDI
00401008 | 8BFD MOV EDI,EBP
0040100A | 83C9 FF OR ECX,FFFFFFFF
0040100D | 33C0 XOR EAX,EAX
0040100F | F2:AE REPNE SCAS BYTE PTR ES:[EDI]
00401011 | F7D1 NOT ECX
00401013 | 49 DEC ECX < === ECX sau lệnh này đúng là chiều dài chuỗi nhập
00401014 | 83F9 10 CMP ECX,10 < === Kiểm tra chiều dài chuỗi nhập với 010h = 16 ký tự
00401017 | 0F85 93000000 JNZ vcrkme02.004010B0 < === Nếu không bằng thì nhảy thoát Sai
0040101D | 8A5D 00 MOV BL,BYTE PTR SS:[EBP] < ===
BL lưu từng ký tự S nhập
00401020 | 33F6 XOR ESI,ESI < === ESI = 00h
00401022 | B2 30 MOV DL,30 < === DL = 030h
00401024 |> 84DB /TEST BL,BL < === so sánh BL với 00h Kiểm tra xem đã hết chuỗi S chưa
00401026 | 74 16 |JE SHORT vcrkme02.0040103E < === Nếu hết rồi thì nhảy
00401028 | 8AC3 |MOV AL,BL < === AL = BL
0040102A | 8BCD |MOV ECX,EBP < === ECX = EBP : lưu địa chỉ của chuỗi S nhập
0040102C |> 3AD0 |/CMP DL,AL < === Kiểm tra xem hai ký
tự lưu ở đây giống nhau không
0040102E | 75 01 ||JNZ SHORT vcrkme02.00401031 < === nếu bằng nhày đến so sánh
Trang 400401030 | 46 ||INC ESI < === Tăng biến ESI lên 1
00401031 |> 83FE 06 ||CMP ESI,6 < === So sánh với 06h
00401034 | 7D 7A ||JGE SHORT vcrkme02.004010B0 < === Nếu lớn hơn thì nhảy NAG SAI
00401036 | 8A41 01 ||MOV AL,BYTE PTR DS:[ECX+1] < ===
AL chứ ký tự kế của S nhập
00401039 | 41 ||INC ECX < == Biến đếm chuỗi tăng 1
0040103A | 84C0 ||TEST AL,AL < === So sánh với 00h 0040103C |.^ 75 EE |\JNZ SHORT vcrkme02.0040102C < === Nếu chưa hết thì lập lại
0040103E |> 33F6 |XOR ESI,ESI < === ESI = 00h
00401040 | FEC2 |INC DL < === ký tự kế tiếp sẽ là 030h + 01h * n ( n là số lần lặp )
00401042 | 80FA 39 |CMP DL,39 < === So sánh với 039h
00401045 |.^ 7E DD \JLE SHORT vcrkme02.00401024 < === Nếu chưa bằng thì tiếp tục lặp
>>>> Thực chất của quá trình này có thể nói như sau : chuỗi S nhập nếu là toàn số thì không có gì xảy ra ( vì ESI sẽ không bao giờ đạt đến 06h ) Nếu bên trong chuỗi có những ký tự khác số thì giá trị của ESI sẽ tăng lên, nhưng ở đây CODER cho ta đến 6 ký tự khác số (CMP ESI,6 )
>>>>>>>> Giai đoạn kiểm tra chuỗi thứ nhất :
QUOTE
00401047 | 0FBE45 03 MOVSX EAX,BYTE PTR SS:[EBP+3] <
=== EAX lưu ký tự thứ 4 : T04
0040104B | 0FBE4D 02 MOVSX ECX,BYTE PTR SS:[EBP+2]
Trang 5< === ECX lưu ký tự thứ 3 : T03
0040104F | 0FBE55 01 MOVSX EDX,BYTE PTR SS:[EBP+1] <
=== EDX lưu ký tự thứ 2 : T02
00401053 | 03C1 ADD EAX,ECX < === EAX = EAX + ECX
00401055 | 0FBECB MOVSX ECX,BL < === ECX lưu ký tự thứ 1 : T01
00401058 | 03C2 ADD EAX,EDX < === EAX = EAX + EDX
>>>> EDX = EAX + ECX – 0Ch
0040105A | 8D9408 40FFFF>LEA EDX,DWORD PTR
DS:[EAX+ECX-C0] < =========
00401061 | 83FA 16 CMP EDX,16 < ==== So sánh giá trị này với 016h
00401064 | 75 4A JNZ SHORT vcrkme02.004010B0 < === Nếu không bằng thì NAG SAI
>>>>>>>> Ở giai đoạn này ta nhận thấy có 4 ký tự được kiểm tra ( 4
ký tự đầu tiên ) Và giá trị của chúng phải là 016h Từ đây ta suy ngược quá trình :
EDX = EAX + ECX – 0C0h = 016h ==== >EAX + ECX = 016h + 0C0h = 0D6h
EAX ( EAX + EDX ) + ECX ( lưu giá trị ký tự thứ nhất ) = 0D6h <
== > EAX + T02 + T01 = 0D6h
EAX ( EAX + ECX ) + T02 + T01 = T01 + T02 + T03 + T04 = 0D6h Giả sử T01 = T02 = T03 = T04 = T00 === > T00 = 0D6h / 4 = 035h Nhưng 035h * 4 = 0D4h === > phép chia trên có dư ( 02h ) ===== > Rất quan trọng để tính chuỗi
>>>> Vậy ta có rất nhiều giá trị thoả mãn được điều này Giả sử ta có : 3838
>>>>>>>> Giai đoạn kiểm tra chuỗi thứ hai :
Trang 6QUOTE
00401066 | 0FBE45 0D MOVSX EAX,BYTE PTR SS:[EBP+D]
< = EAX lưu ký tự thứ 14 : T14
0040106A | 0FBE4D 0A MOVSX ECX,BYTE PTR SS:[EBP+A]
< = ECX lưu ký tự thứ 11 : T11
0040106E | 0FBE55 07 MOVSX EDX,BYTE PTR SS:[EBP+7] <
=== EDX lưu ký tự thứ 8 : T08
00401072 | 03C1 ADD EAX,ECX < === EAX = EAX + ECX
00401074 | 0FBE4D 04 MOVSX ECX,BYTE PTR SS:[EBP+4]
< === ECX lưu ký tự thứ 5 : T05
00401078 | 03C2 ADD EAX,EDX < === EAX = EAX + EDX
>>>> EDX = EAX+ECX-0C0h
0040107A | 8D9408 40FFFF>LEA EDX,DWORD PTR
DS:[EAX+ECX-C0] < =========
00401081 | 83FA 1E CMP EDX,1E < === So sánh EDX với 01Eh
00401084 | 75 2A JNZ SHORT vcrkme02.004010B0 < === Nếu không bằng nhày đến SAI
>>>> Tương tự như trên ta tính được :
T05 + T08 + T11 + T14 = 0DEh === > Và giá trị trung bình là 037h,
có dư cũng là 02h
>>>> Vậy ta có rất nhiều giá trị thoả mãn được điều này Giả sử ta có : 7878
>>>>>>>> Giai đoạn kiểm tra chuỗi thứ ba :
Trang 7QUOTE
00401086 | 0FBE45 0F MOVSX EAX,BYTE PTR SS:[EBP+F] <
= EAX lưu ký tự thứ 16 : T16
0040108A | 0FBE4D 0C MOVSX ECX,BYTE PTR SS:[EBP+C]
< = ECX lưu ký tự thứ 13 : T13
0040108E | 0FBE55 09 MOVSX EDX,BYTE PTR SS:[EBP+9] <
== EDX lưu ký tự thứ 10 : T10
00401092 | 03C1 ADD EAX,ECX < ==== EAX = EAX + ECX
00401094 | 0FBE4D 06 MOVSX ECX,BYTE PTR SS:[EBP+6]
< == ECX lưu ký tự thứ 7 : T07
00401098 | 03C2 ADD EAX,EDX
>>>> EDX = EAX+ECX-0C0h
0040109A | 8D9408 40FFFF>LEA EDX,DWORD PTR
DS:[EAX+ECX-C0] < ======
004010A1 | 83FA 09 CMP EDX,9 < ==== So sánh EDX với 09h 004010A4 | 75 0A JNZ SHORT vcrkme02.004010B0 < === Nếu không bằng nhảy đến SAI
>>>> Tương tự như trên ta tính được :
T07 + T10 + T13 + T16 = 0C9h === > Và giá trị trung bình là 032h,
có dư là 01h
>>>> Vậy ta có rất nhiều giá trị thoả mãn được điều này Giả sử ta có : 2223
>>>>>>>> Như vậy ta chỉ mới có được 4 * 3 = 12 ký tự, còn lại 4 ký tự Đây là 4 ký tự tuỳ ý, ta có thể thêm bất kỳ số nào mà ta thích
>>>>>>>>>>>> Kết luận :
Trang 8QUOTE
1- Chuỗi S nhập phải có chiều dài 16 ký tự
2- Chuỗi nhập được phép có 6 ký tự không phải là số
3- Quá trình mã hoá chỉ diễn ra đối với 12 ký tự, còn 4 ký tự thì tuỳ ta nhập Có thể là số hay chữ hay bất ký thứ gì
>>>>>>>>>>>> Vậy :
QUOTE
Serial : 38387A28B27C28D3
Serial : 3838722822722832