Windows內核分析索引目錄:https://www.cnblogs.com/onetrainee/p/11675224.html
一、內核編程注意細節:
- 在頭文件中使用的是 <ntddk.h>,而非普通的 <windows.h>。
- 在應用層編程時,在內核編程時,要使用自己的WDK文檔。https://docs.microsoft.com/zh-cn/windows-hardware/drivers/?redirectedfrom=MSDN
二、獲取未公開API的方法:
- 特征碼搜索:遍歷內核函數所在的模塊。
- 解析內核PDB文件:用Windbg U 指令查看匯編函數代碼。
注意:在安全編程時,經常需要用到一些微軟未公開文檔化的API,這時就需要自己去尋找。
三、變量定義習慣:
遵循WDK自己的一套規范的變量定義習慣,而不是再用原來的int之類的C語言的變量名稱。
ULONG(unsigned long) PULONG(unsigned long*)
UCHAR(unsigned char) PUCHAR(unsinged char*)
UINT(unsigned int) PUNIT(unsigned int*)
VOID(void) PVOID(void*)
四、返回值:
很多API都返回 NTSTATUS 來表示函數執行的結果,其中有如下含義。
STATUS_SUCCESS 0x0000000 成功
STATUS_INVALID_PARAMETER 0xC000000D 參數無效
STAUS_BUFFER_OVERFLOW 0x80000005 緩沖區長度不夠
更多的信息可以在 ntstatus.h 中查看。
五、內核中的異常處理:
在內核中一個小小的錯誤就可能導致藍屏(例如"讀寫無效內存")
因此需要使用異常處理代碼:
__try {
// 可能出錯的代碼
}
__except (filter_value) {
// 出錯時要執行的代碼
}
filter_value解析:
EXCEPTION_EXECUTE_HANDLER(1) 代碼進入except塊。
EXCEPTION_CONTINUE_SEARCH(0) 不處理異常,由上一層調用函數處理。
EXCEPTION_CONTINUE_EXECUTION(-1), 回去繼續程序錯誤的代碼。
六、常用的內核內存函數
對內存的使用,主要就是:申請、設置、拷貝以及釋放。
PVOID ExAllocatePool(
__drv_strictTypeMatch(__drv_typeExpr)POOL_TYPE PoolType, // 這里主要說明其是 主要分頁內存還是非分頁內存
SIZE_T // NumberOfBytes
);
七、內核字符串種類
在R3層時都是以\0或\0\0結尾。
但在驅動編程中,這樣很容易出現藍屏。
因此,為了避免這種問題,使用內核提供的字符串。
typedef struct _STRING {
USHORT Length;//字節數,不是字符數 一定要* sizeof(CHAR)
USHORT MaximumLength;//字節數,不是字符數 一定要* sizeof(CHAR)
PWSTR Buffer;//非零結尾,中間也可能含有零
}ANSI_STRING, *PANSI_STRING;
typedef struct _UNICODE_STRING {
USHORT Length;//字節數,不是字符數 一定要* sizeof(WCHAR)
USHORT MaximumLength;//字節數,不是字符數 一定要* sizeof(WCHAR)
PWSTR Buffer;//非零結尾,中間也可能含有零
} UNICODE_STRING, *PUNICODE_STRING;
常用字符串API函數: