"Общение" драйвера с Юзермодным приложением

Тема в разделе "WASM.NT.KERNEL", создана пользователем dr_ivers, 21 мар 2007.

  1. dr_ivers

    dr_ivers New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2007
    Сообщения:
    17
    День добрый, товарищи!
    Такой вопрос, у меня драйвер-перехватчик открытия файлов(ntCreateFile, перехват через SDT).
    Он должен фильтровать обращения юзеров к определенным файлам, но критерии фильтра в самом драйвере не находятся. Все уславия и проверки должны выполняться в Юзермодном приложении.

    А теперь вопрос: как можно обеспечить двустороннее "общение" между этими программами?
    Т.е:
    - драйвер перехватил открытие файла (это есть);
    - получил его имя (есть)
    - передал его юзермодномe апп (сейчас это реализовано через Event(CreateEvent, etc))
    - получил ответ от апп, в котором сказано: блокируем или нет (нету :dntknw: )
    - шуруем дальше (есть :))

    Вот собственно и все. Передача данных от драйвера в приложение реализовано по примеру статьи Four-F "Драйверы режима ядра: Часть 14: Базовая техника. Синхронизация: Использование объекта /03.08.04/" (Thnx).

    Буду рад любой помощи, но хотелось бы по-существу ;)
     
  2. slow

    slow New Member

    Публикаций:
    0
    Регистрация:
    27 дек 2004
    Сообщения:
    615
    А через IOCTL свои не пойдет?
     
  3. dr_ivers

    dr_ivers New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2007
    Сообщения:
    17
    Я просто не знаю возможно ли такое. Ведь я могу из-под своего обработчика ntCreateFile установить Event и апп заберет новые данные, но чем в это время должен заниматься сам обработчик? Ведь он должен еще каким-то макаром получить ответ.
    Будет ли все это работать параллельно(обработчик ntCreateFile и рабочая процедура обработки IRP)?
    Если да, тогда можно ставить какие-то задержки в ntCreateFile.
    Как тут лучше поступить? И как все это счастье будет работать в условиях паралелльно работающих нескольких процессов, работающих с файлами...
     
  4. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Использовать общую область памяти - ядро выделяет ядерную неподкачиваемую память и проецирует вторую проекцию на пользовательское пространство.
    Сделать в памяти так - один бит - будет Present-бит и означать то, что информация готова. Остальная часть памяти будет хранить информацию. Пользовательский процесс ждет установки бита P и сразу считывает информацию из этой области. А драйвер записывает информацию в буфер и выставляет бит P.
    Вообщем, простейшие еденицы синхронизации
     
  5. dr_ivers

    dr_ivers New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2007
    Сообщения:
    17
    Понятно. Вот только я немного торможу от фразы

    Можешь немного разъяснить? Я с этим знаком плехо-плехо...
     
  6. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    ExAllocatePoolWithTag - выделение памяти ядра, указывай пул NonPagedPool (пул неподкачиваемой памяти)

    IoAllocateMdl выделяет структуру Memory Descriptor List (MDL), необходимую для операций с проекциями областей памяти.

    MmBuildMdlForNonPagedPool заполнит структуру MDL физическими адресами страниц выделенной памяти и блокирует (возможно, я перевел немного криво, потому что слово "блокировать" обычно имеет отрицаиельный оттенок, а тут lock используется в смысле "прикреплять") область памяти.

    MmMapLockedPagesSpecifyCache создает проекцию заблокированных страниц, указывай ей тип доступа UserMode, что означает, что память будет доступна из пользовательского кода

    После этих махинаций, если драйвер запишет что-нибудь в свой указатель, который вернула ExAllocatePoolWithTag, то эта память будет доступна так же и по юзеомодному указателю, который вернет MmMapLockedPagesSpecifyCache.
    И наоборот. Таким образом память разделяется между драйвером и пользовательским процессом.
     
  7. dr_ivers

    dr_ivers New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2007
    Сообщения:
    17
    Понял. А в Апп я должен просто передать указатель.
    И еще один вопрос: как лучше организвать ожидание на драйверной стороне. Что-то мне подсказывает что никакие Слипы там не пройдут
     
  8. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    dr_ivers
    Event
     
  9. dr_ivers

    dr_ivers New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2007
    Сообщения:
    17
    Это ты к ожиданию?
    Т.е. Event и WaitForSingleObject?
     
  10. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.552
    Адрес:
    Russia
    dr_ivers
    Почитай Four-F (http://www.wasm.ru/article.php?article=drvw2k09)
    и вообще заучи все его статьи , там основа. И тогда этот вопрос бы отпал .
     
  11. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    dr_ivers
    да
     
  12. dr_ivers

    dr_ivers New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2007
    Сообщения:
    17
    Все, всем спасибо за разъяснение.
     
  13. Cr4sh

    Cr4sh New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2006
    Сообщения:
    668
    а ещё через пайп можно =)
     
  14. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    а еще можно создать объект Section и его проецировать. вариантов много вообще +)
     
  15. dr_ivers

    dr_ivers New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2007
    Сообщения:
    17
    Страннейшее дело...
    Создаю область памяти так как объяснил Great (thankx).
    Дальше записываю туда к примеру "TestString" (используя wcscpy()).
    Выводим через DPRINT по кернеловскому указателю - все Ок, наша строка.
    В Апп (на Visual Basic :)) принимаю указатель на юзерспейс-указатель и т.п. но когда пытаюсь прочесть оттуда строку получаю: "T\0e\0T\0e\0", т.е. "TeTe" в юникоде.
    Читаю используя RtlMoveMemory().

    Код драйвера:
    Код (Text):
    1. PVOID MapInUserSpace(PVOID pBuf, PMDL *pMdl, ULONG dwSize){
    2.     PVOID pUserModeBuf = NULL;
    3.     PMDL pBufMdl = NULL;
    4.  
    5.     if (!pMdl)
    6.         return NULL;
    7.     pBufMdl = IoAllocateMdl(pBuf, dwSize, FALSE, FALSE, NULL);
    8.     if (!pBufMdl)
    9.         goto exit;
    10.     MmBuildMdlForNonPagedPool(pBufMdl);
    11.     pUserModeBuf = MmMapLockedPagesSpecifyCache(pBufMdl, UserMode, MmCached, NULL, FALSE,
    12.         NormalPagePriority);
    13. exit:
    14.     *pMdl = pBufMdl;
    15.     return pUserModeBuf;
    16. }
    17.  
    18. VOID UnmapInUserSpace(PMDL pMdl, PVOID pPool, PVOID pUserModeBuf, ULONG Attrib){
    19.     if (pUserModeBuf)
    20.         MmUnmapLockedPages(pUserModeBuf, pMdl);
    21.     if (pMdl)
    22.         IoFreeMdl(pMdl);
    23.     if (pPool)
    24.         if (Attrib)
    25.             ExFreePoolWithTag(pPool, ' gaT');
    26.         else
    27.             ExFreePool(pPool);
    28. }
    29.  
    30. ....
    31. ....
    32. ....
    33.     pszBuffer=(PWSTR)ExAllocatePoolWithTag(NonPagedPool, 0x1000, ' gaT');
    34.     if (pszBuffer) {
    35.         RtlZeroMemory (pszBuffer, 0x1000);
    36.         pszUserBuffer=MapInUserSpace(pszBuffer, &pBufferMdl2, 0x1000);
    37.         RtlZeroMemory(pszBuffer, 0x1000);
    38.         wcscpy(pszBuffer, L"Test string");
    39.     }
    40. ....
    41. ....
    42. ....
    И Апп(ВБ):
    Код (Text):
    1. ReceiveBuffer=""
    2. CopyMemory Buffer(0), Driver.SharedPointer, 12
    3. For i = 0 To 11
    4.      ReceivedBuffer = ReceivedBuffer & Chr(Buffer(i))
    5. Next i
    Driver.SharedPointer - полученный от драйвера указатель на юзермодную проекцию буфера.
    CopyMemory - псевдоним RtlMoveMemory()
     
  16. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    А сорц функций взял у меня :P
    Код (Text):
    1. if (pszBuffer) {
    2.         RtlZeroMemory (pszBuffer, 0x1000);
    3.         pszUserBuffer=MapInUserSpace(pszBuffer, &pBufferMdl2, 0x1000);
    4.         RtlZeroMemory(pszBuffer, 0x1000);
    5.         wcscpy(pszUserBuffer, L"Test string");
    6.     }
    Так не пробовал?
     
  17. dr_ivers

    dr_ivers New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2007
    Сообщения:
    17
    n0name
    Да, ф-ции твои, за что тебе привеликий Thanks!
    (посик рулит)

    А что касается совета - БСОД...
    Да и не правильно это как-то...
     
  18. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    мы телепаты?) багчек код + код по адресу faulting EIP