首页
社区
课程
招聘
[原创]驱动层与应用层通信的实现
发表于: 2013-6-14 16:53 7210

[原创]驱动层与应用层通信的实现

2013-6-14 16:53
7210
WDK环境搭建http://bbs.pediy.com/showthread.php?p=1188247#post1188247
通信的实现参照了这个帖子http://bbs.pediy.com/showthread.php?p=446641
我的第一个驱动层与应用层的通信程序实现搞了好长时间,同时鉴于我太菜,太官方的东西有时候需要把问题搞定了回头才能看懂,所以此篇记录本着通俗易懂非专业形式写出来,对于像这我样菜级别的希望能有所帮助,虽然在看雪上找到这样的选手如同大海捞针,不过我想要KxKxKx,我看了好几天贴也没给个Kx,只有自己发贴了,这样总算在线吧,版主大人,默默祈祷明天我能多几个Kx。
新建个ddk项目,头文件中添加以下类似如下的项:
const ULONG IOCTL_IN= (ULONG)CTL_CODE(FILE_DEVICE_DRIVER17, 0x800, METHOD_IN_DIRECT, FILE_ANY_ACCESS)&0x0000FFFF;
const ULONG IOCTL_OUT =(ULONG)CTL_CODE(FILE_DEVICE_DRIVER17, 0x801, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)&0x0000FFFF;
const ULONG IOCTL_BUFFERED  =(ULONG)CTL_CODE(FILE_DEVICE_DRIVER17, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)&0x0000FFFF;
const ULONG IOCTL_NEITHER=  (ULONG)CTL_CODE(FILE_DEVICE_DRIVER17, 0x803, METHOD_NEITHER, FILE_ANY_ACCESS)&0x0000FFFF;
关于CTL_CODE函数:
第一个参数根据头文件中自动生成的#define FILE_DEVICE_DRIVER17 0x8000来的;
第二个参数由我们自己定义,范围在0x800—0xfff之间就好;
第三个参数有四个选项,上面都包含了,具体说明和区别请参考(别人的博客)http://blog.csdn.net/lujunql/article/details/2546901#comments
第四个参数有FILE_ANY_ACCESS、FILE_READ_ACCESS、FILE_WRITE_ACCESS,看词面就知道什么意思了;
这里的第三个与第四个参数有多种组合,只要把第二个参数设置成不同的就行。
这个函数返回的是一个ULONG型的数据,高16位表示设备类型,低16位是属性之类的定义,所以用&0x0000ffff目的在于仅保留低16位,因为在应用层,我调用设备时的设备类型选的是UNKNOWN,所以仅要低16位;应用层与驱动层通信要调用DeviceIoControl,而DeviceIoControl的第二个参数就是此处CTL_CODE返回的ULONG值,注意这里,由于设备类型我选的是UNKNOWN(0x22),所以这个返回值只有低16位与驱动层是一致的,所以判断的时候要减去0x00220000;

头文件好了,下面是在cpp文件中添加以下几个函数,我理解就是驱动层接到应用层命令后对应的分发处理函数,跟头文件对应;
NTSTATUS DirectOutIo(PIRP Irp, PIO_STACK_LOCATION pIoStackIrp, UINT *sizeofWrite);
NTSTATUS DirectInIo(PIRP Irp, PIO_STACK_LOCATION pIoStackIrp, UINT *sizeofWrite);
NTSTATUS BufferedIo(PIRP Irp, PIO_STACK_LOCATION pIoStackIrp, UINT *sizeofWrite);
NTSTATUS NeitherIo(PIRP Irp, PIO_STACK_LOCATION pIoStackIrp, UINT *sizeofWrite);
关键的地方在DRIVER17_DispatchDeviceControl函数里的如下部分,驱动层接到应用层的消息后,应该就是在这里处理的:
    irpStack = IoGetCurrentIrpStackLocation(Irp);   
    if(irpStack)
    {
                DbgPrint("irpStack\r\n");
                DbgPrint("%u",irpStack->Parameters.DeviceIoControl.IoControlCode);
        switch(irpStack->Parameters.DeviceIoControl.IoControlCode-0x00220000)  
        {
            case IOCTL_IN:                                  
                 status = DirectInIo(Irp, irpStack, &sizeofWrite);
                 break;

            case IOCTL_OUT:                                 
                 status = DirectOutIo(Irp, irpStack, &sizeofWrite);
                 break;

                    case IOCTL_BUFFERED:                                  
                 status = BufferedIo(Irp, irpStack, &sizeofWrite);
                 break;

            case IOCTL_NEITHER:                                 
                 status = NeitherIo(Irp, irpStack, &sizeofWrite);
                 break;

                        default:
                                break;
        }
    }
应用层调用DeviceIoControl,关键在于第2个参数,也是通过CTL_CODE获取,这里的第二、三、四个参数要与驱动层的定义一致,否则会有各种错误出现
(ULONG)CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802,METHOD_BUFFERED,
        FILE_ANY_ACCESS);这些东西弄明白了,实现两层的通信应该就没问题了,要下班了,写的有点乱,把代码上传了。

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

上传的附件:
收藏
免费 5
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//