lên trên ta sẽ đặt BP tại địa chỉ 00404A30.
II - Cracking :
Ấn F9 để run chương trình, nhập lại name và key như ở trên. Bấm OK, Olly sẽ ice
tại điểm mà ta vừa đặt BP.
Ta chú ý đoạn code sau :
Code:
00404A35 . 8B3B MOV EDI, DWORD PTR DS:[EBX] |
00404A37 . B9 FFFFFFFF MOV ECX, -1 |
00404A3C . 2BC0 SUB EAX, EAX | Kiểm tra xem tên có
được
00404A3E . F2:AE REPNE SCAS BYTE PTR ES:[EDI] | nhập vào hay
không ?
00404A40 . F7D1 NOT ECX |
00404A42 . 49 DEC ECX |
[00404A43 . 0F84 08010000 JE Wallpape.00404B51 | không nhập
(ECX=0) => nhảy đến bad boy
Đoạn code trên được dùng để kiểm tra xem name có được nhập vào hay không.
Nếu không -> bad boy.
Tiếp theo :
Code:
00404A49 . 8B7E 5C MOV EDI, DWORD PTR DS:[ESI+5C]|
00404A4C . B9 FFFFFFFF MOV ECX, -1 |
00404A51 . 2BC0 SUB EAX, EAX | Kiểm tra xem key có
được
00404A53 . F2:AE REPNE SCAS BYTE PTR ES:[EDI] | nhập vào hay
không ?
00404A55 . F7D1 NOT ECX |
00404A57 . 49 DEC ECX |
00404A58 . 0F84 F3000000 JE Wallpape.00404B51 | không nhập
(ECX=0) => nhảy đến bad boy
Còn đoạn code trên được dùng để kiểm tra xem key có được nhập vào hay không.
Nếu không -> bad boy.
Ok, do ta đã nhập name và key vào -> hợp lệ. Ta đến đoạn code tiếp theo.
Code:
00404A5E . 6A 00 PUSH 0 ; /Arg1 = 00000000
00404A60 . 8BCB MOV ECX, EBX ; |
00404A62 . E8 24D40200 CALL Wallpape.00431E8B ;
\Wallpape.00431E8B
00404A67 . 50 PUSH EAX ; /Arg1
00404A68 . 8BCE MOV ECX, ESI ; |
00404A6A . E8 21010000 CALL Wallpape.00404B90 ;
\Wallpape.00404B90 | <= Đây là đoạn code tính key từ name nhập vào =>
Trace into
Trace vào ta thấy như sau :
Code:
00404B90 /$ 83EC 2C SUB ESP, 2C
00404B93 |. C74424 00 05000000 MOV DWORD PTR SS:[ESP], 5
00404B9B |. C74424 04 03000000 MOV DWORD PTR SS:[ESP+4], 3
00404BA3 |. C74424 08 07000000 MOV DWORD PTR SS:[ESP+8], 7
00404BAB |. C74424 0C 01000000 MOV DWORD PTR SS:[ESP+C], 1
Dừng lại 1 chút nào Tại đây ta thấy chương trình đã lưu sẵn 1 vài giá trị (5, 3, 7,
1). Ok, ta hãy nhớ nó.
Tiếp theo :
Code:
00404BB3 |. 53 PUSH EBX
00404BB4 |. 56 PUSH ESI
00404BB5 |. 57 PUSH EDI
00404BB6 |. BB 88583422 MOV EBX, 22345888 | EBX = 22345888
Tại địa chỉ 00404BB6, số 22345888(hex) sẽ được lưu vào EBX.
Chúng ta tiếp tục nào :
Code:
00404BBB |. C74424 20 02000000 MOV DWORD PTR SS:[ESP+20], 2
00404BC3 |. C74424 24 06000000 MOV DWORD PTR SS:[ESP+24], 6
00404BCB |. 55 PUSH EBP
00404BCC |. 6A 09 PUSH 9
00404BCE |. C74424 30 04000000 MOV DWORD PTR SS:[ESP+30], 4
00404BD6 |. 33ED XOR EBP, EBP | EBP = 0
00404BD8 |. 896C24 24 MOV DWORD PTR SS:[ESP+24], EBP
Tại đây, ta lại thấy chương trình lưu thêm vài giá trị nữa (2, 6, 4). Không những
thế, nếu để ý, ta sẽ thấy ở địa chỉ 00404BD6, EBP = 0. Mà ở 00404BD8, chương
trình lại lưu EBP => chương trình lưu 0.
Xét lại từ đầu đến giờ, chương trình đã lưu tất cả 8 số theo thứ tự : 5, 3, 7, 1, 2, 6,
4, 0. Trông như 1 chuỗi số từ 0 -> 7 đó nhỉ ? Nhưng không phải đâu, chúng ta sẽ
còn gặp lại nó đấy :D
Ấn F8 để đến địa chỉ tiếp theo :
Code:
00404BDC |. E8 AF760100 CALL Wallpape.0041C290
Không có gì quan trọng trong này => ấn F8 để trace qua thôi :
Code:
00404BE1 |. 8B5424 44 MOV EDX, DWORD PTR SS:[ESP+44]
Sau khi trace qua đây, nhìn sang cửa sổ Registers (FPU) ta sẽ thấy name mà ta đã
nhập vào ở trên (the_lighthouse) được lưu trong EDX. Vậy ta có thể đoán được
phần nào câu code trên dùng để lưu name vào EDX.
Tiếp tục nào các bác :
Code:
00404BE5 |. 83C4 04 ADD ESP, 4
00404BE8 |. 8BF0 MOV ESI, EAX
00404BEA |. 8BFA MOV EDI, EDX
00404BEC |. B9 FFFFFFFF MOV ECX, -1
00404BF1 |. 2BC0 SUB EAX, EAX
00404BF3 |. F2:AE REPNE SCAS BYTE PTR ES:[EDI]
00404BF5 |. F7D1 NOT ECX
00404BF7 |. 49 DEC ECX
00404BF8 |. 74 1A JE SHORT Wallpape.00404C14
Đoạn code trên được dùng để kiểm tra chiều dài name ta nhập vào.
Các bác chú ý đoạn code sau nhé :
Code:
00404BFA |> /45 /INC EBP
00404BFB |. |8BFA |MOV EDI, EDX
00404BFD |. |0FBE442A FF |MOVSX EAX, BYTE PTR DS:[EDX+EBP-
1]
00404C02 |. |03D8 |ADD EBX, EAX
00404C04 |. |B9 FFFFFFFF |MOV ECX, -1
00404C09 |. |2BC0 |SUB EAX, EAX
00404C0B |. |F2:AE |REPNE SCAS BYTE PTR ES:[EDI]
00404C0D |. |F7D1 |NOT ECX
00404C0F |. |49 |DEC ECX
00404C10 |. |3BCD |CMP ECX, EBP
00404C12 |.^\77 E6 \JA SHORT Wallpape.00404BFA
Nhìn vào ta biết được đây là 1 vòng lặp. Và sau đây là cơ chế lặp của nó :
[code]
Quote:
00404BFA |> /45 /INC EBP <==>
EBP = EBP + 1. Do EBP = 0 nên hiện tại EBP sẽ mang giá trị 1.
00404BFB |. |8BFA |MOV EDI, EDX
Quote:
00404BFD |. |0FBE442A FF |MOVSX EAX, BYTE PTR DS:[EDX+EBP-1] <==>
Load từng byte của [EDX+EBP-1] vào EAX. Do hiện tại EBP = 1, nên
[EDX+EBP-1] = [EDX+1-1] = EDX. Vậy chương trình sẽ load từng byte của EDX
vào EAX. Mà ta đã biết, EDX đang lưu name do ta nhập vào, cho nên ở lần loop
đầu tiên, chương trình sẽ load vào EAX hex của kí tự đầu tiên trong name (trong
trường hợp này là số 74 do chữ t có hex là 74). Vậy hiện tại EAX = 74.
Quote:
00404C02 |. |03D8 |ADD EBX, EAX <==>
EBX = EBX + EAX. Mà EBX = 22345888, EAX = 74 => EBX = 22345888 + 74
= 223458FC
00404C04 |. |B9 FFFFFFFF |MOV ECX, -1
00404C09 |. |2BC0 |SUB EAX, EAX
00404C0B |. |F2:AE |REPNE SCAS BYTE PTR ES:[EDI]
00404C0D |. |F7D1 |NOT ECX
00404C0F |. |49 |DEC ECX
00404C10 |. |3BCD |CMP ECX, EBP
00404C12 |.^\77 E6 \JA SHORT Wallpape.00404BFA
Quote:
Tính chiều dài của name (ở đây là 14 kí tự), sau đó so sánh với EBP. Khi EBP <
ECX => tiếp tục loop
[code]
Sau 14 lần loop, ta có như sau :
Quote:
Quote:
Lần loop thứ 1
EBP = 1
EAX = 74 (hex của kí tự t)
EBX = 22345888 + 74
Quote:
Lần loop thứ 2
EBP = 2
EAX = 68 (hex của kí tự h)
EBX = 22345888 + 74 + 68
Quote:
Lần loop thứ 3
EBP = 3
EAX = 65 (hex của kí tự e)
EBX = 22345888 + 74 + 68 + 65
Quote:
Lần loop thứ 4
EBP = 4
EAX = 5F (hex của kí tự _)
EBX = 22345888 + 74 + 68 + 65 + 5F
Quote:
Lần loop thứ 5
EBP = 5
EAX = 6C (hex của kí tự l)
EBX = 22345888 + 74 + 68 + 65 + 5F + 6C
Quote:
Lần loop thứ 6
EBP = 6
EAX = 69 (hex của kí tự i)
EBX = 22345888 + 74 + 68 + 65 + 5F + 6C + 69
Quote:
Lần loop thứ 7
EBP = 7
EAX = 67 (hex của kí tự g)
EBX = 22345888 + 74 + 68 + 65 + 5F + 6C + 69 + 67
Quote:
Lần loop thứ 8
EBP = 8
EAX = 68 (hex của kí tự h)
EBX = 22345888 + 74 + 68 + 65 + 5F + 6C + 69 + 67 + 68
Quote:
Lần loop thứ 9
EBP = 9
EAX = 74 (hex của kí tự t)
EBX = 22345888 + 74 + 68 + 65 + 5F + 6C + 69 + 67 + 68 + 74
Quote:
Lần loop thứ 10
EBP = 10
EAX = 68 (hex của kí tự h)
EBX = 22345888 + 74 + 68 + 65 + 5F + 6C + 69 + 67 + 68 + 74 + 68
Quote:
Lần loop thứ 11
EBP = 11
EAX = 6F (hex của kí tự o)
EBX = 22345888 + 74 + 68 + 65 + 5F + 6C + 69 + 67 + 68 + 74 + 68 + 6F
Quote:
Lần loop thứ 12
EBP = 12
EAX = 75 (hex của kí tự u)
EBX = 22345888 + 74 + 68 + 65 + 5F + 6C + 69 + 67 + 68 + 74 + 68 + 6F + 75
Quote:
Lần loop thứ 13
EBP = 13
EAX = 73 (hex của kí tự s)
EBX = 22345888 + 74 + 68 + 65 + 5F + 6C + 69 + 67 + 68 + 74 + 68 + 6F + 75
+ 73
Quote:
Lần loop thứ 14
EBP = 14
EAX = 65 (hex của kí tự e)
EBX = 22345888 + 74 + 68 + 65 + 5F + 6C + 69 + 67 + 68 + 74 + 68 + 6F + 75
+ 73 + 65