Windows句柄表学习笔记 —— 句柄表全局句柄表
Windows句柄表學習筆記 —— 句柄表&全局句柄表
- 句柄表
- 實驗一:在WinDbg中查看句柄表
- 第一步:打開一個Win32窗口程序
- 第二步:編譯并運行以下代碼
- 第三步:查看運行結果
- 第四步:在WinDbg中定位句柄表
- 句柄表結構
- 實驗二:在WinDbg中查看并分析句柄表結構
- 第一步:打開一個Win32窗口程序
- 第二步:編譯以下代碼并運行
- 第三步:查看運行結果
- 第四步:在WinDbg中定位最后一個句柄
- 第五步:通過句柄定位內核對象
- 全局句柄表
- 全局句柄表結構
- 實驗:在WinDbg中觀察全局句柄表
- 第一步:打開一個Win32窗口程序
- 第二步:獲得進程PID
- 第三步:獲得全局句柄表
- 第四步:查看_EPROCESS結構體
句柄表
描述:
例如:
HANDLE g_hMutex = ::CreateMutex(NULL,FALSE, "XYZ"); HANDLE g_hMutex = ::OpenMutex(MUTEX_ALL_ACCESS,FALSE, "XYZ"); HANDLE g_hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL); HANDLE g_hThread = ::CreateThread(NULL, 0, Proc, NULL, 0, NULL);思考:為什么微軟不直接把內核對象的地址返回給用戶,而是通過句柄的形式
答案:句柄存在的目的是為了避免在應用層直接修改內核對象,如果直接返回內核對象的地址,那么就意味著我們可以在應用層修改這個地址,一旦指向了無效的內核內存地址就會藍屏
注意:
句柄索引定位對應句柄的計算公式:handle = index / 4 * 8
實驗一:在WinDbg中查看句柄表
第一步:打開一個Win32窗口程序
本實驗選擇進程為計算器(calc.exe)
第二步:編譯并運行以下代碼
#include <stdio.h> #include <windows.h>int main() {DWORD PID;HANDLE hPro = NULL;HWND hWnd = ::FindWindow(NULL, "計算器");::GetWindowThreadProcessId(hWnd, &PID);for(int i=0; i<100 ;i++){hPro = ::OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, TRUE, PID);printf("句柄:%x\n", hPro);}getchar();return 0; }第三步:查看運行結果
第四步:在WinDbg中定位句柄表
kd> !process 0 0
kd> dt _EPROCESS 862adda0
kd> dt _HANDLE_TABLE 0xe12ca370
kd> dd 0xe1b6f000
第一個句柄地址 = 0xe1b6f000 + 0x7cc / 4 * 8 = 0xe1b6ff98
kd> dq 0xe1b6ff98
句柄表結構
1:共兩個字節,低字節保留恒為0,高位字節是給SetHandleInformation這個函數用的,比如寫成SethandleInformation(Handle, HANDLE_FLAG_PROTECT_FROM_CLOSE, HANDLE_FLAG_PROTECT_FROM_CLOSE),那么這個位置將被寫入0x02(HANDLE_FLAG_PROTECT_FROM_CLOSE宏的值為0x00000002,取最低字節,最終這塊是0x0200
)
2:這塊是訪問掩碼,是給OpenProess這個函數用的
OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId)具體存的就是這個函數第一個參數的值
3&4:共4個字節,其中bit0和bit2存儲句柄的屬性,默認為0,bit1表示該句柄是否可繼承(參考OpenProcess的第二個參數)
實驗二:在WinDbg中查看并分析句柄表結構
第一步:打開一個Win32窗口程序
本實驗選擇進程為計算器(calc.exe)
第二步:編譯以下代碼并運行
#include <stdio.h> #include <windows.h>int main() {DWORD PID;HANDLE hPro = NULL;HWND hWnd = ::FindWindow(NULL, "計算器");::GetWindowThreadProcessId(hWnd, &PID);for(int i=0; i<100 ;i++){hPro = ::OpenProcess(PROCESS_CREATE_THREAD, TRUE, PID);printf("句柄:%x\n", hPro);}//HANDLE_FLAG_PROTECT_FROM_CLOSE:句柄不可用CloseHandle關閉SetHandleInformation(hPro, HANDLE_FLAG_PROTECT_FROM_CLOSE, HANDLE_FLAG_PROTECT_FROM_CLOSE);getchar();return 0; }第三步:查看運行結果
第四步:在WinDbg中定位最后一個句柄
定位過程參考實驗一
第五步:通過句柄定位內核對象
句柄值:0200003a 8617c7e3
清理后三位bit,后四個字節為地址: 8617c7e0
注意:此時該地址指向 _OBJECT_HEADER ,若想查看真正的內核對象結構體還要加上0x18
實驗中我們使用OpenProcess打開句柄,因此查看_EPROCESS結構體
kd> dt _EPROCESS 8617c7e0 + 0x18
全局句柄表
描述:
PsLookupProcessThreadByCid()
PsLookupProcessByProcessId()
PsLookupThreadByThreadId()
全局句柄表結構
描述:
實驗:在WinDbg中觀察全局句柄表
第一步:打開一個Win32窗口程序
本實驗選擇進程為計算器(calc.exe)
第二步:獲得進程PID
index = 1048 / 4 = 0x106
第三步:獲得全局句柄表
kd> dd PspCidTable
kd> dt _HANDLE_TABLE e1003c58
第四步:查看_EPROCESS結構體
kd> dq e1005000 + 0x106*8
kd> dt _EPROCESS 85e2d540 //后三位屬性位清零
總結
以上是生活随笔為你收集整理的Windows句柄表学习笔记 —— 句柄表全局句柄表的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows事件等待学习笔记(四)——
- 下一篇: Windows异常学习笔记(一)—— C