Đầu tiên chúng ta đổi tên file btc cho 150-ulock.ex_ thành 150-ulock.exe và load vào Olly. Run thử thấy xuất hiện 1 form Keygen có 3 editbox, editbox1 : là unlock code và 2 editbox sau là Name và Serial đang bị disable. Nhưng tạm thời ta chưa điền được gì vào đó cả.
Gõ thử unlock code = 1 và bấm unlock. Hiện lên thông báo sai Unlock code: 'You have entered an invalid Unlock,...'. Tìm thấy 2 đoạn có dòng text này trong olly ở địa chỉ 004010C5, 00401317.
Follow dòng 1 tới địa đoạn :
004010BE > \6A 30 push 30 ; /Style = MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL
004010C0 . 68 A5324000 push 150-uloc.004032A5 ; |Title = "-=[ Unlock Code Error"
004010C5 . 68 BB324000 push 150-uloc.004032BB ; |Text = "You have entered an invalid Unlock Code.
Please try again."
Đoạn nhảy tới đoạn này nằm ở địa chỉ
0040109D . /76 1F jbe short 150-uloc.004010BE
Ngay trước đó có một lệnh so sánh :
00401086 . 6A 11 push 11 ; /Count = 11 (17.)
00401088 . 68 08334000 push 150-uloc.00403308 ; |Buffer = 150-uloc.00403308
0040108D . 68 F1030000 push 3F1 ; |ControlID = 3F1 (1009.)
00401092 . FF75 08 push dword ptr ss:[ebp+8] ; |hWnd
00401095 . E8 38030000 call ; \GetDlgItemTextA
0040109A . 83F8 07 cmp eax, 7
Đoạn này có nghĩa là sẽ so sánh chiều dài của unlock code với 7, nếu nhỏ hơn thì nhảy tới đoạn thông báo sai unlock, nếu lớn hơn thì sẽ tiếp tục tính toán. Ok đặt 1 breakpoint ở địa chỉ 0040109D( chỗ lệnh nhảy) , nhập 1 đoạn unlock code = '11111111' ( 8 ký tự 1) vào bấm unlock. Trace tiếp:
0040109F . E8 29020000 call 150-uloc.004012CD
Mình không tính toán kỹ đoạn này nhưng mục đích cuối cùng của nó là từ chuỗi nhập vào sau một hồi thì sẽ lưu 1 byte vào địa chỉ ds:[403318]
004012EC |. 0005 18334000 add byte ptr ds:[403318], al
Với chuỗi 8 ký tự 1 như trên thì byte 41 sẽ được lưu vào ds:[403318]
Trace tới hàm tiếp theo :
004010A7 . E8 4B020000 call 150-uloc.004012F7 ; \150-uloc.004012F7
Hàm này kiểm tra xem đoạn unlock code có chiều dài > 1 không. Nếu nhỏ hơn thì lại in ra đoạn sai unlock code, nếu đúng :
00401334 |> /8A1418 /mov dl, byte ptr ds:[eax+ebx]
00401337 |3215 18334000 xor dl, byte ptr ds:[403318]
0040133D |. |881418 |mov byte ptr ds:[eax+ebx], dl
00401340 |. |43 |inc ebx
00401341 |. |49 |dec ecx
00401342 |.^\75 F0 \jnz short 150-uloc.00401334
Nó sẽ xor 7B byte bắt đầu từ :ds:[004011C1], với byte lúc nãy tính được( đang lưu tại ds:[403318]) và lưu lại vào chính nó
dẫn tới opcode của chương trình bắt đầu từ ds:[004011C1] bị thay đổi.
Tiếp theo nó sẽ enable 2 editbox name và serial:
004010AF . E8 94020000 call 150-uloc.00401348 ; \150-uloc.00401348
Btc đã hint ta cần phải tìm serial cho user : 0x3004
Nội dung ở bên dưới cũng không có gì quá đặc biệt, chỉ duy nhất tại địa chỉ :
00401135 . E8 AE000000 call 150-uloc.004011E8
Gọi tới đoạn đã bị thay đổi
Và 2 đoạn :
00401291 > /8A98 29334000 mov bl, byte ptr ds:[eax+403329]
00401297 . |3898 3A334000 cmp byte ptr ds:[eax+40333A], bl
ds:[eax+403329] : -> đại chỉ chuỗi serial
ds:[eax+40333A] : -> một địa chỉ lạ.
Ta có thể đoán ra địa chỉ 004011E8: sẽ làm gì đó sau đó lưu lại các byte vào địa chỉ ds:[eax+40333A]
Đến đây chúng ta bắt buộc phải tính toán lại đoạn bắt đầu từ : 004011E8
Ban đầu phương pháp của mình là brute force từ 1 -> 255 điền vào ds:[403318] vì nghĩ có thể tại địa chỉ 004011E8 có thể không phải là 1 function, cách này cũng ra tuy hơi trâu bò tí :D.
Nếu biết đoạn bắt đầu từ 004011E8 là 1 func ta có thể đoán ra đoạn opcode đầu tiên sẽ là :
55 push ebp
-> byte đã được điền vào ds:[403318] = 55 xor ds:[004011C1] ( =70) -> ds:[403318] = 0x25
Điền lại unlock code > 8 ký tự, Xóa hết breakpoint và đặt lại 2 breakpoint tại
004010A7 . E8 4B020000 call 150-uloc.004012F7 ; \150-uloc.004012F7
00401297 . |3898 3A334000 cmp byte ptr ds:[eax+40333A], bl
Trace đến 004010A7 sau đó set lại giá trị tại ô nhớ ds:[403318] = 0x25, điền username=0x3004
Trace đến: 00401297 và dump giá trị từ 40333A -> 40333F, đây chính là flag cần tìm :
21137D5FCAAC07F9