Nếu đúng thì EAX sẽ bằng 0, còn nếu sai thì sẽ có giá trị khác 0 và sẽ nhảy đến thông báo sai... Đây là một lệnh chia không dấu.. Phần chia nguyên của kết quả chia không lấy dấu được đặt
Trang 1Posted by: moonbaby Dec 16 2003, 03:01 PM
Homepage : http://crackme.de
CrackMe : Fant0m4 (CRACKME4.exe)
Coder : fant0m (MASM32 / TASM32)
Type : Name / Serial
Packed : N / A
Crack Tool : OllyDbg 1.09d
Unpack Tool : N / A
Request : Correct Serial – Patch for all Serial
Rule : N/A
Note : N/A
-
>>>> Đặt BreakPoint tại hai điểm :
00401217 | E8 62010000 CALL <JMP.&USER32.GetDlgItemTextA> ;
\GetDlgItemTextA
0040122E | E8 4B010000 CALL <JMP.&USER32.GetDlgItemTextA> ;
\GetDlgItemTextA
>> Trace xuống một chút ta gặp đoạn mã sau :
00401236 | E8 BE000000 CALL CRACKME4.004012F9
0040123B | 83F8 00 CMP EAX,0
0040123E | 74 15 JNZ SHORT CRACKME4.00401255 < === Patch ở đây cho mọi Serial
>> Điều này có nghĩa là trong lệnh CALL sẽ là một quá trình xử lý và trả giá trị về cho EAX Nếu đúng thì EAX sẽ bằng 0, còn nếu sai thì sẽ có giá trị khác 0 và sẽ nhảy đến thông báo sai
>>>> Trace vào trong lệnh này, ta thấy đoạn mã sau :
0040130E | B3 1A MOV BL,1A < === EBX = 1A
00401310 |> 803E 00 /CMP BYTE PTR DS:[ESI],0 < === Kiểm tra xem chuỗi đã kết thúc chưa
00401313 | 74 15 |JE SHORT CRACKME4.0040132A < === Nhảy nếu
Trang 2kết thúc
00401315 | 8A06 |MOV AL,BYTE PTR DS:[ESI] < === Đưa từng ký tự
U vào EAX
00401317 | 02C1 |ADD AL,CL < === EAX + ECX 9 ban đầu ECX = 0, ECX là biến đếm )
00401319 | 32C1 |XOR AL,CL < === EAX xor ECX
0040131B | F6F3 |DIV BL < === Xem giải thích
0040131D | 66:C1E8 08 |SHR AX,8 < === Xem giải thích
00401321 | 04 41 |ADD AL,41 < === EAX + 41h
00401323 | 8807 |MOV BYTE PTR DS:[EDI],AL < === Xem giải thích
00401325 | 47 |INC EDI
00401326 | 46 |INC ESI
00401327 | 41 |INC ECX
00401328 |.^ EB E6 \JMP SHORT CRACKME4.00401310
>> Đối với lệnh DIV BL Đây là một lệnh chia không dấu Phần chia nguyên của kết quả chia không lấy dấu được đặt vào AL, phần chia dư của phép chia cũng không lấy dấu và đặt kết quả vào AH Gỉa sử ta lấy 113 (71h <=> ASCII = o) chia cho 26 (1A), sẽ cho giá trị nguyên là 4 và số dư
là 9 Chuyển sang hệ hex ta có là 4 và 9, như vậy AL = 04 (phần chia nguyên ) và AH = 09 (phần chia dư )
Vậy EAX = 00000904
>> Đây là một phép dịch phải, đơn giản như trong chương trình này ta tó thể hiểu là loại bỏ AL Như vậy sau phép toán này thì EAX = 00000009 Giá trị sau cùng của ký tự đựơc lưu ở địa chỉ trùng với giá trị của EDI lúc bấy giờ
>> EDI tăng thêm 1 có nghĩa là ký tự kế tiếp của chuỗi được mã hoá sẽ nằm sau ký tự trước nó
00401325 | 47 |INC EDI
>> ESI tăng thêm 1 nghĩa là chuyển đến ký tự kế tiếp của chuỗi nhập vào
00401326 | 46 |INC ESI
>> ECX tăng thêm 1 xẽ làm ảnh hưởng đến kết quả tính toán với giá trị
Trang 3của chuỗi U nhập vào
00401327 | 41 |INC ECX
>>>> Trace thêm chút nữa, ta sẽ thấy :
00401334 | 68 84324000 PUSH CRACKME4.00403284 ; /String2 =
"ZJLKUVGF"
00401339 | 68 84314000 PUSH CRACKME4.00403184 ; |String1 =
"12345678"
>> Chuỗi 1 chứa giá S nhập vào và chuỗi 2 chứa giá trị S được mã hoá, và cũng là S thực
>>>> Vậy :
User : Moonbaby Serial : ZJLKUVGF
Posted by: moonbaby Dec 25 2003, 09:44 AM
QUOTE
Homepage : http://crackme.de
CrackMe : rif_crackme4.zip (rif_crackme4.exe )
Coder : $KORBUT (MASM32 / TASM32 )
Type : Name / Serial
Packed : N/A
Crack Tool : OllyDbg 1.09d
Unpack Tool : N/A
Request : Correct Serial
Rule : N/A
Note : N/A
Trang 4-
Đặt BreakPoint tại đây
0040158C | E8 05010000 CALL <JMP.&USER32.GetDlgItemTextA> ;
\GetDlgItemTextA
Chương trình này yêu cầu ta phải bỏ Nag trước khi tiến hành quá trình kiểm tra chuỗi Ta tiến hành như sau :
Ta chuyển lệnh nhảy JNZ ( kiểm tra xem có nhập vào chưa, nếu chưa nhập thì không nhảy, chuyển đến JMP và xuất thông báo yêu cầu nhập Nếu nhập rồi thì nhảy qua JMP để đến thông báo hiện NAG) Vậy ở đây ta chuyển JNZ thành JMP đến địa chỉ ngoài NAG là 004015B3 Lúc này mã
từ 75 0A chuyển thành EB 1E
00401591 | 0BC0 OR EAX,EAX
00401593 75 0A JNZ SHORT rifme4.0040159F < === chuyển thành lệnh JMP (EB 1E)
00401595 | 68 52314000 PUSH rifme4.00403152 ; ASCII "Ye must enter
a serial ! Baka"
0040159A E9 A2000000 JMP rifme4.00401641
0040159F |> 6A 10 PUSH 10 ; /Style =
MB_OK|MB_ICONHAND|MB_APPLMODAL
004015A1 | 68 0A324000 PUSH rifme4.0040320A ; |Title = "Nag, nag, nag, nag, nag "
004015A6 | 68 A7314000 PUSH rifme4.004031A7 ; |Text = "I'm the worst nag you never seen Remove me and code the keygen See the rewls before patching !!!"
004015AB | FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hOwner
004015AE | E8 07010000 CALL <JMP.&USER32.MessageBoxA> ;
\MessageBoxA
004015B3 | B9 59000000 MOV ECX,59
Sau khi nhảy qua đoạn mã lệnh này, ta tiến đến quá trình mã hoá Quá trình mã hoá này bao gồm bốn giai đoạn :
Giai đoạn thứ nhất :
Trang 5Chuyển 59h vào ECX ( giá trị mặc định )
004015B3 | B9 59000000 MOV ECX,59
Làm trống EBX
004015B8 | 33DB XOR EBX,EBX
Nhảy đến địa chỉ đầu tiên trong vòng lặp
004015BA | EB 0C JMP SHORT rifme4.004015C8
Đưa ký tự mặc định tại địa chỉ này vào EAX
004015BC |> 0FBE81 D23240>/MOVSX EAX,BYTE PTR
DS:[ECX+4032D2]
EBX = EAX + EBX === > giá trị lưu ở EBX
004015C3 | 03D8 |ADD EBX,EAX
EBX = EBX xor ECX === > giá trị lưu ở EBX ==== > lưu giá trị sau khi kết thúc vòng lặp
004015C5 | 33D9 |XOR EBX,ECX
Giảm ECX đi 1 === > theo như trên ECX = 59h
004015C7 | 49 |DEC ECX
Tiếp tục vòng lặp đến khi ECX = 00h
004015C8 |> 0BC9 OR ECX,ECX
004015CA |.^ 75 F0 \JNZ SHORT rifme4.004015BC
Giai đoạn này là một gia đoạn mặc định, gí trị cuối cùng của nó bao giò cũng không đổi Sau khi kết thúc vòng lặp, EBX = 000008C9h
Giai đoạn thứ hai
Nhảy đến địa chỉ để bắt đầu quá trình lặp Gán gí trị cho vòng lặp ( số vòng lặp )
004015CC | /EB 0C JMP SHORT rifme4.004015DA
Đưa gí trị mặc định tại địa chỉ DS:[ECX+4032D2] vào EAX
004015CE |> |0FBE81 D23240>/MOVSX EAX,BYTE PTR
DS:[ECX+4032D2]
004015D5 | |33D8 |XOR EBX,EAX
004015D7 | |33D9 |XOR EBX,ECX
004015D9 | |41 |INC ECX
004015DA |> \83F9 59 CMP ECX,59
004015DD |.^ 75 EF \JNZ SHORT rifme4.004015CE
Trang 6Cũng như trên, đây cũng là một quá trình mặc định Sau khi thoát khỏi vòng lặp, cũngcho ta một giá trị không thay đổi EBX = FFFFF708h
Giai đọan thứ ba : Quá trình mã hoá chuỗi U nhập vào
Làm trống ECX
004015DF | 33C9 XOR ECX,ECX
Bắt đầu vào vòng lặp
004015E1 | EB 0C JMP SHORT rifme4.004015EF
Đưa từng ký tự của chuỗi U nhập vào EAX
004015E3 |> 0FBE81 3C3240>/MOVSX EAX,BYTE PTR
DS:[ECX+40323C]
EBX = EBX – EAX ( EBX = 708h ) ==== > Gía trị lưu ở EBX
004015EA | 2BD8 |SUB EBX,EAX
EBX = EBX + ECX ( ban đầu ECX = 00h ) ==== > Giá trị lưu ở EBX (giá trị cuối của vòng lặp )
004015EC | 03D9 |ADD EBX,ECX
Tăng ECX lên 1 ==== > biến đếm của vòng lặp
004015EE | 41 |INC ECX
Tiếp tục nếu chủa hết chuỗi U nhập
004015EF |> 0BC0 OR EAX,EAX
004015F1 |.^ 75 F0 \JNZ SHORT rifme4.004015E3
Sau khi kết thúc vòng lặp EBX = EBX xor 28EBFA5
004015F3 | 81F3 A5BF8E02 XOR EBX,28EBFA5
ECX = ECX + 0Ah ( ECX = chiều dài chuỗi U nhập sau khi kết thúc quá trình lặp )
004015F9 | 83C1 0A ADD ECX,0A
ECX = ECX xor EBX ==== > Giá trị cuối cùng của quá trình mã hoá được lưu lại ở ECX
004015FC | 33CB XOR ECX,EBX
Giai đoạn thứ tư : giai đọan kết hợp chuỗi
004015FE | 51 PUSH ECX ; /<%lX> < === Giũ nguyên định dạng
004015FF | 53 PUSH EBX ; |<%lu> < === Chuyển sang hệ thập phân
00401600 | 68 25324000 PUSH rifme4.00403225 ; |Format =
Trang 7"%lu-1789-%lX-R!F"
00401605 | 68 6E324000 PUSH rifme4.0040326E ; |s = rifme4.0040326E 0040160A | E8 5D000000 CALL <JMP.&USER32.wsprintfA> ;
\wsprintfA
Sau khi qua giai đọan này chuỗi có dạng : XXXX-1789-XXXX-R!F
Vậy ta rút ra kết luận :
1- Có thể xem giá trị để bước vào quá trình mã hoá là một giá trị mặc định EBX = FFFFF708h
2- S thực được lưu ở 0012FC40 0040326E
3- Nếu không bỏ NAG ban đầu đi thì luôn hiện ra thông báo sai cho dù có đúng S đi chăng nữa
Vậy :
QUOTE
User : Moonbaby Serial : 4252060752-1789-FD714C43-R!F
User : HVA-CrAcKeRtEaM Serial : 4252060951-1789-FD714D0D-R!F