郁金香驱动学习>第三课:添加设备对象



#include <ntddk.h>

//定义个INITCODE宏,这个宏表示 初始化的时候载入内存,然后可以从内存中卸载掉
#define INITCODE code_seg("INIT") //;注意这里是不能加分号的 
#define PAGECODE code_seg("PAGE") //表示内存不够用时,可以置换到虚拟内存(硬盘)

//驱动设备
#pragma INITCODE //表示这个函数运行后,就从内存中释放掉
NTSTATUS CreateMyDevice (IN PDRIVER_OBJECT pDriverObject) 
{
        NTSTATUS status; // NTSTATUS 等价于 LONG
        PDEVICE_OBJECT pDevObj;/*用来返回创建设备*/

        //UNICODE_STRING 类型为UNICODE的字符结构,里面包含3个成员,第一个Length 表示buffer字节的长度,不包含NULL,第二个MaximumLength:buffer总的字节大小,第三个Buffer:指向宽字符的指针
        //创建设备名称
        UNICODE_STRING devName;  
        UNICODE_STRING symLinkName;

        //会动态分配一块指向“\\Device\\yjxDDK_Device”的内存指针,赋值给devName.Buffer;
        RtlInitUnicodeString(&devName,L"\\Device\\yjxDDK_Device");/*对devName初始化字串为 "\\Device\\yjxDDK_Device"*/

        //IoCreateDevice 创建设备对象,并更新pDriverObject->DeviceObject 为新创建的设备对象
        //介绍每个参数
        // pDriverObject  该参数用于在驱动程序和新设备对象之间建立连接,
        // 0              第二个参数是设备扩展结构的大小
        // &devName       命名该设备对象的UNICODE_STRING串的地址
        // &FILE_DEVICE_UNKNOWN       设备类型
        // 0              为设备对象提供Characteristics标志
        // TRUE           指出设备是否是排斥的
        // &pDevObj       设备对象的名字,有了名字应用程序就可以访问该设备的驱动对象了
        status = IoCreateDevice( pDriverObject,\
                0,\
                &devName,\
                FILE_DEVICE_UNKNOWN,\
                0, TRUE,\
                &pDevObj);

        //NT_SUCCESS宏定义:表示判断 status>=0 
        if (!NT_SUCCESS(status)) //成功返回0  0>=0 吗 true 取反  false 不执行
        {
                if(status == STATUS_INSUFFICIENT_RESOURCES)
                {
                        KdPrint(("STATUS_INSUFFICIENT_RESOURCES 资源不足"));
                }
                if(status == STATUS_OBJECT_NAME_EXISTS)
                {
                        KdPrint(("STATUS_OBJECT_NAME_EXISTS 指定对象不存在"));
                }
                if(status == STATUS_OBJECT_NAME_COLLISION)
                {
                        KdPrint(("STATUS_INSUFFICIENT_RESOURCES 对象名有冲突"));
                }
                KdPrint(("创建设备错误,返回值是=%d ",status));
                return status;
        }
                
        KdPrint(("创建设备成功,返回值是=%d ",status));

        //所创建设备被设定为直接缓冲I/O,这是设备读写三种方式中的一种
        pDevObj->Flags |= DO_BUFFERED_IO;
        //创建符号链接

        RtlInitUnicodeString(&symLinkName,L"\\??\\yjx888");

        //创建一个设备链接。驱动程序虽然有了设备名称,但是这种设备名只能在内核状态可见,而对于应用程序是不可见的,因此,驱动需要要暴露一个符号链接,来方便应用程序的访问,该链接指向真正的设备名称
        status = IoCreateSymbolicLink( &symLinkName,&devName );
        if (!NT_SUCCESS(status)) 
        {
                KdPrint(("创建符号连接错误,返回值是=%d ",status));
                //删除设备对象
                IoDeleteDevice( pDevObj );
                return status;
        }
        KdPrint(("创建符号连接成功,返回值是=%d ",status));
        return STATUS_SUCCESS;
}



//卸载函数的前置说明
VOID DDK_Unload(IN PDRIVER_OBJECT pDriverObject);  

//设置函数代码存放的代码段,这是是放在init段中
#pragma INITCODE
//NTSTATUS 等价与 LONG  
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING B)
{
        KdPrint(("驱动成功被加载..."));

        //创建设备对象
        CreateMyDevice(pDriverObject);

        //Driverunload 回调函数的一个指针,这里的回调函数是卸载驱动的函数
        pDriverObject->DriverUnload = DDK_Unload;
        return 1;
}
VOID DDK_Unload(IN PDRIVER_OBJECT pDriverObject)
{
        
        //KdPrint使用方法类似printf,注意KdPrint((" ",  ));使用的是双括号。
        //这个比DbgPrint 调用要稍好。因为在free 版不被编译。
        KdPrint(("驱动成功被卸载..."));

        DbgPrint("DbgPrint功能与KdPrint相同");
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
免key版,511U盘资源,速度很快!经测试全部可下 程分四个大章节 初级篇,中级篇,进阶篇,高级篇 初级篇内容:编写一个完整的,简单的外挂 C++的数据类型:Byte,Word,DWORD,int,float API函数的调mouse_event,GetWindowRect,SetCursorPos,FindWindow,SendMessage) CE5.4工具的使用方法 中级篇内容:调试工具的使用技巧,功能CALL的概念 调试工具OD1.1的使用技巧(如硬件断点,条件断点,内存断点。 常用汇编指令与对应高级语言的转换。 游戏功能CALL概念 找第一个功能CALL 外挂框架的构建(通用) 进阶篇内容:分析游戏内部数据,分析常用功能CALL 游戏数据实践找各种功能CALL(如打怪,选怪,物品使用,技能栏之类)及相应的代码编写 高级篇内容:编写完整外挂 完成一个相对完整的外挂,实现 自动挂机,打怪,存放物品之类的功能 1 入门篇.以《QQ连连看为例》 1.1、一个最简单的外挂 1.1.1、游戏窗口数据分析(SPY++) a、取得窗口相对坐标 b、读出游戏窗口信息GetWindowRect c、移动鼠标指针SetCursorPos 1.1.2 用VC++写个最简单的外挂(实现游戏开局) a、鼠拟鼠标单击mouse_event b、鼠标指针移动还原 c、集成到startgame函数里 1.2、用CE查找棋盘数据 1.2.1、CE中的数据类型 a、数据类型:Bit,Byte,Word,Dword,float,double b、用CE查找出坐位号; c、保存分析数据 1.2.2、编程读出坐位号; a、远程读取进程数据 b、打开远程进程 c、读取远程进程数据 1.2.3、用CE查出棋盘基址; a、找棋盘数据基址 b、分析棋盘数据结构 1.2.4、读出当前棋盘数据 a、编程读出棋盘数据 b、棋盘数据显示出来 1.3、用模拟技术编制外挂 1.3.1 分析棋子与棋盘坐标关系 a、鼠标软件模拟,函数SendMessage b、分析窗口内棋子相对坐标X,Y c、软件模拟点击棋盘坐标x,y处的棋子 1.3.2 消掉一对棋子的算法框架 a、遍历棋盘同类型棋子配对 b、构建算法框架 1.3.3 (Check2p)大致框架(算法核心) a、在这一对棋子间找相通路径的原理 b、(Check2p函数)框架代码 c、(CheckLine函数)检测2点是否有连通. 1.3.4 CheckLine实现 a、CheckLine函数实现 b、Check2p核心代码架构 1.3.5 Check2p完整代码实现 1.3.6 编写完整外挂,界面美化 1.4、游戏加速.去掉对动画效果.非HOOK 1.4.1:用OD找出 动画延时代码 1.4.2:写代码去掉延时,实现游戏加速 2 中级篇 以热血江湖为例 2.1、分析前的准备..CALL简介: 2.1.1、CALL调用示例分析.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值