Windows內核分析索引目錄:https://www.cnblogs.com/onetrainee/p/11675224.html
技術學習來源:火哥(QQ:471194425)
注釋:因為自己的知識有限,在句柄那塊說的不是很清除,在學習相關知識之后會自行補上。
通過修改VAD屬性破除鎖頁機制
對於一般的頁屬性修改,我們直接修改_MMVAD_FLAGS.Protection即可。
但是,如果有鎖頁機制,單純改這個是無法實現目的的。(具體情況參見:利用內存鎖定方式頁面修改)
面對這種情況,我們既要修改_MMVAD_FLAGS.Protection,又要修改另一處(下面會詳細講述)。
1. 修改 _SECTION.MMSECTION_FLAGS
一個 section_object 代表了一個內存段, section_object 可以在不同的進程之間共享它所代表的內存, 進程也可以使用 section object 把文件映射到內存中。
我們通過HANDLE來獲取_SECTION_OBJECT的地址,然后修改。
1)獲取句柄值:
如圖,我們通過VirtualProtect的參數獲取其句柄值p。
VirtualProtect(BaseAddress, 0x10000, PAGE_EXECUTE_READWRITE, &p);
句柄值p為0x34,其4位一個,故其索引位 D(0x34/4)。
2)句柄表位置:句柄表在 _EPROCESS+0xc4的位置 +0x0c4 ObjectTable : Ptr32 _HANDLE_TABLE
ntdll!_HANDLE_TABLE
+0x000 TableCode : 0xe2548000
+0x004 QuotaProcess : 0x816be878 _EPROCESS
3)我們查看句柄表 0xe2548000,來獲取 表碼。
其結尾代表表層數,比如 001代表一層,002代表三層個,我們現在是000,故直接查這張表。
kd> dd 0xe2548000
e2548000 00000000 fffffffe e1005431 000f0003
e2548010 e1499d49 00000003 81a84d63 00100020
e2548020 00000000 00000040 e168f2f1 000f000f
因為"句柄描述符"(暫時先這么稱呼),8位一個,前四位地址(最后一位要抹零),后四位屬性。
索引得到0xD處的"句柄描述符",其運算符為 dd 0xe2548000+8*D。
e153b151 000f001f
4)e153b150(最后一位置零)指向的是一個,其指向 _OBJECT_HEADER 的結構,表示內核對象(句柄本身就指向內核對象)
kd> dt _OBJECT_HEADER e153b151
nt!_OBJECT_HEADER
+0x000 PointerCount : 0n16777216
+0x004 HandleCount : 0n1610612736
+0x004 NextToFree : 0x60000000 Void
+0x008 Type : 0x0081fb55 _OBJECT_TYPE
+0x00c NameInfoOffset : 0 ''
+0x00d HandleInfoOffset : 0x10 ''
+0x00e QuotaInfoOffset : 0 ''
+0x00f Flags : 0xd8 ''
+0x010 ObjectCreateInfo : 0x0081ecc7 _OBJECT_CREATE_INFORMATION
+0x010 QuotaBlockCharged : 0x0081ecc7 Void
+0x014 SecurityDescriptor : (null)
+0x018 Body : _QUAD
5)_SECTION 數據結構 (_OBJECT_HEADER+0x18處)
我們通過 dt _OBJECT_HEADER -r1 指令並沒有分析出+0x18處其是什么結果。
+0x018 Body : _QUAD
+0x000 DoNotUseThisField : 2.9027887682017685678e-306
但其指向一個 _SECTION結構體,我們在WRK中看到其定義
typedef struct _SECTION {
MMADDRESS_NODE Address; // +0x0
PSEGMENT Segment; // +0x14
LARGE_INTEGER SizeOfSection; // +0x18
union {
ULONG LongFlags;
MMSECTION_FLAGS Flags; //+0x24
} u;
MM_PROTECTION_MASK InitialPageProtection;
6)查看並修改 _SECTION.MMSECTION_FLAGS屬性。
我們注意到有一個 MMSECTION_FLAGS,這是表示內存段的屬性,我們要修改的內容就在這里。
偏移為 +0x24(通過WRK中結構體的定義推斷出)。
kd> dd e153b150+18+24
e153b18c 00000020
其為 20,正好對應的是R3環的定義(R3環申請內存時頁面保護與_MMVAD_FLAGS.Protection位的對應關系)
#define PAGE_EXECUTE_READ 0x20
我們將其修改為 PAGE_EXECUTE_READWRITE 0x40
ed dd e153b150+18+24 40
7)至此,我們第一步已經完成,下面我們來修改 _MMVAD_FLAGS.Protection即可。
2.修改 _MMVAD_FLAGS.Protection屬性
這里比較簡單,我們之前寫過一篇博客。
根據那篇博客中的描述,很好的修改 _MMVAD_FLAGS.Protection屬性。
---》VAD樹的屬性及其遍歷《---
3.修改結果
本來,我們這篇 利用內存鎖定方式頁面修改 中無法修改的內存,最終發現可以被修改了。
4.后記
注意:對於一般Private之類的內存,我們並不需要修改 _SECTION.MMSECTION_FLAGS,只改_MMVAD_FLAGS.Protection即可。