首页
社区
课程
招聘
[讨论]驱动加入code_seg("INIT")出现蓝屏,问题出自《windows驱动开发技术详解》
发表于: 2010-5-13 01:55 14098

[讨论]驱动加入code_seg("INIT")出现蓝屏,问题出自《windows驱动开发技术详解》

2010-5-13 01:55
14098
DeviceExtension:
8207fea8  8207fdf0 00280026 f8a77150 001a0018
8207feb8  f8a77130 00000000 0000000d 8207fdf0

DriverEntry结束后8207feb8空间被释放,驱动卸载时调用IoDeleteSymbolicLink函数蓝屏,如果将code_seg("INIT")去掉可正常,启动/停止。

驱动源码来自《windows驱动开发技术详解》,诧异的是在网上查询没找到该问题的答案然道都能正常运行?

源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/************************************************************************
* 文件名称:Driver.cpp                                                
* 作    者:张帆
* 完成日期:2007-11-1
*************************************************************************/
 
#include "Driver.h"
 
/************************************************************************
* 函数名称:DriverEntry
* 功能描述:初始化驱动程序,定位和申请硬件资源,创建内核对象
* 参数列表:
      pDriverObject:从I/O管理器中传进来的驱动对象
      pRegistryPath:驱动程序在注册表的中的路径
* 返回 值:返回初始化驱动状态
*************************************************************************/
#pragma INITCODE
extern "C" NTSTATUS DriverEntry (
            IN PDRIVER_OBJECT pDriverObject,
            IN PUNICODE_STRING pRegistryPath    )
{
    NTSTATUS status;
    KdPrint(("Enter DriverEntry\n"));
 
    //注册其他驱动调用函数入口
    pDriverObject->DriverUnload = HelloDDKUnload;
    pDriverObject->MajorFunction[IRP_MJ_CREATE] = HelloDDKDispatchRoutine;
    pDriverObject->MajorFunction[IRP_MJ_CLOSE] = HelloDDKDispatchRoutine;
    pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloDDKDispatchRoutine;
    pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKDispatchRoutine;
     
    //创建驱动设备对象
    status = CreateDevice(pDriverObject);
 
    KdPrint(("DriverEntry end\n"));
    return status;
}
 
/************************************************************************
* 函数名称:CreateDevice
* 功能描述:初始化设备对象
* 参数列表:
      pDriverObject:从I/O管理器中传进来的驱动对象
* 返回 值:返回初始化状态
*************************************************************************/
#pragma INITCODE
extern "C" NTSTATUS CreateDevice (
        IN PDRIVER_OBJECT   pDriverObject)
{
    NTSTATUS status;
    PDEVICE_OBJECT pDevObj;
    PDEVICE_EXTENSION pDevExt;
     
    //创建设备名称
    UNICODE_STRING devName;
    RtlInitUnicodeString(&devName,L"\\Device\\MyDDKDevice");
     
    //创建设备
    status = IoCreateDevice( pDriverObject,
                        sizeof(DEVICE_EXTENSION),
                        &(UNICODE_STRING)devName,
                        FILE_DEVICE_UNKNOWN,
                        0, TRUE,
                        &pDevObj );
    if (!NT_SUCCESS(status))
        return status;
 
    pDevObj->Flags |= DO_BUFFERED_IO;
    pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
    pDevExt->pDevice = pDevObj;
    pDevExt->ustrDeviceName = devName;
    //创建符号链接
    UNICODE_STRING symLinkName;
    RtlInitUnicodeString(&symLinkName,L"\\??\\HelloDDK");
    pDevExt->ustrSymLinkName = symLinkName;
    status = IoCreateSymbolicLink( &symLinkName,&devName );
    if (!NT_SUCCESS(status))
    {
        IoDeleteDevice( pDevObj );
        return status;
    }
    return STATUS_SUCCESS;
}
 
/************************************************************************
* 函数名称:HelloDDKUnload
* 功能描述:负责驱动程序的卸载操作
* 参数列表:
      pDriverObject:驱动对象
* 返回 值:返回状态
*************************************************************************/
#pragma PAGEDCODE
VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject)
{
    PDEVICE_OBJECT  pNextObj;
    KdPrint(("Enter DriverUnload\n"));
    pNextObj = pDriverObject->DeviceObject;
    while (pNextObj != NULL)
    {
        PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
            pNextObj->DeviceExtension;
 
        //删除符号链接
        UNICODE_STRING pLinkName = pDevExt->ustrSymLinkName;
        IoDeleteSymbolicLink(&pLinkName);
        pNextObj = pNextObj->NextDevice;
        IoDeleteDevice( pDevExt->pDevice );
    }
}
 
/************************************************************************
* 函数名称:HelloDDKDispatchRoutine
* 功能描述:对读IRP进行处理
* 参数列表:
      pDevObj:功能设备对象
      pIrp:从IO请求包
* 返回 值:返回状态
*************************************************************************/
#pragma PAGEDCODE
NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,
                                 IN PIRP pIrp)
{
    KdPrint(("Enter HelloDDKDispatchRoutine\n"));
    NTSTATUS status = STATUS_SUCCESS;
    // 完成IRP
    pIrp->IoStatus.Status = status;
    pIrp->IoStatus.Information = 0;  // bytes xfered
    IoCompleteRequest( pIrp, IO_NO_INCREMENT );
    KdPrint(("Leave HelloDDKDispatchRoutine\n"));
    return status;
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/************************************************************************
* 文件名称:Driver.h                                                
* 作    者:张帆
* 完成日期:2007-11-1
*************************************************************************/
#pragma once
 
#ifdef __cplusplus
extern "C"
{
#endif
#include <NTDDK.h>
#ifdef __cplusplus
}
#endif
 
#define PAGEDCODE code_seg("PAGE")
#define LOCKEDCODE code_seg()
#define INITCODE code_seg("INIT")
 
#define PAGEDDATA data_seg("PAGE")
#define LOCKEDDATA data_seg()
#define INITDATA data_seg("INIT")
 
#define arraysize(p) (sizeof(p)/sizeof((p)[0]))
 
typedef struct _DEVICE_EXTENSION {
    PDEVICE_OBJECT pDevice;
    UNICODE_STRING ustrDeviceName;  //设备名称
    UNICODE_STRING ustrSymLinkName; //符号链接名
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
 
// 函数声明
 
extern "C" NTSTATUS CreateDevice (IN PDRIVER_OBJECT pDriverObject);
VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject);
NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,
                                 IN PIRP pIrp);

[注意]看雪招聘,专注安全领域的专业人才平台!

收藏
免费
支持
分享
最新回复 (6)
雪    币: 331
活跃值: (57)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
2
呵呵,我早就遇到过了,原因好像是字符串放在INIT节中,卸载时却被换出内存了。不过现在好像无法重现了。
2010-5-13 10:30
0
雪    币: 3313
活跃值: (2083)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
3
我也正在学习《windows驱动开发技术详解》,驱动卸载时会蓝。。搞得我莫明其妙
2010-5-17 09:38
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
的确是这样,要把CreateDevice函数的#pragma INITCODE改为#pragma PAGEDCODE,我问过作者,也没有给明确的答复。
2010-6-18 16:36
0
雪    币: 243
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
看代码应该是驱动向导生成的。有的东西可以直接删去。
2010-6-18 18:16
0
雪    币: 133
活跃值: (622)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
6
字符串编译在INIT节中  看下PE文件就知道了
2010-6-20 13:10
0
雪    币: 220
活跃值: (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
我在Virtual PC 2007 SP1 + Win2000ProSP4 环境下试了一下加载和卸载没有任何问题啊,我是直接用DDK提供的编译环境编译的HelloDDK.sys

不知楼主的测试环境是怎么样的,是不是跟操作系统版本有关?
2010-6-20 15:38
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册