HVA Forum > Box thảo luận Reverse Engeneering, tutorial Reverse Engeneering > CrackMe dành cho NEWNEWBIE Posted by: moonbaby Dec 9 2003, 10:43 AM Homepage : http://crackme.de CrackMe : crackme1.zip ( crackme1.exe ) Coder : BadSector ( 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 ở hai điểm sau : 00401148 . E8 DE000000 CALL <JMP.&USER32.GetDlgItemTextA> ; \GetDlgItemTextA 004011C8 . E8 5E000000 CALL <JMP.&USER32.GetDlgItemTextA> ; \GetDlgItemTextA >> >> Kiểm tra chuỗi nhập vào : 00401148 . E8 DE000000 CALL <JMP.&USER32.GetDlgItemTextA> ; \GetDlgItemTextA 0040114D . 83F8 00 CMP EAX,0 < == Nhảy nếu chuỗi không được nhập 00401150 . 0F84 99000000 JE Crackme1.004011EF 00401156 . 83F8 04 CMP EAX,4 < === Nhảy nếu chuỗi nhập ít hơn 4 ký tự 00401159 . 0F82 90000000 JB Crackme1.004011EF Dò theo địa chỉ 004011EF , thì đây là xuất hiện thông báo sai, yêu cầu làm lại. >> >> Quá trình tạo chuỗi đầu tiên : xét từ phải sang trái 00401168 > /0FBE81 F32040>MOVSX EAX,BYTE PTR DS:[ECX+4020F3] < == Xét từng ký tự 0040116F . |83F8 20 CMP EAX,20 00401172 . |74 07 JE SHORT Crackme1.0040117B 00401174 . |6BC0 04 IMUL EAX,EAX,4 00401177 . |03D8 ADD EBX,EAX 00401179 . |8BF3 MOV ESI,EBX 0040117B > |41 INC ECX 0040117C . |3B4D FC CMP ECX,DWORD PTR SS:[EBP-4] 0040117F .^\75 E7 JNZ SHORT Crackme1.00401168 >> Hai câu lệnh này là chuyển từng ký tự của U đã nhập vào EAX, và xét cho đến hết chuỗi 00401168 > /0FBE81 F32040>MOVSX EAX,BYTE PTR DS:[ECX+4020F3] 0040117F .^\75 E7 JNZ SHORT Crackme1.00401168 >> Hai câu lệnh này là để kiểm tra khoảng trắng ở đầu chuỗi U, nếu có thì 0040116F . |83F8 20 CMP EAX,20 00401172 . |74 07 JE SHORT Crackme1.0040117B >> Nhân EAX cho 4 sau đó cất kết quả vào EAX ( ở đây có nghĩa là nhân ký tự đầu của U được mã hoá sang số hex cho 4 ) 00401174 . |6BC0 04 IMUL EAX,EAX,4 >> Cộng EAX vào EBX và cất kết quả vào EBX, do ban đâu EBX = 0 nên EBX = EAX 00401177 . |03D8 ADD EBX,EAX >> Đưa giá trị của EBX vào ESI == > EBX = ESI 00401179 . |8BF3 MOV ESI,EBX >> Tăng giá trị ECX lên một, ở đây có thể coi ECX sẽ là biến đếm. 0040117B > |41 INC ECX >> Lệnh so sánh ở đây có nghĩa là kiểm tra xem đã đến cuỗi cuối chuỗi chưa, nếu đến rồi thì không nhảy, còn nếu chưa thì tiếp tục làm lại. ( EBP = 0012FBD8 nếu EPB-4 = 0012FBD4 ) 0040117C . |3B4D FC CMP ECX,DWORD PTR SS:[EBP-4] 0040117F .^\75 E7 JNZ SHORT Crackme1.00401168 >> Quay trở lại hai câu lệnh này : 00401177 . |03D8 ADD EBX,EAX 00401179 . |8BF3 MOV ESI,EBX >> Như thế, sau mỗi vòng lặp thì giá trị của EBX và ESI được cộng dồn lên. Hay dễ hiểu hơn là ta nói: EBX = ESI = (Tổng của tất cả các ký tự của U nhập ở dàn hex ) x 4 >> >> Quá trình mã hoá chuỗi thứ hai : xét từ trái sáng phải 00401186 . BB 89476500 MOV EBX,654789 0040118B > 0FBE81 F22040>MOVSX EAX,BYTE PTR DS:[ECX+4020F2] 00401192 . 4B DEC EBX 00401193 . 6BC3 02 IMUL EAX,EBX,2 00401196 . 03D8 ADD EBX,EAX 00401198 . 4B DEC EBX 00401199 . 49 DEC ECX 0040119A .^ 75 EF JNZ SHORT Crackme1.0040118B >> Đưa một số mặc định ( 654789 ) vào EBX , như vậy lúc này chỉ có ESI là chứa số được mã hoá ở giai đoạn một == > EBX = 00654789h 00401186 . BB 89476500 MOV EBX,654789 >> Xét từng ký tự của U đã nhập vào theo chiều từ phải sang trái ( ngược lại giai đọan một ). Quá trình được tiến hành cho đến hết chuỗi. 0040118B > 0FBE81 F22040>MOVSX EAX,BYTE PTR DS:[ECX+4020F2] 0040119A .^ 75 EF JNZ SHORT Crackme1.0040118B >> Trừ EBX đi 1 == > EBX = 00654788h 00401192 . 4B DEC EBX >> Nhân EBX cho 2 sau đó kết quả được cất ở EAX == > EAX = 00CA8F10h 00401193 . 6BC3 02 IMUL EAX,EBX,2 >> Cộng EAX và EBX, kết quả được cất ở EBX == > EBX = 012FD698h ADD EBX,EAX >> Trừ EBX đi 1, kết quả vẫn ở EBX == > EBX = 012FD697h 00401198 . 4B DEC EBX >> Trừ ECX đi 1, ở đây ECX chính là chiều dài chuỗi U đã nhập. 00401199 . 49 DEC ECX >> Như thế, sau mỗi vòng lặp kết quả sẽ đựơc cất ở EBX. == > EBX = DE52B947 >> >> Ở đây, chuỗi số mã hoá thứ hai này là một chuỗi số được mặc định sẵn, sự khác biết về kết quả chỉ là do số vòng lặp hay nói cách khác là do chiều dài chuỗi U đã nhập vào mà thôi. >> Vậy sau hai lần mã hoá ta có : ESI = 1438h : lưu kết quả chuỗi được mã hoá lần đầu EBX = DE52B947h : lưu kết quả chuỗi được mã hoá lần sau. >> >> Quá trình mã hoá chuỗi lần cuối , hay nói cách khác là kết hợp chuỗi . 0040119C . 56 PUSH ESI ; /<%lu> < == Chuỗi dạng HEX chuyển DEC 0040119D . 53 PUSH EBX ; |<%lX> < == Chuỗi giữ nguyên định dạng 0040119E . 68 C7204000 PUSH Crackme1.004020C7 ; |Format = "BS- %lX-%lu" 004011A3 . 68 BB214000 PUSH Crackme1.004021BB ; |s = Crackme1.004021BB 004011A8 . E8 6C000000 CALL <JMP.&USER32.wsprintfA> ; \wsprintfA Ở đoạn này chuỗi số của ESI được chuyển từ hệ 16 sang hệ 19 == > ESI = 1438h = 5176 0040119C . 56 PUSH ESI ; /<%lu> Chuỗi của EBX giữ nguyên định dạng tức là dạng hệ 16 được chuyển thành mã ASCII = DE52B947 0040119D . 53 PUSH EBX ; |<%lX> Kết hợp vào thành một chuỗi S thực, được cất ở EAX = BS-DE52B947- 5176 0040119E . 68 C7204000 PUSH Crackme1.004020C7 ; |Format = "BS- %lX-%lu" 004011A3 . 68 BB214000 PUSH Crackme1.004021BB ; |s = Crackme1.004021BB 004011A8 . E8 6C000000 CALL <JMP.&USER32.wsprintfA> ; \wsprintfA Kiểm tra chuỗi được nhập vào, nếu không nhập thì xuất hiện thông báo sai 004011C8 . E8 5E000000 CALL <JMP.&USER32.GetDlgItemTextA> ; \GetDlgItemTextA 004011CD . 83F8 00 CMP EAX,0 004011D0 . 74 1D JE SHORT Crackme1.004011EF Quá trình kiểm tra hai chuỗi S : 004011D4 > /0FBE81 572140>MOVSX EAX,BYTE PTR DS:[ECX+402157] 004011DB . |0FBE99 BB2140>MOVSX EBX,BYTE PTR DS:[ECX+4021BB] 004011E2 . |3BC3 CMP EAX,EBX 004011E4 . |75 09 JNZ SHORT Crackme1.004011EF < === Patch ở đây. 004011E6 . |83F8 00 CMP EAX,0 004011E9 . |74 19 JE SHORT Crackme1.00401204 004011EB . |41 INC ECX 004011EC .^\EB E6 JMP SHORT Crackme1.004011D4 Đưa từng ký tự của chuỗi S nhập vào EAX 004011D4 > /0FBE81 572140>MOVSX EAX,BYTE PTR DS:[ECX+402157] Đưa từng ký tự của chuỗi được mã hoá vào EBX 004011DB . |0FBE99 BB2140>MOVSX EBX,BYTE PTR DS:[ECX+4021BB] Kiểm tra từng ký tự, nếu không bằng thì nhảy ngay, không cần kiểm tra tiếp 004011E2 . |3BC3 CMP EAX,EBX 004011E4 . |75 09 JNZ SHORT Crackme1.004011EF Kiểm tra xem đã kết thúc chuỗi chưa, nếu kết thúc rồi thì nhảy đến thông báo đúng 004011E6 . |83F8 00 CMP EAX,0 004011E9 . |74 19 JE SHORT Crackme1.00401204 Nếu chưa đến cuỗi chuỗi và chuỗi như nhau thì quá trình được lặp lại. 004011EB . |41 INC ECX 004011EC .^\EB E6 JMP SHORT Crackme1.004011D4 >> >> Ở chương trình này, nếu muốn patch thì tại địa chỉ 004011E4 . |75 09 JNZ SHORT Crackme1.004011EF ta thay dổi JNZ thành JE hay thành lệnh JMP đến thông báo đúng hay đến ngay dòng lệnh nhảy sát phía sau nó. Vậy : User : Moonbaby Serial : BS-23AE2AE9-3292 . BS-DE52B947- 517 6 00 4 01 1 9E . 68 C7 204 000 PUSH Crackme1 .00 402 0C7 ; |Format = "BS- %lX-%lu" 00 4 01 1 A3 . 68 BB 214 00 0 PUSH Crackme1 .00 402 1BB ; |s = Crackme1 .00 402 1BB 00 4 01 1 A8 . E8 6C 000 000 CALL. Crackme1 .00 4 01 1 EF < === Patch ở đây. 00 4 01 1 E6 . |83F8 00 CMP EAX ,0 00 4 01 1 E9 . |74 19 JE SHORT Crackme1 .00 4 01 2 04 00 4 01 1 EB . | 41 INC ECX 00 4 01 1 EC .^EB E6 JMP SHORT Crackme1 .00 4 01 1 D4 Đưa. trái 00 4 01 1 68 > /0FBE 81 F3 204 0>MOVSX EAX,BYTE PTR DS:[ECX+ 402 0F3] < == Xét từng ký tự 00 4 01 1 6F . |83F8 20 CMP EAX, 20 00 4 01 1 72 . |74 07 JE SHORT Crackme1 .00 4 01 1 7B 00 4 01 1 74 . |6BC0 04