Windows驅(qū)動程序設(shè)計入門.ppt
《Windows驅(qū)動程序設(shè)計入門.ppt》由會員分享,可在線閱讀,更多相關(guān)《Windows驅(qū)動程序設(shè)計入門.ppt(49頁珍藏版)》請在裝配圖網(wǎng)上搜索。
Windows驅(qū)動程序設(shè)計入門 2 Windows的虛擬內(nèi)存管理 3 Windows的虛擬內(nèi)存管理 Windows的虛擬內(nèi)存管理機(jī)制為應(yīng)用程序和驅(qū)動程序提供了兩種服務(wù) 使每個進(jìn)程都擁有自己獨(dú)立的內(nèi)存地址空間 對于32位Windows而言 每個任務(wù)可尋址的內(nèi)存地址空間都為0 x00000000 0 xFFFFFFFF 232 4GB 當(dāng)物理內(nèi)存不夠4GB時 虛擬內(nèi)存管理模塊會用磁盤空間模擬內(nèi)存空間 并且該模擬過程對應(yīng)用程序是透明的 4 用戶地址空間與內(nèi)核地址空間 Windows將每個進(jìn)程的4GB的獨(dú)立地址空間又劃分為用戶地址空間 0 x00000000 0 x7FFFFFFF 和內(nèi)核地址空間 0 x80000000 0 xFFFFFFFF 兩部分 操作系統(tǒng)內(nèi)核代碼和數(shù)據(jù)存放在內(nèi)核地址空間 每個進(jìn)程自己私有的代碼和數(shù)據(jù)存放在用戶地址空間雖然Windows的內(nèi)核代碼和數(shù)據(jù)被映射到了每個進(jìn)程的地址空間中 所有進(jìn)程看到的內(nèi)容是相同的 但在實(shí)際的物理內(nèi)存中 只有內(nèi)核代碼和數(shù)據(jù)的一份拷貝 5 用戶地址空間與內(nèi)核地址空間 6 用戶模式與內(nèi)核模式 為了更好地保護(hù)系統(tǒng) Windwos規(guī)定了兩種處理器工作模式 用戶模式和內(nèi)核模式 工作在用戶模式的程序只能使用CPU支持指令集的一個子集 只能訪問用戶空間中的內(nèi)存 并且不能直接訪問硬件 工作在內(nèi)核模式的程序不受任何限制 可以使用CPU支持的任意指令 可以訪問任意的內(nèi)存空間 可以直接訪問硬件 所有的Windows應(yīng)用程序都工作于用戶模式 Windows內(nèi)核程序都工作于內(nèi)核模式 也可以認(rèn)為 位于用戶空間的代碼都工作于用戶模式 位于內(nèi)核空間的代碼都工作于內(nèi)核模式 應(yīng)用程序只能通過Windows規(guī)定的一些API訪問內(nèi)核模式的代碼和數(shù)據(jù) 7 Windows系統(tǒng)結(jié)構(gòu) 8 什么是Windows驅(qū)動程序 Windows驅(qū)動程序是一種位于內(nèi)核地址空間并且工作于內(nèi)核模式的一種特殊的程序類型 sys文件 驅(qū)動程序是操作系統(tǒng)信任的一個內(nèi)核擴(kuò)展模塊 驅(qū)動程序和操作系統(tǒng)之間遵循的是容器與插件模型 OS負(fù)責(zé)管理Driver的生命周期 Driver是一種被動的軟件模塊 驅(qū)動程序類似于DLL程序 它是一個回調(diào)函數(shù) 子程序 的集合體 這些函數(shù)由OS在適當(dāng)?shù)臅r候調(diào)用驅(qū)動程序也可以通過Windows內(nèi)核API獲得OS的一些服務(wù) 9 編驅(qū)動程序用什么編程語言 C語言C 語言 1的情況下會用到匯編語言目前還不能用其它高級語言編寫驅(qū)動程序 10 編驅(qū)動程序用什么開發(fā)工具 WDK WindowsDriverKit 可以到微軟網(wǎng)站上免費(fèi)下載 DriverStudio CompuwareNuMega公司的產(chǎn)品 DDKWinDriver DDK 11 WDK中包含什么 與Windows內(nèi)核API函數(shù)相關(guān)的頭文件 如ddk h wdm h等 與Windows內(nèi)核API函數(shù)相關(guān)的導(dǎo)入庫 wdm lib等 內(nèi)核專用C運(yùn)行時間庫的頭文件和導(dǎo)入庫關(guān)于驅(qū)動程序編程模型和內(nèi)核API函數(shù)的幫助文檔C 編譯器和鏈接器 綜合創(chuàng)建工具內(nèi)核調(diào)試工具 分析工具 12 內(nèi)核模式下我們能調(diào)用哪些函數(shù) Windows內(nèi)核輸出的內(nèi)核API函數(shù) WDK提供的運(yùn)行時間庫其它驅(qū)動程序提供的服務(wù) 13 內(nèi)核模式下我們不能調(diào)用哪些函數(shù) Windows的用戶模式API函數(shù) ISO規(guī)定的C C 標(biāo)準(zhǔn)函數(shù)庫 14 最簡單的NT式驅(qū)動程序 extern C include extern C NTSTATUSDriverEntry INPDRIVER OBJECTDriverObject INPUNICODE STRINGRegistryPath NTSTATUSstatus STATUS UNSUCCESSFUL KdPrint將輸入字符串發(fā)送到一個特殊內(nèi)存區(qū) 利用DbgView工具可以觀察該內(nèi)存區(qū)的內(nèi)容 KdPrint HelloWorld returnstatus 15 關(guān)于最簡單驅(qū)動的問題 第一個extern C 的作用是什么 第二個extern C 的作用是什么 typedeflongNTSTATUS defineIN ifdefDBG defineKdPrint a DbgPrint a else defineKdPrint a endif 16 驅(qū)動程序的入口函數(shù) NTSTATUSDriverEntry INPDRIVER OBJECTDriverObject INPUNICODE STRINGRegistryPath returnstatus 參數(shù)DriverObject表示指向驅(qū)動對象的指針 參數(shù)RegistryPath表示該驅(qū)動所對應(yīng)的注冊表服務(wù)鍵的子目錄返回值表示初始化是否成功 17 DDK中一個驅(qū)動型工程的組成 MAKEFILE文件 一般不作改動Sources文件 1 指示了整個工程由哪些源程序和資源文件構(gòu)成 2 包含了主要的編譯參數(shù) 指導(dǎo)編譯器和鏈接器的工作 cpp文件和 h文件如何build驅(qū)動工程 用DDK中的build工具 build工具會根據(jù)MAKEFILE文件和Sources文件以及相關(guān)環(huán)境變量的指示編譯并鏈接工程中的 cpp文件和 h文件 18 如何安裝NT型驅(qū)動程序 方法1 在注冊表HKEY LOCAL MACHINE SYSTEM CurrentControlSet Services下增加一個新的項目 可以將該服務(wù)指定為開機(jī)自啟動 也可以指定為按需啟動 如果是按需啟動 則可以用netstart命令啟動 用netstop命令停止 方法2 編寫另外的用戶模式程序利用SCM函數(shù)按需啟動 方法3 在調(diào)試階段可以利用第三方的工具如 DriverMoniter和IntallDriver隨時安裝和卸載 19 如何調(diào)試驅(qū)動程序 方法1 打印調(diào)試信息 即用DbgPrint函數(shù)打印調(diào)試信息 然后在驅(qū)動運(yùn)行時用Dbgview等工具觀察這些信息 方法2 分析內(nèi)存轉(zhuǎn)儲 dump 文件 方法3 使用WinDbg SoftICE等高級調(diào)試工具 20 用WinDbg VMWare進(jìn)行雙機(jī)調(diào)試 Step1 安裝WinDbg和VMWare 并在VMWare中安裝好WindowsXP Step2 設(shè)置好WMWare的虛擬串口Step3 將虛擬機(jī)中的WindowsXP設(shè)置為調(diào)試運(yùn)行模式 修改boot ini文件 Step4 以調(diào)試方式啟動虛擬機(jī)中的WindowsXPStep5 啟動WinDbgStep6 設(shè)置WinDbg的Symbol文件路徑 設(shè)置C源程序路徑 Step7 設(shè)置斷點(diǎn) 監(jiān)視變量 21 HelloWorld版的WDM驅(qū)動程序 extern C include wdm h extern C NTSTATUSDriverEntry INPDRIVER OBJECTDriverObject INPUNICODE STRINGRegistryPath NTSTATUSstatus STATUS DEVICE CONFIGURATION ERROR KdPrint HellowWorld returnstatus 22 如何安裝WDM驅(qū)動程序 必須編寫一個安裝指示文件 inf 指導(dǎo)Windows將驅(qū)動程序安裝到指定位置 一般安裝在windows system32 drivers子目錄下 并在注冊表中進(jìn)行登記 對于即插即用類設(shè)備的驅(qū)動 操作系統(tǒng)會自動發(fā)現(xiàn)該設(shè)備并調(diào)用 添加新硬件 程序向用戶詢問相應(yīng)的inf文件的位置 對于非即插即用類設(shè)備的驅(qū)動 用戶必須自己手動調(diào)用 添加新硬件 程序 并通過告訴該程序inf文件的位置 23 inf文件主要包含了哪些內(nèi)容 設(shè)備類型 設(shè)備型號 廠商信息 程序版本號 對操作系統(tǒng)版本和CPU類型的要求 源文件 sys文件 的文件名和所在位置安裝目標(biāo)子目錄在注冊表中添加哪些內(nèi)容硬件配置信息安全配置信息 24 驅(qū)動對象 DriverObject 在操作系統(tǒng)首次裝載一個驅(qū)動程序之后 它會創(chuàng)建一個數(shù)據(jù)結(jié)構(gòu)用來記錄該驅(qū)動 該數(shù)據(jù)結(jié)構(gòu)我們稱為驅(qū)動對象 DriverObject 驅(qū)動對象記錄與驅(qū)動程序本身相關(guān)的信息 它主要包含了除了DriverEntry之外的其它驅(qū)動程序入口函數(shù)的入口地址 驅(qū)動程序是一種具有多個入口函數(shù)的程序 驅(qū)動對象是由操作系統(tǒng)創(chuàng)建 然后作為DriverEntry的第一個參數(shù)傳遞給你的程序 在獲得驅(qū)動對象的指針之后 你的程序需要對其中的一些字段進(jìn)行初始化 25 驅(qū)動對象 DriverObject 驅(qū)動對象在DDK的頭文件 ntddk h 中按如下方式定義 typedefstruct DRIVER OBJECT CSHORTType CSHORTSize DRIVER OBJECT PDRIVER OBJECT 由上面的定義可以看成 驅(qū)動對象不同于C 中的Class 它只是一個Struct 26 27 驅(qū)動對象的一些關(guān)鍵字段 一 DriverStartIo PDRIVER STARTIO 指向StartIO入口函數(shù)的指針 DriverUnload PDRIVER UNLOAD 指向DriverUnload入口函數(shù)的指針 在驅(qū)動程序被從內(nèi)存中卸載時 DriverUnload入口函數(shù)會被操作系統(tǒng)調(diào)用 你應(yīng)該在該函數(shù)內(nèi)部做一些與DriverEntry向?qū)?yīng)的資源清除工作 MajorFunction 一個數(shù)組 數(shù)組中每一元素又是一個指向函數(shù)的指針PDRIVER DISPATCH 數(shù)組中每一個指針指向一個入口函數(shù) 在接收到不同的請求包 IRP 時 OS會調(diào)用不同的入口函數(shù) 28 驅(qū)動對象的一些關(guān)鍵字段 二 DeviceObject PDEVICE OBJECT 指向一個鏈表的指針 該鏈表中每一個節(jié)點(diǎn)都存儲了一個FDO對象 每一個FDO都代表一個由該驅(qū)動維護(hù)的硬件設(shè)備實(shí)例 在WDM模型中 該鏈表由OS自動維護(hù) DriverExtension PDRIVER EXTENSION 指向另外一個結(jié)構(gòu)體 該結(jié)構(gòu)體中唯一有用的字段為AddDevice AddDevice字段指向一個入口函數(shù) 在操作系統(tǒng)發(fā)現(xiàn)一個新的設(shè)備實(shí)例時 它會自動調(diào)用AddDevice函數(shù) 你應(yīng)該在該函數(shù)中做一些與設(shè)備實(shí)例相關(guān)的初始化工作 29 DriverEntry函數(shù)的主要工作 在操作系統(tǒng)創(chuàng)建的驅(qū)動對象中填寫其它入口函數(shù)的地址 使得操作系統(tǒng)在必要的時候能夠找到這些入口函數(shù)并調(diào)用它們 創(chuàng)建一個或多個設(shè)備對象 并將這些對象掛接在驅(qū)動對象所指示的鏈表上 只針對NT型驅(qū)動 與該設(shè)備相關(guān)的其他初始化工作 VOID PDRIVER UNLOAD INPDRIVER OBJECTDriverObject VOID PDRIVER STARTIO INPDEVICE OBJECTDeviceObject INPIRPIrp NTSTATUS PDRIVER DISPATCH INPDEVICE OBJECTDeviceObject INPIRPIrp NTSTATUS PDRIVER ADD DEVICE INPDRIVER OBJECTDriverObject INPDEVICE OBJECTPhysicalDeviceObject 30 DriverUnload函數(shù)的主要工作 刪除以鏈表形式掛接在驅(qū)動對象上的一個或多個設(shè)備對象 只針對NT型驅(qū)動 進(jìn)行與DriverEntry函數(shù)中相對應(yīng)的反初始化工作 例如如果在DriverEntry函數(shù)中申請了堆內(nèi)存 那么在DriverUnload函數(shù)中應(yīng)該釋放該堆內(nèi)存 VOIDDriverUnload PDRIVER OBJECTDriverObject RtlFreeUnicodeString 31 第二簡單的驅(qū)動程序 extern C include VOIDHelloDDKUnload INPDRIVER OBJECTpDriverObject NTSTATUSHelloDDKDispatchRoutine INPDEVICE OBJECTpDevObj INPIRPpIrp extern C NTSTATUSDriverEntry INPDRIVER OBJECTpDriverObject INPUNICODE STRINGpRegistryPath NTSTATUSstatus STATUS SUCCESS KdPrint EnterDriverEntry n KdPrint RegistryPath wZ n pRegistryPath pDriverObject DriverUnload HelloDDKUnload pDriverObject MajorFunction IRP MJ CREATE HelloDDKDispatchRoutine pDriverObject MajorFunction IRP MJ CLOSE HelloDDKDispatchRoutine pDriverObject MajorFunction IRP MJ WRITE HelloDDKDispatchRoutine pDriverObject MajorFunction IRP MJ READ HelloDDKDispatchRoutine KdPrint LeaveDriverEntry n returnstatus 32 第二簡單的驅(qū)動程序 續(xù) VOIDHelloDDKUnload INPDRIVER OBJECTpDriverObject KdPrint EnterDriverUnload n KdPrint LeaveDriverUnload n NTSTATUSHelloDDKDispatchRoutine INPDEVICE OBJECTpDevObj INPIRPpIrp NTSTATUSstatus STATUS SUCCESS KdPrint EnterHelloDDKDispatchRoutine n KdPrint LeaveHelloDDKDispatchRoutine n returnstatus 33 設(shè)備對象 DeviceObject 針對每一個硬件設(shè)備 Windows都需要用一個數(shù)據(jù)結(jié)構(gòu)來記錄它的相關(guān)信息 這個數(shù)據(jù)結(jié)構(gòu)就叫做設(shè)備對象 DevcieObject 因?yàn)橐粋€驅(qū)動程序可以同時管理多個同類型的硬件設(shè)備 因此一個驅(qū)動對象可以對應(yīng)多個設(shè)備對象 對應(yīng)同一個驅(qū)動對象的多個設(shè)備對象構(gòu)成一個鏈表掛接在驅(qū)動對象的DeviceObject字段上 設(shè)備對象由驅(qū)動程序負(fù)責(zé)創(chuàng)建和初始化 由操作系統(tǒng)負(fù)責(zé)保存和管理 設(shè)備對象可以有名字 其他驅(qū)動程序或應(yīng)用程序可以通過該名字找到該設(shè)備對象 34 TheDeviceObject 35 設(shè)備對象的一些關(guān)鍵字段 一 DriverObject PDRIVER OBJECT 指向與該設(shè)備對象相對應(yīng)的驅(qū)動對象的指針 NextDevice PDEVICE OBJECT 指向下一個設(shè)備對象的指針 利用該字段與同一個驅(qū)動對象對應(yīng)的多個設(shè)備對象就可以構(gòu)成一個單鏈表 該鏈表最后掛接在驅(qū)動對象的DeviceObject字段上 36 設(shè)備對象的一些關(guān)鍵字段 二 Flags ULONG 保存了一些標(biāo)志位 這些標(biāo)志位指示了該設(shè)備的一些工作方式 37 設(shè)備對象的一些關(guān)鍵字段 三 Characteristics ULONG 另外一組標(biāo)志位集合 DeviceExtension PVOID 指向一個擴(kuò)展內(nèi)存區(qū) 該內(nèi)存區(qū)的大小和使用方式由程序員規(guī)定 一般在該區(qū)域存放一個自定義的結(jié)構(gòu)體 用于存儲硬件設(shè)備特有的信息 今后稱該結(jié)構(gòu)體為設(shè)備擴(kuò)展對象 該擴(kuò)展內(nèi)存區(qū)由操作系統(tǒng)負(fù)責(zé)創(chuàng)建并維護(hù) DeviceType DEVICE TYPE 一個枚舉型變量 指明該設(shè)備的類型 FILE DEVICE UNKNOWN AlignmentRequirement ULONG 指定該設(shè)備使用內(nèi)存時的對齊方式 FILE BYTE ALIGNMENT FILE WORD ALIGNMENT FILE 512 BYTE ALIGNMENT 38 如何創(chuàng)建設(shè)備對象 利用內(nèi)核API函數(shù)IoCreateDevice創(chuàng)建設(shè)備對象 OS負(fù)責(zé)申請并管理設(shè)備對象所需內(nèi)存 并對其中的一些字段按照輸入?yún)?shù)做了初始化 最后將其掛接在設(shè)備對象鏈表上 NTSTATUSIoCreateDevice INPDRIVER OBJECTDriverObject 設(shè)備對象所對應(yīng)的驅(qū)動對象INULONGDeviceExtensionSize 設(shè)備擴(kuò)展區(qū)的大小INPUNICODE STRINGDeviceNameOPTIONAL 設(shè)備對象名稱INDEVICE TYPEDeviceType 設(shè)備類型INULONGDeviceCharacteristics 設(shè)備對象特征INBOOLEANExclusive 一般設(shè)為FALSEOUTPDEVICE OBJECT DeviceObject 由操作系統(tǒng)創(chuàng)建的設(shè)備對象 的起始地址利用該參數(shù)返回 39 如何刪除設(shè)備對象 在WDM驅(qū)動中 如果接收到IRP MN REMOVE DEVICE消息 則應(yīng)刪除設(shè)備對象 在NT式驅(qū)動中 在DriverUnload函數(shù)中刪除設(shè)備對象 在創(chuàng)建設(shè)備對象之后如果出錯也應(yīng)該及時刪除對象 通過調(diào)用內(nèi)核API函數(shù)IoDeleteDevice刪除設(shè)備對象 NTSTATUSstatus IoCreateDevice if NT SUCCESS status returnstatus if IoDeleteDevice pdo returnstatus 40 設(shè)備對象的命名 Windows系統(tǒng)中有一個稱為 對象管理器 的執(zhí)行模塊復(fù)雜集中管理系統(tǒng)中所有的內(nèi)核對象 其中包括驅(qū)動對象和設(shè)備對象 對象管理器給大多數(shù)內(nèi)核對象都起了名字 并把這些名字組織為具有樹形結(jié)構(gòu)的命名空間 設(shè)備對象一般都位于該命名空間的 Device子目錄下其他內(nèi)核模塊和驅(qū)動程序都可以通過設(shè)備的名字獲得該設(shè)備對象的指針 利用IoGetDeviceObjectPointer 并通過該指針向驅(qū)動對象發(fā)送IRP 用戶模式的應(yīng)用程序?qū)?Device子目錄沒有訪問權(quán) 41 設(shè)備對象的命名 續(xù) 為了給自己的設(shè)備對象命名 必須將名字存放在一個UNCODE STRING型的字符串中 并將其作為IoCreateDevice的第3個參數(shù)傳入 UNICODE STRINGdevname RtlInitUnicodeString 42 設(shè)備對象名與符號鏈接 因?yàn)閼?yīng)用程序只能訪問Windows內(nèi)核對象空間中的 子目錄 而對對 Device子目錄沒有訪問權(quán)限 因此必須在 子目錄中創(chuàng)建一個符號鏈接 將其指向 Device子目錄中的名字 符號鏈接就類似于Windows文件系統(tǒng)中的快捷方式創(chuàng)建符號鏈接的方法是調(diào)用IoCreateSymbolicLink 43 設(shè)備對象名與符號鏈接 續(xù) UNICODE STRINGdevname UNICODE STRINGlinkname RtlInitUnicodeString 44 應(yīng)用程序如何通過設(shè)備名打開設(shè)備 在用戶模式下 子目錄叫做 子目錄 因此通過 子目錄下的符號鏈接名就可以找到設(shè)備對象 并打開指向設(shè)備對象的句柄 hDevice CreateFile Simple1 GENERIC WRITE GENERIC READ FILE SHARE WRITE FILE SHARE READ NULL OPEN EXISTING 0 NULL ReadFile hDevice lpBuffer WriteFile hDevice lpBuffer 45 創(chuàng)建完設(shè)備對象后還需做什么 設(shè)置設(shè)備擴(kuò)展對象的內(nèi)容設(shè)置設(shè)備對象的flags字段設(shè)定該設(shè)備的工作方式 fdo AlignmentRequirement fdo Flags DO BUFFERED IO DO POWER PAGABLE 創(chuàng)建設(shè)備對象棧 可選 等所有準(zhǔn)備工作做完之后一定要清除flags字段的DO DEVICE INITIALIZING標(biāo)志告訴OS可以接收IRP了 fdo Flags 46 第三個例子程序 47 基于I O請求包 IRP 的工作方式 48 應(yīng)用程序與驅(qū)動程序的通信 Windows應(yīng)用程序與WDM通信的一般過程是 應(yīng)用程序先用CreateFile函數(shù)打開設(shè)備 然后用ReadFile從WDM中讀取數(shù)據(jù) 用WriteFile函數(shù)向WDM寫數(shù)據(jù) 用DeviceIoControl函數(shù)向WDM發(fā)送自定義的控制信息 最后用CloseHandle函數(shù)關(guān)閉設(shè)備 對于異步IO請求還可以用CancelIo函數(shù)取消 這些函數(shù)調(diào)用使得IO管理器產(chǎn)生相應(yīng)的IRP發(fā)送給驅(qū)動程序 49 第四個例子程序- 1.請仔細(xì)閱讀文檔,確保文檔完整性,對于不預(yù)覽、不比對內(nèi)容而直接下載帶來的問題本站不予受理。
- 2.下載的文檔,不會出現(xiàn)我們的網(wǎng)址水印。
- 3、該文檔所得收入(下載+內(nèi)容+預(yù)覽)歸上傳者、原創(chuàng)作者;如果您是本文檔原作者,請點(diǎn)此認(rèn)領(lǐng)!既往收益都?xì)w您。
下載文檔到電腦,查找使用更方便
9.9 積分
下載 |
- 配套講稿:
如PPT文件的首頁顯示word圖標(biāo),表示該P(yáng)PT已包含配套word講稿。雙擊word圖標(biāo)可打開word文檔。
- 特殊限制:
部分文檔作品中含有的國旗、國徽等圖片,僅作為作品整體效果示例展示,禁止商用。設(shè)計者僅對作品中獨(dú)創(chuàng)性部分享有著作權(quán)。
- 關(guān) 鍵 詞:
- Windows 驅(qū)動程序 設(shè)計 入門
鏈接地址:http://ioszen.com/p-6570473.html