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
20042039A | 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
1500420379 | 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
5lea 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
600437D68 | 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]
被覆蓋了。
- 因為原來的代碼佔用3個位元組,改後的代碼佔用5個位元組,後面的代碼
固內嵌補丁記得要補回被覆蓋的部分
反匯編視窗中按下
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
心得分享
- 因為
x64dbg
和Ollydbg
使用上有一些差異,例如在分析mfc42
的函數的時候,並沒有很好的註解出來。所以建議在F12
暫停(P)後,可以使用Alt + F9
執行到使用者代碼(U),方可找到是哪裡呼叫了彈出Nag
函數的位址。
註:以上參考了
x64dbg
x64dbg’s documentation!
CSDN billvsme的专栏 的 OllyDbg 使用笔记 (十四)