giống như hộp dựng banh tennis, khi bạn bỏ trái banh nào vào đầu tiên thì bạn phải lấy ra sau cùng ,vì bỏ vào trước thì trái banh sẽ nằm ở phía dưới đáy hộp.Như vậy trái banh sau cùng bỏ vào thì sẽ được lấy ra đầu tiên. Do đó 1 tên khác của STACK là LIFO (Last In,Fist Out : đến sau cùng, ra trước tiên) Để dò tìm trong STACK , bộ xử l dùng 2 thanh ghi là ESP (Stack pointer: con trỏ ngăn xếp ) trỏ đến đỉnh STACK và SS (Stack segment) giữ lại địa chỉ đọan . Đến đây bạn ko hiểu cũng ko sao, bạn chỉ nhớ cặp thanh ghi SS:ESP dùng để lấy “trái banh tenis” ở đỉnh hộp ra. Với cách lưu trữ như trên chúng ta mới có thể lấy đúng các địa chỉ trở về khi các hàm gọi (Call) nhau “í ới” như ví dụ sau: Quote: 5136:0100 CALL 0200 5136:0103 INT 20 5136:0200 CALL 0200 5136:0203 RET 5136:0300 CALL 0400 5136:0303 RET 5136:0400 RET Ở đây tại địa chỉ 100h gọi chỉ thị 200h, bộ vi xử ly’ sẽ nạp địa chỉ trở về 103h vào Stack để biết đường trở về, sau đó nhảy đến địa chỉ 200h để thực hiện lệnh ở đó. Lúc này trong Stack sẽ là: Quote: STACK : 103h Đến địa chỉ 200h nó gặp lệnh gọi chỉ thị tại địa chỉ 300h. Trước khi đi đến địa chỉ 300h, nó phải lưu địa chỉ trở về là 203h vào Stack. Lúc này trong stack là: Quote: STACK : 103h 203h Đến địa chỉ 300h lại gặp lệnh gọi 400h, lại phải nạp địa chỉ trở về là 303h vào Stack: Quote: STACK : 103h 203h 303h Bây giờ đến 400h gặp lệnh RET trở về , nó vào Stack dùng SS:ESP lấy địa chỉ ở đỉnh Stack là 303h để quay về. Đến đây trong Stack chỉ còn : Quote: STACK : 103h 203h Đến 303h gặp RET, nó lại vào Stack dùng SS:ESP lấy địa chỉ ở đỉnh stack hiện giờ là 203h để quay về. Tương tự như vậy khi quay về tại 103h gặp chỉ thị INT 20 thì kết thúc chương trình. Những điều tui mô tả ở trên hơi khó hiểu và chán nhưng hiểu được Stack thì sẽ giúp bạn rất nhiều sau này. Chắc các bạn cũng đã từng thấy trong forum có các bài viết nói về crack theo phương pháp dùng Stack, bây giờ thì các bạn đã hiểu được phần nào về nó. Trở lại SI, ta nói về F11 nhé. Như các bạn biết F11=”^G @SS:ESP;” Đến đây thì bạn đã hiểu được chức năng của nó rồi. F11 sẻ bắt SI “go” từ vị trí địa chỉ hiện tại “trôi qua” các chỉ thị lệnh rồi đến địa chỉ mà cặp thanh ghi SS:ESP trỏ đến (tức là địa chỉ ở đến đỉnh stack). Giả sử tui đang đứng tại vị trí 200h trong ví dụ trên, nếu dùng lệnh F12 thì chương trình chạy đến đâu gặp lệnh RET đầu tiên thì ngừng, vậy đến địa chỉ 400h thì SI ngừng. Còn nếu dùng lệnh F11 thì chương trình sẽ chạy dến địa chỉ ở đỉnh Stack lúc này là 103h thì ngừng . Vậy là hiểu F11 và F12 rồi hé. Nói chung dùng F11 hay F12 gì cũng được, miễn sao đến chương trình cần crack nhanh nhất là được . Thường thì F11 nhanh hơn, nhưng nếu các bạn đến đích không được thì dùng F12. Còn nếu các bạn “sáng kiến” kết hợp dùng F11 rồi F12 tá lã thì coi chừng “die” luôn vì khi dùng F12 trước khi đến lệnh RET mà nó gặp lệnh push hay pop làm thay đổi stack thì khi dùng F11 máy tính của ta điên luôn. (hí hí tui cũng đã thử rồi) Theo như benina thì dùng lệnh F12 chắc ăn hơn . Vậy chúng ta nên thống nhất dùng F12 đi nhé. Các bạn thấy tui lãng xẹt không, giải thích F11 cho đã rồi kêu dùng F12. híhíhí . Ở đây benina chỉ muốn giới thiệu các bạn khái niệm về Stack mà thôi. Hiểu nó thì dễ dàng cho chúng ta sau này. Bây giờ còn phải giải thích về F10, F8 và F5 nữa .Đúng là làm newbie mệt thiệt. Hình như tui đi lạc đề rồi, chúng ta đang nói về công việc crack trong SI mà. Uhm, vậy chúng ta trở lại vấn đề chính nhe. Đến đây là chúng ta chúng ta đã vào được đọan mã của chương trình cần crack bằng cách nhấn F12. - Bước 5 : Bước kế tiếp là chúng ta phải biết được chúng ta đang đứng đâu trong chương trình để bắt đầu dò tìm tử nguyệt của nó.Trước tiên tui xin giới thiệu về 2 hàm thường dùng để đặt breakpoint trong SI là hmemcpy và GetDlgItemTextA để từ đó chúng ta hiểu được hiện dữ liệu trong chương trình đang chứa gì , và chúng ta đang đứng đâu trong nó. a) Hàm hmemcpy có nghĩa như sau: Quote: Hàm Hmemcpy là 1 hàm API dùng để đọc, thao tác, so sánh, và đặt string vào vùng nhớ RAM. Hàm này lấy thông tin của bạn nhập vào và đặt nó vào vùng nhớ. Sau đó thao tác trên chúng như so sánh , di chuyển (Ví dụ như so sánh số serial đúng và fake serial mà ta nhậo vào). Có rất nhiều chương trình sử dụng hàm này, nên thường khi crack ta đặt breakpoint tại hàm này. b) Hàm GetDlgItemTextA như sau: Quote: UINT GetDlgItemText( HWND hDlg, // handle of dialog box (handle của hộp dialog) int nIDDlgItem, // identifier of control (nhận dạng của điều khiển) LPTSTR lpString, // address of buffer for text (địa chỉ buffer của đọan text mà ta đã nhận được) int nMaxCount // maximum size of string (Kích thước qui định lớn nhất của chuổi string mà ta đã nhận được, nếu lớn hơn thì sẽ bị cắt phần dư) ); (tìm đọc phần 2 của tut HowtobecomeCracker để có khái niệm về hDlg và nIDDlgItem) Return Values (Giá trị trở về của hàm): Nếu hàm tiến hành thực thi , thì giá trị trở về của hàm là số k y’ tự được copy vào buffer (chúng ta sẽ tìm hiểu buffer là gì sao, các bạn chỉ hiểu nôm na đó là 1 địa chỉ tạm thời trong bộ nhớ),không bao gồm k y' tự null báo cho máy tính biết là điểm kết thúc của chuổi ký tự. Nếu hàm thực thi sai, giá trị trở về là zero Tóm lại: Hàm GetDlgItemTextA cho ta biết bao nhiêu k y’ tự đã nhập vào. Ví dụ ta nhập : name: benina ; thì hàm GetDlgItemTextA sẽ cho giá trị trở về là 6 chứa trong thanh ghi EAX. Vì vậy sau hàm GetDlgItemTextA thường là các "tiết mục" xử l y’ thanh ghi EAX Đến đây là phần quan trọng mà tui muốn nói đây: Giả sử chương trình yêu cầu bạn nhập : Name : benina Password : 123456789 Bạn đặt breakpoint trong SI là bpx getdlgitemtexta Thóat SI và cho chương trình chạy tiếp (bấm OK trong hộp registeration) SI sẽ ngắt chương trình tại hàm getdlgitemtexta đầu tiên xử l y’ chuổi name, vậy muốn chương trình chạy đến đọan mã xử lý chuổi password thì ta bấm F5. SI sẽ thóat ,rồi chạy tiếp chương trình ,khi gặp hàm getdlgitemtexta xử l y’ chuổi password thì ngắt (break). Đến đây chúng ta lại biết thêm 1 chức năng nữa của SI là phím F5. F5=”^x” F5 chỉ là lệnh thóat khỏi SI , trong trường hợp này thay vì bấm F5 ta bấm CTRL+D cũng được. Vậy CTRL+D khác F5 như thế nào? Thưa bạn CTRL+D gọi hay thóat khỏi SI đều được. Còn F5 ko gọi được SI mà chỉ thóat khỏi SI mà thôi. Vậy khi viết tut sau này, ví dụ tui nói bạn bấm 2 lần F5 là bạn hiểu như thế nào rồi nhé. Đối với hàm hmemcpy ta cũng làm tương tự như trên, để đến đọan mã xử ly’ password ta bấm F5 như trên. Phải công nhận để newbie hiểu thì phải viết dài dòng lê thê có nhiều khi đến Xomali luôn nà cũng chưa muốn dừng. - Bước 6 :Đến đây tui xin mô tả 1 y' tưởng crack ứng dụng những kiến thức ở tut 2A: Như các bạn biết , sau khi sử dụng F5 , chúng ta hiện đứng tại đọan mã bắt đầu xử lý chuổi password. Vậy password của chúng ta đang nằm đâu đó trong bộ nhớ , y’ tưởng crack ở đây là đặt breakpoint tại địa chỉ của password trong bộ nhớ. Bất cứ khi nào chương trình “đụng” đến nó như read, write thì SI sẽ ngắt và báo cho chúng ta biết để dễ dàng tìm ra tử nguyệt (ví dụ như khi so sánh pass nhập vào và serial đúng, thì chương trình phải read password trong bộ bộ nhớ khi ấy SI sẽ bào cho ta biết …hehe). Muốn vậy ta làm như sau: Như tut 2A đã nói , đầu tiên ta xem pass của chúng ta nằm đâu trong bộ nhớ, dùng lệnh: s 0 l ffffffff ‘chuổi pass đã nhập’ ví dụ : s 0 l ffffffff ‘123456789’ SI sẽ cho ta biết địa chỉ pass đang nằm trong bộ nhớ : ví dụ là 015f:0063f580 Sau đó đặt breakpoint tại địa chỉ này : BPM 015f:0063f580 Hay BPR 015f:0063f580 015f:0063f580+9 rw (+9 ở đây là chiều dài chuổi pass của chúng ta) Sau đó bấm CTRL+D để thóat SI cho chương trình chạy xem sao. Từ trước đến giờ chưa bao giờ benina thực hiện đặt breakpoint kiểu này thành công . Máy của benina chưa bao giờ snap (bắt dính) được điều này. Benina có đọc 1 tut của nước ngòai nói về điều này là do SI dùng trong bộ xử l y’ pentium nên ko thể thực hiện được như những gì đã nói ở trên (ko biết có đúng ko). Nhưng dù sao đi nữa tui cũng muốn bạn nên thử xem sao. - Bước 7 : Nếu chúng ta chưa tìm ra tử nguyệt theo cách trên thì chúng ta buộc phải dò tìm từng dòng lệnh thôi. Muốn thi hành từng lệnh 1 ta dùng F10 hoặc F8. Tui xin trích dẫn lời giải thích của Cracker Hacnho về F10 và F8 như sau: “Bạn có thể cho SoftICE thi hành từng lệnh một bằng cách dùng lệnh P (hay nhấn F10) hoặc lệnh T (hay nhấn F8). Sự khác nhau giữa 2 lệnh này là ở chổ lệnh P xem 1 lời gọi hàm Call xxxx như 1 lệnh đơn lẻ và cho thi hành toàn bộ thủ tục xxxx được gọi bởi lệnh Call này, sau đó dừng lại ở lệnh kế tiếp ngay sau lệnh Call xxxx, còn lệnh T sẽ nhảy đến dòng lệnh đầu tiên của thủ tục xxxx và dừng lại. Lệnh T tất nhiên sâu sắc hơn lệnh P nhưng lúc nào cũng dùng nó thay thế cho lệnh P thì không phải là 1 ý hay, bạn rất dễ bị lệnh này dẫn đến 1 thủ tục không đâu và "quên cả đường về". Điều quan trọng là phải biết lúc nào cần dùng T và lúc nào cần dùng P. Thời gian sẽ dạy cho bạn điều đó. “ Tui xin lấy ví dụ sau để mô tả : Ta có đọan mã sau: Quote: * Reference To: USER32.GetDlgItemTextA, Ord:0102h | :004010DB E852010000 Call 00401232 :004010E0 0BC0 or eax, eax :004010E2 7405 je 004010E9 :004010E4 83F804 cmp eax, 00000004 :004010E7 7315 jnb 004010FE . USER32.GetDlgItemTextA, Ord: 01 0 2h | :00 4 01 0 DB E852 01 0 00 0 Call 00 4 01 2 32 :00 4 01 0 E0 0BC0 or eax, eax :00 4 01 0 E2 7 405 je 00 4 01 0 E9 :00 4 01 0 E4 83F 804 cmp eax, 00 000 004 :00 4 01 0 E7 7 315 jnb 00 4 01 0 FE . Quote: 513 6: 01 0 0 CALL 02 00 513 6: 01 0 3 INT 20 513 6 :02 00 CALL 02 00 513 6 :02 03 RET 513 6 :03 00 CALL 04 00 513 6 :03 03 RET 513 6 :04 00 RET Ở đây tại địa chỉ 10 0h gọi chỉ thị 200 h, bộ. : ví dụ là 01 5 f :00 63f5 80 Sau đó đặt breakpoint tại địa chỉ này : BPM 01 5 f :00 63f5 80 Hay BPR 01 5 f :00 63f5 80 01 5 f :00 63f5 80+ 9 rw (+9 ở đây là chiều dài chuổi pass của chúng ta) Sau đó bấm CTRL+D