Posted by: moonbaby Jan 6 2004, 11:42 AM QUOTE Homepage : http://crackme.de CrackMe : cronosp3.zip (puzzle3.exe) Coder : cronos (DON’T KNOW) Type : Code.2 Packed : N / A Crack Tool : OllyDbg 1.09d Unpack Tool : N / A Request : Correct Code.2 Rule : N/A Note : N/A >>>>>>>> Đặt BreakPoint : QUOTE >> Gọi hộp thoại thông báo nhập code. 00401325 |. E8 51000000 CALL <JMP.&USER32.DialogBoxParamA> ; \DialogBoxParamA >> Đoạn mã này chứa quá trình kiểm tra chuỗi nhập và trả về giá trị cho EAX đồng thời lưu thêm một kết quả ở EDX. Giá trị có được của EAX tương đương với số cổng mà chúng ta vượt qua được. 0040132A |. E8 4BFFFFFF CALL 7GATES.0040127A < === Đặt BreakPoint tại đây. 0040132F |. 8945 F8 MOV DWORD PTR SS:[EBP-8],EAX 00401332 |. 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8] >> Kiểm tra giá trị của EAX, nếu EAX = 00h thì thông báo không mở được cổng nào. 00401335 |. 85C0 TEST EAX,EAX >> Nhảy đến thông báo số cổng mở được 00401337 |. 75 0D JNZ SHORT 7GATES.00401346 00401339 |. 68 30204000 PUSH 7GATES.00402030 ; /Arg1 = 00402030 ASCII "Thats real sad, you didn't open any gates" 0040133E |. E8 DEFEFFFF CALL 7GATES.00401221 ; \7GATES.00401221 00401343 |. 59 POP ECX 00401344 |. EB 25 JMP SHORT 7GATES.0040136B >> Trả về EDX số cổng vượt qua được. 00401346 |> 8B55 F8 MOV EDX,DWORD PTR SS:[EBP-8] >> Kiểm tra xem ta đã vượt qua được bao nhiêu cổng 00401349 |. 83FA 07 CMP EDX,7 >> Nếu vượt qua được hết tất cả bảy cổng thỉ nhảy đến thông báo hoàn tất, 0040134C |. 7D 12 JGE SHORT 7GATES.00401360 >> không thì hiện thông báo số cổng vượt qua 0040134E |. FF75 F8 PUSH DWORD PTR SS:[EBP- 8] ; /Arg2 00401351 |. 68 5A204000 PUSH 7GATES.0040205A ; |Arg1 = 0040205A ASCII "You opened % gates" 00401356 |. E8 DCFEFFFF CALL 7GATES.00401237 ; \7GATES.00401237 0040135B |. 83C4 08 ADD ESP,8 0040135E |. EB 0B JMP SHORT 7GATES.0040136B >> Hiển thị thông báo chúc mừng đã vượt qua được hết 7 cổng. 00401360 |> 68 6D204000 PUSH 7GATES.0040206D ; ASCII "Congratulations, you opened all the gates" 00401365 |. E8 B7FEFFFF CALL 7GATES.00401221 >> >> >> Quá trình kiểm tra chuỗi nhập QUOTE >> Giá trị ban đầu tại địa chỉ SS:[EBP-4] ban đầu có giá trị bằng 00h. Có giá trị tăng 1 sau mỗi vòng lặp 0040128A |> /8B4D FC /MOV ECX,DWORD PTR SS:[EBP-4] >> Chuổi chúng ta nhập sẽ được chuyển sang dạng số thập lúc phân ( ví dụ : nhập 12 thì cho là 0Ch ) và được đưa vào EAX. 0040128D |. |A1 08214000 |MOV EAX,DWORD PTR DS:[402108] >> Chuẩn bị EDX cho phép chia tiếp theo sau 00401292 |. |99 |CDQ >> Lấy EAX chia cho giá trị được lưu ở địa chỉ DS:[ECX*4+402000]. Ban đầu ECX = 00h. Nói thêm : truy đến địa chỉ này ta nhận thấy có bảy ký tự được lưu sẵn ( mặc định ), cách nhau đúng 4 vị trí. Giá trị của chúng lần lượt là : 0Bh; 0Dh; 11h; 13h; 17h; 1Dh; 1F;. Kết quả của phép chia này được lưu giữ ở hai nơi : phần nguyên được lưu giữ ở EAX và phần dư được lư trữ ở EDX. 00401293 |. |F73C8D 002040>|IDIV DWORD PTR DS:[ECX*4+402000] >> Đưa phần dư phép chia vào lưu trữ ở EAX. Phần nguyên coi như bỏ đi, không quan tâm. 0040129A |. |8BC2 |MOV EAX,EDX >> Đưa giá trị tại địa chỉ SS:[EBP-4] vào lưu ở EDX. Ban đầu có giá trị bằng 00h. Có giá trị tăng 1 sau mỗi vòng lặp 0040129C |. |8B55 FC |MOV EDX,DWORD PTR SS:[EBP-4] >> Nhân EAX với giá trị được lưu ở địa chỉ DS:[EDX*4+4020E8]. Nói thêm : mỗi lần gọi chương trình thì Code.01 luôn cho ta một chuỗi gồm bảy con số, các con số này được lưu ở đây. Nhưng cần lưu ý thêm : chẳng hạn như có ký tự h thì sao, lúc này thì h sẽ có mã hex theo quy định của chương trình là 14h. Tương tự như vậy ta có g : 10h; i : 12h; j : 13h Và kết quả được lưu giữ ở EAX. 0040129F |. |F72C95 E82040>|IMUL DWORD PTR DS:[EDX*4+4020E8] >> Đưa giá trị tại địa chỉ SS:[EBP-4] vào lưu ở ECX. Ban đầu có giá trị bằng 00h. Có giá trị tăng 1 sau mỗi vòng lặp 004012A6 |. |8B4D FC |MOV ECX,DWORD PTR SS:[EBP-4] >> Chuẩn bị EDX cho phép chia tiếp theo sau 004012A9 |. |99 |CDQ >> Lấy EAX chia cho giá trị được lưu ở địa chỉ DS:[ECX*4+402000]. Kết quả của phép chia này được lưu giữ ở hai nơi : phần nguyên được lưu giữ ở EAX và phần dư được lư trữ ở EDX. 004012AA |. |F73C8D 002040>|IDIV DWORD PTR DS:[ECX*4+402000] >> Đưa giá trị tại địa chỉ SS:[EBP-4] vào lưu ở EACX. Ban đầu có giá trị bằng 00h. Có giá trị tăng 1 sau mỗi vòng lặp 004012B1 |. |8B45 FC |MOV EAX,DWORD PTR SS:[EBP-4] >> Lưu giá trị phần dư của phép chia thứ hai (004012AA) vào địa chỉ DS:[EAX*4+4020E8]. Có nghĩa là nó thay thế giá trị cũ. 004012B4 |. |891485 E82040>|MOV DWORD PTR DS:[EAX*4+4020E8],EDX >> Đưa giá trị tại địa chỉ SS:[EBP-4] vào lưu ở ECX. Ban đầu có giá trị bằng 00h. Có giá trị tăng 1 sau mỗi vòng lặp 004012BB |. |8B4D FC |MOV ECX,DWORD PTR SS:[EBP-4] >> Đưa giá trị được lưu giữ ở DS:[ECX*4+4020E8] vào EAX. Nói cách khác là đưa giá trị phần dư của phép chia thứ hai (004012AA) vào EAX. 004012BE |. |8B048D E82040>|MOV EAX,DWORD PTR DS:[ECX*4+4020E8] >> Kiểm tra xem EAX có bằng 0 hay không 004012C5 |. |85C0 |TEST EAX,EAX >> Nhảy đến quá trình kế tiếp nếu lớn hơn hoặc bằng. 004012C7 |. |7D 14 |JGE SHORT 7GATES.004012DD 004012C9 |. |8B55 FC |MOV EDX,DWORD PTR SS:[EBP-4] 004012CC |. |8B0C95 002040>|MOV ECX,DWORD PTR DS:[EDX*4+402000] 004012D3 |. |8B45 FC |MOV EAX,DWORD PTR SS:[EBP-4] 004012D6 |. |010C85 E82040>|ADD DWORD PTR DS:[EAX*4+4020E8],ECX >> Nếu EAX != 0h thì sẽ nhảy đến đây. Đưa giá trị tại địa chỉ SS:[EBP-4] vào lưu ở EDX. Ban đầu có giá trị bằng 00h. Có giá trị tăng 1 sau mỗi vòng lặp 004012DD |> |8B55 FC |MOV EDX,DWORD PTR SS:[EBP-4] >> ECX sẽ chứa phần dư của phép chia thứ hai (004012AA). 004012E0 |. |8B0C95 E82040>|MOV ECX,DWORD PTR DS:[EDX*4+4020E8] >> Giảm giá trị này đi 1. 004012E7 |. |49 |DEC ECX >> Nếu ECX = 00h thì tiếp tục, không nhảy 004012E8 |. |75 03 |JNZ SHORT 7GATES.004012ED >> Tăng giá trị được lư trữ tại địa chỉ này lên 1 đơn vị. Như phần đầu tiên ta đã nói. Gái trị ở đây cho biết số vòng mà chúng ta vượt qua. Điều này có nghĩa sau phép chia thứ hai thì số dư phải bằng 1 004012EA |. |FF45 F8 |INC DWORD PTR SS:[EBP-8] >> Tăng giá trị tại địa chỉ này lên 1 đơn vị. 004012ED |> |FF45 FC |INC DWORD PTR SS:[EBP-4] >> Đưa giá trị ở đây vào EAX. Ban đầu có giá trị là 1 và tăng sau mỗi vòng lặp. 004012F0 |. |8B45 FC |MOV EAX,DWORD PTR SS:[EBP-4] >> Kiểm tra xem đã đi hết 7 cửa chưa 004012F3 |. |83F8 07 |CMP EAX,7 >> Nếu đã đi hết thì nhảy thoát ra và trở về quá trình thông báo 004012F6 |.^\7C 92 \JL SHORT 7GATES.0040128A >> Đưa kết quả số cửa mở được lưu vào EAX. 004012F8 |. 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8] >>>> Tóm tắt quá trình : QUOTE 1- Code.01-i là giá trị từng số mà chương trình đưa ra ( i = 1 7 ) 2- Code.02 là giá trị của ta nhập vào được chuyển sang hệ thập lục phân. 3- Code.03-1 là giá trị từng số mặc định mà chương trình đã cho ( i = 1 7 ) 4- Code.04 là phần dư của phép chia ( Code.02 / Code.03-i ) 5- Code.05 = Code.04 * Code.01-i 6- Code.06 là phần dư của phép chia (Code.05 / Code.03-i ) 7- Code.06 == 1 >>>> Vậy ta có kết luận : QUOTE 1- Tuỳ thuộc vào giá trị của Code.01 mà ta có các giá trị của Code.02 khác nhau. 2- Giá trị phần dư của phép chia thứ hai phải bằng 1. 3- Đối với chương trình này thì PATCH là cách tốt nhất . 7GATES .00 402 0 30 ; /Arg1 = 00 402 0 30 ASCII "Thats real sad, you didn't open any gates" 00 4 01 3 3E |. E8 DEFEFFFF CALL 7GATES .00 4 01 2 21 ; 7GATES .00 4 01 2 21 00 4 01 3 43 |. 59 POP ECX 00 4 01 3 44. 7GATES .00 402 05A ; |Arg1 = 00 402 05A ASCII "You opened % gates" 00 4 01 3 56 |. E8 DCFEFFFF CALL 7GATES .00 4 01 2 37 ; 7GATES .00 4 01 2 37 00 4 01 3 5B |. 83C4 08 ADD ESP,8 00 4 01 3 5E |. EB 0B JMP. hoặc bằng. 00 4 01 2 C7 |. |7D 14 |JGE SHORT 7GATES .00 4 01 2 DD 00 4 01 2 C9 |. |8B55 FC |MOV EDX,DWORD PTR SS:[EBP-4] 00 4 01 2 CC |. |8B0C95 00 204 0>|MOV ECX,DWORD PTR DS:[EDX*4+ 402 000 ] 00 4 01 2 D3 |. |8B45