004012FA /$ 33D2 XOR EDX,EDX 004012FC |. 33C9 XOR ECX,ECX ; <== ECX = 0 004012FE |> 02D0 /ADD DL,AL ; <== DL = DL + AL 00401300 |. 41 |INC ECX ; <== ECX = ECX + 1 00401301 |. C1C8 08 |ROR EAX,8 00401304 |. 83F9 04 |CMP ECX,4 ; <== If ECX < 4 Then Loop 00401307 |.^ 75 F5 \JNZ SHORT SV_Keyge.004012FE 00401309 |. 80FA 54 CMP DL,54 ; <== If DL = 0x54 Then Continue Check Đoạn code này tính giá trị DL = tổng của 4 byte cuối (thông qua lệnh ROR EAX,8). If DL = 0x54 thì tiếp tục check típ. Tất nhiên là tới địa chỉ 00401307 ta lại change cờ Z từ 0 thành 1 để đi tiếp xem sao : 0040130E |. 8D3D 46304000 LEA EDI,DWORD PTR DS:[403046] ; <== EDI = 403046 00401314 |. 33DB XOR EBX,EBX ; <== EBX = 0 00401316 |> 3107 /XOR DWORD PTR DS:[EDI],EAX ; <== XOR 00401318 |. 83C7 04 |ADD EDI,4 ; <== EDI = EDI + 4 0040131B |. 43 |INC EBX 0040131C |. 83FB 07 |CMP EBX,7 0040131F |.^ 75 F5 \JNZ SHORT SV_Keyge.00401316 ; <== LOOPING Vòng lặp code này đem XOR 1 Table mặc định với giá trị EAX (vẫn là 4 bytes cuối của Table 8 bytes). Sau khi kết thúc vòng lặp xong : 00401321 |. 8D3D 46304000 LEA EDI,DWORD PTR DS:[403046] ; <== EDI = 403046 00401327 |. FFD7 CALL EDI Chẹp, đoạn này giống đoạn CALL EDI lúc trước quá. Trace into vào trong : Các opcode vẫn đang trong trường hợp của Merc nha. Vậy thì đây roài, ta phải làm sao để khi XOR EAX (4 bytes cuối) với Table tại địa chỉ 403046 thì được các opcode dạng thế này : 6A 00 68 ?? ?? 40 00 <== Push Title 68 ?? ?? 40 00 <== Push Text : Phải là GoodBoy 6A 00 <== Push hwnd E8 0D E3 FF FF <== Call MessageBoxA Chắc hẳn các bạn sẽ hỏi cái này Merc lấy ở đâu ra ? Câu trả lời là từ … NAG và từ suy luận mà ra. Đây là Calling Conventions của hàm MessageBoxA mà. Giờ đặt Encrypt là Table ở địa chỉ 403046 lúc ban đầu : Encrypt : FE 00 68 FB A4 40 00 A8 B2 30 40 C0 FE 00 E8 CD 77 FF FF 03 04 90 90 50 00 00 Decrypt : 6A 00 68 3B 30 40 00 68 26 30 40 00 6A 00 E8 0D E3 FF FF C3 04 90 90 50 00 00 Key : 94 00 00 C0 Key ở đây chính là giá trị 4 bytes cuối của table 8 bytes ha. Nhưng cái C3 ở đâu mà có vậy. Ờ thì thực hiện gọi Goodboy xong thì nó phải RET để quay trở lại vùng code sau hàm CALL EDI chớ. Không nó cứ ở trong đấy mãi àh . Đơn giản ghê :D. Hê xem nào : 94 + C0 – FF – 1 = 0x54. Tuyệt. Tiếp nào : 00404026 chính là địa chỉ của chuỗi : “Yeah that’s right !!”. Goodboy roài :D. Oki, có được 4 bytes cuối rồi, coi như ta có được 50% Serial roài. Còn 4 bytes đầu giờ tính thế nào đây. Nào bây giờ restart lại crackme – nhập : Name : Merc Code : 12345678D96572A3 F9 và trace into vào đây : 00401265 . 8D3D 68324000 LEA EDI,DWORD PTR DS:[403268] 0040126B . FFD7 CALL EDI ; <== Trace into Hê trace vào em nó cóc exception mới đau. Vậy phải change Code (mọi người cứ làm thế nào cho nó bị exception là oki) : Name : Merc Code : AAAAAAAAD96572A3 Exception roài : Stack Window : ESP đang trỏ tới Address chứa giá trị Exception là : C0000096. Now nhấn F8 để trace tới 7C90EAF5 và trace into. Sau đó trace downward tới đây : 7C93785B E8 F3BEFCFF CALL ntdll.7C903753 ; <== Trace into Tới đây tiếp : 7C903786 E8 0E000000 CALL ntdll.7C903799 ; <== Trace into Tới đây tiếp : 7C9037BD FFD1 CALL ECX ; <== Trace into 00401000 /. 55 PUSH EBP 00401001 |. 8BEC MOV EBP,ESP 00401003 |. 52 PUSH EDX 00401004 |. 8B55 08 MOV EDX,[ARG.1] 00401007 |. FF32 PUSH DWORD PTR DS:[EDX] 00401009 |. 8F05 90364000 POP DWORD PTR DS:[403690] ; <== Nhìn coi Hê hê, giá trị [403690] nhận được từ đây nè. Lão tác giả code cái crackme này hay ghê. Và giá trị của nó chính là giá trị exception mà ESP ban nãy trỏ tới. Như vậy để bypass nốt cái đoạn check này : 00401288 . 83C7 04 ADD EDI,4 0040128B . 8B07 MOV EAX,DWORD PTR DS:[EDI] 0040128D . 3B05 90364000 CMP EAX,DWORD PTR DS:[403690] 00401293 . 75 1C JNZ SHORT SV_Keyge.004012B1 Thì mọi người hiểu phải làm sao rùi chứ. Ở đây Merc vẫn nhắc lại là EAX = C0000094 nha (vì nó nhận giá trị 4 bytes cuối theo qui tắc reverse order – bị đảo ngược lại ấy mà : tức là trong vùng nhớ (cửa sổ dump ấy) là : 94 00 00 C0 thì EAX = C0000094). Oki như vậy giá trị Exception ờ hàm CALL EDI đầu tiên phải có giá trị C0000094. Google em nó phát, ra luôn đây là exception từ lỗi divide by zero. Oki như vậy Opcode tại hàm CALL EDI đầu tiên phải ít nhất có dạng : 00403268 F7F1 DIV ECX 0040326A 90 NOP 0040326B 90 NOP 0040326C 94 XCHG EAX,ESP 0040326D 0000 ADD BYTE PTR DS:[EAX],AL 0040326F C000 00 ROL BYTE PTR DS:[EAX],0 Vì lúc này ECX đang bằng 0 mùh. Vậy cuối cùng Key : F7F19090940000C0. Key này được tính từ đoạn code lấy 2 kí tự trong szCode convert qua HEX rồi XOR với từng kí tự trong szName. Cuối cùng có 1 solution : Name : Merc Serial : BA94E2F3D96572A3 Đến đây code Keygen không còn là vấn đề nữa nhỉ :) III. Conclusion : Lâu rùi Merc chưa viết 1 Tut nào cho REA. Từ trước đến nay chả ai khen Merc diễn đạt dễ hiểu, thế mà lại lười viết, giờ lại viết 1 Tut đi phân tích Code kiểu này. Chắc chắn là dài dòng và có những chỗ khó hiểu. Mong mọi người thông cảm. Những chỗ nào chưa đúng thì mọi người chỉ rõ cho Merc thấy nhé. Mong là với Tut nhỏ này, các bạn newbie có thêm một chút kinh nghiệm trong việc đọc code và suy luận. Tất cả chỉ là vấn đề thời gian :). Best Regards ! [Merc] ++ ==[ Greatz Thanks To ]== ++ My family, Computer_Angel, Moonbaby , Zombie_Deathman, Littleboy, Benina, QHQCrker, The_Lighthouse, Kienmanowar, Hoadongnoi, Nini, all REA‘s members, Zoi, TQN, HacNho, RongChauA, Deux, tlandn, light.phoenix, dqtln, dump, ARTEAM all my friend, and YOU. ++ ==[ Thanks To ]== ++ PhuongThanh37, hurt_heart, thienthandien, iamidiot, WhyNotBar, trickyboy, dzungltvn, takada, haule_nth, hytkl, clarken vv các bạn đã đóng góp rất nhiều cho REA. Hi vọng các bạn sẽ tiếp tục phát huy :) ++ ==[ Group Greetings ]== ++ EXETOOLS ~ WOODMAN ~ ARTEAM ~ SNDTEAM ~ TSRh ~ PEDIY ~ ICUTEAM … ++ ==[ Kiss To My Love :) ]== ++ 16-9-2006 Act I: W32.TrivialOverwrite. (Lưu ý các bác nên đỗi tên File virus w32.TO.exe thành w32.TO.exe.bak, thì các chương trình chống vi rus khác sẽ cho bạn debug, cũng như là làm những cái káhc trên nó). Requirements: -) Những hiểu biết cơ ba3n về 32 bit – ASM và windows api's. -) PE explorer or Một tool giống như vậy. -) PEid, or một trình phân tích dấu tích Portable Executable packer/compiler. -) Và một hiểu biết cơ bản về công cụ đang sử dụng. Description: . chỉ 403 046 lúc ban đầu : Encrypt : FE 00 68 FB A4 40 00 A8 B2 30 40 C0 FE 00 E8 CD 77 FF FF 03 04 90 90 50 00 00 Decrypt : 6A 00 68 3B 30 40 00 68 26 30 40 00 6A 00 E8 0D E3 FF FF C3 04 90. này : 00 4 01 2 88 . 83C7 04 ADD EDI,4 00 4 01 2 8B . 8B07 MOV EAX,DWORD PTR DS:[EDI] 00 4 01 2 8D . 3B05 903 6 400 0 CMP EAX,DWORD PTR DS:[ 403 6 90] 00 4 01 2 93 . 75 1C JNZ SHORT SV_Keyge .00 4 01 2 B1 Thì. PUSH EDX 00 4 01 0 04 |. 8B55 08 MOV EDX,[ARG .1] 00 4 01 0 07 |. FF32 PUSH DWORD PTR DS:[EDX] 00 4 01 0 09 |. 8F05 903 6 400 0 POP DWORD PTR DS:[ 403 6 90] ; <== Nhìn coi Hê hê, giá trị [ 403 6 90] nhận được