## 4.2 處理訪問違例
當程序嘗試訪問它們沒有權限訪問的頁面的時候或者以一種不合法的方式訪問內存的 時候,就會產生訪問違例。導致違例錯誤的范圍很廣,從內存溢出到不恰當的處理空指針都 有可能。從安全角度考慮,每一個訪問違例都應該仔細的審查,因為它們有可能被利用。
當調試器處理訪問違例的時候,需要搜集所有和違例相關的信息,棧框架,寄存器,以及引起違例的指令。接著我們就能夠用這些信息寫一個利用程序或者創建一個二進制的補丁 文件。
PyDbg 能夠很方便的實現一個違例訪問處理函數,并輸出相關的奔潰信息。這次的測試 目標就是危險的 C 函數 strcpy() ,我們用它創建一個會被溢出的程序。接下來我們再寫一個 簡短的 PyDbg 腳本附加到進程并處理違例。溢出的腳本 buffer_overflow.py,代碼如下:
```
# buffer_overflow.py
from ctypes import *
msvcrt = cdll.msvcrt
# Give the debugger time to attach, then hit a button
raw_input("Once the debugger is attached, press any key.")
# Create the 5-byte destination buffer
buffer = c_char_p("AAAAA")
# The overflow string
overflow = "A" * 100
# Run the overflow
msvcrt.strcpy(buffer, overflow)
```
問題出在這句 msvcrt.strcpy(buffer, overflow),接受的應該是一個指針,而傳遞給函數的是一個變量,函數就會把 overflow 當作指針使用,把里頭的值當作地址用(0x41414141414.....)。可惜這個地址是很可能是不能用的。現在我們已經構造了測試案例, 接下來是處理程序了。
```
# access_violation_handler.py
from pydbg import *
from pydbg.defines import *
# Utility libraries included with PyDbg
import utils
# This is our access violation handler
def check_accessv(dbg):
# We skip first-chance exceptions
if dbg.dbg.u.Exception.dwFirstChance:
return DBG_EXCEPTION_NOT_HANDLED
crash_bin = utils.crash_binning.crash_binning()
crash_bin.record_crash(dbg)
print crash_bin.crash_synopsis()
dbg.terminate_process()
return DBG_EXCEPTION_NOT_HANDLED
pid = raw_input("Enter the Process ID: ")
dbg = pydbg()
dbg.attach(int(pid)) dbg.set_callback(EXCEPTION_ACCESS_VIOLATION,check_accessv)
dbg.run()
```
現在運行 buffer_overflow.py,并記下它的進程號,我們先暫停它等處理完以后再運行。
執行 access_violation_handler.py 文件,輸入測試套件的 PID.當調試器附加到進程以后,在測 試套件的終端里按任何鍵,接下來你應該看到和表 4-1 相似的輸出。
```
python25.dll:1e071cd8 mov ecx,[eax+0x54] from thread 3376 caused access violation when attempting to read from 0x41414195 CONTEXT DUMP
EIP: 1e071cd8 mov ecx,[eax+0x54]
EAX: 41414141 (1094795585) -> N/A
EBX: 00b055d0 ( 11556304) -> @U`" B`Ox,`O )Xb@|V`"L{O+H]$6 (heap)
ECX: 0021fe90 ( 2227856) -> !$4|7|4|@%,\!$H8|!OGGBG)00S\o (stack)
EDX: 00a1dc60 ( 10607712) -> V0`w`W (heap)
EDI: 1e071cd0 ( 503782608) -> N/A
ESI: 00a84220 ( 11026976) -> AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA (heap)
EBP: 1e1cf448 ( 505214024) -> enable() -> NoneEnable automa (stack)
ESP: 0021fe74 ( 2227828) -> 2? BUH` 7|4|@%,\!$H8|!OGGBG) (stack)
+00: 00000000 ( 0) -> N/A
+04: 1e063f32 ( 503725874) -> N/A
+08: 00a84220 ( 11026976) -> AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA (heap)
+0c: 00000000 ( 0) -> N/A
+10: 00000000 ( 0) -> N/A
+14: 00b055c0 ( 11556288) -> @F@U`" B`Ox,`O )Xb@|V`"L{O+H]$ (heap)
disasm around:
0x1e071cc9 int3
0x1e071cca int3
0x1e071ccb int3
0x1e071ccc int3
0x1e071ccd int3
0x1e071cce int3
0x1e071ccf int3
0x1e071cd0 push esi
0x1e071cd1 mov esi,[esp+0x8]
0x1e071cd5 mov eax,[esi+0x4]
0x1e071cd8 mov ecx,[eax+0x54]
0x1e071cdb test ch,0x40
0x1e071cde jz 0x1e071cff
0x1e071ce0 mov eax,[eax+0xa4]
0x1e071ce6 test eax,eax
0x1e071ce8 jz 0x1e071cf4
0x1e071cea push esi
0x1e071ceb call eax
0x1e071ced add esp,0x4
0x1e071cf0 test eax,eax
0x1e071cf2 jz 0x1e071cff
SEH unwind:
0021ffe0 -> python.exe:1d00136c jmp [0x1d002040]
ffffffff -> kernel32.dll:7c839aa8 push ebp
```
Listing 4-1:PyDbg 捕捉到的奔潰信息
輸出了很多有用的信息片斷。第一個部分指出了那個指令引發了訪問異常以及指令在哪 個塊里。這個信息可以幫助 你寫出漏洞利用程序或者用靜態分析工具分析問題出在哪里。 第二部分轉儲出了所有寄存器的值,特別有趣的是,我們將 EAX 覆蓋成了 0x41414141(0x41 是大寫 A 的的十六進制表示)。同樣,我們看到 ESI 指向了一個由 A 組成的字符串。和 ESP+08 指向同一個地方。第三部分是在故障指令附近代碼的反匯編指令。最后一塊是奔潰發生時候 注冊的結構化異常處理程序的列表。
用 PyDbg 構建一個奔潰處理程序就是這么簡單。不僅能夠自動化的處理崩潰,還能在 在事后剖析進程發生的一切。下節,我們用 PyDbg 的進程內部快照功能創建一個進 程 rewinder。
- 序
- 1 搭建開發環境
- 1.1 操作系統準備
- 1.2 獲取和安裝 Python2.5
- 1.3 配置 Eclipse 和 PyDev
- 2 調試器設計
- 2.1 通用 CPU 寄存器
- 2.2 棧
- 2.3 調試事件
- 2.4 斷點
- 3 自己動手寫一個 windows 調試器
- 3.2 獲得 CPU 寄存器狀態
- 3.3 實現調試事件處理
- 3.4 全能的斷點
- 4 PyDBG---純 PYTHON 調試器
- 4.1 擴展斷點處理
- 4.2 處理訪問違例
- 4.3 進程快照
- 5 IMMUNITY----最好的調試器
- 5.1 安裝 Immunity 調試器
- 5.2 Immunity Debugger 101
- 5.3 Exploit 開發
- 5.4 搞定反調試機制
- 6 HOOKING
- 6.1 用 PyDbg 實現 Soft Hooking
- 6.2 Hard Hooking
- 7 Dll 和代碼注入
- 7.1 創建遠線程
- 7.2 邪惡的代碼
- 8 FUZZING
- 8.1 Bug 的分類
- 8.2 File Fuzzer
- 8.3 改進你的 Fuzzer
- 9 SULLEY
- 9.1 安裝 Sulley
- 9.2 Sulley primitives
- 9.3 獵殺 WarFTPD
- 10 Fuzzing Windows 驅動
- 10.1 驅動通信
- 10.2 用 Immunity fuzzing 驅動
- 10.4 構建 Driver Fuzzer
- 11 IDAPYTHON --- IDA 腳本
- 11.1 安裝 IDAPython
- 11.2 IDAPython 函數
- 11.3 腳本例子
- 12 PyEmu
- 12.1 安裝 PyEmu
- 12.2 PyEmu 一覽
- 12.3 IDAPyEmu