Проблемы с IoCallDriver

Тема в разделе "WASM.BEGINNERS", создана пользователем Svarov, 29 мар 2010.

  1. Svarov

    Svarov New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2010
    Сообщения:
    5
    Здравствуйте!

    Пытаюсь написать драйвер, который просто пересылал бы код управления (IOCTL) нижележащему драйверу.
    Вроде делаю по шаблону, который взял с этого же могучего сайта (не помню в какой теме это было), но почему-то все зарывается на вызове API IoCallDriver.

    Вот код:
    Код (Text):
    1. *Includes*
    2. .data
    3. ;===Variables===
    4. TargetDevName dw '\','D','e','v','i','c','e','\','U','S','B','F','D','O','-','0',0h
    5. dbg_err db "Error!",0dh,0h
    6. format db '%S',0h
    7. ctrl_code dd 0
    8. ;===END===
    9.  
    10. .code
    11. DriverEntry proc pDriverObject:DRIVER_OBJECT, pusRegistryPath:UNICODE_STRING
    12.  
    13. Call OpenFile
    14.  
    15. mov eax,STATUS_DEVICE_CONFIGURATION_ERROR
    16. Ret
    17. DriverEntry endp
    18.  
    19. ;==============================PROCEDURES====================
    20. OpenFile proc
    21. local unstruc:UNICODE_STRING
    22. local p_iosb:IO_STATUS_BLOCK
    23. local p_devobj:DEVICE_OBJECT
    24. local p_irpstr:_IRP
    25. local p_event:KEVENT
    26. local p_fo:FILE_OBJECT
    27. local irpvar:DWORD
    28.  
    29. invoke RtlInitUnicodeString,addr unstruc,offset TargetDevName
    30.  
    31. Invoke DbgPrint,offset format,unstruc.Buffer;юникод-строка нормальная
    32.  
    33. Invoke IoGetDeviceObjectPointer,addr unstruc,SYNCHRONIZE+FILE_ALL_ACCESS,addr p_fo,addr p_devobj
    34.  
    35. mov dword ptr [dbg_err+1],eax
    36. Invoke DbgPrint,offset dbg_err;в eax STATUS_SUCCESS
    37.  
    38. invoke KeInitializeEvent,addr p_event,NotificationEvent,0
    39.  
    40. mov ctrl_code,00220444h
    41.  
    42. invoke IoBuildDeviceIoControlRequest,ctrl_code,addr p_devobj,0,0,0,0,0,addr p_event,addr p_iosb
    43. mov irpvar,eax
    44.  
    45. mov dword ptr [dbg_err+1],eax
    46. invoke DbgPrint,offset dbg_err;в eax указатель на IRP пакет
    47.  
    48. invoke IoCallDriver,addr p_devobj,irpvar; вот здесь система падает. BSOD 0x0000007E (0xC0000005,0x001200A0,0xF7A269CC,0xF7A266C8)
    49. mov dword ptr [dbg_err+1],eax
    50. Invoke DbgPrint,offset dbg_err
    51.  
    52. cmp eax,STATUS_PENDING
    53. je Wait
    54. jmp Next
    55. Wait:
    56. invoke KeWaitForSingleObject,addr p_event,Executive,KernelMode,0,0
    57.  
    58. Next:
    59. mov eax,0
    60. mov eax,p_iosb.Status
    61. mov dword ptr [dbg_err+1],eax
    62. Invoke DbgPrint,offset dbg_err
    63.  
    64. endproc:
    65. invoke ObDereferenceObject,addr p_fo
    66. ret
    67. OpenFile endp
    68.  
    69. end DriverEntry
    Никак я самостоятельно не могу понять в чем же причина... Очень большая просьба подсказать где я намудрил.
    Честно признаюсь это моя первая попытка написать драйвер, до этого были только простенькие юзерские приложения, так что не судите строго. Я ассемблер-то начал изучать всего полгода назад...
     
  2. JCronuz

    JCronuz New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2007
    Сообщения:
    1.240
    Адрес:
    Russia
    Код (Text):
    1. NTSTATUS
    2.   IoCallDriver(
    3.     IN PDEVICE_OBJECT  DeviceObject,
    4.     IN OUT PIRP  Irp
    5.     );
    PIRP надо передавать, так
    Код (Text):
    1. invoke IoCallDriver,addr p_devobj,addr irpvar
     
  3. Svarov

    Svarov New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2010
    Сообщения:
    5
    Нет, так тоже не получается. На том же месте вылетает в STOP ошибку: NO_MORE_IRP_STACK_LOCATIONS 0x00000035 (0xF7A22AB8,0x000000.....).

    У меня в irpvar уже указатель на заполненный irp-пакет полученный после вызова IoBuildDeviceIoControlRequest, так зачем же на него еще и addr делать?
     
  4. C2H5OH

    C2H5OH New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2008
    Сообщения:
    42
    Чет ты перемудрил
    Код (Text):
    1. pIrp PIRP NULL
    2. ...
    3. invoke IoBuildDeviceIoControlRequest,
    4. mov pIrp,eax
    5. .if eax == NULL
    6.     mov status ,STATUS_INSUFFICIENT_RESOURCES
    7.     jmp exit
    8. .endif
    9. invoke IoCallDriver,devobj, pIrp
    Нормально все работает...
     
  5. JCronuz

    JCronuz New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2007
    Сообщения:
    1.240
    Адрес:
    Russia
    Да. Не увидел.
     
  6. Svarov

    Svarov New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2010
    Сообщения:
    5
    *Со вздохом* Да вроде действительно должно работать, на msdn'е есть такой же пример только на СИ и вместо USB там подключаются к PCI.

    Наблюдение:
    У меня перед вызовом IoGetDeviceObjectPointer структура DEVICE_OBJECT имеет какие-то непонятные данные. Интересно это так и должно быть? Я думал все неинициализированные структуры заполняются нулями.

    Ладно, попробую составить IRP вручную.
     
  7. Svarov

    Svarov New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2010
    Сообщения:
    5
    Ни фига ничего не выходит. Но по-крайней мере я понял что проблема, скорее всего, в неправильно составленном IRP.

    У меня уже такая каша в голове со всеми этими IRP и прочим, я уже и не знаю что пробовать.
    Вот пример с msdn'а: http://support.microsoft.com/kb/256161
    Делал по аналогии.

    Может все-таки кто-нибудь подскажет, где я ошибся? Буду просто сверхпризнателен :)
     
  8. Svarov

    Svarov New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2010
    Сообщения:
    5
    Все, разобрался. Проблема была в том, что IoGetDeviceObjectPointer некорректно заполнял структуру DEVICE_OBJECT. Сделал через ZwOpenFile-ObReferenceObjectByHandle-IoGetRelatedObject и все заработало.

    У меня остался последний вопрос:
    Как мне послать физическому устройству (например USB-хабу) IOCTL_INTERNAL запрос? Получается надо послать запрос драйверу шины (usbd), а вот как это реализовать?