大家好,祝大家新年快乐,新年快乐,
我正在使用我正在制作的驱动程序遇到一些问题。一切正常,直到我处理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;
}
有谁知道我做错了什么? 非常感谢帮助!
答案 0 :(得分:3)
Irp-&gt; MdlAddress可能为NULL,请使用Irp-&gt; UserBuffer。
熟悉内核调试器并诊断蓝屏。你需要它。
答案 1 :(得分:1)
汉斯的回答是正确的,只是发布了一些可能有助于您调试某些内核调试器的问题的事情。
这是(分析输出)的一部分
BUGCHECK_STR: ACCESS_VIOLATION
DEFAULT_BUCKET_ID: NULL_CLASS_PTR_DEREFERENCE
LAST_CONTROL_TRANSFER: from 804e3d77 to f7bd6549
STACK_TEXT:
f3931c60 804e3d77 85e1eca8 85d8f7a0 806ed070 test_drv!MyWrite+0x39 [c:\fiddle\test_drv\drv.c @ 58]
WARNING: Stack unwind information not available. Following frames may be wrong.
f3931c84 8057a510 85e1eca8 85d8f7a0 85c76788 nt!IofCallDriver+0x32
f3931d38 804df06b 000007e8 00000000 00000000 nt!NtWriteFile+0x3eb
f3931ddc 804fa477 f72d9b85 85c79340 00000000 nt!ZwYieldExecution+0xb96
f3931e20 7c90e027 7c80b1f9 ffffffff 00000017 nt!KeInitializeTimer+0x10c
00000000 00000000 00000000 00000000 00000000 ntdll+0xe027
STACK_COMMAND: kb
FAULTING_SOURCE_CODE:
54: if(pIoStackIrp)
55: {
56:
57:
> 58: pWriteDataBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
59:
60: return NtStatus;
61:
62: if( pWriteDataBuffer != NULL )
63: {
这是Irp的内容
kd> dt Irp
Local var @ 0xf3931c6c Type _IRP*
0x85d8f7a0
+0x000 Type : 0n6
+0x002 Size : 0x94
+0x004 MdlAddress : (null)
+0x008 Flags : 0xa00
+0x00c AssociatedIrp : <unnamed-tag>
+0x010 ThreadListEntry : _LIST_ENTRY [ 0x85e27560 - 0x85e27560 ]
+0x018 IoStatus : _IO_STATUS_BLOCK
+0x020 RequestorMode : 1 ''
+0x021 PendingReturned : 0 ''
+0x022 StackCount : 1 ''
+0x023 CurrentLocation : 1 ''
+0x024 Cancel : 0 ''
+0x025 CancelIrql : 0 ''
+0x026 ApcEnvironment : 0 ''
+0x027 AllocationFlags : 0xc ''
+0x028 UserIosb : 0x0012ff34 _IO_STATUS_BLOCK
+0x02c UserEvent : (null)
+0x030 Overlay : <unnamed-tag>
+0x038 CancelRoutine : (null)
+0x03c UserBuffer : 0x0041c1d8 Void
+0x040 Tail : <unnamed-tag>
您可以检查MdlAddress是否为NULL并且您要传递的函数'MmGetSystemAddressForMdlSafe'需要第一个参数a'指向要映射相应基本虚拟地址的缓冲区的指针。'
希望这会有所帮助:)