BSOD при выгрузке драйвера

Тема в разделе "WASM.NT.KERNEL", создана пользователем Llirik, 9 дек 2010.

  1. Llirik

    Llirik Member

    Публикаций:
    0
    Регистрация:
    18 июл 2008
    Сообщения:
    471
    Когда я пытаюсь выгрузить свой драйвер при помощи
    invoke ControlService, hService, SERVICE_CONTROL_STOP, addr _ss
    invoke DeleteService, hService
    получаю Экран смерти. кусок кода драйвера:
    Код (Text):
    1.     .386p
    2. option casemap:none
    3. .model flat, stdcall
    4.  
    5. include \masm32\include\ntstatus.inc
    6. include \masm32\include\ntddk.inc
    7. include \masm32\include\ntoskrnl.inc
    8. include \masm32\include\ntddkbd.inc
    9. include \masm32\include\hal.inc
    10.  
    11. includelib \masm32\lib\ntoskrnl.lib
    12. includelib \masm32\lib\hal.lib
    13.  
    14. include \masm32\Macros\Strings.mac
    15.  
    16. include common.inc
    17. IOCTL_KEYBOARD_DETACH   equ CTL_CODE(FILE_DEVICE_UNKNOWN, 800h, METHOD_BUFFERED, FILE_ANY_ACCESS)
    18. .data
    19. CCOUNTED_UNICODE_STRING    "\\Device\\KeyMouse", g_usDeviceName, 4
    20. CCOUNTED_UNICODE_STRING    "\\??\\KeyMouse", g_usSymbolicLinkName, 4
    21. CCOUNTED_UNICODE_STRING "\\Device\\KeyboardClass0", g_usTargetDeviceName, 4
    22. CCOUNTED_UNICODE_STRING "\\Software\\Mkkm", g_usUserKeyName, 4
    23. CCOUNTED_UNICODE_STRING "KeyData", KeyDataValueName, 4
    24. CCOUNTED_UNICODE_STRING "KeyData2", KeyData2ValueName, 4
    25. CCOUNTED_UNICODE_STRING "KeyFlag", KeyFlagValueName, 4
    26. CCOUNTED_UNICODE_STRING "KeyFlag2", KeyFlag2ValueName, 4
    27. FALSE       equ 0
    28. TRUE        equ 1
    29. fScanCode dd 0
    30. ScanCode dd ?
    31. KeyFlags dd ?
    32. zlpRegScanCode dd ?
    33. cb dd  ?
    34. x dw ?
    35. y dw ?
    36. buttons dw ?
    37. KeyDeviceObject   PDEVICE_OBJECT ?
    38. pTargetFileObject   PFILE_OBJECT  ?
    39. ;;g_pEventObject                    PKEVENT         ?
    40. ;;g_EventSpinLock                   KSPIN_LOCK      ?   ; locks key data list
    41. g_dwPendingRequests             DWORD           ?
    42.  
    43. FiDO_DEVICE_EXTENSION STRUCT
    44.     pNextLowerDeviceObject  PDEVICE_OBJECT  ?
    45.     pTargetFileObject   PFILE_OBJECT    ?
    46. FiDO_DEVICE_EXTENSION ENDS
    47. PFiDO_DEVICE_EXTENSION typedef ptr FiDO_DEVICE_EXTENSION
    48. ......
    49.  
    50. DriverUnload proc pDriverObject:PDRIVER_OBJECT
    51. local status:NTSTATUS
    52. local pTopmostDeviceObject:PDEVICE_OBJECT
    53. ;;invoke ExFreePool,zlpRegScanCode
    54.         mov eax, KeyDeviceObject
    55.         or (DEVICE_OBJECT ptr [eax]).Flags, DO_DEVICE_INITIALIZING
    56.  
    57.         invoke IoGetAttachedDeviceReference, KeyDeviceObject
    58.         mov pTopmostDeviceObject, eax
    59.  
    60.         .if eax != KeyDeviceObject
    61.  
    62.             ; Someone sits on the top of us. Do nothing except restoring
    63.             ; Flags field in the filter device object
    64.  
    65.             mov eax, KeyDeviceObject
    66.             and (DEVICE_OBJECT ptr [eax]).Flags, not DO_DEVICE_INITIALIZING
    67.                        
    68.         .else          
    69.  
    70.             mov eax, KeyDeviceObject
    71.             mov eax, (DEVICE_OBJECT ptr [eax]).DeviceExtension
    72.             mov ecx, (FiDO_DEVICE_EXTENSION ptr [eax]).pTargetFileObject
    73.  
    74.             fastcall ObfDereferenceObject, ecx
    75.  
    76.             mov eax, KeyDeviceObject
    77.             mov eax, (DEVICE_OBJECT ptr [eax]).DeviceExtension
    78.             mov eax, (FiDO_DEVICE_EXTENSION ptr [eax]).pNextLowerDeviceObject
    79.  
    80.             invoke IoDetachDevice, eax
    81.            
    82.             mov status, STATUS_SUCCESS
    83.  
    84.             ; Destroy filter device.
    85.  
    86.             mov eax, KeyDeviceObject
    87.             and KeyDeviceObject, NULL
    88.             invoke IoDeleteDevice, eax
    89.  
    90.             ; Our driver is still not unloadable because we might have outstanding IRPs
    91.  
    92.         .endif
    93.  
    94.         ; Dereference the device object pointer returned by IoGetAttachedDeviceReference
    95.  
    96.         invoke ObDereferenceObject, pTopmostDeviceObject
    97.  
    98.     invoke IoDeleteSymbolicLink, addr g_usSymbolicLinkName
    99.  
    100.     mov eax, pDriverObject
    101.     invoke IoDeleteDevice, (DRIVER_OBJECT PTR [eax]).DeviceObject
    102.  
    103.     ret
    104.  
    105. DriverUnload endp
    106. .....
    107.  
    108. .code INIT
    109.  
    110.  
    111. DriverEntry proc pDriverObject:PDRIVER_OBJECT, pusRegistryPath:PUNICODE_STRING
    112.  local status:NTSTATUS
    113.  
    114. local pTargetDeviceObject:PDEVICE_OBJECT
    115.  
    116.  
    117.      mov status, STATUS_DEVICE_CONFIGURATION_ERROR
    118.  
    119. invoke IoCreateDevice, pDriverObject, sizeof FiDO_DEVICE_EXTENSION, addr g_usDeviceName, FILE_DEVICE_UNKNOWN, \
    120.                                               0, TRUE, addr KeyDeviceObject
    121. .if eax == STATUS_SUCCESS
    122.          invoke IoCreateSymbolicLink, addr g_usSymbolicLinkName, addr g_usDeviceName
    123.  
    124.          .if eax == STATUS_SUCCESS
    125.  
    126.      invoke IoGetDeviceObjectPointer, addr g_usTargetDeviceName, FILE_READ_DATA, \
    127.                                       addr pTargetFileObject, addr pTargetDeviceObject
    128.             mov eax, pDriverObject
    129.              assume eax:PTR DRIVER_OBJECT
    130.     mov ecx, IRP_MJ_MAXIMUM_FUNCTION + 1
    131.     .while ecx
    132.     dec ecx
    133.     mov [eax].MajorFunction[ecx*(sizeof PVOID)], offset DriverDispatch
    134.     .endw
    135.              mov [eax].DriverUnload, offset DriverUnload
    136.              assume eax:nothing
    137. ;;;     invoke QueryValueKey
    138.         invoke IoAttachDeviceToDeviceStack, KeyDeviceObject, pTargetDeviceObject   
    139.                 .if eax != NULL
    140.  
    141.                     mov edx, eax
    142.  
    143.                     ; Fill filter device object extension
    144.  
    145.                     mov ecx, KeyDeviceObject
    146.                     mov eax, (DEVICE_OBJECT ptr [ecx]).DeviceExtension
    147.                     assume eax:ptr FiDO_DEVICE_EXTENSION
    148.                     mov [eax].pNextLowerDeviceObject, edx
    149.                     push pTargetFileObject
    150.                     pop [eax].pTargetFileObject
    151.                     assume eax:nothing
    152.  
    153.                     assume edx:ptr DEVICE_OBJECT
    154.                     assume ecx:ptr DEVICE_OBJECT
    155.  
    156.                     mov eax, [edx].DeviceType
    157.                     mov [ecx].DeviceType, eax
    158.  
    159.                     mov eax, [edx].Flags
    160.                     and eax, DO_DIRECT_IO + DO_BUFFERED_IO + DO_POWER_PAGABLE
    161.                     or [ecx].Flags, eax
    162.                     and [ecx].Flags, not DO_DEVICE_INITIALIZING
    163.                     assume edx:nothing
    164.                     assume ecx:nothing
    165.  
    166.                     mov status, STATUS_SUCCESS
    167.  
    168.                 .else       ; IoAttachDeviceToDeviceStack failed
    169.  
    170.                     ; We have failed to attach
    171.  
    172.                     invoke ObDereferenceObject, pTargetFileObject
    173.                
    174.                     invoke IoDeleteDevice, KeyDeviceObject
    175.                     and KeyDeviceObject, NULL
    176.  
    177.                     ; Let the driver to be unloaded
    178.        
    179.                     mov eax, pDriverObject
    180.                     mov (DRIVER_OBJECT PTR [eax]).DriverUnload, offset DriverUnload
    181.                     mov status, STATUS_NO_SUCH_DEVICE
    182.  
    183.                 .endif
    184.              mov status, STATUS_SUCCESS
    185.          .else
    186.              invoke IoDeleteDevice, KeyDeviceObject
    187.          .endif
    188.      .endif
    189.  
    190.      mov eax, status
    191.  
    192. ret
    193.  
    194. DriverEntry endp
    195.  
    196.  
    197.  end DriverEntry
    Подскажите, пожалуйста, что здесь не так.
     
  2. TSS

    TSS New Member

    Публикаций:
    0
    Регистрация:
    13 апр 2009
    Сообщения:
    494
    Проблема скорее всего в pending irp. Код не смотрел =]
     
  3. Llirik

    Llirik Member

    Публикаций:
    0
    Регистрация:
    18 июл 2008
    Сообщения:
    471
    А можно по подробнее?)
     
  4. TSS

    TSS New Member

    Публикаций:
    0
    Регистрация:
    13 апр 2009
    Сообщения:
    494
    Если вкратце, то для примера возьмем какой-нибудь i8042prt.

    После того как в ISR создастся DPC, а в ней вызовется колбек Keyboard Class Driver'a, заполнится очередь уже класс драйвера, и далее IRP_READ присланный RIT'ом задерживается пока не будет заполнен сканкодами. И только после этого irp завершится класс драйвером клавиатуры. Если в этот момент выгрузить фильтр, то заполненный irp улетит обратно в никуда( фильтр то выгружен ). Решение этой проблемы публиковалось на rootkits.com если ничего не путаю.
     
  5. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    код ошибки случаем не DRIVER_UNLOADED_WITHOUT_CANCELLING_PENDING_OPERATION ?
     
  6. Llirik

    Llirik Member

    Публикаций:
    0
    Регистрация:
    18 июл 2008
    Сообщения:
    471
    Спасибо. Я учёл Ваш совет и немного переделал код, но проблема была вот в этом:
    mov eax, KeyDeviceObject
    and KeyDeviceObject, NULL
    invoke IoDeleteDevice, eax
    Я зачем-то пытался удалить KeyboardClass0)))
    Но, у меня есть ещё один вопрос. Как отключить от стека устройство не находящееся на его вершине?
     
  7. tchunya

    tchunya New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2008
    Сообщения:
    29
    Гы! Никак