Вот сталкнулся с такой проблемой: Програма должна постоянно считывать через из драйвера через: ReadFile струткуру следующего типа: typedef struct _TMySTRUC // структура описывающая запрос к драйверу { HANDLE z1; HANDLE z2; } TMySTRUC, *PMySTRUC; ВОт не могу написать как именно осуществить запись со стороны драйвера. к примеру: Code: TMySTRUC mystruc; mystruc->z1=11111; mystruc->z2=22222; irpStack = IoGetCurrentIrpStackLocation (Irp); if (irpStack->MajorFunction == IRP_MJ_READ) { ВОт что сюда вставить, чтобы передаться струкруру mystruc????? } Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; Еще чуть запустался с IRP_MJ_READ и IRP_MJ_WRITE КАк я понял irpStack->MajorFunction == IRP_MJ_READ будет тогда когда програма будет читать данные из драйвера т.е. readfile, а IRP_MJ_WRITE - когда будет писать чтото драйверу. Перебрал кучу документаций так толком и не понял как осуществить чтение и запись.
какой тип ввода-вывода? 1) если buffered (DO_BUFFERED_IO), тогда Irp->AssotiatedIrp.SystemBuffer указывает на системный буффер, который потом будет скопирован в пользовательский выходной (если это IRP_MJ_READ) или в который уже скопирован входной (если это IRP_MJ_WRITE) другие типы тебе пока не нужны.. запутаешься нафиг. тебе нужно лишь проверить длину буффера и скопировать туда структуру
Чтото начал делать в этоге при копировании идет BSOD Вообще драйвер должен перехватывать запуск процессов. И потом по требованию возвращать PID и PARENT последнего запущенного процесса. Код функции обработчика: Code: if (irpStack->MajorFunction == IRP_MJ_READ) { DPRINT("READ"); if (irpStack->Parameters.Read.Length < 8) { DPRINT("LENGTH < 8"); Irp->IoStatus.Status = status = STATUS_BUFFER_TOO_SMALL; Irp->IoStatus.Information = 0; IoCompleteRequest (Irp, IO_NO_INCREMENT); return status; } else { DPRINT("LENGTH OK"); Еcли раскоментировать, то BSOD >>> //RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, &RUNPROC, 8); Irp->IoStatus.Status = status = STATUS_SUCCESS; IoCompleteRequest (Irp, IO_NO_INCREMENT); return status; } } где TRUNPROC RUNPROC typedef struct _TRUNPROC { HANDLE parent; HANDLE PID; } TRUNPROC, *PRUNPROC; И вот вопрос еще один. Как мне получать то, что выводится через DbgPrint? Юзаю WinDbg. Т.е. я запускаю через него прогу, которая общается с драйвером, но почемуто сообщения от DbgPrint на экране они не появляются
Путаешь. Для просмотра сообщений от DbgPrint тебе нужен DebugView от Sysinternals. Сейчас посмотрю код.
Если я не ошибаюсь, то для передачи информации драйвер<->программа драйвер должен создать устройство, через которое будет передаваться инфа. Вот тебе: http://www.wasm.ru/article.php?article=apihook_3 (см.Взаимодействие драйвера с приложением) И вот: http://wasm.ru/article.php?article=drvw2k04
не с устройсвом всё ок. всё создано отлично. И пашет отлично. А вот тока как именно драйвер должен передать ответ - хз. На счет васма - процел всё - толком там не описано.
Да сделай ты через DeviceIoControl, проще будет, один из аргументов функции - буфер для обратного ответа. Будешь передавать драйверу IOCTL коды. Code: #define IOCTL_GETPID CTL_CODE(FILE_DEVICE_UNKNOWN, 0x01, \ METHOD_BUFFERED, \ FILE_READ_DATA | FILE_WRITE_DATA) А драйвер будет обрабатывать их. Code: DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MyIrp; ... NTSTATUS MyIrp(IN PDEVICE_OBJECT dev, IN PIRP pirp) { ... switch (ioctl_code) { case IOCTL_GETPID: GetPid(); break; default: ns = STATUS_INVALID_DEVICE_REQUEST; } ...
с DbgPrint разобрался + ---------- Суть в том, что я юзаю DeviceIoControl для чуть другйо функции. а именно - защита процесса. Чтобы его не могли выкинуть стандартными методами. у меня он заюзан вот так: if (irpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL) ProtectedPid = (HANDLE)irpStack->Parameters.DeviceIoControl.IoControlCode;
переписал на DeviceIoControl но чуть не допер как получить параметр. сделал вот что. но тут чегото не хватает. А именно знаний в С: Code: if (irpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL) { switch (irpStack->Parameters.DeviceIoControl.IoControlCode) { case 0x12345: if (irpStack->Parameters.DeviceIoControl.InputBufferLength == sizeof(HANDLE)) { ------> Вот тут я туплю. Как правильно сделать? ProtectedPid=Irp->AssociatedIrp.SystemBuffer; DPRINT("PID= %d",ProtectedPid); } break; default: status = STATUS_INVALID_DEVICE_REQUEST; } }
Тут указаны примеры для разных методов: Code: stack = IoGetCurrentlrpStackLocation (Irp); switch (pIrpStack->MajorFunction) { case IRP_MJ_CREATE: case IRP_MJ_CLOSE: break; case IRP_MJ_DEVICE_CONTROL: switch (stack->Parameters.DeviceloControl.loControlCode) { [b]case IOCTL_MY_BUFFERED:[/b] InBuffer = Irp->AssociatedIrp.SystemBuffer; InLength = stack->Parameters.DeviceloControl.InputBuffer.Length; OutBuffer = Irp->AssociatedIrp.SystemBuffer; OutLength = stack->Parameters.DeviceloControl.OutputBufferLength; [b]case IOCTL_MY_IN_DIRECT:[/b] //OutBuffer доступен только для чтения InBuffer = Irp->AssociatedIrp.SystemBuffer; InLength = stack->Parameters.DeviceloControl.InputBufferLength; OutBuffer = MmGetSystemAddressForMdl( Irp->MdlAddress ); OutLength = stack->Parameters.DeviceloControl.OutputBufferLength; break; [b]case IOCTL_MY_OUT_DIRECT:[/b] //OutBuffer доступен для чтения/записи InBuffer = Irp->AssociatedIrp.SystemBuffer; InLength = stack->Parameters.DeviceloControl.InputBufferLength; OutBuffer = MmGetSystemAddressForMdl( Irp->MdlAddress); OutLength = stack->Parameters.DeviceloControl.OutputBufferLength; break; [b]case IOCTL_MY_NEITHER:[/b] InBuffer = irpStack->Parameters.DeviceloControl.TypeInputBuffer; InLength = irpStack->Parameters.DeviceIoControl.InputBufferLength; OutBuffer = Irp->UserBuffer; OutLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength; break; Также обязательно прочитай:
подскажите что я делаю не так. почему BSOD? При установке ProtectedPid - ставится всё нормально и пашет отлично. А при чтении его - BSOD. читаю через PID,TrId:dword; DeviceIoControl(hDriver, $23456, nil, 0, @PID, 4, TrId, nil); Вот код обработчика Code: HANDLE ProtectedPid; NTSTATUS DriverDispatcher(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS status; PIO_STACK_LOCATION irpStack; irpStack = IoGetCurrentIrpStackLocation (Irp); if (irpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL) { switch (irpStack->Parameters.DeviceIoControl.IoControlCode) { case 0x12345: if (irpStack->Parameters.DeviceIoControl.InputBufferLength == sizeof(HANDLE)) { ProtectedPid=*(HANDLE *)Irp->AssociatedIrp.SystemBuffer; DPRINT("PID= %d",ProtectedPid); } break; case 0x23456: if (irpStack->Parameters.Read.Length < 4) { DPRINT("LENGTH < 4"); Irp->IoStatus.Status = status = STATUS_BUFFER_TOO_SMALL; Irp->IoStatus.Information = 0; IoCompleteRequest (Irp, IO_NO_INCREMENT); return status; } else { DPRINT("LENGTH OK"); Irp->IoStatus.Information = 4; // чтото тут я не мойму как реализовать. *(HANDLE *)Irp->AssociatedIrp.SystemBuffer=ProtectedPid; Irp->IoStatus.Status = status = STATUS_SUCCESS; IoCompleteRequest (Irp, IO_NO_INCREMENT); return status; } break; default: status = STATUS_INVALID_DEVICE_REQUEST; } } Irp->IoStatus.Status = status; IoCompleteRequest (Irp, IO_NO_INCREMENT); return status; }
Кто тебе сказал что ты можешь какие угодно io control code задавать? Юзай макрос IOCTL_CODE() Самое главное - тип ввода-вывода (младшие 2 бита), у тебя видно тип не buffered во втором случае (да и в первом тоже)
2 _Great_ Ты имеешь ввиду что именно через CTL_CODE и истанавливаются прва на запись, чтение и мето ввода-вывод? Вот еще сталкнулся с такой проблемой. Иногда почемуто програма не может связаться с драйвером. Драйвер у меня как сервис. Поэтому я делаю: net stop MyDRV потом перекомпиливаю драйвер затем: net start MyDRV Все пахало нормально. но потом через несколько перезагрузок почемуто из програмы не возможно связаться с драйвером. т.е. CreateFile('\\.\MyDRVS', GENERIC_ALL, 0, nil, OPEN_EXISTING, 0, 0); возвращает INVALID_HANDLE_VALUE Хотя драйвер пашет нормально - по дебаговым сообщением видно что создания процессов перехватываются. НО связи по сей час нет. уже перезагружался пару раз - дохлое дело. Также заметил один интерестный факт. Вроде все програмы и DLL ки виндовые отображаются на память, а драйвера получается что нет? потому что при запущенном драйвере можно спакойно удалить файл драйвара.
А самому лень посмотреть? winioctl.h Code: #define CTL_CODE( DeviceType, Function, Method, Access ) ( ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) )
А тебе драйвера то не рано ещё писать? ; ) И DLL и EXE любую можно удалить без проблем как и драйвер. Просто после загрузки драйвера винда не лочит попытки удаления его файла на диске, а для user-mode модулей - лочит. Т.е. файл остается открытым для user-mode модулей и закрывается сразу после загрузки для драйверов (а нахер ему быть открытым). Но, ИМХО, одно из двух писал НЕ ты. Либо "драйвер не отображается на память", либо сам драйвер ; ) Учитесь как надо кодить всё хотел кому-нибудь показать чтоб оценили гыгыг
Некоторые биты ио контрол кода служебные. А ты рандомно задаешь все число. Поэтому и глюки GetLastError() ?
2 _Great_ спасибо за разъяснение. Переписал все через CTL_CODE. Но всеже также осталась проблема с доступом к драйверу. GetLastError дает код ошибки - 317