C++驅動基礎
阿新 • • 發佈:2019-01-27
入口與物件
設計高標準驅動程式當然少不了核心和記憶體管理、程序管理等等,程式設計師編寫的所有內容無礙乎離不了一個結構,那就是DRIVER_OBJECT,它對應著一個驅動結構,
最簡單的驅動程式
Win32程式裡有Winmain(),而windows中的DriverEntry和其中的WINDOWSmain函式一樣必不可少。
#include <ntddk.h>
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
){
NTSTATUS status = STATYS_UNSUCCESSFUL;
return status;
}
DriverEntry引數及其作用:
引數 | 作用 |
---|---|
DIVER_OBJECT指標 | 對應編寫的驅動程式,系統預分配記憶體 |
RegistryPath字串 | 登錄檔子鍵,專用於本程式資訊儲存到登錄檔中 |
DriverEntry的返回值決定這個驅動的載入是否成功,如果返回STATUS_SUCCESS,則驅動將成功載入,否則不成功載入。
重點:當讀者打算反彙編閱讀一個核心程式的時候,先可尋找DriverEntry的位置。
分發函式和解除安裝函式
分發函式指標,就是用來處理髮送到這個驅動程式中的請求的,包含於DRIVER_OBJECT中。windows總是自己呼叫DRIVER_OBJECT下的分發函式來處理這些被髮總到驅動中的請求。所以可以理解編寫驅動程式的實質是編寫請求處理請求的分發函式。
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
){
ULONG i;
for(i=0;i<IRP_MJ_MAXIMUM_FUNCTION;++i)
{
DriverObject->MajorFunctions[i] = MyDispatchFunction;
}
}
然後編寫MyDispatchFunction:
NTSTATUS MyDispatchFunction(PDEVICE_OBJECT device,PIRP irp) {
//device是由本驅動生成的裝置
//irp是一個系統請求
//這個函式要處理的是傳送給裝置device的請求irp
}
解除安裝函式不放在分發函式陣列中,在解除安裝時,該函式動態執行,起到了該驅動的動態解除安裝的作用:
NTSTATUS MyDispatchFunction(PDEVICE_OBJECT driver){
//無返回值,地址設定到DriverObject->DriverUnload;
}
裝置與符號連結
如果一個驅動程式只是想寫寫日誌檔案或者核心鉤子來做一些Rootkit,就不發要分發函式:
#include <ntifs.h>
DriverEntry(
IN PDRIVER_OBJECT river,
IN PUNICODE_STRING Reg_path
){
NTSTATUS status;
PDEVICE_OBJECT device;
UNICODE_STRING device_name = RTL_CONSTANT_STRING("\\Device\\MyCDO");
UNICODE_STRING symb_link = RTL_CONSTANT_STRING("\\DosDevice\\MyCDOSL");
STATUS=IoCreateDevice(
driver,
0,
device_name,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&device
);
if(!NT_SUCCESS(status))
return status;
status=IoCreateSymbolicLink(
&symb_link,
&device_name
);
if(!NT_SUCCESS(status)){
IoDeleteDevice(device);
return status;
}
device->Flag &=~DO_DEVICE_INITIALIZING;
return status;
}
這個驅動載入之後,生成了一個叫\Device\MyCDO的裝置,符號連線叫做\DosDevices\MySDOSL,應用層可以通過開啟符號連結開啟裝置。