Like Share Discussion Bookmark Smile

J.J. Huang   2019-08-29   x64dbg   瀏覽次數:

x64dbg - 第二十四章 | 反匯編練習(十三)

目標程式

檔案下載:DVDMenuStudio.exe
解壓密碼:morosedog


程式簡介

DVD Menu Studio是一個完整的矢量,2D,3D和位圖設計和編輯軟件包,可以在更短的時間內建立任何類型的DVD菜單。
它會自動處理導出格式的所有技術問題,它會進行必要的調整大小,圖層合併/分離,子圖片顏色映射,切換抗鋸齒,信箱覆蓋,可選腳本建立,熱點分配,自動路由等。


任務目標

  • 試用期限已過,破解註冊。

分析程式

  • 執行DVDMenuStudio.exe

  • 彈出Nag,顯示30 days left (還剩30天試用期)

  • 點擊Enter Reg.Code

  • 點擊OK

  • 彈出Please enter your name視窗

  • 輸入Name:123Serial Number:456Unlick Code:789

  • 點擊OK

  • 彈出Please check Serial Number....視窗

  • 輸入Name:123456789Serial Number:123456789Unlick Code:123456789

  • 點擊OK

  • 彈出The registration code seems to be not valid.Please check if you didn't made any mistake.視窗

  • 點擊Continue

  • 進入主程式

  • 點擊Help

  • 點擊About...

  • 彈出Registerd to: Unregistered

檢驗顯示是使用Microsoft Visual C++ 6.0編寫。


前置作業

  • 調整系統時間為一個月後
  • 執行DVDMenuStudio.exe
  • 彈出Nag顯示0 days left Please Register this copy (Click on But button to see how) (還剩0天請註冊此副本(點擊但按鈕查看方法))
  • 關閉程式
  • 還原系統時間
  • 執行DVDMenuStudio.exe
  • 依舊彈出Nag顯示0 days left Please Register this copy (Click on But button to see how) (還剩0天請註冊此副本(點擊但按鈕查看方法))

額外補充

  • 逆向常用API函數
  • 內嵌補丁:內嵌補丁,內嵌代碼補丁的簡稱,在我們難以直接修改指定代碼時,插入並運行洞穴代碼(Code Cave)的補丁代碼,實現對程序打補丁。
    這種技術常用於對程序經過運行時壓縮(或加密處理)而難以直接修改的情況。

搜尋思路

  • C++撰寫的,使用函數搜尋 (輸入框函數:KillTimer)
  • 使用搜尋字串找關鍵字。

修改思路

  • 修改驗證的邏輯

實際分析

  • 開啟DVDMenuStudio.exe

  • 於反匯編視窗點選右鍵選擇搜尋(S)->目前模組->跨模組呼叫(I)

  • 發現KillTimer,對其設定中斷點

  • F9執行程式

  • 點擊Enter Reg.Code

  • 輸入Name:123Serial Number:456Unlick Code:789

  • 點擊OK

  • 斷點在004DC1A7 | FF15 B4575E00 | call dword ptr ds:[<&KillTimer>] |

  • 觀察程式

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    004DC19D   | 83F8 03               | cmp eax,3                                |
    004DC1A0 | 75 1E | jne dvdmenustudio.4DC1C0 |
    004DC1A2 | 8B57 1C | mov edx,dword ptr ds:[edi+1C] |
    004DC1A5 | 50 | push eax |
    004DC1A6 | 52 | push edx |
    004DC1A7 | FF15 B4575E00 | call dword ptr ds:[<&KillTimer>] |
    004DC1AD | 6A 00 | push 0 |
    004DC1AF | 6A 00 | push 0 |
    004DC1B1 | 68 5C666400 | push dvdmenustudio.64665C | 64665C:"The registration code seems to be not valid.\nPlease check if you didn't made any mistake."
    004DC1B6 | E8 919D0D00 | call dvdmenustudio.5B5F4C |
    004DC1BB | E9 B7000000 | jmp dvdmenustudio.4DC277 |
    004DC1C0 | 83F8 04 | cmp eax,4 |
    004DC1C3 | 75 1E | jne dvdmenustudio.4DC1E3 |
    004DC1C5 | 50 | push eax |
    004DC1C6 | 8B47 1C | mov eax,dword ptr ds:[edi+1C] |
    004DC1C9 | 50 | push eax |
    004DC1CA | FF15 B4575E00 | call dword ptr ds:[<&KillTimer>] |
    004DC1D0 | 6A 00 | push 0 |
    004DC1D2 | 6A 00 | push 0 |
    004DC1D4 | 68 FC656400 | push dvdmenustudio.6465FC | 6465FC:"Thank you for your support!\nPlease Exit the Software and start it again to validate the code."
    004DC1D9 | E8 6E9D0D00 | call dvdmenustudio.5B5F4C |
    004DC1DE | E9 94000000 | jmp dvdmenustudio.4DC277 |
    004DC1E3 | 83F8 05 | cmp eax,5 |
    004DC1E6 | 75 15 | jne dvdmenustudio.4DC1FD |
    004DC1E8 | 8B4F 1C | mov ecx,dword ptr ds:[edi+1C] | ecx:&"0"
    004DC1EB | 50 | push eax |
    004DC1EC | 51 | push ecx | ecx:&"0"
    004DC1ED | FF15 B4575E00 | call dword ptr ds:[<&KillTimer>] |
    004DC1F3 | 6A FF | push FFFFFFFF |
    004DC1F5 | FF15 D0545E00 | call dword ptr ds:[<&ExitProcess>] |
    004DC1FB | EB 7A | jmp dvdmenustudio.4DC277 |
    004DC1FD | 83F8 06 | cmp eax,6 |
    004DC200 | 75 0D | jne dvdmenustudio.4DC20F |
    004DC202 | 8B57 1C | mov edx,dword ptr ds:[edi+1C] |
    004DC205 | 50 | push eax |
    004DC206 | 52 | push edx |
    004DC207 | FF15 B4575E00 | call dword ptr ds:[<&KillTimer>] |
    004DC20D | EB 68 | jmp dvdmenustudio.4DC277 |
    004DC20F | 83F8 0A | cmp eax,A | A:'\n'
    004DC212 | 75 2D | jne dvdmenustudio.4DC241 |
    004DC214 | 50 | push eax |
    004DC215 | 8B47 1C | mov eax,dword ptr ds:[edi+1C] |
    004DC218 | 50 | push eax |
    004DC219 | FF15 B4575E00 | call dword ptr ds:[<&KillTimer>] |
  • 發現註解The registration code seems to be not valid.\nPlease check if you didn't made any mistake.

  • 表示為註冊碼似乎無效

  • 向下發現註解Thank you for your support!\nPlease Exit the Software and start it again to validate the code.

  • 表示為感謝你的支持!請退出軟件並再次啟動以驗證代碼

  • 觀察程式

    • 004DC19D | 83F8 03 | cmp eax,3 |
    • 004DC1C0 | 83F8 04 | cmp eax,4 |
    • 004DC1E3 | 83F8 05 | cmp eax,5 |
  • 可以判斷這為switch的判斷程式

  • 向上觀察

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    004DBD80   | 55                    | push ebp                                 |
    004DBD81 | 8BEC | mov ebp,esp |
    004DBD83 | 6A FF | push FFFFFFFF |
    004DBD85 | 68 17B85D00 | push dvdmenustudio.5DB817 |
    004DBD8A | 64:A1 00000000 | mov eax,dword ptr fs:[0] |
    004DBD90 | 50 | push eax |
    004DBD91 | 64:8925 00000000 | mov dword ptr fs:[0],esp |
    004DBD98 | 81EC 68010000 | sub esp,168 |
    004DBD9E | 8B45 08 | mov eax,dword ptr ss:[ebp+8] |
    004DBDA1 | 53 | push ebx |
    004DBDA2 | 56 | push esi |
    004DBDA3 | 57 | push edi | edi:&"0"
    004DBDA4 | 83F8 01 | cmp eax,1 |
    004DBDA7 | 8BF9 | mov edi,ecx | edi:&"0", ecx:&"0"

  • 發現004DBD80為開始點

  • 移除所有中斷點

  • 004DBD80設定中斷點

  • F9執行程式

  • 點擊Enter Reg.Code

  • 輸入Name:123Serial Number:456Unlick Code:789

  • 點擊OK

  • 斷點在004DBD80 | 55 | push ebp |

  • F8一步一步過,並持續觀察

  • 步過到下方指令時

    1
    004DBD9E   | 8B45 08               | mov eax,dword ptr ss:[ebp+8]             |
  • mov eax,dword ptr ss:[ebp+8]會異動eax的值

  • 004DBD9E | 8B45 08 | mov eax,dword ptr ss:[ebp+8] |按下空白鍵

  • 將指令修改為mov eax, 0x4,按下確定

  • 修改後如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // 修改前
    004DBD9E | 8B45 08 | mov eax,dword ptr ss:[ebp+8] |
    004DBDA1 | 53 | push ebx |
    004DBDA2 | 56 | push esi |
    004DBDA3 | 57 | push edi | edi:&"0"
    004DBDA4 | 83F8 01 | cmp eax,1 |
    004DBDA7 | 8BF9 | mov edi,ecx | edi:&"0", ecx:&"0"
    // 修改後
    004DBD9E | B8 04000000 | mov eax,4 |
    004DBDA3 | 57 | push edi | edi:&"0"
    004DBDA4 | 83F8 01 | cmp eax,1 |
    004DBDA7 | 8BF9 | mov edi,ecx | edi:&"0", ecx:&"0"
  • 比較修改前和修改後

  • 發現004DBDA2004DBDA3被覆蓋掉了

    • 因為原來的代碼佔用3個位元組,改後的代碼佔用5個位元組,後面的代碼push ebxpush esi被覆蓋了。
  • 點擊修補程式 或是快捷鍵Ctrl + P

  • 點擊復原選取項目(R)

  • 還原修改的指令

  • 使用內嵌補丁的方式

  • 反彙編視窗移動到最下方

  • 會看到一堆無用代碼的記憶體位址 (0000)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    005E47C0   | 0000                  | add byte ptr ds:[eax],al                 |
    005E47C2 | 0000 | add byte ptr ds:[eax],al |
    005E47C4 | 0000 | add byte ptr ds:[eax],al |
    005E47C6 | 0000 | add byte ptr ds:[eax],al |
    005E47C8 | 0000 | add byte ptr ds:[eax],al |
    005E47CA | 0000 | add byte ptr ds:[eax],al |
    005E47CC | 0000 | add byte ptr ds:[eax],al |
    005E47CE | 0000 | add byte ptr ds:[eax],al |
    005E47D0 | 0000 | add byte ptr ds:[eax],al |
    005E47D2 | 0000 | add byte ptr ds:[eax],al |
    005E47D4 | 0000 | add byte ptr ds:[eax],al |
    005E47D6 | 0000 | add byte ptr ds:[eax],al |
    005E47D8 | 0000 | add byte ptr ds:[eax],al |
    005E47DA | 0000 | add byte ptr ds:[eax],al |
    005E47DC | 0000 | add byte ptr ds:[eax],al |
    005E47DE | 0000 | add byte ptr ds:[eax],al |
    005E47E0 | 0000 | add byte ptr ds:[eax],al |
  • 挑選一個005E47C4來做代碼開始 (你可以挑選在別的地方)

  • 修改後如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // 修改前
    005E47C4 | 0000 | add byte ptr ds:[eax],al |
    005E47C6 | 0000 | add byte ptr ds:[eax],al |
    005E47C8 | 0000 | add byte ptr ds:[eax],al |
    005E47CA | 0000 | add byte ptr ds:[eax],al |
    // 修改後
    005E47C4 | B8 04000000 | mov eax,4 |
    005E47C9 | 53 | push ebx |
    005E47CA | 56 | push esi |
    005E47CB | E9 D375EFFF | jmp dvdmenustudio.4DBDA3 |
  • 反匯編視窗中按下Ctrl + G輸入004DBD9E,會跳轉到004DBD9E位址

  • 004DBD9E | 8B45 08 | mov eax,dword ptr ss:[ebp+8] |按下空白鍵

  • 將指令修改為jmp 0x005E47C4,按下確定

  • 修改後如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // 修改前
    004DBD9E | 8B45 08 | mov eax,dword ptr ss:[ebp+8] |
    004DBDA1 | 53 | push ebx |
    004DBDA2 | 56 | push esi |
    004DBDA3 | 57 | push edi | edi:&"0"
    004DBDA4 | 83F8 01 | cmp eax,1 |
    004DBDA7 | 8BF9 | mov edi,ecx | edi:&"0", ecx:&"0"
    // 修改後
    004DBD9E | E9 218A1000 | jmp dvdmenustudio.5E47C4 |
    004DBDA3 | 57 | push edi |
    004DBDA4 | 83F8 01 | cmp eax,1 |
    004DBDA7 | 8BF9 | mov edi,ecx |
  • 移除所有中斷點

  • F9執行程式

  • 一直彈出Thank you for your support!\nPlease Exit the Software and start it again to validate the code.視窗

  • 在此可以假設Switch一直在迴圈檢核

  • 根據觀察SwitchCase的值為1~6

  • eax賦予為0

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // 修改前
    005E47C4 | B8 04000000 | mov eax,4 |
    005E47C9 | 53 | push ebx |
    005E47CA | 56 | push esi |
    005E47CB | E9 D375EFFF | jmp dvdmenustudio.4DBDA3 |
    // 修改後
    005E47C4 | B8 04000000 | mov eax,4 |
    005E47C9 | 53 | push ebx |
    005E47CA | 56 | push esi |
    005E47CB | E9 D375EFFF | jmp dvdmenustudio.4DBDA3 |
  • F9執行程式

  • 恭喜程式真正被破解


分析總結

  • 004DBD9ESwitch賦予eax的位址
  • Switch持續迴圈

修改思路

根據分析總結

  • 004DBD9E指定到內嵌補丁位址

實際修改

  • 開啟DVDMenuStudio.exe

  • 反匯編視窗中按下Ctrl + G輸入004DBD9E,會跳轉到004DBD9E位址

  • 004DBD9E | 8B45 08 | mov eax,dword ptr ss:[ebp+8] |按下空白鍵

  • 將指令修改為jmp 0x005E47C4,按下確定

  • 修改後如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // 修改前
    004DBD9E | 8B45 08 | mov eax,dword ptr ss:[ebp+8] |
    004DBDA1 | 53 | push ebx |
    004DBDA2 | 56 | push esi |
    004DBDA3 | 57 | push edi | edi:&"0"
    004DBDA4 | 83F8 01 | cmp eax,1 |
    004DBDA7 | 8BF9 | mov edi,ecx | edi:&"0", ecx:&"0"
    // 修改後
    004DBD9E | E9 218A1000 | jmp dvdmenustudio.5E47C4 |
    004DBDA3 | 57 | push edi |
    004DBDA4 | 83F8 01 | cmp eax,1 |
    004DBDA7 | 8BF9 | mov edi,ecx |
  • 反匯編視窗中按下Ctrl + G輸入005E47C4,會跳轉到005E47C4位址

  • 005E47C4 | 0000 | add byte ptr ds:[eax],al |按下空白鍵

  • 將指令修改為mov eax,0x0,按下確定

  • 005E47C6 | 0000 | add byte ptr ds:[eax],al |按下空白鍵

  • 將指令修改為push ebx,按下確定

  • 005E47C8 | 0000 | add byte ptr ds:[eax],al |按下空白鍵

  • 將指令修改為push esi,按下確定

  • 005E47CA | 0000 | add byte ptr ds:[eax],al |按下空白鍵

  • 將指令修改為jmp 0x004DBDA3,按下確定

  • 修改後如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // 修改前
    005E47C4 | 0000 | add byte ptr ds:[eax],al |
    005E47C6 | 0000 | add byte ptr ds:[eax],al |
    005E47C8 | 0000 | add byte ptr ds:[eax],al |
    005E47CA | 0000 | add byte ptr ds:[eax],al |
    // 修改後
    005E47C4 | B8 04000000 | mov eax,0 |
    005E47C9 | 53 | push ebx |
    005E47CA | 56 | push esi |
    005E47CB | E9 D375EFFF | jmp dvdmenustudio.4DBDA3 |
  • 點擊修補程式 或是快捷鍵Ctrl + P

  • 點擊修補檔案(P)

  • 另存檔名DVDMenuStudio.crack.exe

  • 恭喜補丁產生DVDMenuStudio.crack.exe


註:以上參考了
x64dbg
x64dbg’s documentation!
CSDN billvsme的专栏OllyDbg 使用笔记 (十三)