Когда я пытаюсь выгрузить свой драйвер при помощи invoke ControlService, hService, SERVICE_CONTROL_STOP, addr _ss invoke DeleteService, hService получаю Экран смерти. кусок кода драйвера: Код (Text): .386p option casemap:none .model flat, stdcall include \masm32\include\ntstatus.inc include \masm32\include\ntddk.inc include \masm32\include\ntoskrnl.inc include \masm32\include\ntddkbd.inc include \masm32\include\hal.inc includelib \masm32\lib\ntoskrnl.lib includelib \masm32\lib\hal.lib include \masm32\Macros\Strings.mac include common.inc IOCTL_KEYBOARD_DETACH equ CTL_CODE(FILE_DEVICE_UNKNOWN, 800h, METHOD_BUFFERED, FILE_ANY_ACCESS) .data CCOUNTED_UNICODE_STRING "\\Device\\KeyMouse", g_usDeviceName, 4 CCOUNTED_UNICODE_STRING "\\??\\KeyMouse", g_usSymbolicLinkName, 4 CCOUNTED_UNICODE_STRING "\\Device\\KeyboardClass0", g_usTargetDeviceName, 4 CCOUNTED_UNICODE_STRING "\\Software\\Mkkm", g_usUserKeyName, 4 CCOUNTED_UNICODE_STRING "KeyData", KeyDataValueName, 4 CCOUNTED_UNICODE_STRING "KeyData2", KeyData2ValueName, 4 CCOUNTED_UNICODE_STRING "KeyFlag", KeyFlagValueName, 4 CCOUNTED_UNICODE_STRING "KeyFlag2", KeyFlag2ValueName, 4 FALSE equ 0 TRUE equ 1 fScanCode dd 0 ScanCode dd ? KeyFlags dd ? zlpRegScanCode dd ? cb dd ? x dw ? y dw ? buttons dw ? KeyDeviceObject PDEVICE_OBJECT ? pTargetFileObject PFILE_OBJECT ? ;;g_pEventObject PKEVENT ? ;;g_EventSpinLock KSPIN_LOCK ? ; locks key data list g_dwPendingRequests DWORD ? FiDO_DEVICE_EXTENSION STRUCT pNextLowerDeviceObject PDEVICE_OBJECT ? pTargetFileObject PFILE_OBJECT ? FiDO_DEVICE_EXTENSION ENDS PFiDO_DEVICE_EXTENSION typedef ptr FiDO_DEVICE_EXTENSION ...... DriverUnload proc pDriverObject:PDRIVER_OBJECT local status:NTSTATUS local pTopmostDeviceObject:PDEVICE_OBJECT ;;invoke ExFreePool,zlpRegScanCode mov eax, KeyDeviceObject or (DEVICE_OBJECT ptr [eax]).Flags, DO_DEVICE_INITIALIZING invoke IoGetAttachedDeviceReference, KeyDeviceObject mov pTopmostDeviceObject, eax .if eax != KeyDeviceObject ; Someone sits on the top of us. Do nothing except restoring ; Flags field in the filter device object mov eax, KeyDeviceObject and (DEVICE_OBJECT ptr [eax]).Flags, not DO_DEVICE_INITIALIZING .else mov eax, KeyDeviceObject mov eax, (DEVICE_OBJECT ptr [eax]).DeviceExtension mov ecx, (FiDO_DEVICE_EXTENSION ptr [eax]).pTargetFileObject fastcall ObfDereferenceObject, ecx mov eax, KeyDeviceObject mov eax, (DEVICE_OBJECT ptr [eax]).DeviceExtension mov eax, (FiDO_DEVICE_EXTENSION ptr [eax]).pNextLowerDeviceObject invoke IoDetachDevice, eax mov status, STATUS_SUCCESS ; Destroy filter device. mov eax, KeyDeviceObject and KeyDeviceObject, NULL invoke IoDeleteDevice, eax ; Our driver is still not unloadable because we might have outstanding IRPs .endif ; Dereference the device object pointer returned by IoGetAttachedDeviceReference invoke ObDereferenceObject, pTopmostDeviceObject invoke IoDeleteSymbolicLink, addr g_usSymbolicLinkName mov eax, pDriverObject invoke IoDeleteDevice, (DRIVER_OBJECT PTR [eax]).DeviceObject ret DriverUnload endp ..... .code INIT DriverEntry proc pDriverObject:PDRIVER_OBJECT, pusRegistryPath:PUNICODE_STRING local status:NTSTATUS local pTargetDeviceObject:PDEVICE_OBJECT mov status, STATUS_DEVICE_CONFIGURATION_ERROR invoke IoCreateDevice, pDriverObject, sizeof FiDO_DEVICE_EXTENSION, addr g_usDeviceName, FILE_DEVICE_UNKNOWN, \ 0, TRUE, addr KeyDeviceObject .if eax == STATUS_SUCCESS invoke IoCreateSymbolicLink, addr g_usSymbolicLinkName, addr g_usDeviceName .if eax == STATUS_SUCCESS invoke IoGetDeviceObjectPointer, addr g_usTargetDeviceName, FILE_READ_DATA, \ addr pTargetFileObject, addr pTargetDeviceObject mov eax, pDriverObject assume eax:PTR DRIVER_OBJECT mov ecx, IRP_MJ_MAXIMUM_FUNCTION + 1 .while ecx dec ecx mov [eax].MajorFunction[ecx*(sizeof PVOID)], offset DriverDispatch .endw mov [eax].DriverUnload, offset DriverUnload assume eax:nothing ;;; invoke QueryValueKey invoke IoAttachDeviceToDeviceStack, KeyDeviceObject, pTargetDeviceObject .if eax != NULL mov edx, eax ; Fill filter device object extension mov ecx, KeyDeviceObject mov eax, (DEVICE_OBJECT ptr [ecx]).DeviceExtension assume eax:ptr FiDO_DEVICE_EXTENSION mov [eax].pNextLowerDeviceObject, edx push pTargetFileObject pop [eax].pTargetFileObject assume eax:nothing assume edx:ptr DEVICE_OBJECT assume ecx:ptr DEVICE_OBJECT mov eax, [edx].DeviceType mov [ecx].DeviceType, eax mov eax, [edx].Flags and eax, DO_DIRECT_IO + DO_BUFFERED_IO + DO_POWER_PAGABLE or [ecx].Flags, eax and [ecx].Flags, not DO_DEVICE_INITIALIZING assume edx:nothing assume ecx:nothing mov status, STATUS_SUCCESS .else ; IoAttachDeviceToDeviceStack failed ; We have failed to attach invoke ObDereferenceObject, pTargetFileObject invoke IoDeleteDevice, KeyDeviceObject and KeyDeviceObject, NULL ; Let the driver to be unloaded mov eax, pDriverObject mov (DRIVER_OBJECT PTR [eax]).DriverUnload, offset DriverUnload mov status, STATUS_NO_SUCH_DEVICE .endif mov status, STATUS_SUCCESS .else invoke IoDeleteDevice, KeyDeviceObject .endif .endif mov eax, status ret DriverEntry endp end DriverEntry Подскажите, пожалуйста, что здесь не так.
Если вкратце, то для примера возьмем какой-нибудь i8042prt. После того как в ISR создастся DPC, а в ней вызовется колбек Keyboard Class Driver'a, заполнится очередь уже класс драйвера, и далее IRP_READ присланный RIT'ом задерживается пока не будет заполнен сканкодами. И только после этого irp завершится класс драйвером клавиатуры. Если в этот момент выгрузить фильтр, то заполненный irp улетит обратно в никуда( фильтр то выгружен ). Решение этой проблемы публиковалось на rootkits.com если ничего не путаю.
Спасибо. Я учёл Ваш совет и немного переделал код, но проблема была вот в этом: mov eax, KeyDeviceObject and KeyDeviceObject, NULL invoke IoDeleteDevice, eax Я зачем-то пытался удалить KeyboardClass0))) Но, у меня есть ещё один вопрос. Как отключить от стека устройство не находящееся на его вершине?