日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

(34)内核编程基础

發布時間:2025/3/21 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 (34)内核编程基础 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、未文檔化函數、未導出函數

未文檔化就是WDK文檔里搜不到,但是在導出表里的函數,要使用這種函數可以使用GetProcAddress函數獲取函數地址;

未導出函數就是不在導出表的函數,可以通過特征碼搜索或者解析內核PDB的方式找到函數地址,通過函數指針調用。

二、WDK數據類型

WDK數據類型在ntdef.h中定義,下面列舉部分,注意,并沒有UINT

typedef unsigned char UCHAR; typedef unsigned short USHORT; typedef unsigned long ULONG;

三、NTSTATUS 返回值

很多內核函數的返回值都是 NTSTATUS,這是一個4字節整型。
例如:

STATUS_SUCCESS 0x00000000 成功 STATUS_INVALID_PARAMETER 0xC000000D 參數無效 STATUS_BUFFER_OVERFLOW 0x80000005 緩沖區長度不夠

四、內核異常處理

在內核中,一個小小的錯誤就可能導致藍屏,比如:讀寫一個無效的內存地址。為了讓自己的內核程序更加健壯,強烈建議大家在編寫內核程序時,使用異常處。
Windows提供了結構化異常處理機制,一般的編譯器都是支持的,如下:

__try{//可能出錯的代碼 } __except(filter_value) {//出錯時要執行的代碼 }

出現異常時,可根據filter_value的值來決定程序該如果執行,當filter_value的值為:
EXCEPTION_EXECUTE_HANDLER(1),代碼進入except塊
EXCEPTION_CONTINUE_SEARCH(0),不處理異常,由上一層調用函數處理
EXCEPTION_CONTINUE_EXECUTION(-1),回去繼續執行錯誤處的代碼

用一段代碼演示:

__try {PULONG ptr = NULL;*ptr = 0x1234; } __except(EXCEPTION_EXECUTE_HANDLER) { DbgPrint("非法訪問內存.\r\n"); }

五、常用的內核內存函數

C語言內核
mallocExAllocatePool
memsetRtlFillMemory
memcpyRtlMoveMemory
freeExFreePool

六、內核字符串及常用字符串函數

為了提高安全性,內核中的字符串不再是字符串首地址指針作為開始,0作為結尾,而是采用了以下兩個結構體:

ANSI_STRING字符串:

typedef struct _STRING {USHORT Length;USHORT MaximumLength;PCHAR Buffer; }STRING;

UNICODE_STRING字符串:

typedef struct _UNICODE_STRING {USHORT Length;USHORT MaxmumLength;PWSTR Buffer; } UNICODE_STRING;

下面的表格列出了常用的字符串函數:

功能ANSI_STRING字符串UNICODE_STRING字符串
創建RtlInitAnsiStringRtlInitUnicodeString
復制RtlCopyStringRtlCopyUnicodeString
比較RtlCompareStringRtlCompareUnicoodeString
轉換RtlAnsiStringToUnicodeStringRtlUnicodeStringToAnsiString

七、課后練習

1、申請一塊內存,并在內存中存儲GDT、IDT的所有數據。然后在debugview中顯示出來,最后釋放內存。

#include <ntddk.h> #include <ntdef.h>// 卸載函數 VOID DriverUnload(PDRIVER_OBJECT driver) {DbgPrint("驅動程序停止運行了.\r\n"); }// 入口函數,相當于main NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path) { UCHAR GDT[6];UCHAR IDT[6];ULONG GdtAddr,GdtLen,IdtAddr,IdtLen;PUCHAR pBuffer = NULL;ULONG i;// 設置一個卸載函數,便于退出driver->DriverUnload = DriverUnload;// 讀取GDT, IDT__asm{sgdt fword ptr GDTsidt fword ptr IDT}GdtAddr = *(PULONG)(GDT+2);GdtLen = *(PUSHORT)GDT;IdtAddr = *(PULONG)(IDT+2);IdtLen = *(PUSHORT)IDT;// DbgPrint("GDT: %08X size: %04X\r\n", GdtAddr, GdtLen);// DbgPrint("IDT: %08X size: %04X\r\n", IdtAddr, IdtLen);// 申請內存pBuffer = (PUCHAR)ExAllocatePool(PagedPool, GdtLen + IdtLen);// 檢查申請是否成功if (NULL == pBuffer){DbgPrint("申請內存失敗.\r\n");return STATUS_UNSUCCESSFUL;}// 拷貝GDT, IDT數據RtlMoveMemory(pBuffer, (PUCHAR)GdtAddr, GdtLen);RtlMoveMemory(pBuffer + GdtLen, (PUCHAR)IdtAddr, IdtLen);// 打印數據DbgPrint("打印GDT\r\n");for (i = 0; i < GdtLen; i += 16){DbgPrint("%08X %08X %08X %08X %08X\r\n", GdtAddr + i, ((PULONG)(GdtAddr + i))[0],((PULONG)(GdtAddr + i))[1],((PULONG)(GdtAddr + i))[2],((PULONG)(GdtAddr + i))[3]);}DbgPrint("打印IDT\r\n");for (i = 0; i < IdtLen; i += 16){DbgPrint("%08X %08X %08X %08X %08X\r\n", IdtAddr + i, ((PULONG)(IdtAddr + i))[0],((PULONG)(IdtAddr + i))[1],((PULONG)(IdtAddr + i))[2],((PULONG)(IdtAddr + i))[3]);}// 釋放內存ExFreePool(pBuffer); return STATUS_SUCCESS; }

2、編寫代碼,實現如下功能:

<1> 初始化一個字符串

<2> 拷貝一個字符串

<3> 比較兩個字符串是否相等

<4> ANSI_STRING與UNICODE_STRING字符串相互轉換

不知為何,Unicode字符串中如果有中文,dbgview和windbg打印出來是空白。

#include <ntddk.h> #include <ntdef.h>// 卸載函數 VOID DriverUnload(PDRIVER_OBJECT driver) {DbgPrint("驅動程序停止運行了.\r\n"); }// 入口函數,相當于main NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path) { // 創建字符串ANSI_STRING AnsiSrc;ANSI_STRING AnsiDst;UNICODE_STRING UnicodeString;// 初始化字符串 RtlInitAnsiString(&AnsiSrc,"my first ANSI_STRING");RtlInitUnicodeString(&UnicodeString,L"my first UNICODE_STRING");// 打印字符串DbgPrint("%s Length: %d MaximumLength: %d\r\n", AnsiSrc.Buffer, AnsiSrc.Length, AnsiSrc.MaximumLength);DbgPrint("%ws Length: %d MaximumLength: %d\r\n", UnicodeString.Buffer, UnicodeString.Length, UnicodeString.MaximumLength);// 拷貝字符串RtlCopyString(&AnsiDst, &AnsiSrc);// 比較字符串if (RtlCompareString(&AnsiSrc, &AnsiDst, TRUE) == 0){DbgPrint("字符串相等.\r\n");}else{DbgPrint("字符串不相等.\r\n");}// Unicode轉AnsiDbgPrint("Unicode轉Ansi\r\n");RtlUnicodeStringToAnsiString(&AnsiDst,&UnicodeString,TRUE); DbgPrint("%s Length: %d MaximumLength: %d\r\n", AnsiDst.Buffer, AnsiDst.Length, AnsiDst.MaximumLength);// 設置一個卸載函數,便于退出driver->DriverUnload = DriverUnload;return STATUS_SUCCESS; }

總結

以上是生活随笔為你收集整理的(34)内核编程基础的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。