(40)写拷贝
一、什么是寫拷貝
寫拷貝是VAD樹里的屬性。當訪問一個線性地址,頁表項 PTE = 0 時,就會觸發缺頁異常,跳轉到異常處理函數,處理函數會檢查VAD樹,看看這個線性地址到底是沒掛物理頁,還是寫拷貝,或者是別的什么情況。
舉個例子,在Windows XP系統里,MessageBoxA 這個函數位于 ntdll.dll,假如我想HOOK它,比如把它頭兩個字節的 MOV EDI,EDI 改成JMP,此時由于 PTE = 0,就會觸發缺頁異常。然后異常處理函數遍歷 VAD 樹,就會發現 MessageBoxA 的屬性是 WriteCopy.
此時,如果你對數據進行修改,系統會幫你拷貝一份 MessageBoxA 的代碼,然后你的HOOK就只對本進程有效。
二、如何在windbg中打印 VAD 樹
首先,!process 0 0 查看進程信息
PROCESS 81ecbd50 SessionId: 0 Cid: 0118 Peb: 7ffde000 ParentCid: 05c4DirBase: 11edc000 ObjectTable: e15ae880 HandleCount: 18.Image: MessageBoxA_PDE_PTE.exe然后查看 EPROCESS 結構:
kd> dt _EPROCESS 81ecbd50 ntdll!_EPROCESS...+0x11c VadRoot : 0x81e8e8d8 Void+0x120 VadHint : 0x81e8e8d8 Void+0x124 CloneRoot : (null) +0x128 NumberOfPrivatePages : 0x4a+0x12c NumberOfLockedPages : 0+0x130 Win32Process : 0xe1ad8608 Void+0x134 Job : (null) ...然后 !vad 打印:
kd> !vad 0x81e8e8d8 VAD level start end commit 81d440b0 ( 1) 10 10 1 Private READWRITE 81e2cb70 ( 2) 20 20 1 Private READWRITE 81e8e8d8 ( 0) 30 12f 6 Private READWRITE 81d12318 ( 3) 130 132 0 Mapped READONLY Pagefile-backed section 81e552c8 ( 2) 140 140 0 Mapped READONLY Pagefile-backed section 81e25c60 ( 4) 150 24f 9 Private READWRITE 81d71d60 ( 3) 250 25f 6 Private READWRITE 81dead50 ( 5) 260 26f 0 Mapped READWRITE Pagefile-backed section 81f12898 ( 4) 270 285 0 Mapped READONLY \WINDOWS\system32\unicode.nls 81e3f2d8 ( 6) 290 2d0 0 Mapped READONLY \WINDOWS\system32\locale.nls 81d5e648 ( 5) 2e0 320 0 Mapped READONLY \WINDOWS\system32\sortkey.nls 81ec9320 ( 7) 330 335 0 Mapped READONLY \WINDOWS\system32\sorttbls.nls 81d707f0 ( 6) 340 380 0 Mapped READONLY Pagefile-backed section 81e929c0 ( 7) 3d0 3df 8 Private READWRITE 81e90970 ( 8) 3e0 3e0 1 Private READWRITE 81b47688 ( 9) 3f0 3f0 1 Private READWRITE 81b29358 ( 1) 400 41a 18 Mapped Exe EXECUTE_WRITECOPY \;F:\VBoxSvr\Projects\MessageBoxA_PDE_PTE\Debug\MessageBoxA_PDE_PTE.exe 81d400a8 ( 6) 420 4e7 0 Mapped EXECUTE_READ Pagefile-backed section 81b0f3a0 ( 7) 4f0 5f2 0 Mapped READONLY Pagefile-backed section 81d5ed80 ( 8) 600 8ff 0 Mapped EXECUTE_READ Pagefile-backed section 81e918b0 ( 9) 900 90f 8 Private READWRITE 81d40110 (10) 910 912 0 Mapped READONLY \WINDOWS\system32\ctype.nls 81d18980 (11) 920 92d 0 Mapped READWRITE Pagefile-backed section 81fc0768 (12) 930 930 1 Private READWRITE 81d4b238 ( 5) 10200 10371 7 Mapped Exe EXECUTE_WRITECOPY \;F:\VBoxSvr\Projects\MessageBoxA_PDE_PTE\Debug\MSVCR100D.dll 81aee750 ( 7) 62c20 62c28 1 Mapped Exe EXECUTE_WRITECOPY \WINDOWS\system32\lpk.dll 81e55128 ( 8) 73fa0 7400a 16 Mapped Exe EXECUTE_WRITECOPY \WINDOWS\system32\usp10.dll 81d8fd30 ( 6) 76300 7631c 1 Mapped Exe EXECUTE_WRITECOPY \WINDOWS\system32\imm32.dll 81d55d00 ( 7) 76d70 76d91 1 Mapped Exe EXECUTE_WRITECOPY \WINDOWS\system32\apphelp.dll 81d57998 ( 8) 77bd0 77bd7 1 Mapped Exe EXECUTE_WRITECOPY \WINDOWS\system32\version.dll 81d19630 ( 4) 77d10 77d9f 2 Mapped Exe EXECUTE_WRITECOPY \WINDOWS\system32\user32.dll 81d90128 ( 6) 77da0 77e48 5 Mapped Exe EXECUTE_WRITECOPY \WINDOWS\system32\advapi32.dll 81ea8c48 ( 7) 77e50 77ee1 1 Mapped Exe EXECUTE_WRITECOPY \WINDOWS\system32\rpcrt4.dll 81d5e618 ( 5) 77ef0 77f38 2 Mapped Exe EXECUTE_WRITECOPY \WINDOWS\system32\gdi32.dll 81d40178 ( 6) 77fc0 77fd0 1 Mapped Exe EXECUTE_WRITECOPY \WINDOWS\system32\secur32.dll 81da9d10 ( 3) 7c800 7c91d 5 Mapped Exe EXECUTE_WRITECOPY \WINDOWS\system32\kernel32.dll 81d5bca0 ( 2) 7c920 7c9b2 5 Mapped Exe EXECUTE_WRITECOPY \WINDOWS\system32\ntdll.dll 81dc4f70 ( 4) 7f6f0 7f7ef 0 Mapped EXECUTE_READ Pagefile-backed section 81b2f1d8 ( 3) 7ffa0 7ffd2 0 Mapped READONLY Pagefile-backed section 81d13f88 ( 5) 7ffdd 7ffdd 1 Private READWRITE 81f5c498 ( 4) 7ffde 7ffde 1 Private READWRITE Total VADs: 41 average level: 6 maximum depth: 12三、如何繞過寫拷貝
提供兩種思路:
1、另外申請一個線性地址,映射到MessageBoxA的物理頁,設置PTE的R/W屬性,使其可讀寫。
2、修改 VAD 樹,將寫拷貝改為可讀可寫。
總結
- 上一篇: (39)通过 PID 获取 EPROCE
- 下一篇: (41)缺页异常简介