欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

DDK_HelloWorld卸载例程细化(驱动学习笔记四)

发布时间:2023/12/14 52 豆豆
生活随笔 收集整理的这篇文章主要介绍了 DDK_HelloWorld卸载例程细化(驱动学习笔记四) 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

DDK_HelloWorld卸载例程细化

  • 0x0 蓝屏
  • 0x1 头文件、cpp文件
  • 0x2 PDEVICE_EXTENSION

0x0 蓝屏

  • 在编译DDK卸载程序时,误将符号名字写成了设备名,从而导致卸载时直接蓝屏
  • 加载驱动的时候发生蓝屏,使用windbg定位到问题点如下:

    pDevobj正常,但是提示pDevExt为空指针从而导致蓝屏,想了想觉得很奇怪,难道是PDEVICE_EXTENSION定义错了?反复查看定义未发现有什么不妥,
    但是windbg中也显示pDevobj->DeviceExtension为空,后来左右对比发现如下代码:

    在创建设备的时候,DEVICE_EXTENSION的大小竟然为0,难怪会是空指针!
    将代码改为如下后,加载驱动便不再蓝屏了:
  • 按照《Windows驱动开发技术详解》里的代码将HelloDDK编译后,发现每次卸载驱动的时候都会发生蓝屏,使用windbg定位到问题故障点如下:

    根据dbg上查看到的信息发现是存储pLinkName的内存访问错误,反复检查流程,发现逻辑并没有什么问题,同时发现pDevExt->ustrSymLinkName和ustrDeviceName都是异常的内存,因此怀疑是内存已经被释放了?
    我们找到ustrSymLinkName和ustrDeviceName被赋值的地方如下:

    我们发现它们的赋值是在创建设备的过程中进行的,检查创建过程的值发现它们确确实实是被成功赋值了,可是为什么后面又没有了呢?
    我们看到该函数时位于内存标志位INIT的内存区域的

    书上对INIT内存区域的描述是函数只是在加载的时候需要载入内存,但是当驱动程序成功加载后,函数就会从内存中卸载掉,如下:

    我的理解是,如果把CreateDevice函数放在INIT内存区域,函数内的赋值操作也会保存在INIT内存区域,那么在加载驱动的时候,给符号和设备名进行赋值的时候,一起正常。但是加载成功后,该段内存区域即被释放,所以当卸载驱动再次调用该段内存区域时,由于该内存区域已经被释放了,所以导致了蓝屏
    因此,解决办法是,把该函数放到PAGE内存区域,即不再蓝屏
    然而,事情没有结束
    在正常卸载掉驱动后,再次把该函数改到INIT内存区域,卸载驱动也不会出现蓝屏。这是否意味着,真正蓝屏的原因是由于之前内存中还保存着一些东西?按理来说,如果内存中有符号名是无法再次创建驱动成功的。

    真正的原因还待进一步去研究…
  • 0x1 头文件、cpp文件

    根据观察到的情况,通常,声明、定义结构体、重定义变量名放在头文件中,具体实现放在CPP文件中

    0x2 PDEVICE_EXTENSION

    根据源代码调用PDEVICE_EXTENSION时发现始终无法找到该结构体,后来发现原来该结构体需要自己定义,坑爹啊…如下:

    typedef struct _DEVICE_EXTENSION {PDEVICE_OBJECT pDevice;UNICODE_STRING ustrDeviceName; // 设备名称UNICODE_STRING ustrSymLinkName; // 符号链接名 }DEVICE_EXTENSION,*PDEVICE_EXTENSION;

    TO be continue…

    总结

    以上是生活随笔为你收集整理的DDK_HelloWorld卸载例程细化(驱动学习笔记四)的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。