Like Share Discussion Bookmark Smile

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

x64dbg - 第二十六章 | 反匯編練習(十五)

目標程式

檔案下載:[ReverseMe. NAGs.exe](/download/x64dbg/chapter26/ReverseMe. NAGs.7z)
解壓密碼:morosedog


任務目標

  • 移除所有的Nag視窗

分析程式

  • 執行ReverseMe. NAGs.exe
  • 彈出Nag視窗
  • 等待數秒後,開啟主程式
  • 內容if you click tht 'Register' button, you register the program, thus avoiding the closing nag. Your task is to remove both nags in the code !!! (如果單擊“註冊”按鈕,則註冊程序,從而避免關閉嘮叨。 你的任務是刪除代碼中的兩個嘮叨!)
  • 不要點擊Register
  • 點擊Exit
  • 彈出Nag視窗

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


搜尋思路

  • 透過堆疊觀察調用的函數分析

修改思路

  • 針對彈出的Nag視窗做處理

實際分析

  • 開啟ReverseMe. NAGs.exe

  • F9執行程式

  • 彈出Nag視窗

  • 回到x64dbg

  • F12暫停(P)

  • 開啟呼叫堆疊視窗 (Alt + K)

    1
    2
    3
    4
    5
    位址       返回到      來自       大小 註解                       Par
    0018BF34 704A539B 777D78D7 3C user32.777D78D7 系統
    0018BF70 704D1640 704A539B 44 mfc42.704A539B 系統
    0018BFB4 0042039F 704D1640 4 mfc42.704D1640 使用者
    0018BFB8 00000000 0042039F reverseme. nags.0042039F 使用者
  • 發現有一個返回到0042039F

  • 右鍵點選跟隨目標(T)

  • 跳轉到0042039F | 8D8424 C8370000 | lea eax,dword ptr ss:[esp+37C8] |

  • 向上觀察

    1
    2
    0042039A   | E8 C1280100           | call <JMP.&Ordinal#2514>                 |
    0042039F | 8D8424 C8370000 | lea eax,dword ptr ss:[esp+37C8] |
  • 0042039A設定中斷點

  • Ctrl + F2 重新啟動(S)

  • F9執行程式

  • 並未彈出Nag視窗

  • F8步過

  • 彈出Nag視窗

  • F9繼續執行

  • 斷點在0042039A | E8 C1280100 | call <JMP.&Ordinal#2514> |

  • F8步過

  • 彈出主程式

  • 點擊Exit

  • F9繼續執行

  • 斷點在0042039A | E8 C1280100 | call <JMP.&Ordinal#2514> |

  • F8步過

  • 彈出Nag視窗

  • F9繼續執行

  • 程序結束

  • 開啟ReverseMe. NAGs.exe

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

  • 向上觀察

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    00420379   | 74 3F                 | je reverseme. nags.4203BA                |
    0042037B | 8D4C24 4C | lea ecx,dword ptr ss:[esp+4C] |
    0042037F | 89B424 CC370000 | mov dword ptr ss:[esp+37CC],esi |
    00420386 | 890D F4694400 | mov dword ptr ds:[4469F4],ecx |
    0042038C | 8B56 08 | mov edx,dword ptr ds:[esi+8] | edx:EntryPoint
    0042038F | 8D4C24 4C | lea ecx,dword ptr ss:[esp+4C] |
    00420393 | 899424 A0370000 | mov dword ptr ss:[esp+37A0],edx | edx:EntryPoint
    0042039A | E8 C1280100 | call <JMP.&Ordinal#2514> |
    0042039F | 8D8424 C8370000 | lea eax,dword ptr ss:[esp+37C8] |
    004203A6 | 8D4C24 20 | lea ecx,dword ptr ss:[esp+20] |
    004203AA | 50 | push eax |
    004203AB | E8 2A270100 | call <JMP.&Ordinal#858> |
    004203B0 | 8B4C24 1C | mov ecx,dword ptr ss:[esp+1C] |
    004203B4 | 890D F4694400 | mov dword ptr ds:[4469F4],ecx |
    004203BA | 55 | push ebp |
  • 發現je reverseme. nags.4203BA跳轉實現時,會跳過0042039A彈出視窗


分析總結

  • 0042039A為彈出視窗,而前後Nag和主程式,都是調用這個函數
  • 00420379判斷是否跳過彈出Nag視窗

修改思路

  • 執行次數為雙數在彈出視窗
    • 設定參數執行次數紀錄
    • 根據執行次數決定是否跳轉

額外補充

  • 根據PE標示的資料位置,找尋暫存次數的記憶體位址
  • 找尋到的位置須設置硬體斷點,測試程序沒有對該位址做寫入,方可使用該位址
  • 這邊暫定使用00445EA0位址做儲存位址

  • 內嵌補丁的內容
    1
    2
    3
    4
    5
    lea ecx, dword ptr [esp+4C]   // 補上被覆蓋的指令
    inc byte ptr [00445EA0] // 00445EA0 位址的值 + 1
    cmp byte ptr [00445EA0],2 // 比較 00445EA0位置的值 是否 等於 2
    je 0x0042037F // 跳轉實現到0042037F,繼續執行彈出視窗
    jmp 004203BA // 跳轉到略過彈出`Nag`視窗

實際修改

  • 使用內嵌補丁的方式

  • 開啟ReverseMe. NAGs.exe

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

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

  • 暫定使用00437D68為內嵌補丁的開始位址

    1
    2
    3
    4
    5
    6
    00437D68   | 0000                  | add byte ptr ds:[eax],al                 |
    00437D6A | 0000 | add byte ptr ds:[eax],al |
    00437D6C | 0000 | add byte ptr ds:[eax],al |
    00437D6E | 0000 | add byte ptr ds:[eax],al |
    00437D70 | 0000 | add byte ptr ds:[eax],al |
    00437D72 | 0000 | add byte ptr ds:[eax],al |
  • 反匯編視窗中按下Ctrl + G輸入00420379,會跳轉到00420379位址

  • 00420379 | 74 3F | je reverseme. nags.4203BA |按下空白鍵

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

  • 修改後如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    // 修改前
    00420379 | 74 3F | je reverseme. nags.4203BA |
    0042037B | 8D4C24 4C | lea ecx,dword ptr ss:[esp+4C] |
    0042037F | 89B424 CC370000 | mov dword ptr ss:[esp+37CC],esi |
    00420386 | 890D F4694400 | mov dword ptr ds:[4469F4],ecx |
    0042038C | 8B56 08 | mov edx,dword ptr ds:[esi+8] | edx:EntryPoint
    0042038F | 8D4C24 4C | lea ecx,dword ptr ss:[esp+4C] |
    00420393 | 899424 A0370000 | mov dword ptr ss:[esp+37A0],edx | edx:EntryPoint
    // 修改後
    00420379 | E9 EA790100 | jmp reverseme. nags.437D68 |
    0042037E | 90 | nop |
    0042037F | 89B424 CC370000 | mov dword ptr ss:[esp+37CC],esi |
    00420386 | 890D F4694400 | mov dword ptr ds:[4469F4],ecx |
    0042038C | 8B56 08 | mov edx,dword ptr ds:[esi+8] | edx:EntryPoint
    0042038F | 8D4C24 4C | lea ecx,dword ptr ss:[esp+4C] |
    00420393 | 899424 A0370000 | mov dword ptr ss:[esp+37A0],edx | edx:EntryPoint
  • 比較修改前和修改後

  • 發現0042037B被覆蓋掉了

    • 因為原來的代碼佔用3個位元組,改後的代碼佔用5個位元組,後面的代碼lea ecx,dword ptr ss:[esp+4C]被覆蓋了。
  • 固內嵌補丁記得要補回被覆蓋的部分

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

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

  • 選擇XEDParse將指令修改為lea ecx, dword ptr [esp+4C],按下確定

  • 持續向下修改

  • 選擇XEDParse將指令修改為inc byte ptr [00445EA0],按下確定

  • 持續向下修改

  • 選擇XEDParse將指令修改為cmp byte ptr [00445EA0],2,按下確定

  • 持續向下修改

  • 選擇XEDParse將指令修改為je 0x0042037F,按下確定

  • 持續向下修改

  • 選擇XEDParse將指令修改為jmp 004203BA,按下確定

  • 修改後如下

    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
    // 修改前
    00437D68 | 0000 | add byte ptr ds:[eax],al |
    00437D6A | 0000 | add byte ptr ds:[eax],al |
    00437D6C | 0000 | add byte ptr ds:[eax],al |
    00437D6E | 0000 | add byte ptr ds:[eax],al |
    00437D70 | 0000 | add byte ptr ds:[eax],al |
    00437D72 | 0000 | add byte ptr ds:[eax],al |
    00437D74 | 0000 | add byte ptr ds:[eax],al |
    00437D76 | 0000 | add byte ptr ds:[eax],al |
    00437D78 | 0000 | add byte ptr ds:[eax],al |
    00437D7A | 0000 | add byte ptr ds:[eax],al |
    00437D7C | 0000 | add byte ptr ds:[eax],al |
    00437D7E | 0000 | add byte ptr ds:[eax],al |
    // 修改後
    00437D68 | 8D4C24 4C | lea ecx,dword ptr ss:[esp+4C] |
    00437D6C | FE05 A05E4400 | inc byte ptr ds:[445EA0] |
    00437D72 | 803D A05E4400 02 | cmp byte ptr ds:[445EA0],2 |
    00437D79 | 90 | nop |
    00437D7A | 0F84 FF85FEFF | je reverseme. nags.42037F |
    00437D80 | E9 3586FEFF | jmp reverseme. nags.4203BA |
    00437D85 | 90 | nop |
    00437D86 | 0000 | add byte ptr ds:[eax],al |
    00437D88 | 0000 | add byte ptr ds:[eax],al |
    00437D8A | 0000 | add byte ptr ds:[eax],al |
    00437D8C | 0000 | add byte ptr ds:[eax],al |
  • 移除所有中斷點

    • 如果沒有移除所有中斷點,會發現我們設定的硬體中斷點,會被我們的內嵌補丁的代碼呼叫,而中斷
  • F9執行程式

  • 直接開啟主程式

  • 未彈出Nag視窗

  • 點擊修補程式 或是快捷鍵Ctrl + P

  • 點擊修補檔案(P)

  • 另存檔名ReverseMe. NAGs.crack.exe

  • 恭喜補丁產生ReverseMe. NAGs.crack.exe


心得分享

  • 因為x64dbgOllydbg使用上有一些差異,例如在分析mfc42的函數的時候,並沒有很好的註解出來。所以建議在F12暫停(P)後,可以使用Alt + F9執行到使用者代碼(U),方可找到是哪裡呼叫了彈出Nag函數的位址。

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