Như thế, với một U nhập bất ký tên bạn chẳng hạn, ta có thể tính ra ngay P thông qua bảng chuyển đổi ASCII... Quan xát ở cửa sổ Registers FPU ta nhận thấy EBX chỉ chứa 4 ký tự đầu tiên
Trang 1Posted by: moonbaby Dec 10 2003, 10:04 AM
Homepage : http://crackme.de
CrackMe : ad_cm2.zip( AD_CM#2.exe )
Coder : ArturDents
Type : Serial
Packed : N/A
Crack Tool : OllyDbg 1.09d
Unpack Tool : N/A
Request : Correct Serial
Rule : N/A
Note : N/A
-
Chương trình này tôi giải thích trước, các bạn tìm theo code :
Dưới đây là đoạn mã hóa S :
- Con trỏ đặt ở vị trí đầu tiên, tính chiều dài chuỗi ( giả sử là L1 )
- Trừ số hex của ký tự đó với chiều dài L1, nói cách khác là lùi ký tự đó lại L1 vị trí ( ví dụ với chuỗi MBBMBB có L1=6h, M=4Dh, lấy 4Dh-6h=47h )
- Con trỏ chuyển đến lý tự thứ hai, tính lại chiều dài chuỗi, lúc này chiều dài chuỗi là L2, có thể nhận thấy ngay L2=L1-1
- Lập lại bước trên ( L2=5h; B=42h, 42h-5h=3Dh )
- Quá trình cứ tiếp diễn đến ký tự cuối cùng
00401154 |> /8A10 /MOV DL,BYTE PTR DS:[EAX]
00401156 | |2AD1 |SUB DL,CL
00401158 | |3813 |CMP BYTE PTR DS:[EBX],DL
0040115A | |75 18 |JNZ SHORT AD_CM#2.00401174 < ==== Patch ở đây ( nếu bạn muốn )
0040115C | |40 |INC EAX
0040115D | |43 |INC EBX
0040115E |.^\E2 F4 \LOOPD SHORT AD_CM#2.00401154
Chỉ cần một ký tự không bằng là lập tức chương trình nhảy ngay
Trang 2Như thế, với một U nhập bất ký ( tên bạn chẳng hạn), ta có thể tính ra ngay P thông qua bảng chuyển đổi ASCII
Vậy :
User : Moonbaby Serial : Ehii^^`x
Posted by: moonbaby Dec 10 2003, 02:34 PM
Homepage : http://crackme.de
CrackMe : bengaly-km3.zip ( Key4.exe )
Coder : Bengaly ( 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
-
>>>> Set BreakPoint tại hai điểm :
004012BD | E8 0C010000 CALL <JMP.&USER32.GetDlgItemTextA> ;
\GetDlgItemTextA
004012D3 | E8 F6000000 CALL <JMP.&USER32.GetDlgItemTextA> ;
\GetDlgItemTextA
>> Đưa chuỗi U vào lưu ở địa chỉ 0040303F
004012F6 |> \68 3F304000 PUSH Key4.0040303F ; /String =
"Moonbaby"
>> Don sạnh chuẩn bị cho quá trình mã hoá chuỗi
00401300 | 33F6 XOR ESI,ESI
00401302 | 33DB XOR EBX,EBX
Trang 3>> Chuyển giá trị của EAX vào ECX, giá trị của EAX lúc này là chiều dài của chuỗi U nhập vào, như vậy ECX sẽ chứa chiều dài chuỗi, còn EAX sẽ chứa giá trị 1
00401304 | 8BC8 MOV ECX,EAX
00401306 | B8 01000000 MOV EAX,1
>>>> Đoạn mã hoá chuỗi U nhập vào
0040130B |> 8B1D 3F304000 /MOV EBX,DWORD PTR DS:[40303F]
00401311 | 0FBE90 1F3540>|MOVSX EDX,BYTE PTR
DS:[EAX+40351F]
00401318 | 2BDA |SUB EBX,EDX
0040131A | 0FAFDA |IMUL EBX,EDX
0040131D | 8BF3 |MOV ESI,EBX
0040131F | 2BD8 |SUB EBX,EAX
00401321 | 81C3 43353504 |ADD EBX,4353543
00401327 | 03F3 |ADD ESI,EBX
00401329 | 33F2 |XOR ESI,EDX
0040132B | B8 04000000 |MOV EAX,4
00401330 | 49 |DEC ECX
00401331 |.^ 75 D8 \JNZ SHORT Key4.0040130B
>> Chuyển U đã được lưu ở 40303F vào chứa trong EBX ở dạng số hex Quan xát ở cửa sổ Registers FPU ta nhận thấy EBX chỉ chứa 4 ký tự đầu tiên của chuỗi U và đặt ngược ( ví dụ ở trên là Moonbaby lần lượt theo hệ hex là 4D 6F 6F 6E…, khi lưu ở trong EBX sẽ là EBX = 6E6F6F4D ) 0040130B |> 8B1D 3F304000 /MOV EBX,DWORD PTR DS:[40303F]
>> Chuyển từng ký tự của chuỗi được tạo sẵn vào EDX Truy theo địa chỉ này ta thấy ký tự đầu tiên có mã là 25h
00401311 | 0FBE90 1F3540>|MOVSX EDX,BYTE PTR
DS:[EAX+40351F]
>> Lấy EBX trừ đi EDX và lưu kết quả ở EBX ( như trên ta tính được EBX = 6E6F6F28 )
00401318 | 2BDA |SUB EBX,EDX
>> Nhân EDX cho EBX và lưu kết quả ở EBX, EBX = F61B10C8
Trang 4131A | 0FAFDA |IMUL EBX,EDX
>> Đưa giá trị của EBX vào lưu ở ESI, như vậy ESI = EBX = F61B10C8 0040131D | 8BF3 |MOV ESI,EBX
>> Giảm EBX đi 1 đơn vị == > EBX = F61B10C7
0040131F | 2BD8 |SUB EBX,EAX
Cộng thêm EBX với một giá trị mặc định là 4353543 == > EBX =
FA50460A
00401321 | 81C3 43353504 |ADD EBX,4353543
>> Cộng EBX vào ESI và kết quả lưu ở ESI == > ESI = F06B56D2
00401327 | 03F3 |ADD ESI,EBX
XOR EDX cho ESI, kết quả được lưu ở ESI == > ESI = F06B56F7
00401329 | 33F2 |XOR ESI,EDX
>> Đưa 4 vào lưu ở EAX
0040132B | B8 04000000 |MOV EAX,4
>> Giả ECX đi 1, có nghĩa là ta đã hoàn thành được một lần lặp
00401330 | 49 |DEC ECX
>> Tiến hành quá trình lặp cho đến khi ECX = 0
00401331 |.^ 75 D8 \JNZ SHORT Key4.0040130B
>>>> Ở quá trình lặp lại lần thứ hai và các lần sau cần lưu ý :
00401311 | 0FBE90 1F3540>|MOVSX EDX,BYTE PTR
DS:[EAX+40351F]
do EAX của ta lúc này là 4 chứ không phải 1 như lần lặp đầu tiên nên giá trị của EDX nằm ở địa chỉ 4h + 40351Fh., truy tới địa chỉ này thì EDX = 65h
>> Như vậy, giá trị của ESI chỉ khác ở vòng lặp lần đâu tiên, còn các vòng sau là giá trị giống nhau
>>>> Quá trình kiểm tra chuỗi S nhập vào
00401333 | 56 PUSH ESI
00401334 | 68 3F314000 PUSH Key4.0040313F ; ASCII "123456"
00401339 | E8 4A000000 CALL Key4.00401388
0040133E | 5E POP ESI ; Key4.00403145
0040133F | 3BC6 CMP EAX,ESI
Trang 500401341 | /75 15 JNZ SHORT Key4.00401358
>> Đoạn mã này là để đưa giá trị của S thật vào ESI và S nhập vào EAX ( dưới dạng số hex )
00401333 | 56 PUSH ESI
00401334 | 68 3F314000 PUSH Key4.0040313F ; ASCII "123456"
00401339 | E8 4A000000 CALL Key4.00401388
0040133E | 5E POP ESI ; Key4.00403145
>> So sánh hai chuỗi , nếu không bằng thì nhảy đến thông báo sai
0040133F | 3BC6 CMP EAX,ESI
00401341 | /75 15 JNZ SHORT Key4.00401358 < === Patch ở đây
>>>> Đến đọan này, qua sát trên các thanh ghi ta thấy có một điểm lạ là giá trị của ESI là giá trị của U nhập sau lần nhảy thứ nhất (2,3,4,….) được giữ lại Và đây cũng là giá trị được dùng để so sánh với giá trị S nhập vào Vậy ta kết luận ngay được đây chính là số S đúng
>>>> Qua đây, ta kết luận :
1- U chỉ cần 4 ký tự là đủ ( dài hơn cũng không ảnh hưởng gì )
2- Chỉ có hai giá trị cho EDX là 25h và 65h
3- Giá trị của chuỗi mã hoá trong lần lặp thứ hai và các lần sau là giống nhau và là số S đúng Do vậy, nếu viết keygen thì chỉ cần quan tâm đến quá trình xử lý lần thứ hai là được, lần đầu và các lần khác không cần thiết
Vậy :
User : Moonbaby Serial : 673364010