00 控制代碼表

2021-09-11 01:14:20 字數 3652 閱讀 4173

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...