文号
t72673
阅读
7959
回复
7
收藏
3
内核驱动开发---串口过滤驱动连载(part1)
2015/07/19
IP:天津
本程序来自<寒江独钓>Windows内核安全编程和<windows内核安全与驱动开发>中串口过滤一章
书中的程序绑定了串口设备0到31,而且只写了过滤发送而没有写过滤接收


程序被我修改为只过滤串口设备\Device\Serial2,而且过滤发送和接收
一般串口助手看到串口名称为COM*,但是在内核中串口设备的路径为"\Device\Serial*"




程序如下
#include "DriverEntry.h"
#define DEBUG
    #ifdef DEBUG
    #define __asm_3 __asm int 3
    #define _asm_3 __asm int 3
    #else
    #define __asm_3  
    #define _asm_3  
    #endif
  
#endif
  
PDEVICE_OBJECT fltobj = NULL; //过滤设备
PDEVICE_OBJECT nextobj = NULL; //真实设备
//驱动程序是从DriverEntry开始执行的
NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,//pDriverObject指向本驱动的驱动对象指针
    IN PUNICODE_STRING pRegistryPath)//本驱动所在的注册表路径
{
    _asm_3;//中断
    NTSTATUS status = 0;//初始化一个状态
    UNICODE_STRING Name;//驱动与设备名
      
    pDriverObject->DriverUnload = DriverUnload;//驱动卸载时候调用的派遣函数
    for (size_t i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
    {
        pDriverObject->MajorFunction = Device_General;//Device_General处理除了读,写,电源事件
    }
    pDriverObject->MajorFunction[IRP_MJ_READ] = Device_Read;//串口接收时会调用这个派遣函数
    pDriverObject->MajorFunction[IRP_MJ_WRITE] = Device_Write;//串口发送时会调用这个派遣函数
    pDriverObject->MajorFunction[IRP_MJ_POWER] = Device_Power;   
      
    PFILE_OBJECT fileobj = NULL;  //文件指针
    PDEVICE_OBJECT devobj = NULL; //串口设备
    RtlInitUnicodeString(&Name, L"\\Device\\Serial2");//串口设备路径
  
    status = IoGetDeviceObjectPointer(&Name, //打开串口设备\\Device\\Serial2
        FILE_ALL_ACCESS, //全部读写权限
        &fileobj,//无用的文件对象指针
        &devobj);//打开串口
  
    if (!NT_SUCCESS(status)) //如果返回的状态是错误的
    {
        _asm_3;     //中断
        return status;//返回驱动加载错误
    }
    ObDereferenceObject(fileobj);//返回状态为成功立即释放无用的文件对象指针
  
    ccpAttachDevice( //创建一个过滤设备并附加到串口设备\\Device\\Serial2上
        pDriverObject,//DriverEntry传进来的本驱动的驱动对象
        devobj,//串口设备\\Device\\Serial2
        &fltobj,//过滤设备
        &nextobj);//真实设备
      
    return STATUS_SUCCESS;
}
  
NTSTATUS
ccpAttachDevice(    //创建一个过滤设备并附加到串口设备上
PDRIVER_OBJECT Driver,  //DriverEntry传入
PDEVICE_OBJECT oldobj,  //源设备
PDEVICE_OBJECT *fltobj, //创建的过滤设备
PDEVICE_OBJECT *next)   //真事的设备
{
  
    NTSTATUS status = 0;
    PDRIVER_OBJECT topDev = NULL;
      
    status = IoCreateDevice( //创建一个过滤设备
        Driver,     //DriverEntry传入
        0,          //设备扩展
        NULL,       //过滤设备不需要名称
        oldobj->DeviceType,//设备类型
        0,          //设备特征
        FALSE,      //是否独占
        fltobj      //创建好的过滤设备
        );
    if (!NT_SUCCESS(status)) //如果错误
    {
        fltobj = NULL;
        DbgPrint("%s第%s行发生错误",__FILE__,__LINE__);
        return status;
    }
  
    //拷贝标记位 
    //内存传输策略
    if (oldobj->Flags & DO_BUFFERED_IO) (*fltobj)->Flags |= DO_BUFFERED_IO;
    if (oldobj->Flags & DO_DIRECT_IO) (*fltobj)->Flags |= DO_DIRECT_IO;
    if (oldobj->Flags & DO_BUFFERED_IO) (*fltobj)->Flags |= DO_BUFFERED_IO;
  
    if (oldobj->Characteristics & FILE_DEVICE_SECURE_OPEN)
        (*fltobj)->Characteristics |= FILE_DEVICE_SECURE_OPEN;
    (*fltobj)->Flags |= DO_POWER_PAGABLE;
  
    status = IoAttachDeviceToDeviceStackSafe(*fltobj, oldobj, &topDev); //把创建好的过滤设备附加到串口设备
    if ((!NT_SUCCESS(status)) || (topDev == NULL))//如果失败了
    {
        IoDeleteDevice(*fltobj);//删除创建的过滤设备
        *fltobj = NULL;
        return status;
    }
    //此时fltobj是创建好并且附加成功的过滤设备
    *next = topDev;//设备栈最下面的真实设备
  
    (*fltobj)->Flags = (*fltobj)->Flags & ~DO_DEVICE_INITIALIZING;
    return status;
}
  
NTSTATUS Device_Read(//读 //如果这个派遣函数被调用了说明单片机往计算机发送了数据
    _In_ struct _DEVICE_OBJECT *DeviceObject,
    _Inout_ struct _IRP *Irp)
{
    _asm_3 
  
        PIO_STACK_LOCATION Irpsp = IoGetCurrentIrpStackLocation(Irp);
        NTSTATUS stayus = Device_General(DeviceObject, Irp);//从真实设备读取数据
        //此时单片机发往计算机的数据在Irp->AssociatedIrp->SystemBuffer中
        //数据的长度在Irp->IoStatusInformation中
        return stayus;
}
  
NTSTATUS Device_Write(//写 //如果这个派遣函数被调用了说明计算机往单片机发送了数据
    _In_ struct _DEVICE_OBJECT *DeviceObject,
    _Inout_ struct _IRP *Irp)
{
    //此时计算机发出的数据在Irp->AssociatedIrp->SystemBuffer中
    PIO_STACK_LOCATION Irpsp = IoGetCurrentIrpStackLocation(Irp);
    //数据长度在Irps->Parameters.Write.Length中
    _asm_3
        return  Device_General(DeviceObject, Irp);
}
  
NTSTATUS Device_General(//通用处理
    _In_ struct _DEVICE_OBJECT *DeviceObject,
    _Inout_ struct _IRP *Irp)
{
    //_asm_3;
    IoSkipCurrentIrpStackLocation(Irp);//跳过当前栈空间
    return IoCallDriver(nextobj, Irp);  //将请求发送给真实的设备
}
NTSTATUS Device_Power(//Power处理
    _In_ struct _DEVICE_OBJECT *DeviceObject,
    _Inout_ struct _IRP *Irp)
{
    //_asm_3;
    PoStartNextPowerIrp(Irp);
    IoSkipCurrentIrpStackLocation(Irp);//跳过当前栈空间
    return PoCallDriver(nextobj, Irp);  //将请求发送给真实的设备
}
  
  
  
  
VOID DriverUnload(PDRIVER_OBJECT driver)
{
    //_asm_3;
    if (nextobj != NULL)
        IoDetachDevice(nextobj); //解除引用
  
    if (fltobj != NULL)
        IoDeleteDevice(fltobj); //删除过滤设备
    DbgPrint("%s%d卸载完毕", __FILE__, __LINE__);
}
  
NTSTATUS Device_Conteol(//设备控制
_In_ struct _DEVICE_OBJECT *DeviceObject,
_Inout_ struct _IRP *Irp)
{
    //_asm_3
      
    return 0;
}
修改前.png 修改后.png
张静茹作者
11年5个月前IP:天津
779965
1楼
2.png
引用
评论
11年5个月前IP:广东
781863
2楼
看来这里编程的人比较少,多好的东西,都没人支持呀!
引用
评论
张静茹作者
11年5个月前IP:天津
781916
3楼
引用 starpeng:
看来这里编程的人比较少,多好的东西,都没人支持呀!
写驱动的人少,资料也少
引用
评论
11年5个月前IP:湖南
781937
4楼
引用 张静茹:
本程序来自<寒江独钓>Windows内核安全编程和<windows内核安全与驱动开发>中串口过滤一章  

这句感觉不太对。
支持!正在学51,还只会跑流水灯[s::Q]
引用
评论
张静茹作者
11年5个月前IP:天津
781943
5楼
引用 仓生木品:
这句感觉不太对。
支持!正在学51,还只会跑流水灯
<windows内核安全与驱动开发>是<天书夜读 从汇编到windows内核>和寒江独钓 windows内核安全编程的整合版,
引用
评论
张静茹作者
10年8个月前修改于 10年8个月前IP:江苏
814757
6楼
DeviceTree,Usb Tree View 与WinObj 下载
attachment icon devicetree_v230.zip 1.93MB ZIP 51次下载

attachment icon WinObj.zip 447.65KB ZIP 39次下载

attachment icon usbtreeview.zip 266.68KB ZIP 37次下载
引用
评论
笔记
{{note.content}}
{{n.user.username}}
{{fromNow(n.toc)}} {{n.status === noteStatus.disabled ? "已屏蔽" : ""}} {{n.status === noteStatus.unknown ? "正在审核" : ""}} {{n.status === noteStatus.deleted ? '已删除' : ''}}
  • 编辑
  • 删除
  • {{n.status === 'disabled' ? "解除屏蔽" : "屏蔽" }}
我也是有底线的