DDK_HelloWorld卸载例程细化
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…