Nó sẽ hiện ra như thế này : 00) BPX USER32!GetWindowTextA C=01 Để ra khỏi SoftICE, các bác ấn Ctrl-D hoặc F5 hoặc dùng lệnh X. Okey, các bác đã bẫy bất kì lệnh gọi GetWindowTextA. Bây giờ các bác hãy nhập số nào đó (ta gọi là FS nha) và ấn OK… chuyện gì sẽ xảy ra? Còn gì nữa, 1 cái nag văng ra nói rằng bác nhập sai registration number. Nhưng như dzậy có nghĩa là sao, nghĩa là nó không gọi hàm GetWindowTextA, vậy thì chúng ta sẽ thử với GetDlgItemTextA. Nhưng trước hết chúng ta phải xóa cái breakpoint đã đặt đi đã. Vào SoftICE đánh : bc 0 , xong chúng ta set breakpoint mới : BPX GetDlgItemTextA Chúng ta hãy thử lại nha 3.1.3 Làm việc với SoftICE Oh, nó đã làm việc! Bây giờ chúng ta… uống ly nước đã, em khát nước quá rùi ;)) OK, bây giờ chúng ta đang ở trong SoftICE , tại cái nơi mà function GetDlgItemTextA bắt đầu. Để “nhảy” đến nơi mà nó được gọi, các bác hãy nhấn F11. Rùi, chúng ta đang ở trong SGLSET.EXE , nếu các bác không biết thì các bác hãy nhìn vào dòng nằm giữa khung code window và comand window, các bác sẽ thấy như thế này: SGLSET!.text+1B13 Bây giờ các bác có thể disable breakpoint bằng lệnh : bd 0 Nếu các bác muốn enable nó lại thì các bác dùng lệnh : be 0 Các bác nhìn vào dòng đầu tiên trong code window : CALL [USER32!GetDlgItemTextA] Để thấy những lệnh ở trên, các bác nhấn Ctrl-Up. Nếu các bác không bít gì về Assembler thì các bác hãy nhìn xuống đây : RET Kết thúc function PUSH EBP___________________________Bắt đầu function MOV EBP,ESP SUB ESP,0000009C PUSH ESI LEA EAX,[EBP-34] ___________________ EAX=EBP-34 PUSH EDI MOVE ESI,ECX PUSH 32 _____________________________Lưu chiều dài của FS PUSH EAX___________________________ Lưu địa chỉ của text buffer PUSH 000003F4_______________________Lưu Identifier của control PUSH DWORD PTR [ESI+1C]______________Lưu handle của dialog CALL [USER32!GetDlgItemTextA] _________Chúng ta đang ở đây Em xin giải thích chút xíu : lệnh PUSH có nhiệm vụ lưu lại giá trị cho lần sử dụng sau. Các bác chú ý vào 2 dòng màu đỏ. Nhìn vào đoạn lệnh trên chúng ta bít được địa chỉ của text buffer đã được cất giữ trong EAX, và EAX đó là EBP-34. Bây giờ chúng ta hãy nhìn vào EBP-34, nó sẽ như thế này : d ebp-3 Chúng ta nhấn F10 đến khi thấy cái gì liên quan đến EBP-34, và nó đây (không bít có giống của các bác không) : LEA EAX, [EBP+FFFFFF64]_______________EAX=EBP-9C LEA ECX, [EBP-34]_____________________ECX=EBP-34 PUSH EAX____________________________ Lưu EAX PUSH ECX_____________________________Lưu ECX CALL 00403DD0______________________Gọi function ADD ESP, 08__________________________Xóa thông tin đã lưu TEST EAX, EAX_________________________Kiểm tra function lần nữa JNZ 00402BC0________________________Nhảy nếu không bằng 0 Theo em thì đây là 1 đoạn code so sánh, nó làm việc như thế này : Nhập vào 2 giá trị , trở về 0 nếu 2 giá trị bằng nhau, còn không bằng nhau thì khác 0. Okey, cái gì nằm phía sau [EBP+FFFFFF64], do SoftICE không thể tự negative number, nên để tìm giá trị thật của nó các bác làm phép tính như thế này: 100000000 – FFFFFF64 = 9C Trong SoftICE , các bác cũng có thể thực hiện phép tính ấy bằng lệnh : ? 0 – FFFFFF64 Tại sao là 0 mà không phải 100000000 ( không lẽ 0=100000000 => điều này trái với các quy tắt toán học ) ? Đó là số 100000000 qua lớn đối với SoftICE, nhưng khi ta thay 100000000 bằng 0 thì nó cũng cho kết quả như vậy. Và bây giờ là lúc xem cái gì nằm phía sau EBP-9C ( hồi hộp quá ) , các bác làm như sau : d ebp-9c Ah, data window hiện ra cho chúng ta 1 dãy số - registration number đây ư ? không đâu ( mà sao cái số này giống cái số mà hồi nãy ta nhập vào quá hen ) . Các bác có nhớ đoạn code ở trên không, nó so sánh 2 số : 1 là số ta nhập vào , còn số thứ 2 chính là registration number. Do vậy chúng ta tiếp tục “nhảy” với F10 nha ;) ( cố lên các bác , thằng TaskLock sắp là của các bác rùi đấy) . Và chúng ta sẽ đến đoạn code này đây ( nó giống đoạn code ở trên đấy các bác ạ ) : LEA EAX, [EBP-68] ____________________EAX=EBP-68 LEA ECX, [EBP-34]_____________________ECX=EBP-34 PUSH EAX____________________________Lưu EAX PUSH ECX____________________________ Lưu ECX CALL 00403DD0________________________Gọi function ADD ESP, 08_________________________Xóa thông tin đã lưu TEST EAX, EAX________________________Kiểm tra function lần nữa JNZ 00402BFF _______________________Nhảy nếu không bằng 0 Và các bác hãy chú ý đến dòng LEA EAX, [EBP-68] , nó dấu cái gì vậy ? Thui thắc mắc làm cái gì, ta dùng lệnh d là biết nó dấu gì thui mà. Nào, các bác đánh cùng em nha : d ebp-68 Hehehe, đây rùi, cuối cùng thì cái registration number nó cũng vác mặt ra !!! Mong rằng các bác cũng làm được như em. Bye các bác nha, hẹn gặp lại ở phần sau !!! (típ theo) 3.2 Phần mềm thực hành : Command Line 95 Đây là 1 chương trình khá dể, nó chỉ dùng 1 đoạn code đơn giản để tính số serial, do đó chúng ta sẽ dùng nó để làm ví dụ. 3.2.1 Tìm hiểu về chương trình Sau khi kiểm tra (cách kiểm tra xem ở phần trước), các bác bít đây là 1 chương trình 32bit, và nó yêu cầu chúng ta nhập tên đăng kí và registration trong 1 hộp thoại. Okie, sau khi bít những thông tin “quý báu” trên, chúng ta sẽ đến bắt đầu “bẫy” nó. Hehehe dzui qua’ ;)) 3.2.2 “Bẫy” các chuỗi code Giống như với TaskLock “xấu số”, chúng ta sẽ đặt breakpoint. Chúng ta có thể set breakpoint cho cả 2 function : GetWindowTextA và GetDlgItemTextA. Vào SoftICE (đừng nói là các bác không bít vào nha, đọc đến đây rùi mà nỡ nói 2 chữ không bít là buồn em lắm đó), rùi đánh : BPX GetWindowTextA BPX GetDlgItemTextA Bây giờ chúng ta mở hộp thoại đăng ký ra, nhập tên ( gọi là FN – Fake Name ) và nhập số nào đó ( em nhập là 12345 và ta hãy gọi số này là FS – Fake Serial ), sau đó nhấn OK… Và… BÙM, SoftICE nhảy ra giữa màn hình tại function GetDlgItemTextA. Cũng như với TaskLock, chúng ta nhấn F11 để trở về đoạn lệnh gọi function. Chúng ta nhấn Ctrl-Up để kéo màn hình lên trên và sẽ thấy đoạn code sau : MOV ESI,[ESP+0C] PUSH 1E_____________________________Lưu chiều dài lớn nhất của FN PUSH 0040A680_______________________Địa chỉ đến buffer PUSH 000003ED_______________________Control handle PUSH ESI_____________________________Dialog handle CALL [USER32!GetDlgItemTextA] Các bác có thấy cái gì không ? Đó là số 40A680. Để xem nó giấu cái gì nào, okey chúng ta hãy đánh : d 40A680 Và cái gì hiện ra trong data window vậy các bác. Well, chúng ta hãy nhìn vào phần đầu của đoạn code : PUSH 00 PUSH 00 PUSH 000003F6_______________________Control handle MOV EDI, 00401680___________________Lưu địa chỉ đến buffer PUSH EDI____________________________Dialog handle CALL [USER32!GetDlgItemInt] Chắc các bác đang thắc mắc GetDlgItemInt là cái quái gì phải không ? Ở đây em xin nói ngoài lề 1 chút : GetDlgItemInt là 1 function giống với GetDlgItemText, nó trả về giá trị integer từ hộp thoại text. Nó được trả về trong EAX, vì vậy chúng ta “nhảy” qua đoạn lệnh này, và nhìn vào register window … Của em là nó như thế này : EAX=00003039 Và để biết 3039 là cái gì, chúng ta đánh : ? 3039 Okey, chúng ta sẽ có gì nào : 00003039 0000012345 “09” ___|_________|________| ___|_________|________| __hex_______dec______ascii Như các bác thấy, nó hiện ra FS mà chúng ta đã đánh vào ban nãy. Bây giờ chúng ta típ tục, các bác hãy nhìn vào đoạn code theo sau, trước tiên là FS đã được lưu lại : MOV [0040A548], EAX___________________Lưu FS MOV EDX, EAX_________________________”đặt” FS vào EDX 3.1.3 Đoạn code tính số serial Và đây chính là đoạn code tính số serial : MOV ECX, FFFFFFFF______________________Tính chiều dài FN SUB EAX, EAX REPNZ SCASB NOT ECX DEC ECX_______________________________EAX chứa chiều dài FN MOVSX EAX, BYTE PTR [0040A680]____________Nhận byte tại 40A680 IMUL ECX, EAX___________________________ECX = ECX * EAX SHL ECX, 0A____________________________Đổi chỗ 0A ADD ECX, 0002F8CC______________________Thêm 2F8CC vào kết quả MOV [0040A664], ECX Và đây mới là đoạn code mà ta mong đợi nhất ( cố lên các bác, sắp xong rùi :) : CMP ECX, EDX___________________________So sánh EAX và EDX JZ 00402DA6___________________________Nhảy nếu bằng Sau khi “nhảy” đến CMP ECX,EDX , các bác có thể xem đoạn code thực của nó bằng cách đánh vào : ? ecx Và nó sẽ hiện ra như sau (không bít có giống của các bác không) : 000DC0CC 0000901324 Hehehehhe……đến đây thì chúng ta đã có được registration number của mình rùi đó là 901324. Bây giờ các bác thử nhập lại registration number xem có được không, được quá đi chứ lị :))))))) 4. Tạo keymaker cho phần mềm Command Line 95 =============================== Chúng ta nhìn vào đoạn code tính số serial ở trên, và dịch nó sang C. Em làm ví dụ này để thấy làm thế nào để tính được real serial : Real serial= [( kí tự viết hoa đầu tiên * chiều dài của chuỗi)<< 0x0A ]+0x2F8CC Ở đây các bác chú ý 2 vấn đề : + các kí tự trong FN sẽ được chuyển sang chữ hoa khi bạn gõ chúng trong text box. + “<< 0x0a” có nghĩa là “ nhân với 2^10” Trong C nó sẽ như thế này : #include <string.h> #include <stdio.h> int main() { unsigned long code; unsigned char buffer[0*1e]; . thế này: 10 000 000 0 – FFFFFF64 = 9C Trong SoftICE , các bác cũng có thể thực hiện phép tính ấy bằng lệnh : ? 0 – FFFFFF64 Tại sao là 0 mà không phải 10 000 000 0 ( không lẽ 0 = 10 000 000 0 => điều. 0 = 10 000 000 0 => điều này trái với các quy tắt toán học ) ? Đó là số 10 000 000 0 qua lớn đối với SoftICE, nhưng khi ta thay 10 000 000 0 bằng 0 thì nó cũng cho kết quả như vậy. Và bây giờ là lúc xem cái. window … Của em là nó như thế này : EAX =00 003 039 Và để biết 303 9 là cái gì, chúng ta đánh : ? 303 9 Okey, chúng ta sẽ có gì nào : 00 003 039 00 00 012 345 09 ” ___|_________|________| ___|_________|________|