1. 程式人生 > >C++驅動基礎

C++驅動基礎

入口與物件

設計高標準驅動程式當然少不了核心和記憶體管理、程序管理等等,程式設計師編寫的所有內容無礙乎離不了一個結構,那就是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,應用層可以通過開啟符號連結開啟裝置。