读书人

驱动高手来看看奇怪的有关问题,为什么

发布时间: 2012-04-11 17:42:33 作者: rapoo

驱动高手来看看奇怪的问题,为什么简单的往用户写数据会蓝屏

用DeviceIoControl和驱动通信,原来没事 ,现在不知道出现蓝屏,困惑很长时间了也不知道原因,请高手指教,

主要问题在 requestControl 函数中.







#include "stdio.h"
#include "pch.h"
#include "..\intrface.h"
#include "ntddk.h"

char dataBuffer[4096]={'\0'};
char zml[]="zheshizml";
PDRIVER_OBJECT thisDriverObject;
UNICODE_STRING ustrSymLinkName;
typedef struct _DEVICE_EXTENSION

{

PDEVICE_OBJECT fdo; //功能设备对象FDO
PDEVICE_OBJECT NextStackDevice; //FDO的下层驱动设备
UNICODE_STRING ustrDeviceName; //设备名
UNICODE_STRING ustrSymLinkName; //符号链接
}DEVICE_EXTENSION, *PDEVICE_EXTENSION;


typedef struct _SERVICE_DESCRIPTOR_TABLE
{
PVOID ServiceTableBase;
PULONG ServiceCounterTableBase;
ULONG NumberOfService;
ULONG ParamTableBase;
}SERVICE_DESCRIPTOR_TABLE,*PSERVICE_DESCRIPTOR_TABLE; //由于KeServiceDescriptorTable只有一项,这里就简单点了
extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;

//__declspec(dllimport) ServiceDescriptorTableEntry KeServiceDescriptorTable;



NTSTATUS addDevice(IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject);
NTSTATUS jiChaJiYong(IN PDEVICE_OBJECT fdo,
IN PIRP Irp);

NTSTATUS requestControl(IN PDEVICE_OBJECT DeviceObject,

IN PIRP Irp);

NTSTATUS UnloadDriver (IN PDRIVER_OBJECT DriverObject);
NTSTATUS dataCopy ( void* newAddress,void* oldAddress,int copyLength );
NTSTATUS fileDispath (IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);

NTSTATUS DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{ DEVICE_OBJECT pdo;
DriverObject->DriverExtension->AddDevice =addDevice;
DriverObject->MajorFunction[IRP_MJ_PNP] = jiChaJiYong;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=requestControl;
DriverObject->MajorFunction[IRP_MJ_CREATE]=fileDispath;
DriverObject->MajorFunction[IRP_MJ_CLOSE]=fileDispath;
DriverObject->DriverUnload=UnloadDriver;
thisDriverObject=DriverObject;
addDevice(DriverObject,&pdo);

return STATUS_SUCCESS; }

NTSTATUS addDevice(IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject) {
NTSTATUS status;
PDEVICE_OBJECT device_object;
PDEVICE_EXTENSION device_extension;
UNICODE_STRING devName,symLinkName;
WCHAR deviceNameBuffer[] = L"\\Device\\hello66";
WCHAR dosDeviceNameBuffer[] = L"\\??\\hello66";

RtlInitUnicodeString(&devName,deviceNameBuffer);
RtlInitUnicodeString(&symLinkName,dosDeviceNameBuffer);

status= IoCreateDevice ( DriverObject,sizeof(DEVICE_EXTENSION),
&devName,FILE_DEVICE_UNKNOWN,0,FALSE,&device_object);
if ( !NT_SUCCESS (status ) ) {
return status ; }
device_extension = (PDEVICE_EXTENSION)device_object->DeviceExtension;
device_extension->fdo=device_object;
//device_extension->NextStackDevice =
//IoAttachDeviceToDeviceStack(device_object, PhysicalDeviceObject);
device_object->Flags |=DO_DIRECT_IO|DO_BUFFERED_IO;
device_object->Flags &= ~DO_DEVICE_INITIALIZING;
device_extension->ustrSymLinkName=symLinkName;
//device_object->Flags|= DO_BUFFERED_IO | DO_POWER_PAGABLE;


IoCreateSymbolicLink(&symLinkName,&devName);
ustrSymLinkName=symLinkName;


return STATUS_SUCCESS; }


NTSTATUS jiChaJiYong(IN PDEVICE_OBJECT fdo,
IN PIRP Irp)
{
NTSTATUS status;
PDEVICE_EXTENSION dx=(PDEVICE_EXTENSION)fdo->DeviceExtension;
PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
ULONG MinorFunction = IrpStack->MinorFunction;
IoSkipCurrentIrpStackLocation(Irp);
// status = IoCallDriver( dx->NextStackDevice, Irp);
/*if( MinorFunction==IRP_MN_REMOVE_DEVICE)
{
//取消设备接口:
//IoSetDeviceInterfaceState(&dx->ifSymLinkName, FALSE);
// RtlFreeUnicodeString(&dx->ifSymLinkName);

//调用IoDetachDevice()把fdo从设备栈中脱开:
if (dx->NextStackDevice) {
IoDetachDevice(dx->NextStackDevice); }
//删除fdo:
IoDeleteDevice(fdo);
}

//返回值:
return status;
}*/
//Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x7A * 4;
return STATUS_SUCCESS; }






NTSTATUS requestControl(IN PDEVICE_OBJECT DeviceObject,

IN PIRP Irp)

{
typedef struct _readWriteMode {
void* address;
int length; } RWMODE,*PRWMODE;

void *inputData,*outDataAddress=NULL;
PIO_STACK_LOCATION IrpStack;
ULONG ControlCode;
ULONG InputLength,OutputLength;
NTSTATUS status=STATUS_SUCCESS;
RWMODE rwmode={0};
IrpStack=IoGetCurrentIrpStackLocation(Irp); //获取当前IRP所在的I/O堆栈
ControlCode=IrpStack->Parameters.DeviceIoControl.IoControlCode; //取得控制码
InputLength=IrpStack->Parameters.DeviceIoControl.InputBufferLength;

//取输入缓冲区大小
OutputLength=IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
#define MY_IOCTL_READ 0X90
#define MY_IOCTL_WRITE 0X91
#define MY_IOCTL_KETABLE 0x92
#define MY_IOCTL_OUTADDRESS 0x93

//取输出缓冲区大小
switch(ControlCode) {
case MY_IOCTL_WRITE:
//pIrp->AssociatedIrp.SystemBuffer;

inputData=(char*)Irp->AssociatedIrp.SystemBuffer;

if ( InputLength < sizeof ( rwmode) ) {
break ; }
dataCopy(&rwmode,inputData,sizeof ( rwmode));
if( rwmode.length>4096) { rwmode.length=4096; }
dataCopy(dataBuffer,rwmode.address,rwmode.length );
break ;


//向调试器输出字符串
break;
case 0x100:
outDataAddress=(char*)MmGetSystemAddressForMdlSafe(Irp->MdlAddress,
NormalPagePriority);
if ( outDataAddress==NULL ) {break; }
//dataCopy (outDataAddress,dataBuffer,OutputLength);
RtlCopyMemory (outDataAddress,zml,9);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information =OutputLength;
break;
case MY_IOCTL_OUTADDRESS :
outDataAddress=(char*)MmGetSystemAddressForMdlSafe(Irp->MdlAddress,
NormalPagePriority);
dataCopy(outDataAddress,&outDataAddress,OutputLength);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information =OutputLength;
break;

case MY_IOCTL_KETABLE :
outDataAddress=(char*)MmGetSystemAddressForMdlSafe(Irp->MdlAddress,
NormalPagePriority);
dataCopy(outDataAddress,KeServiceDescriptorTable,OutputLength);
Irp->IoStatus.Status = STATUS_SUCCESS;


Irp->IoStatus.Information =OutputLength;
break;
case 0x90 :
outDataAddress=(char*)MmGetSystemAddressForMdlSafe(Irp->MdlAddress,
NormalPagePriority);
strcpy(outDataAddress,zml);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information =9;
break;
default:
status=STATUS_INVALID_DEVICE_REQUEST;

//输入的控制码不支持

}
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status ;

}

NTSTATUS UnloadDriver (IN PDRIVER_OBJECT DriverObject) {
NTSTATUS status=STATUS_SUCCESS;
PDEVICE_EXTENSION p=(PDEVICE_EXTENSION)DriverObject->DeviceObject->DeviceExtension;
status= IoDeleteSymbolicLink
(&(p->ustrSymLinkName));
if ( !NT_SUCCESS (status ) ) {
status=IoDeleteSymbolicLink( &ustrSymLinkName); }
IoDeleteDevice(DriverObject->DeviceObject);
return status;
}


NTSTATUS dataCopy ( void* newAddress,void* oldAddress,int copyLength ) {
char* add1=(char*)newAddress;
char* add2=(char*)oldAddress;
int i=0;
for ( i=0;i<=copyLength;i++ ) {
*add1=*add2;
add1++;
add2++; }
return STATUS_SUCCESS; }
NTSTATUS fileDispath ( IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp ) {
return STATUS_SUCCESS; }

[解决办法]
建议把格式调整好不然看着头疼
[解决办法]
表示看起来很有压力
[解决办法]
请把蓝屏时的信息贴出来
或者给dump
[解决办法]
在函数 内,有两个IOCTL CODE,
其中,case 0x100:
有语句 RtlCopyMemory (outDataAddress,zml,9),如果输出缓冲区大小不到9,可能会缓冲区越界。
还有,case 0x90 :
有语句:strcpy(outDataAddress,zml);如果输出缓冲区SIZE小于字符串zml的长度,也可能越界。
看看是不是这个原因?

读书人网 >驱动开发

热点推荐