C驱动编程蓝屏死机
大家好,祝大家除夕/新年快乐,
我目前制作的驱动程序遇到了一些问题。一切工作正常,直到我开始处理 WriteFile() 请求。我的司机试图处理所有事情,但我遇到了蓝屏死机。
我必须查明此语句错误的确切位置:
pWriteDataBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
这是我完整的驱动程序代码(我正在遵循各种教程,所以不要介意可怕的格式,我没有时间整理事情:
#include "ntddk.h"
const WCHAR deviceNameBuffer[] = L"\\Device\\MemoryMirrorDevice";
const WCHAR SymbolicLinkName[] = L"\\DosDevices\\MemoryMirrorLink";
PDEVICE_OBJECT g_DevicePointer= NULL; // Global pointer to our device object
int i = 0;
int y;
VOID OnUnload( IN PDRIVER_OBJECT DriverObject ){
UNICODE_STRING SymbolicLinkNameString;
DbgPrint("OnUnload called\n");
RtlInitUnicodeString(&SymbolicLinkNameString, SymbolicLinkName);
IoDeleteSymbolicLink(&SymbolicLinkNameString);
IoDeleteDevice(DriverObject->DeviceObject);
}
int IsStringTerminated(PCHAR pString, unsigned int uiLength){
int bStringIsTerminated = 0;
unsigned int uiIndex = 0;
while(uiIndex < uiLength && bStringIsTerminated == FALSE)
{
if(pString[uiIndex] == '\0')
{
bStringIsTerminated = 1;
}
else
{
uiIndex++;
}
}
return bStringIsTerminated;
}
NTSTATUS MyWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp){
NTSTATUS NtStatus = STATUS_SUCCESS;
PIO_STACK_LOCATION pIoStackIrp = NULL;
PCHAR pWriteDataBuffer;
DbgPrint("MyWrite\r\n");
pIoStackIrp = IoGetCurrentIrpStackLocation(Irp);
if(pIoStackIrp)
{
pWriteDataBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
return NtStatus;
if( pWriteDataBuffer != NULL )
{
if(IsStringTerminated(pWriteDataBuffer, pIoStackIrp->Parameters.Write.Length))
{
DbgPrint(pWriteDataBuffer);
}
}
}
return NtStatus;
}
void CheckErrors(NTSTATUS ntStatus){
i++;
DbgPrint("%i \n",i);
switch(ntStatus){
case STATUS_INSUFFICIENT_RESOURCES:
DbgPrint("INSUFFICIENT RESOURCES\n");
break;
case STATUS_OBJECT_NAME_EXISTS:
DbgPrint("Name exists\n");
break;
case STATUS_OBJECT_NAME_COLLISION:
DbgPrint("Name collission\n");
break;
case STATUS_SUCCESS:
DbgPrint("Success!\n");
break;
default:
DbgPrint("Error is not filtered!\n");
}
}
NTSTATUS OnStubDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp){
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT );
return STATUS_SUCCESS;
}
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING theRegistryPath ){
NTSTATUS ntStatus = STATUS_SUCCESS;
UNICODE_STRING DeviceName;
UNICODE_STRING SymbolicLinkNameString;
DriverObject->DriverUnload = OnUnload;
RtlInitUnicodeString (&DeviceName, deviceNameBuffer );
RtlInitUnicodeString (&SymbolicLinkNameString, SymbolicLinkName);
ntStatus = IoCreateDevice ( DriverObject,0, &DeviceName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &g_DevicePointer);
CheckErrors(ntStatus);
if(ntStatus == STATUS_SUCCESS){
ntStatus = IoCreateSymbolicLink( &SymbolicLinkNameString, &DeviceName);
CheckErrors(ntStatus);
}
for(y = 0; y < IRP_MJ_MAXIMUM_FUNCTION; y++ ){
DriverObject->MajorFunction[y] = OnStubDispatch;
}
DriverObject->MajorFunction[IRP_MJ_WRITE] = MyWrite;
return STATUS_SUCCESS;
}
代码失败了当我的驱动程序收到 IRp 写入请求时:
#include <iostream>
#include <windows.h>
using namespace std;
int _cdecl main(void){
HANDLE hFile;
DWORD dwReturn;
hFile = CreateFile("\\\\.\\MemoryMirrorLink",
GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, 0, NULL);
if(hFile){
WriteFile(hFile, "Hello from user mode!",sizeof("Hello from user mode!"), &dwReturn, NULL);
printf("Succes!");
CloseHandle(hFile);
} else {
printf("kthxbye: ");
cerr<<GetLastError()<<endl;
}
cin.ignore();
return 0;
}
有谁知道我做错了什么? 非常感谢帮助!
Hello and a happy new years eve/new year everybody,
I'm having some problems with the driver I'm currently making. Everything works fine up until I get to handle an WriteFile() request. My driver tries to handle everything but I get a blue screen of death.
I got to pinpoint the exact location of the error to this statement:
pWriteDataBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
Here is my complete driver code (I was following various tutorials so don't mind the horrible format, I haven't had time to tidy things up:
#include "ntddk.h"
const WCHAR deviceNameBuffer[] = L"\\Device\\MemoryMirrorDevice";
const WCHAR SymbolicLinkName[] = L"\\DosDevices\\MemoryMirrorLink";
PDEVICE_OBJECT g_DevicePointer= NULL; // Global pointer to our device object
int i = 0;
int y;
VOID OnUnload( IN PDRIVER_OBJECT DriverObject ){
UNICODE_STRING SymbolicLinkNameString;
DbgPrint("OnUnload called\n");
RtlInitUnicodeString(&SymbolicLinkNameString, SymbolicLinkName);
IoDeleteSymbolicLink(&SymbolicLinkNameString);
IoDeleteDevice(DriverObject->DeviceObject);
}
int IsStringTerminated(PCHAR pString, unsigned int uiLength){
int bStringIsTerminated = 0;
unsigned int uiIndex = 0;
while(uiIndex < uiLength && bStringIsTerminated == FALSE)
{
if(pString[uiIndex] == '\0')
{
bStringIsTerminated = 1;
}
else
{
uiIndex++;
}
}
return bStringIsTerminated;
}
NTSTATUS MyWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp){
NTSTATUS NtStatus = STATUS_SUCCESS;
PIO_STACK_LOCATION pIoStackIrp = NULL;
PCHAR pWriteDataBuffer;
DbgPrint("MyWrite\r\n");
pIoStackIrp = IoGetCurrentIrpStackLocation(Irp);
if(pIoStackIrp)
{
pWriteDataBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
return NtStatus;
if( pWriteDataBuffer != NULL )
{
if(IsStringTerminated(pWriteDataBuffer, pIoStackIrp->Parameters.Write.Length))
{
DbgPrint(pWriteDataBuffer);
}
}
}
return NtStatus;
}
void CheckErrors(NTSTATUS ntStatus){
i++;
DbgPrint("%i \n",i);
switch(ntStatus){
case STATUS_INSUFFICIENT_RESOURCES:
DbgPrint("INSUFFICIENT RESOURCES\n");
break;
case STATUS_OBJECT_NAME_EXISTS:
DbgPrint("Name exists\n");
break;
case STATUS_OBJECT_NAME_COLLISION:
DbgPrint("Name collission\n");
break;
case STATUS_SUCCESS:
DbgPrint("Success!\n");
break;
default:
DbgPrint("Error is not filtered!\n");
}
}
NTSTATUS OnStubDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp){
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT );
return STATUS_SUCCESS;
}
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING theRegistryPath ){
NTSTATUS ntStatus = STATUS_SUCCESS;
UNICODE_STRING DeviceName;
UNICODE_STRING SymbolicLinkNameString;
DriverObject->DriverUnload = OnUnload;
RtlInitUnicodeString (&DeviceName, deviceNameBuffer );
RtlInitUnicodeString (&SymbolicLinkNameString, SymbolicLinkName);
ntStatus = IoCreateDevice ( DriverObject,0, &DeviceName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &g_DevicePointer);
CheckErrors(ntStatus);
if(ntStatus == STATUS_SUCCESS){
ntStatus = IoCreateSymbolicLink( &SymbolicLinkNameString, &DeviceName);
CheckErrors(ntStatus);
}
for(y = 0; y < IRP_MJ_MAXIMUM_FUNCTION; y++ ){
DriverObject->MajorFunction[y] = OnStubDispatch;
}
DriverObject->MajorFunction[IRP_MJ_WRITE] = MyWrite;
return STATUS_SUCCESS;
}
The code fails the moment my driver receives a IRp write request:
#include <iostream>
#include <windows.h>
using namespace std;
int _cdecl main(void){
HANDLE hFile;
DWORD dwReturn;
hFile = CreateFile("\\\\.\\MemoryMirrorLink",
GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, 0, NULL);
if(hFile){
WriteFile(hFile, "Hello from user mode!",sizeof("Hello from user mode!"), &dwReturn, NULL);
printf("Succes!");
CloseHandle(hFile);
} else {
printf("kthxbye: ");
cerr<<GetLastError()<<endl;
}
cin.ignore();
return 0;
}
Does anyone know what I'm doing wrong?
Help is very much appreciated!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Irp->MdlAddress 可能为 NULL,请使用 Irp->UserBuffer 代替。
熟悉内核调试器和诊断蓝屏。你会需要它。
Irp->MdlAddress is probably NULL, use Irp->UserBuffer instead.
Get familiar with the kernel debugger and diagnosing blue screens. You'll need it.
汉斯的答案是正确的,只需发布更多内容,可能会帮助您使用某些内核调试器调试进一步的问题。
这是(一部分)!analyze 输出
,这里是 Irp 的内容,
您可以检查 MdlAddress 是否为 NULL,并且您要传递给的函数“MmGetSystemAddressForMdlSafe”需要第一个参数“指向缓冲区的指针,该缓冲区对应的基虚拟地址”地址将被映射。
希望这会有所帮助:)
Hans's answer is correct, just posting a few more things that might help you in debugging further issues with some kernel debugger.
Here is (a part of) !analyze output
and here is the content of Irp
You can check that MdlAddress is NULL and the function 'MmGetSystemAddressForMdlSafe' to which you are passing this expects the first argument a 'Pointer to a buffer whose corresponding base virtual address is to be mapped.'
Hope this will help :)