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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

Windows驱动开发学习笔记(二)—— 驱动调试内核编程基础

發布時間:2025/3/21 windows 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Windows驱动开发学习笔记(二)—— 驱动调试内核编程基础 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Windows驅動開發學習筆記(二)—— 驅動調試&內核編程基礎

    • 基礎知識
    • 驅動調試
      • PDB(Program Debug Database)
      • WinDbg 加載 PDB
      • 實驗:調試 .sys 文件
        • 第一步:編譯代碼
        • 第二步:將 .sys 文件拷貝到虛擬機中
        • 第三步:添加 pdb 文件路徑
        • 第四步:部署 .sys 文件并運行
    • 內核編程基礎
      • 內核API的使用
      • 未導出函數的使用
      • 基本數據類型
      • 返回值
      • 內核中的異常處理
      • 常用內核函數(內存操作)
      • 內核字符串種類
      • 內核字符串常用函數

基礎知識

  • 驅動程序無法在當前系統中進行調試,否則會導致系統卡死
  • 可以采用雙機調試的方式調試驅動程序
  • 驅動調試

    當我們使用 windbg 查看某一個地址的反匯編時,例如:

    windbg 能夠自動幫我們識別出該地址屬于哪個函數(紅框部分)

    思考:windbg 是如何識別出該地址對應的函數的?

    PDB(Program Debug Database)

  • PDB文件是在我們編譯工程的時候產生的,它是和對應的模塊(exe或dll)一起生成出來的
  • 每個模塊編譯的時候都可以生成自己的PDB文件,比如 .exe / .dll / .sys 等等
  • 0環調試器(例如 WinDbg)正是通過解析pdb文件來找到函數與地址之間的對應關系
  • WinDbg 加載 PDB



    實驗:調試 .sys 文件

    第一步:編譯代碼

    #include "ntddk.h"//卸載函數 VOID DriverUnload(PDRIVER_OBJECT driver) {DbgPrint("驅動程序已停止.\r\n"); }//驅動程序入口函數,相當于控制臺的main函數 NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath) {__asm{int 3mov eax, eaxmov eax, eaxmov eax, eax}DbgPrint("驅動程序已運行.\r\n");//設置一個卸載函數 便于退出DriverObject->DriverUnload = DriverUnload;return STATUS_SUCCESS; }

    第二步:將 .sys 文件拷貝到虛擬機中

    第三步:添加 pdb 文件路徑


    第四步:部署 .sys 文件并運行


    WinDbg 成功截獲中斷即可

    內核編程基礎

    內核API的使用

  • 在應用層編程時,可以使用WINDOWS提供的各種API函數,只要導入頭文件<windows.h>就可以了。但是在內核編程的時候,不能像在Ring3那樣直接使用
  • 微軟為內核程序提供了專用的API,只要在程序中包含相應的頭文件就可以使用了,如:#include <ntddk.h> (前提是已經正確安裝了WDK)
  • 在應用層編程的時候,我們通過MSDN來了解函數的詳細信息,在內核編程的時候,要使用WDK自己的幫助文檔
  • 未導出函數的使用

    描述

  • WDK說明文檔中只包含了內核模塊導出的函數,對于未導出的函數,則不能直接使用。
  • 如果要使用未導出的函數,只要自己定義一個函數指針,為函數指針提供正確的函數地址就可以使用了
  • 獲取未導出的函數地址

  • 特征碼搜索
  • 解析內核PDB文件
  • 基本數據類型

    在內核編程的時候,強烈建議大家遵守WDK的編碼習慣,不要這樣寫:unsigned long length;

    WDK類型

    ULONG(unsigned long) PULONG(unsigned long *) UCHAR(unsigned char) PUCHAR(unsigned char *) UINT(unsigned int) PUNIT(unsigned int *) VOID(void) PVOID(void *)

    返回值

    大部分內核函數的返回值都是NTSTATUS類型,如:

    NTSTATUS PsCreateSystemThread(); NTSTATUS ZwOpenProcess(); NTSTATUS ZwOpenEvent();

    這個值能說明函數執行的結果,如:

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

    當調用的內核函數時,如果返回的結果不是STATUS_SUCCESS,就說明函數執行中遇到了問題,具體是什么問題,可以在ntstatus.h文件中查看

    內核中的異常處理

    描述

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

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

    filter_value:

    EXCEPTION_EXECUTE_HANDLER(1) //代碼進入except塊 EXCEPTION_CONTINUE_SEARCH(0) //不處理異常,由上一層調用函數處理 EXCEPTION_CONTINUE_EXECUTION(-1) //回去繼續執行錯誤處的代碼

    常用內核函數(內存操作)

    內核字符串種類

    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;

    內核字符串常用函數

    總結

    以上是生活随笔為你收集整理的Windows驱动开发学习笔记(二)—— 驱动调试内核编程基础的全部內容,希望文章能夠幫你解決所遇到的問題。

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