首页
社区
课程
招聘
[求助]【求助】新手学内核编程,遇到问题!编译后的驱动蓝屏。
发表于: 2017-11-14 18:00 3174

[求助]【求助】新手学内核编程,遇到问题!编译后的驱动蓝屏。

2017-11-14 18:00
3174
新人学驱动,用的资料是谭文的windows内核编程。
照抄了它的那段串口过滤的代码,好记性不如烂笔头嘛。照着他的代码敲了一遍。
下面贴代码

#include <ntddk.h>
#define NTSTRSAFE_LIB
#include <ntstrsafe.h>

#ifndef SetFlag
#define SetFlag(_F,_SF)       ((_F) |= (_SF))
#endif
#ifndef ClearFlag
#define ClearFlag(_F,_SF)     ((_F) &= ~(_SF))
#endif
#define CCP_MAX_COM_ID 32

// 过滤设备和真实设备
static PDEVICE_OBJECT s_fltobj[CCP_MAX_COM_ID] = { 0 };
static PDEVICE_OBJECT s_nextobj[CCP_MAX_COM_ID] = { 0 };

#define  DELAY_ONE_MICROSECOND  (-10)
#define  DELAY_ONE_MILLISECOND (DELAY_ONE_MICROSECOND*1000)
#define  DELAY_ONE_SECOND (DELAY_ONE_MILLISECOND*1000)

// 打开一个端口设备
PDEVICE_OBJECT ccpOpenCom(ULONG id, NTSTATUS *status)
{
UNICODE_STRING name_str;
static WCHAR name[32] = { 0 };
PFILE_OBJECT fileobj = NULL;
PDEVICE_OBJECT devobj = NULL;

// 输入字符串。
memset(name, 0, sizeof(WCHAR) * 32);
RtlStringCchPrintfW(
name, 32,
L"\\Device\\Serial%d", id);
RtlInitUnicodeString(&name_str, name);

// 打开设备对象
*status = IoGetDeviceObjectPointer(&name_str, FILE_ALL_ACCESS, &fileobj, &devobj);
if (*status == STATUS_SUCCESS)
ObDereferenceObject(fileobj);

return devobj;
}

NTSTATUS  ccpAttachDevice(
PDRIVER_OBJECT driver,
PDEVICE_OBJECT oldobj,
PDEVICE_OBJECT *fltobj,
PDEVICE_OBJECT *next)
{
NTSTATUS status;
PDEVICE_OBJECT topdev = NULL;

// 生成设备,然后绑定之。
status = IoCreateDevice(driver,
0,
NULL,
oldobj->DeviceType,
0,
FALSE,
fltobj);//***********************************************自己调试,这段代码过不去,初步估计是蓝屏的地方********************************

if (status != STATUS_SUCCESS)
return status;

// 拷贝重要标志位。
if (oldobj->Flags & DO_BUFFERED_IO)
(*fltobj)->Flags |= DO_BUFFERED_IO;
if (oldobj->Flags & DO_DIRECT_IO)
(*fltobj)->Flags |= DO_DIRECT_IO;
if (oldobj->Flags & DO_BUFFERED_IO)
(*fltobj)->Flags |= DO_BUFFERED_IO;
if (oldobj->Characteristics & FILE_DEVICE_SECURE_OPEN)
(*fltobj)->Characteristics |= FILE_DEVICE_SECURE_OPEN;
(*fltobj)->Flags |= DO_POWER_PAGABLE;
// 绑定一个设备到另一个设备上
topdev = IoAttachDeviceToDeviceStack(*fltobj, oldobj);
if (topdev == NULL)
{
// 如果绑定失败了,销毁设备,重新来过。
IoDeleteDevice(*fltobj);
*fltobj = NULL;
status = STATUS_UNSUCCESSFUL;
return status;
}
*next = topdev;

// 设置这个设备已经启动。
(*fltobj)->Flags = (*fltobj)->Flags & ~DO_DEVICE_INITIALIZING;
return STATUS_SUCCESS;
}

VOID MyattchallComs(PDRIVER_OBJECT driver)
{
ULONG i;
PDEVICE_OBJECT com_ob;
NTSTATUS stats, stats2;
for (i = 0; i < 32; i++)
{
com_ob = ccpOpenCom(i, &stats);
if (com_ob = NULL)
continue;
stats2 = ccpAttachDevice(driver, com_ob, &s_fltobj[i], &s_nextobj[i]);
}
}

VOID KDriverUnload(PDRIVER_OBJECT driver)
{
ULONG i;
LARGE_INTEGER interval;
//卸载绑定
for (i = 0; i < 32; i++)
{
if (s_nextobj[i] != NULL)
IoDetachDevice(s_nextobj[i]);
}
//等待5秒。处理已经流入分发函数的irp
interval.QuadPart = (5 * 1000 * DELAY_ONE_MILLISECOND);
KeDelayExecutionThread(KernelMode, FALSE, &interval);
//卸载虚拟设备
for (i = 0; i < 32; i++)
{
if (s_fltobj[i] != NULL)
IoDeleteDevice(s_fltobj[i]);
}
DbgPrint("first:our driver is unloading...\r\n");

}

//irp分发函数
NTSTATUS MydispatchApi(PDEVICE_OBJECT device, PIRP irp)
{
PIO_STACK_LOCATION irpsp = IoGetCurrentIrpStackLocation(irp);
NTSTATUS stats;
ULONG i, j;
for (i = 0; i < 32; i++)
{
if (s_fltobj[i] == device)
{
// 所有电源操作,全部直接放过。
if (irpsp->MajorFunction == IRP_MJ_POWER)
{
// 直接发送,然后返回说已经被处理了。
PoStartNextPowerIrp(irp);
IoSkipCurrentIrpStackLocation(irp);//irp此时发送给的是设备栈顶端的s_fltobj[i],不过滤的irp需要跳过这个设备,发送给下一个设备reojb,故调用这个函数
return PoCallDriver(s_nextobj[i], irp);
}
if (irpsp->MajorFunction == IRP_MJ_WRITE)
{
//先获取写入数据长度
ULONG len = irpsp->Parameters.Write.Length;
//获得缓冲区
PUCHAR buf = NULL;
if (irp->MdlAddress != NULL)
buf =
(PUCHAR)
MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority);
else
buf = (PUCHAR)irp->UserBuffer;
if (buf == NULL)
buf = (PUCHAR)irp->AssociatedIrp.SystemBuffer;

// 打印内容
for (j = 0; j<len; ++j)
{
DbgPrint("comcap: Send Data: %2x\r\n",
buf[j]);
}
}
IoSkipCurrentIrpStackLocation(irp);//irp此时发送给的是设备栈顶端的s_fltobj[i],不过滤的irp需要跳过这个设备,发送给下一个设备reojb,故调用这个函数
return PoCallDriver(s_nextobj[i], irp);
}
}
irp->IoStatus.Information = 0;
irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
IoCompleteRequest(irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_patch)
{
size_t i;
for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
{
driver->MajorFunction[i] = MydispatchApi;
}
MyattchallComs(driver);
DbgPrint("first:hello.my driver!");
driver->DriverUnload = KDriverUnload;
return STATUS_SUCCESS;

}
我自己双击调试 发现是 status = IoCreateDevice这段代码执行不过去,但是我仔细检查了参数和前后文,也对比了原书中的代码,实在想不透到底是哪里错了

请高手给予指正!
万分感谢!



[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 12
活跃值: (142)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
好吧 
最后自己反复调试,发现了错误的地方
NTSTATUS  stats,  stats2;
for  (i  =  0;  i  <  32;  i++)
{
com_ob  =  ccpOpenCom(i,  &stats);
if  (com_ob  =  NULL)
continue;
stats2  =  ccpAttachDevice(driver,  com_ob,  &s_fltobj[i],  &s_nextobj[i]);
}
这段代码里  com_ob==NULL  才对

哎  编程果然需要细致,粗心大意导致的漏洞真是找死人!!!!
2017-11-14 19:01
0
雪    币: 0
活跃值: (143)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
没事儿,多调试调试就好啦~
2017-11-15 10:08
0
游客
登录 | 注册 方可回帖
返回
//