Quá trình này xét chuỗi S nhập vào.. Ta thấy, ngay sau lệnh CALL là một lệnh so sánh với 0 và sau đó là lệnh nhảy điều kiện, như vậy trong lệnh CALL sẽ là một quá trình kiểm tra và trả g
Trang 1Posted by: moonbaby Dec 15 2003, 02:50 PM
Homepage : http://crackme.de
CrackMe : due-cm1.zip (due-cm1.exe)
Coder : Duelist (MASM32 / TASM32)
Type : Serial
Packed : N / A
Crack Tool : OllyDbg 1.09d
Unpack Tool : N / A
Request : Correct Serial
Rule : N/A
Note : N/A
-
>>>> Đối với nhưng chương trình được viết bằng MASM32 / TASM32,
ta thường nên tìm đến diểm đặt BreakPoint là GetDlgItemTextA (nếu có) :
00401107 E8 55020000 CALL <JMP.&USER32.GetDlgItemTextA> ;
\GetDlgItemTextA
>>>> Quá trình mã hoá chuỗi nhập vào :
0040110E > /80B8 F7204000>CMP BYTE PTR DS:[EAX+4020F7],0
00401115 |74 18 JE SHORT due-cm1.0040112F
00401117 |80B0 F7204000>XOR BYTE PTR DS:[EAX+4020F7],43 0040111E |80B0 F7204000>XOR BYTE PTR DS:[EAX+4020F7],1E
00401125 |80B0 F7204000>XOR BYTE PTR DS:[EAX+4020F7],55 0040112C |40 INC EAX
0040112D ^\E2 DF LOOPD SHORT due-cm1.0040110E
>> Chuỗi nhập vào được lưu ở địa chỉ 4020F7 vì EAX lúc này bằng 0 Quá trình này xét chuỗi S nhập vào Nếu không được nhập sẽ nhảy đến thông báo sai ( nhảy qua vòng lặp mã hoá chuỗi )
0040110E > /80B8 F7204000>CMP BYTE PTR DS:[EAX+4020F7],0
00401115 |74 18 JE SHORT due-cm1.0040112F
>> Lấy từng ký tự của chuỗi nhập và đem XOR với 43h, 1Eh và 55h, kết quả được lưu đúng vào vị trí của ký tự đó ban đầu
Trang 200401117 |80B0 F7204000>XOR BYTE PTR DS:[EAX+4020F7],43 <
== 67
0040111E |80B0 F7204000>XOR BYTE PTR DS:[EAX+4020F7],1E <
== 30
00401125 |80B0 F7204000>XOR BYTE PTR DS:[EAX+4020F7],55 <
== 85
Như vậy chuỗi sau khi được mã hoá sẽ thay thế vị trí của chuỗi ban đầu
>>>> Quá trình so sánh chuỗi S được mã hoá và chuỗi mặc định trong chương trình Ta thấy, ngay sau lệnh CALL là một lệnh so sánh với 0 và sau đó là lệnh nhảy điều kiện, như vậy trong lệnh CALL sẽ là một quá trình kiểm tra và trả giá trị về cho EAX
00401158 E8 64000000 CALL due-cm1.004011C1 ;
\due-cm1.004011C1
0040115D 83F8 00 CMP EAX,0
00401160 74 1B JE SHORT due-cm1.0040117D
>> >> Trace vào trong lệnh CALL này ta thấy một tập hợp lệnh
004011C5 | B8 01000000 MOV EAX,1
004011CA | 8B7D 08 MOV EDI,DWORD PTR SS:[EBP+8] ;
due-cm1.004020F7
004011CD | 8B75 0C MOV ESI,DWORD PTR SS:[EBP+C]
004011D0 | 8B4D 10 MOV ECX,DWORD PTR SS:[EBP+10]
004011D3 | F3:A6 REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:> 004011D5 | 67:E3 05 JCXZ SHORT due-cm1.004011DD
004011D8 | B8 00000000 MOV EAX,0
004011DD |> C9 LEAVE
>> Tăng giá trị đếm lên 1
004011C5 | B8 01000000 MOV EAX,1
>> Đưa giá trị của chuỗi S được mã hoá vào lưu ở EDI
004011CA | 8B7D 08 MOV EDI,DWORD PTR SS:[EBP+8] ;
due-cm1.004020F7
>> Đưa gía trị của chuỗi mặc định lưu ở ESI
004011CD | 8B75 0C MOV ESI,DWORD PTR SS:[EBP+C]
Trang 3>> Đưa chiều dài của chuỗi mặc định vào lưu ở ECX
004011D0 | 8B4D 10 MOV ECX,DWORD PTR SS:[EBP+10]
>> Hai chuỗi được so sánh cho đến cuối cùng (REPE = Lặp lại cho đến khi bằng) Quá trình này được tính vòng lặp thông qua giá trị của ECX Vòng lặp sẽ ngừng khi ECX = 0
004011D3 | F3:A6 REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:>
>> Sau khi kết thúc lệnh trên (REPE) thì ECX=0, lệnh nhay bên dưới được thực hiện khi CX=0 ( JCXZ = nhảy nếu CX = 0 )
004011D5 | 67:E3 05 JCXZ SHORT due-cm1.004011DD
>> Nếu hai chuỗi giống nhau thì sẽ nhảy qua lệnh này và vì thế như ban đầu trước khi thực hiện thì EAX = 1 Vậy, ở đây nếu muốn Patch, ta cho EAX =1 nghĩa là sửa thành MOV EAX,1
004011D8 | B8 00000000 MOV EAX,0 < == Patch ở đây nếu muốn
>>>> Như trên ta đã nói, chuỗi mặc định được lưu ở ESI, ở địa chỉ
4020D3 Truy đến địa chỉ này ta thấy một dãy ký tự
“{aexdm&kzikcem&<&fm jam{&jq&l}mda{| “ ( : có mã hex là 7F, không có dấu ngoặc kép ) Đến đây ta đảo ngược quá trình mã hoá ( làm ngược lại quá trình mã hoá chuỗi S nhập vào của ta ), ta tìm được chuỗi S thực
Vậy :
Serial : simple.crackme.4.newbies.by.duelist
FINISHED – 15/12/2003
Posted by: moonbaby Dec 15 2003, 02:52 PM
Homepage : http://crackme.de
CrackMe : due-cm4.zip (due-cm4.exe)
Coder : Duelist (MASM32 / TASM32)
Type : Name / Serial
Trang 4Packed : N / A
Crack Tool : OllyDbg 1.09d
Unpack Tool : N / A
Request : Correct Serial
Rule : N/A
Note : N/A
-
>>>> Đặt BreakPoint :
00401137 A3 AF214000 MOV DWORD PTR DS:[4021AF],EAX
>>>> Quá trình kiểm tra chuỗi nhập vào
00401137 A3 AF214000 MOV DWORD PTR DS:[4021AF],EAX <
=== Lưu chiều dài chuỗi
0040113C 83F8 00 CMP EAX,0 < === Chuỗi đã được nhập hay chưa 0040113F 0F84 D5000000 JE due-cm4.0040121A
00401145 83F8 08 CMP EAX,8 < ==== Chuỗi có chiều dài hơn 8 ký tự
00401148 0F8F CC000000 JG due-cm4.0040121A
Kiểm tra chiều dài chuỗi nhập của U và S Chúng phải bằng nhau
00401169 3BF0 CMP ESI,EAX
0040116B 0F85 A9000000 JNZ due-cm4.0040121A
>>>> Lưu chuỗi U nhập ở địa chỉ 00402160 Nhưng ký tự cuối cùng của chuỗi U đã bị cắt bỏ
0040117F E8 F4010000 CALL
<JMP.&USER32.SendDlgItemMessageA> ; \SendDlgItemMessageA <
==== CALL 00401378
Lưu chuỗi S ở địa chỉ 00402179
00401192 E8 E1010000 CALL
<JMP.&USER32.SendDlgItemMessageA> ; \SendDlgItemMessageA <
==== CALL 00401378
>>>> Quá trình xử lý chuỗi U nhập
0040119D 0FBE81 602140>MOVSX EAX,BYTE PTR
Trang 5DS:[ECX+402160]
004011A4 83F8 00 CMP EAX,0 ; Switch (cases 0 7A)
004011A7 74 32 JE SHORT due-cm4.004011DB
004011A9 BE FFFFFFFF MOV ESI,-1
004011AE 83F8 41 CMP EAX,41
004011B1 7C 67 JL SHORT due-cm4.0040121A
004011B3 83F8 7A CMP EAX,7A
004011B6 77 62 JA SHORT due-cm4.0040121A
004011B8 83F8 5A CMP EAX,5A
004011BB 7C 03 JL SHORT due-cm4.004011C0
004011BD 83E8 20 SUB EAX,20 ; Cases 5A ('Z'),5B ('['),5C ('\'),5D (']'),5E ('^'),5F ('_'),60 ('`'),61 ('a'),62 ('b'),63 ('c'),64 ('d'),65 ('e'),66 ('f'),67 ('g'),68 ('h'),69 ('i'),6A ('j'),6B ('k'),6C ('l'),6D ('m') of switch 004011A4 004011C0 > 46 INC ESI ; Cases 41 ('A'),42 ('B'),43 ('C'),44 ('D'),45
('E'),46 ('F'),47 ('G'),48 ('H'),49 ('I'),4A ('J'),4B ('K'),4C ('L'),4D ('M'),4E ('N'),4F ('O'),50 ('P'),51 ('Q'),52 ('R'),53 ('S'),54 ('T') of switch 004011A4 004011C1 0FBE96 172040>MOVSX EDX,BYTE PTR
DS:[ESI+402017]
004011C8 3BC2 CMP EAX,EDX
004011CA ^ 75 F4 JNZ SHORT due-cm4.004011C0
004011CC 0FBE86 3C2040>MOVSX EAX,BYTE PTR
DS:[ESI+40203C]
004011D3 8981 94214000 MOV DWORD PTR
DS:[ECX+402194],EAX
004011D9 ^ EB C1 JMP SHORT due-cm4.0040119C
>> Đoạn mã này kiểm tra xem các ký tự U nhập có thuộc dạng đặc biệt hay không Nếu đúng thì hiện thông báo sai
004011AE 83F8 41 CMP EAX,41
004011B1 7C 67 JL SHORT due-cm4.0040121A
004011B3 83F8 7A CMP EAX,7A
004011B6 77 62 JA SHORT due-cm4.0040121A
004011B8 83F8 5A CMP EAX,5A
004011BB 7C 03 JL SHORT due-cm4.004011C0
>> Đây là quá trình mã hoá chuỗi, được diễn giải như sau : trong chương
Trang 6trình đã lưu sẵn hai chuỗi, ta gọi là MagicString1 được lưu ở địa chỉ
402017 và MagicString2 được lưu ở 40203C Lấy từng ký tự của chuỗi U nhập vào trừ cho 20h, sau đó cộng biến đếm lên 1 Giá trị sau khi trừ được đem so sánh với từng giá trị (ký tự ) của chuỗi MagicString1, quá trình này tiếp diễn cho đến khi hai ký tự này giống nhau Lúc này, giá trị của biến đếm ESI sẽ được dùng để xác định vị trí của ký tự trong chuỗi
MagicString2, ký tự này được chuyển vào lưu ở địa chỉ 402194 Quá trình này được tiếp diễn cho đến hết chuỗi Chuỗi ký tự được lưu ở địa chỉ
402194 chính là chuỗi S thực
004011BD 83E8 20 SUB EAX,20 < === trừ cho 20h
004011C0 > 46 INC ESI < === biến đếm cho biết giá trị khi hai ký tự trùng nhau
004011C1 0FBE96 172040>MOVSX EDX,BYTE PTR
DS:[ESI+402017] < === MagicString1
004011C8 3BC2 CMP EAX,EDX < === so sánh U với MagicString1 004011CA ^ 75 F4 JNZ SHORT due-cm4.004011C0 < === nếu chưa đúng thì làm lại
004011CC 0FBE86 3C2040>MOVSX EAX,BYTE PTR
DS:[ESI+40203C] < === MagicString2
004011D3 8981 94214000 MOV DWORD PTR
DS:[ECX+402194],EAX < == Chuỗi S thực thiếu
>>>> Quá trình so sánh chuỗi Ở đây ta nhận thấy sau lệnh CALL là một lệnh so sánh, như vậy trong lệnh CALL này là một quá trình xử lý để trả
về giá trị
004011EB E8 54000000 CALL due-cm4.00401244 ;
\due-cm4.00401244
004011F0 83F8 01 CMP EAX,1
>> Trace thẳng vào trong, ta có tập mã lệnh
00401248 | B8 01000000 MOV EAX,1
0040124D | 8B7D 08 MOV EDI,DWORD PTR SS:[EBP+8] < ===
Chuỗi S nhập
00401250 | 8B75 0C MOV ESI,DWORD PTR SS:[EBP+C] < === Chuỗi
S thiếu
Trang 700401253 | 8B4D 10 MOV ECX,DWORD PTR SS:[EBP+10] < === Chiều dài hai chuỗi
00401256 | F3:A6 REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
00401258 | 67:E3 05 JCXZ SHORT due-cm4.00401260
>> Quá trình so sánh lặp này diễn ra cho từng ký tự
00401256 | F3:A6 REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
00401258 | 67:E3 05 JCXZ SHORT due-cm4.00401260
>>>> Tuy nhiên, ở đây ta lưu ý đến một điều là chuỗi U khi đem mã hoá
đã bị trừ mất đi ký tự cuối Như vậy chuỗi tạo thành bị thiếu đi 1 ký tự, nếu nhập kiểm tra sẽ cho kết quả không đúng Nhưng ta lại không tìm thấy đoạn mã đề cập đến ký tự cuối cùng được mã hoá và gắn kết vào chuỗi S thiếu như thế nào, vậy ta đặt ra một giả thuyết là ký tự cuỗi cùng không quan trọng và không dùng để so sánh, chỉ là ký tự điền đầy
>> Thử với giả thiết này cho kết quả đúng
>>>> Vậy ta có kết luận :
1- Chuỗi S nhập và U nhập phải có chiều dài bằng nhau và lớn hơn 8 ký
tự
2- Các ký tự của chuỗi U nhập không được là ký tự đặc biệt
3- Chuỗi mã hoá cuối cùng sẽ được cho thêm một ký tự
User : Moonbaby Serial : 7SS04S47