應用安全 --- vmp流程
VMP (2.0.3-2.13) 尋找OEP詳細教程
?? 前置準備
- 工具: OllyDbg / x64dbg / IDA Pro
- 插件: OllyDumpEx、Scylla(用于后續dump)
- 目標: 被VMP保護的程序
?? 方法一:VirtualProtect斷點法(經典方法)
第一步:設置VirtualProtect斷點
text
1. 打開調試器,加載目標程序
2. Ctrl+G 跳轉到 VirtualProtect 函數
3. 在VirtualProtect入口處下斷點(F2)
第二步:分析區段保護修改
assembly
運行程序(F9),每次斷在VirtualProtect時:
- 查看堆棧參數:
參數1: lpAddress (要修改的內存地址)
參數2: dwSize (大小)
參數3: flNewProtect (新保護屬性)
參數4: lpflOldProtect (舊保護屬性指針)
- 記錄修改的是哪個區段:
.text - 代碼段
.data - 數據段
.rdata - 只讀數據段
關鍵點:當VirtualProtect修改 .text段 的屬性為可執行(如PAGE_EXECUTE_READ)時,說明即將執行原始代碼!
第三步:尋找VM_RETN
text
1. 最后一次VirtualProtect后,不要按F9
2. 單步跟蹤(F8),尋找特征:
- PUSHAD/PUSHFD (保存寄存器)
- 大量垃圾代碼
- 尋找RETN指令
3. 在關鍵RETN處下斷點
4. F9運行到RETN
第四步:.text段內存斷點
text
1. 查看內存映射(M鍵或View->Memory)
2. 找到.text段基址
3. 右鍵 -> Breakpoint -> Memory, on access(訪問斷點)
4. F9運行
5. 斷下時查看EIP,可能已在OEP或附近
?? 方法二:ESP定律法(更簡單)
完整步驟:
assembly
1. 程序停在入口點
2. 記錄ESP的值(例如:0012FFA4)
3. 右鍵ESP寄存器 -> Follow in Dump
4. 在數據窗口,選中前4字節 -> Breakpoint -> Hardware, on access -> DWORD
5. F9運行
6. 斷下后,單步幾下(F8),通常會到達OEP
特征識別:
- 看到PUSH ebp / MOV ebp, esp
- 或 PUSH ebx / PUSH esi / PUSH edi
- 標準的函數序言 = OEP!
?? 方法三:內存鏡像法(針對2.0x版本)
text
步驟:
1. Ctrl+G -> ImageBase(程序基址,如00400000)
2. 右鍵 -> Follow in Dump
3. 在數據窗口,右鍵 -> Breakpoint -> Memory, on execution
4. F9運行
5. 第一次斷下繼續F9
6. 第二/三次斷下,查看附近代碼,可能是OEP
?? 方法四:StrongOD插件自動化
text
使用OllyDbg + StrongOD插件:
1. 加載程序
2. 插件 -> StrongOD -> VMP
3. 選擇版本(2.0x)
4. 點擊"查找OEP"
5. 自動停在OEP或附近
手動驗證:
- 查看代碼是否正常
- 是否有標準函數序言
- 交叉引用是否合理
? OEP識別特征
真正的OEP通常有這些特征:
assembly
典型C/C++程序:
00401000 PUSH EBP
00401001 MOV EBP, ESP
00401003 SUB ESP, XXX
或Delphi程序:
00401000 PUSH EBX
00401001 PUSH ESI
00401002 PUSH EDI
或簡單程序:
00401000 CALL XXXXXXXX ; 調用初始化函數
00401005 MOV EAX, XXX
錯誤的位置特征:
- 大量垃圾指令
- 不正常的跳轉
- 沒有函數調用
- 全是NOP或重復指令
?? 調試示例(實戰)
assembly
假設目標:test.exe (VMP 2.08)
1. OD加載,停在: 00D51000
2. 下VirtualProtect斷點
3. F9運行,第1次斷下:修改.data段
4. F9運行,第2次斷下:修改.rsrc段
5. F9運行,第3次斷下:修改.text段 ← 關鍵!
堆棧參數顯示:
00401000 ; lpAddress (.text段基址)
00003000 ; dwSize
00000020 ; PAGE_EXECUTE_READ
6. F8單步幾下,看到:
00D52341 POPAD
00D52342 POPFD
00D52343 RETN
7. F8執行RETN后,跳到:00401000
8. 查看00401000處代碼:
00401000 55 PUSH EBP
00401001 8BEC MOV EBP, ESP
00401003 6AFF PUSH -1
? 這就是OEP!
?? 注意事項
-
不同版本差異:
- VMP 2.0x 相對簡單
- VMP 2.13 可能有多層虛擬化
-
多次虛擬機嵌套:
- 可能需要多次使用方法
- 注意識別真假OEP
-
STOLEN BYTES:
- OEP前幾個字節可能被偷取
- 需要從虛擬機中提取還原
-
后續工作:
- 找到OEP只是第一步
- 還需Dump內存、修復IAT
- 使用Scylla或ImportREC修復導入表
?? 完整脫殼流程
text
1. 找OEP (上述方法)
2. Dump內存 (OllyDumpEx)
3. 修復IAT (Scylla)
4. 測試脫殼后程序
5. 如有問題,檢查Stolen Bytes
需要具體某個樣本的詳細演示嗎?
浙公網安備 33010602011771號