Posted by: moonbaby Dec 29 2003, 03:48 AM QUOTE Homepage : http://crackme.de CrackMe : d2k2_crackme01.zip ( d2k2_crackme01.exe ) Coder : diablo2oo2 ( 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 >>>>>>>> Đặt BreakPoint tại hai điểm sau : QUOTE 00401254 |. E8 8F010000 CALL <JMP.&USER32.GetDlgItemTextA> ; \GetDlgItemTextA 004012F3 |. E8 F0000000 CALL <JMP.&USER32.GetDlgItemTextA> ; \GetDlgItemTextA >>>>>>>> Quá trình kiểm tra chuỗi U nhập : QUOTE 00401259 |. 84C0 TEST AL,AL < ==== Kiểm tra xem đã nhập chuỗi chưa 0040125B |. 0F84 06010000 JE d2k2_cra.00401367 < === Nếu chưa thì nhảy đến thông báo nhập 00401261 |. 3C 20 CMP AL,20 < ==== Chiều dài chuỗi không được quá 20 ký tự 00401263 |. 0F8F 13010000 JG d2k2_cra.0040137C < ==== Nếu quá thông báo nhập lại 00401269 |. 3C 05 CMP AL,5 < ==== Chiều dài chuỗi không ít hơn 5 ký tự 0040126B |. 0F8C 20010000 JL d2k2_cra.00401391 < ==== Nếu ít hơn thông báo nhập lại >>>>>>>> Giai đoạn mã hoá chuỗi U nhập lần thứ nhất : QUOTE >>>> Nạp chuỗi U nhập vào EBX ==== > EBX = 40318C 00401271 |. 8D1D 8C314000 LEA EBX,DWORD PTR DS:[40318C] >>>> Làm xạch ECX ===== > ECX = 00h 00401277 |. 33C9 XOR ECX,ECX >>>> Chuyển 05h vào AL ==== > Đây là biến đếm mặc định của vòng lặp thứ nhất. Điều này có nghĩa quá trình lặp không tiến hành hết chuỗi U nhập mà chỉ xảy ra đối với 5 ký tự đầu tiên của U nhập. 00401279 |. B0 05 MOV AL,5 >>>> Làm sạch EDX ==== > EDX = 00h 0040127B |. 33D2 XOR EDX,EDX >>>> Đưa từng ký tự của chuỗi U nhập vào CL. 0040127D |> 8A0C1A MOV CL,BYTE PTR DS:[EDX+EBX] >>>> ECX = CL xor 29 ==== > Giá trị được lưu ở CL ( ECX ) 00401280 |. 80F1 29 XOR CL,29 >>>> ECX = CL + AL ===== > Giá trị được lưu ở CL ( ECX ) 00401283 |. 02C8 ADD CL,AL >>>> So sánh gí trị của ECX ( CL ) với 41h, nếu nhỏ hơn thì nhảy đến địa chỉ 004012A6 00401285 |. 80F9 41 CMP CL,41 00401288 |. 7C 1C JL SHORT d2k2_cra.004012A6 >>>> So sánh gía trị của ECX ( CL ) với 5Ah, nếu lớn hơn thì nhảy đến địa chỉ 004012A6 0040128A |. 80F9 5A CMP CL,5A 0040128D |. 7F 17 JG SHORT d2k2_cra.004012A6 >>>> Lưu giá trị của ECX ( CL ) vào địa chỉ DS:[EDX+40313C], nhưng do EDX = 00h nên đó cũng chính là địa chỉ 40313C. 0040128F |> 888A 3C314000 MOV BYTE PTR DS:[EDX+40313C],CL >>>> Làm sạch vị trí kế tiếp cho giá trị CL tiếp theo. 00401295 |. C682 3D314000>MOV BYTE PTR DS:[EDX+40313D],0 >>>> Tăng EDX ( DL ) lên 1, có nghĩa là địa chỉ lưu sẽ tăng thêm 1, hay nói cách khác gí trị sau sẽ được lưu ngay sau giá trí trước đó. 0040129C |. FEC2 INC DL >>>> Giảm AL đi 1, có nghĩa là vòng lặp giảm đi 1 lần. 0040129E |. FEC8 DEC AL >>>> Khi giá trị của EAX = 00h có nghĩa là kết thức vòng lặp 004012A0 |. 3C 00 CMP AL,0 004012A2 |. 74 08 JE SHORT d2k2_cra.004012AC >>>> Trở lại vòng lặp, tiếp tục quá trình cho đến khi EAX = 00h 004012A4 |.^ EB D7 JMP SHORT d2k2_cra.0040127D >>>> Nếu giá trị của ECX không nằm trong khoảng [041h , 05Ah] ( điều này có nghĩa : mặc định là kết quả xuất ra là các ký tự dạng chữ hoa ) thì sẽ gán 052h cho CL. 004012A6 |> B1 52 MOV CL,52 < ==== điểm đến của địa chỉ 00401288 và 0040128D >>>> Thêm AL vào CL === > kết quả đươc lưu ở ECX === > Sau đó nhảy về địa chỉ 0040128F để lưu giữ kết quả. Và tiếp tục quá trình mã hoá. 004012A8 |. 02C8 ADD CL,AL 004012AA |.^ EB E3 JMP SHORT d2k2_cra.0040128F >>>>>>>> Giai đoạn mã hoá thứ hai : QUOTE >>>> Làm sạch EDX, chuẩn bị cho giai đoạn mã hoá thứ hai. 004012AC |> \33D2 XOR EDX,EDX >>>> Chuyển 05h vào EAX === > EAX sẽ là biến đếm cho giai đoạn thứ hai ==== > cũng chỉ lấy 05 ký tự đầu tiên của chuỗi U nhập vào. 004012AE |. B8 05000000 MOV EAX,5 >>>> Đưa từng ký tự của U nhập vào ECX ( CL ) 004012B3 |> 8A0C1A MOV CL,BYTE PTR DS:[EDX+EBX] >>>> ECX = CL xor 27h ==== > Kết quả được lưu ở ECX . 004012B6 |. 80F1 27 XOR CL,27 >>>> ECX = CL + AL ===== > Kết quả được lưu ở ECX 004012B9 |. 02C8 ADD CL,AL >>>> ECX = CL + 01h ==== > Kết quả được lưu ở ECX 004012BB |. 80C1 01 ADD CL,1 >>>> Quá trình này giống như trên. Kiểm tra giá trị cảu ECX với 041h và 05Ah 004012BE |. 80F9 41 CMP CL,41 004012C1 |. 7C 1C JL SHORT d2k2_cra.004012DF 004012C3 |. 80F9 5A CMP CL,5A 004012C6 |. 7F 17 JG SHORT d2k2_cra.004012DF >>>> Đưa giá trị sau cùng ở ECX vào lưu ở DS:[EDX+403141]. Chú ý điều này, nếu ta tính toán địa chỉ lưu kết quả ở giai đoạn mã hoá đầu tiên thì sẽ thấy địa chỉ lưu giá trị ở giai đoạn thứ hai nằm sát ngay sau giai đoạn đầu tiên. Chúng tạo thành một chuỗi liên tục bắt đầu ở địa chỉ 40313C. 004012C8 |> 888A 41314000 MOV BYTE PTR DS:[EDX+403141],CL >>>> Chuẩn bị vị trí cho giá trị kế tiếp. 004012CE |. C682 42314000>MOV BYTE PTR DS:[EDX+403142],0 >>>> Tăng EDX lên 1, có nghĩa là giá trị sau sẽ được lưu kế tiếp giá trị trước đó. 004012D5 |. FEC2 INC DL >>>> Giảm biến đếm đi 1. Đến khi EAX = 00h thì kết thúc vòng lặp 004012D7 |. FEC8 DEC AL 004012D9 |. 3C 00 CMP AL,0 004012DB |. 74 08 JE SHORT d2k2_cra.004012E5 >>>> Trở về quá trình lặp lần kế nếu chưa kết thúc vòng lặp. 004012DD |.^ EB D4 JMP SHORT d2k2_cra.004012B3 >>>> Nếu giá trị của CL bên trên không nằm trong 041h và 05Ah thì gán cho CL = 04Dh. 004012DF |> B1 4D MOV CL,4D >>>> ECX = CL + AL ===== > Giá trị được lưu ở ECX và được lưu ở địa chỉ DS:[EDX+403141] 004012E1 |. 02C8 ADD CL,AL >>>> Tiến hành quá trình lưu giá trị của ECX. 004012E3 |.^ EB E3 JMP SHORT d2k2_cra.004012C8 >>>>>>>> Kết thúc hai giai đoạn này thì tại địa chỉ 40313C ta thu được một chuỗi mã hoá. Ta gọi chuỗi này là chuỗi MagicStringS >>>>>>>> Quá trình kiểm tra chuỗi S nhập vào : QUOTE 004012F8 |. 66:85C0 TEST AX,AX < == Nếu chưa nhập chuyển đến thông báo sai 004012FB |. 74 55 JE SHORT d2k2_cra.00401352 >>>> Nếu chiều dài chuỗi nhập không bằng 10 ký tự thì nhảy đến thông báo sai. 004012FD |. 66:83F8 0A CMP AX,0A < === 0Ah = 10 00401301 |. 7F 4F JG SHORT d2k2_cra.00401352 00401303 |. 7C 4D JL SHORT d2k2_cra.00401352 >>>>>>>> Đây là quá trình mã hoá chuỗi MagicStringS lần cuối đồng thời so sánh với chuỗi S nhập QUOTE >>>> Làm sạch EAX, EBX, ECX, EDX === > chuẩn bị cho giai đoạn so sánh chuỗi S nhập và S thực 00401305 |. 33C0 XOR EAX,EAX < ===== EAX = 00h 00401307 |. 33DB XOR EBX,EBX < ===== EBX = 00h 00401309 |. 33C9 XOR ECX,ECX < ===== ECX = 00h 0040130B |. 33D2 XOR EDX,EDX < ===== EDX = 00h >>>> Đưa chuỗi S nhập vào EAX 0040130D |. 8D05 B4314000 LEA EAX,DWORD PTR DS:[4031B4] >>>> Đưa từng ký tự của chuỗi S nhập vào BL ( EBX ) 00401313 |> 8A1C01 MOV BL,BYTE PTR DS:[ECX+EAX] >>>> Đưa từng ký tự của chuỗi MagicStringS vào DL ( EDX ) 00401316 |. 8A91 3C314000 MOV DL,BYTE PTR DS:[ECX+40313C] >>>> Nhảy đến thông báo đúng nếu kết thúc quá trình so sánh ( vì lúc đó BL hay EBX sẽ không có giá trị nào hay EBX = 00h ) 0040131C |. 80FB 00 CMP BL,0 0040131F |. 0F84 81000000 JE d2k2_cra.004013A6 QUOTE 00401325 |. 80C2 05 ADD DL,5 < === Tăng EAX lên 5 00401328 |. 80FA 5A CMP DL,5A < === So sánh với 05Ah 0040132B |. 7F 14 JG SHORT d2k2_cra.00401341 < ==== Nhảy nếu lớn hơn 0040132D |> 80F2 0C XOR DL,0C < === 00401330 |. 80FA 41 CMP DL,41 00401333 |. 7C 11 JL SHORT d2k2_cra.00401346 00401335 |. 80FA 5A CMP DL,5A 00401338 |. 7F 12 JG SHORT d2k2_cra.0040134C 0040133A |> 41 INC ECX 0040133B |. 38DA CMP DL,BL >>>>>>>> Ở đây cho thấy quá trình so sánh chuỗi S thực với S nhập vào từng ký tự. Nếu có bất kỳ một ký tự nào không bằng sẽ nhảy đến thông báo sai. Vì vậy nếy ta chuyển JNZ thành JE thì ta tìm ra được chuỗi thực tương ứng với U nhập vào. 0040133D ^ 75 D4 JNZ SHORT d2k2_cra.00401313 < === Patch ở đây nếu muốn 0040133F |. EB 11 JMP SHORT d2k2_cra.00401352 00401341 |> 80EA 0D SUB DL,0D < === Địa chỉ đến của lệnh nhảy ở địa chỉ 0040132B 00401344 |.^ EB E7 JMP SHORT d2k2_cra.0040132D < == Nhảy trở về tiếp tục quá trình 00401346 |> B2 4B MOV DL,4B 00401348 |. 02D1 ADD DL,CL 0040134A |.^ EB EE JMP SHORT d2k2_cra.0040133A 0040134C |> B2 4B MOV DL,4B 0040134E |. 2AD1 SUB DL,CL 00401350 |.^ EB E8 JMP SHORT d2k2_cra.0040133A >>>>>>>> Toàn bộ quá trình này chỉ có một mục đích duy nhất là tạo chuỗi S thực phải là các ký tự chữ hoa. QUOTE >>>>>>>> Kết luận : 1- Chuỗi U nhập phải có chiều dài từ 5 – 20 ký tự 2- S nhập phải đúng bằng 10 ký tự. 3- Quá trình so sánh diễn ra với từng ký tự, nếu bất kỳ một ký tự không bằng sẽ thoát vòng kiểm tra và hiện thông báo sai. 4- Chuỗi U được mã hoá ở hai giai đọna trên chỉ là MagicStringS. 5- Giai đọan kiểm tra chuỗi bao hàm luôn quá trình mã hoá MagicStringS để tạo được chuỗi S thực tương ứng với U nhập vào. >>>>>>>> Vậy : QUOTE User : Moonbaby Serial : CCBBGFEDCT User : HVA-CrAcKeRtEaM Serial : CBVUTFZYXB . hay EBX = 00 h ) 00 4 01 3 1C |. 80FB 00 CMP BL ,0 00 4 01 3 1F |. 0F84 8 10 000 00 JE d2k2_cra .00 4 01 3 A6 QUOTE 00 4 01 3 25 |. 80C2 05 ADD DL,5 < === Tăng EAX lên 5 00 4 01 3 28 |. 80FA 5A CMP. 05 Ah 00 4 01 3 2B |. 7F 14 JG SHORT d2k2_cra .00 4 01 3 41 < ==== Nhảy nếu lớn hơn 00 4 01 3 2D |> 80F2 0C XOR DL,0C < === 00 4 01 3 30 |. 80FA 41 CMP DL, 41 00 4 01 3 33 |. 7C 11 JL SHORT d2k2_cra .00 4 01 3 46. 20 ký tự 00 4 01 2 63 |. 0F8F 13 01 0 00 0 JG d2k2_cra .00 4 01 3 7C < ==== Nếu quá thông báo nhập lại 00 4 01 2 69 |. 3C 05 CMP AL,5 < ==== Chiều dài chuỗi không ít hơn 5 ký tự 00 4 01 2 6B |. 0F8C 20 0 10 000