Всем привет! Начал изучать кодинг в нулевом кольце по книжке Колисниченко "Руткиты под Windows". Попробовал собрать и запустить драйвер по примеру, приведенному в книге. Вот листинг: Код (Text): #include <ntddk.h> typedef struct _DEVICE_EXTENSION { PDEVICE_OBJECT pdo; UNICODE_STRING ustrSymLinkName; } DEVICE_EXTENSION,*PDEVICE_EXTENSION; DRIVER_UNLOAD MyUnload; VOID MyUnload(IN PDRIVER_OBJECT pDriverObject) { PDEVICE_OBJECT pNextDevObj; int i; DbgPrint("Unloading driver"); pNextDevObj=pDriverObject->DeviceObject; for(i=0; pNextDevObj!=NULL;i++) { PDEVICE_EXTENSION dx=(PDEVICE_EXTENSION)pNextDevObj->DeviceExtension; UNICODE_STRING *pLinkName=& (dx->ustrSymLinkName); pNextDevObj=pNextDevObj->NextDevice; DbgPrint("MyUnload Deleting Device (%d) : pointer to PDO=%X",i,dx->pdo); DbgPrint("MyUnload Deleting SymLink =%ws : pointer to PDO=%X",pLinkName->Buffer); IoDeleteSymbolicLink(pLinkName); IoDeleteDevice(dx->pdo); } } NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath) { NTSTATUS status=STATUS_SUCCESS; PDEVICE_OBJECT pdo; UNICODE_STRING devName; UNICODE_STRING symLinkName; PDEVICE_EXTENSION dx; DbgPrint("Entering DriverEntry..."); DbgPrint("RegistryPath=%ws",pRegistryPath->Buffer); RtlInitUnicodeString(&devName,L"\\Device\\MyDevice"); RtlInitUnicodeString(&symLinkName,L"\\DosDevices\\MyDevice"); pDriverObject->DriverUnload=(PDRIVER_UNLOAD)MyUnload; status=IoCreateDevice(pDriverObject,sizeof(DEVICE_EXTENSION),&devName, FILE_DEVICE_UNKNOWN,0,FALSE,&pdo); if(!NT_SUCCESS(status)) { DbgPrint("DriverEntry IoCreateDeviceError"); return status; } dx=(PDEVICE_EXTENSION)pdo->DeviceExtension; dx->pdo=pdo; dx->ustrSymLinkName=symLinkName; status=IoCreateSymbolicLink(&symLinkName,&devName); if(!NT_SUCCESS(status)) { IoDeleteDevice(pdo); return status; } DbgPrint("DriverEntry successfully completed"); return status; } Вопросы: 1) При загрузке его утилитой instdrv, собранной по исходникам из этой же книги, не получается создать устройство. 2) зачем нужна структура dx? в листинге она не используется. Подозреваю, что не хватает какого-то системного вызова, которому она передается в качестве аргумента
1. Какой статус возвращается? 2. Как это не используется? В ней же имя ссылки хранится, которое потом используется для уничтожения в Unload.
1) статус не возвращается - утилита для загрузки пишет "Can't get a handle to \\.\MyDevice". Отладочных сообщений не возникает. никаких. 2) спасибо, не заметил)
1.Вы не обрабатывайте запрос create. 2. структура нужна для специфицеских задач конкретного драйвера поэтому она разработчиком созжается
Mika0x65 Да, устройство MyDevice создалось h0t Я правильно понимаю, что без специального обработчика функция CreateFile, которая пытается открыть устройство, как файл, работать не будет?
Lecko Если у тебя в драйвере нет обработчика IRP_MJ_CREATE, но ты при этом создаешь "устройство" и симлинк к нему, то пытаться открыть файл через CreateFile бессмысленно. I/O Manager не найдет адрес обработчика и вернет ошибку. Обычно в коде нужно предусматрить обработчики MJ*-функций, нечто типа Код (Text): for(i= 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) { driverObject->MajorFunction[i]= defaultDispatch; } driverObject->MajorFunction[IRP_MJ_CREATE] = DispatchRead; driverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DeviceControlDispatch; где простейший defaultDispatch для твоего "устройства" будет примерно таким Код (Text): NTSTATUS defaultDispatch( IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp ) { pIrp->IoStatus.Information = 0; pIrp->IoStatus.Status = STATUS_SUCCESS; IofCompleteRequest(pIrp,IO_NO_INCREMENT); return STATUS_SUCCESS; }
Заработало, всем спасибо! как выяснилось, для полного счастья ему не хватало обработчика IRP_MJ_CREATE. Особое спасибо steelfactor Полный код драйвера, если у других читателей Колисниченко возникнет такой же трабл: Код (Text): #include <ntddk.h> typedef struct _DEVICE_EXTENSION { PDEVICE_OBJECT pdo; UNICODE_STRING ustrSymLinkName; } DEVICE_EXTENSION,*PDEVICE_EXTENSION; DRIVER_UNLOAD MyUnload; VOID MyUnload(IN PDRIVER_OBJECT pDriverObject) { PDEVICE_OBJECT pNextDevObj; int i; DbgPrint("Unloading driver"); pNextDevObj=pDriverObject->DeviceObject; for(i=0; pNextDevObj!=NULL;i++) { PDEVICE_EXTENSION dx=(PDEVICE_EXTENSION)pNextDevObj->DeviceExtension; UNICODE_STRING *pLinkName=& (dx->ustrSymLinkName); pNextDevObj=pNextDevObj->NextDevice; DbgPrint("MyUnload Deleting Device (%d) : pointer to PDO=%X",i,dx->pdo); DbgPrint("MyUnload Deleting SymLink =%ws : pointer to PDO=%X",pLinkName->Buffer); IoDeleteSymbolicLink(pLinkName); IoDeleteDevice(dx->pdo); } } NTSTATUS DriverDefaultHandler(IN PDEVICE_OBJECT pDeviceObject, IN PIRP Irp) { PIO_STACK_LOCATION pSL = IoGetCurrentIrpStackLocation (Irp) ; switch (pSL->MajorFunction) { case IRP_MJ_CREATE : case IRP_MJ_CLOSE : case IRP_MJ_CLEANUP : { Irp->IoStatus.Status = STATUS_SUCCESS; break; } default: { Irp->IoStatus.Status = STATUS_NOT_SUPPORTED ; } } Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Irp->IoStatus.Status; } NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath) { NTSTATUS status=STATUS_SUCCESS; PDEVICE_OBJECT pdo; UNICODE_STRING devName; UNICODE_STRING symLinkName; PDEVICE_EXTENSION dx; int i; DbgPrint("Entering DriverEntry..."); DbgPrint("RegistryPath=%ws",pRegistryPath->Buffer); RtlInitUnicodeString(&devName,L"\\Device\\MyDevice"); RtlInitUnicodeString(&symLinkName,L"\\DosDevices\\MyDevice"); pDriverObject->DriverUnload=(PDRIVER_UNLOAD)MyUnload; for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) pDriverObject->MajorFunction[i] = DriverDefaultHandler; status=IoCreateDevice(pDriverObject,sizeof(DEVICE_EXTENSION),&devName, FILE_DEVICE_UNKNOWN,0,FALSE,&pdo); if(!NT_SUCCESS(status)) { DbgPrint("DriverEntry IoCreateDeviceError"); return status; } pdo->Flags &= ~DO_DEVICE_INITIALIZING; dx=(PDEVICE_EXTENSION)pdo->DeviceExtension; dx->pdo=pdo; dx->ustrSymLinkName=symLinkName; status=IoCreateSymbolicLink(&symLinkName,&devName); if(!NT_SUCCESS(status)) { IoDeleteDevice(pdo); return status; } DbgPrint("DriverEntry successfully completed"); return status; }