java 内核驱动程序_内核第三讲,进入ring0,以及编写第一个内核驱动程序.
內(nèi)核第三講,進入ring0,以及編寫第一個內(nèi)核驅(qū)動程序.
一丶進入ring0之前的簡介
進入0環(huán)之前,我們要明白操作系統(tǒng)的設(shè)計,操作系統(tǒng)允許驅(qū)動程序使用In out等等特權(quán)指令來操作高2G的內(nèi)存.那么必然會有接口.
圖示如下.
那么我們可以模擬一個驅(qū)動程序來進入0環(huán).
而操作系統(tǒng)提供的接口的,有專門的名稱.?叫做DDK,?現(xiàn)在改名為WDK了.
DDK:?Driver Development Kit? 驅(qū)動程序開發(fā)包,例如我們寫的3環(huán)系統(tǒng)下,用到的SDK,也可以成為是API.只不過現(xiàn)在叫做內(nèi)核方法(內(nèi)核函數(shù))了.
WDK:Windows Driver Kit
WDK是DDK升級而來的.操作系統(tǒng)為了支持熱插拔,所以對DDK升級了.熱插拔就是U盤插入系統(tǒng).不用安裝驅(qū)動了.和U盤綁定在一起了.
我自己用的是WDK7.1.7600,會上傳到課堂資料中.有興趣的可以下載.
注意:?如果編寫驅(qū)動程序,請下載對應(yīng)系統(tǒng)的WDK,因為驅(qū)動程序不兼容.只會跟著系統(tǒng)走.
二丶WDK的安裝.
下載之后直接下一步,下一步即可.?如果不會建議百度.
三丶進入0環(huán),編寫第一個內(nèi)核驅(qū)動程序
在進入ring0之前,我們要知道,不管是驅(qū)動程序,或者是應(yīng)用程序,都會有一個入口點.
比如控制臺的入口點是?main,窗口的是winmain.那么看下驅(qū)動程序的入口點是什么.
PS:安裝好WDK之后,會有幫助文檔.可以參考幫助文檔.
如果我們要編寫內(nèi)核驅(qū)動,則要看內(nèi)核驅(qū)動的入口點,也就是kerner mode,內(nèi)核模型.
如果是編寫硬件驅(qū)動,則尋找WDM即可.
NTSTATUS
DriverEntry( //驅(qū)動的入口點
__instruct _DRIVER_OBJECT *DriverObject,
__in PUNICODE_STRING RegistryPath
)
{...}
返回值:?STATUS_SUCCESS
內(nèi)核輸出的API
ULONG
DbgPrint(
IN PCHAR Format,
. . . . [arguments]
);
利用入口我們可以簡單編寫一個內(nèi)核驅(qū)動了.
驅(qū)動我們可以用C語言去寫.也可以是C++
#include //編寫內(nèi)核驅(qū)動需要包含NTddk頭文件.
NTSTATUS DriverEntry(__instruct _DRIVER_OBJECT *DriverObject,
__in PUNICODE_STRING RegistryPath)
{int i = 0;
DbgPrint("HelloWorld, %p\r\n",&i);returnSTATUS_SUCCESS;
}
在編譯驅(qū)動程序的是否,我們需要一個sources??文件
格式:
TARGETNAME=MyFirstDrive //指明編譯的文件名
TARGETTYPE=DRIVER //指明編譯的類型
SOURCES= MyFirstDrive.c //指明編譯的文件
圖示:
編譯的時候找我們的開發(fā)包.
通過開始程序,找到我們的開發(fā)包中的編譯XP命令框.點開.
輸入編譯命令?build?文件名
回車就可以編譯我們的驅(qū)動程序了.
成功會生成一個sys后綴的文件.那么我們就可使用了.
四丶雙機調(diào)試,加載我們的驅(qū)動.
我們以調(diào)試系統(tǒng)啟動.然后使用加載驅(qū)動的工具,加載我們的驅(qū)動,那么就可以在調(diào)試器中看到我們的驅(qū)動代碼了.
當我們啟動之后,我們可以查看下調(diào)試器,可以調(diào)試我們的代碼.
請注意我們打印的地址,地址是高2G的空間.所以我們就進入了0環(huán)空間了.
五丶編寫驅(qū)動卸載功能.
我們的驅(qū)動現(xiàn)在可以加載.啟動.停止.但是不能卸載.原因就是我們沒有寫卸載的函數(shù).
比如我們的DLL,? DLL來的是否還分為4中情況.
很簡單.只需要把我們的驅(qū)動代碼改變一下即可.
#include //編寫內(nèi)核驅(qū)動需要包含NTddk頭文件.//卸載回調(diào)函數(shù)
VOID Unload(__in struct _DRIVER_OBJECT *DriverObject)
{
DbgPrint("Unload MyDrive\n");
}
NTSTATUS DriverEntry(__instruct _DRIVER_OBJECT *DriverObject,
__in PUNICODE_STRING RegistryPath)
{int i = 0;
DbgPrint("HelloWorld, %p\r\n",&i);//注冊一下驅(qū)動卸載的函數(shù)
DriverObject->DriverUnload =Unload;returnSTATUS_SUCCESS;
}
給個卸載的函數(shù)指針即可.注意啟動入口點的參數(shù)是一個結(jié)構(gòu)體.啟動你想要支持卸載驅(qū)動.那么就寫上卸載驅(qū)動的函數(shù)指針即可.
六丶藍屏的出現(xiàn).
編寫驅(qū)動代碼,不像我們編寫ring3下的應(yīng)用程序,崩潰了就是崩潰了.?我們寫驅(qū)動程序恨不得寫一行,檢查500行.
看下藍屏的實現(xiàn).只要我們的程序異常,那么就會藍屏.
代碼:
#include //編寫內(nèi)核驅(qū)動需要包含NTddk頭文件.//卸載回調(diào)函數(shù)
VOID Unload(__in struct _DRIVER_OBJECT *DriverObject)
{
DbgPrint("Unload MyDrive\n");
}
NTSTATUS DriverEntry(__instruct _DRIVER_OBJECT *DriverObject,
__in PUNICODE_STRING RegistryPath)
{int i = 0;int *p = NULL; //異常代碼.會造成C05訪問異常.
DbgPrint("HelloWorld, %p\r\n",&i);*p = 1; //代碼會產(chǎn)生異常,系統(tǒng)會藍屏.//注冊一下驅(qū)動卸載的函數(shù)
DriverObject->DriverUnload =Unload;returnSTATUS_SUCCESS;
}
很簡單,就加了一行C05訪問異常的代碼.
重新編譯一下.并且驅(qū)動加載.
因為家里電腦系統(tǒng)原因,藍屏了會緊接著重啟.所以來不及截圖.請大家自己嘗試.
課堂代碼資料:
轉(zhuǎn)載請著名出處,謝謝.
總結(jié)
以上是生活随笔為你收集整理的java 内核驱动程序_内核第三讲,进入ring0,以及编写第一个内核驱动程序.的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: udp接受_UDP协议-看这篇就够了
- 下一篇: 推流工具_【软件分享】小熊录屏VIP版(