1、什麼是控制代碼(核心物件)
當乙個程序建立或開啟乙個乙個核心物件時,將獲得乙個控制代碼,通過這個控制代碼可以訪問核心物件。
如:handle g_hmutex = ::createmutex(null, false, 「xyz」);
handle g_hmutex = ::openmutex(mutex_all_access, false, 「xyz」);
handle g_hevent = ::createevent(null, true, false, 「xyz」);
handle g_hthread = ::createthread(null, 0, proc, null, 0, null);
2、為什麼要由控制代碼
控制代碼存在的目的是為了應用層直接修改核心物件。
handle g_hevent = ::createevent(null, true, false, 「xyz」);
如果g_hevent 儲存的是event核心物件的位址,那麼久意味著我們可以在應用層修改這個位址,一旦指向了無效的核心記憶體位址就會藍屏。
3、控制代碼表在**
每個程序對應乙個0環的結構體叫eprocess,在這個結構體中有乙個成員objecttable,它是乙個結構體_handle_table
kd> dt _eprocess
ntdll!_eprocess
…,.+0x0c4 objecttable : ptr32 _handle_table
…kd> dt _handle_table
ntdll!_handle_table
+0x000 tablecode : uint4b //控制代碼表位址,控制代碼表在**
+0x004 quotaprocess : ptr32 _eprocess
+0x008 uniqueprocessid : ptr32 void
+0x00c handletablelock : [4] _ex_push_lock
+0x01c handletablelist : _list_entry
+0x024 handlecontentionevent : _ex_push_lock
+0x028 debuginfo : ptr32 _handle_trace_debug_info
+0x02c extrainfopages : int4b
+0x030 firstfree : uint4b
+0x034 lastfree : uint4b
+0x038 nexthandleneedingpool : uint4b
+0x03c handlecount : int4b
+0x040 flags : uint4b
+0x040 strictfifo : pos 0, 1 bit
實驗:用如下**做實驗查詢控制代碼表位置:
#include #include #include void test()
//handle_flag_protect_from_close 控制代碼不可用closehandle()函式關閉
//sethandleinformation(hpro, handle_flag_protect_from_close, handle_flag_protect_from_close);
}int main()
首先,我們在虛擬機器中執行附件中的「計算器」,然後執行我們的程式,上面我們連續開啟了100此核心,物件,這個核心物件一定存在我們的控制代碼表裡,真正的控制代碼每個成員是8個位元組,控制代碼錶值仍然是按4個位元組來計算的。先在windbug中找到當前這個程序
!process 0 0
檢視程序結構體找到出c4位置:
檢視_handle_table結構體找到第乙個成員就是一張表的起始位址
檢視控制代碼相關值
同過控制代碼0x69c找控制代碼表中對應的值
我們可以看到這些控制代碼對應的控制代碼表中的值都是一樣的。
控制代碼表項分四小哥部分如下圖:
1處共兩個位元組,低位元組保留恒為0,高位元組主要是給sethandleinformation這個函式用的,比如寫成sethandleinformation(hpro, handle_flag_protect_from_close, handle_flag_protect_from_close);那麼這個值將被寫入0x02,handle_flag_protect_from_close這個巨集的值為0x00000002,取最低位元組,最終1這部分是0x0200
2這部分是訪問掩碼,是個openprocess用的,::openprocess(process_create_thread, true, pid);具體存的就是這個函式的第乙個引數值
3和4兩個部分共計4個位元組,其中bit0~bit2存的是控制代碼屬性,其中bit2,bit0預設為0,1 bit1表示該控制代碼是否可繼承,openprocess第二個引數與bit有關。
bit31 ~ bit3則是存放該核心物件在核心中的具體位址。
下面我們改一下上面的**如下來驗證上面的陳述
#include #include #include void test()
//handle_flag_protect_from_close 控制代碼不可用closehandle()函式關閉
sethandleinformation(hpro, handle_flag_protect_from_close, handle_flag_protect_from_close);
}int main()
重複上面的操作,找到控制代碼表中最後乙個控制代碼對應的值
我們可以看到這裡被我們改了
核心物件前都有
_object_header結構體,所以我們控制代碼表要檢視eprocess應改用指令
dt _eprocess 866f4008+18
我們再看一下我們開啟的計算器程序的位址可以看到866f4008+18 = 866f4020
04 控制代碼表
核心物件概念 像程序 執行緒 檔案 互斥體 事件等在核心中都有乙個結構體,這些結構體由核心負責管理,我們管這些結構體叫做核心物件。應用層 程序 執行緒 檔案 核心層 eprocess ethread file obje 判斷核心是否核心物件小技巧 在搜尋closehandle 函式,其關閉的都是核心...
Windows程式設計知識要點總結3 2 控制代碼
以下為網上轉的,列在控制代碼的總結裡,我自己也還未仔細看過以下內容 sdk程式設計中視窗id,控制代碼,指標三者相互轉換函式 id handle hwnd三者之間的互相轉換 id 控制代碼 hwnd getdlgitem hparentwnd,id id 指標 cwnd getdlgitem 控制代...
物件導向程式設計系列六 控制代碼類
1 控制代碼類 前面的章節中提到,在繼承體系中,從派生類物件到基類物件的轉換中最終得到的是乙個基類物件,派生類的部分會被切掉,而對應的指標或引用的轉換則並不改變派生類物件,而是將指標或引用繫結到派生類物件中,這樣一來才可以實現執行時的動態繫結,如下 1 void get prices item ba...