Изучаю перехват API в ring0 по статье http://www.wasm.ru/article.php?article=apihook_3 В ней есть простой IO-драйвер Код (Text): #include <ntddk.h> #define DEBUG #ifdef DEBUG #define DPRINT DbgPrint #else #define DPRINT #endif UNICODE_STRING DeviceName; UNICODE_STRING SymbolicLinkName; PDEVICE_OBJECT deviceObject = NULL; VOID DriverUnload(IN PDRIVER_OBJECT DriverObject) { DPRINT("Driver unloaded"); IoDeleteSymbolicLink(&SymbolicLinkName); // удаляем символическую ссылку IoDeleteDevice(deviceObject); // удаляем устройство return; } NTSTATUS DriverDispatcher( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PIO_STACK_LOCATION pisl; NTSTATUS ns = STATUS_SUCCESS; PCSTR Data; pisl = IoGetCurrentIrpStackLocation(Irp); Irp->IoStatus.Information = 0; if ( pisl->MajorFunction == IRP_MJ_WRITE) { ULONG Length = pisl->Parameters.Write.Length; Data = Irp->UserBuffer; __try { DbgPrint("%s", Data); } __except(EXCEPTION_EXECUTE_HANDLER) { Irp->IoStatus.Information = 0; ns = STATUS_IN_PAGE_ERROR; } } Irp->IoStatus.Status = ns; IoCompleteRequest(Irp, IO_NO_INCREMENT); return ns; } NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { NTSTATUS st; PCWSTR dDeviceName = L"\\Device\\MyDriver"; PCWSTR dSymbolicLinkName = L"\\DosDevices\\MyDriver"; PDRIVER_DISPATCH *ppdd; DPRINT("Driver loaded"); RtlInitUnicodeString(&DeviceName, dDeviceName); RtlInitUnicodeString(&SymbolicLinkName, dSymbolicLinkName); st = IoCreateDevice(DriverObject, // указатель на DriverObject 0, // размер памяти (device extension) &DeviceName, // имя создаваемого устройства FILE_DEVICE_NULL, // тип создаваемого устройства 0, // характеристики устройства FALSE, // "эксклюзивное" устройство &deviceObject); // указатель на объект устройства if (st == STATUS_SUCCESS) st = IoCreateSymbolicLink(&SymbolicLinkName, // имя создаваемой символической ссылки &DeviceName); // имя устройства ppdd = DriverObject->MajorFunction; // обьявляю процедуры обработки ввода-вывода ppdd ppdd[IRP_MJ_CREATE] = ppdd[IRP_MJ_CLOSE ] = ppdd[IRP_MJ_WRITE ] = DriverDispatcher; DriverObject->DriverUnload = DriverUnload; return st; } Читаю символьную ссылку на обьект драйвер Код (Text): HANDLE hDriver; DWORD Written; PCHAR Str; hDriver = CreateFile("\\\\.\\MyDriver", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); if (hDriver != INVALID_HANDLE_VALUE) { WriteFile(hDriver, Str, lstrlen(Str), &Written, NULL); } CloseHandle(hDriver); Возникает BSOD, по умолчанию в системе установлен малый дамп памяти 64кб. Возможно идентифицировать ошибку?
Здесь тоже ошибка Было Код (Text): (st == STATUS_SUCCESS) st = IoCreateSymbolicLink(&SymbolicLinkName, // имя создаваемой символической ссылки &DeviceName); Изменил на // (st == STATUS_SUCCESS) st = IoCreateSymbolicLink(&SymbolicLinkName, // имя создаваемой символической ссылки &DeviceName);
улыбнуло )) ты if потерял на предыдущей строке IF (st == STATUS_SUCCESS) st = IoCreateSymbolicLink(&SymbolicLinkName, // имя создаваемой символической ссылки &DeviceName);
Код вроде правильный. Правда, не увидел инициализации передаваемой строки - по коду передается треш. Тогда будет падать на DbgPrint("%s", Data); Учись отлаживаться на тестовой http://silverstr.ufies.org/lotr0/windbg-vmware.html
Да. Это некорректное утверждение. Каждый из методов передачи данных имеет свою сферу применения. Например, Buffered I/O совершенно точно не подойдёт для больших объёмов данных (больше 1 ГБ), в этом случае останется использоваться только Neither.
x64 Ну ясен пень, имелось в виду, что автору конкретно в данной ситуации для изучения дров и написания своего первого драйвера, который создает девайс объект, лучше всего подойдет именно buffered. Ну а про сферы применения ты, конечно, прав, тем более, что это все прекрасно описано в мсдн. Не надо цитировать мсдн
st = IoCreateDevice(DriverObject, // указатель на DriverObject 0, // размер памяти (device extension) &DeviceName, // имя создаваемого устройства FILE_DEVICE_NULL, // тип создаваемого устройства 0, // характеристики устройства FALSE, // "эксклюзивное" устройство &deviceObject); // указатель на объект устройства IF (st == STATUS_SUCCESS) st = IoCreateSymbolicLink(&SymbolicLinkName, // имя создаваемой символической ссылки &DeviceName); // имя устройства
В MSDN и бегом давай. И чтоб духу твоего здесь не было покуда не наступит просветление. Воистину, ибо так. Аминь.
Read the f*cking msdn) А так же статьи Four-F http://www.wasm.ru/article.php?article=drvw2k04 http://www.wasm.ru/article.php?article=drvw2k05 deviceObject->Flags |= DO_BUFFERED_IO; // при инициализации А потом обращаться к системному буфферу в Irp->AssociatedIrp.SystemBuffer. В него скопируется входной пользовательский буффер (если таковое предполагается в запросе - IRP_MJ_WRITE / IRP_MJ_DEVICE_CONTROL) Число, указанное в Irp->IoStatus.Information, будет означать количество байт, которое нужно скопировать в пользовательский буффер (если таковое предполагается в запросе - IRP_MJ_READ / IRP_MJ_DEVICE_CONTROL, иначе это будет означать число фактически записанных байт - IRP_MJ_WRITE, возможны и другие варианты вроде бы). За подробностями в мсдн.