Как из драйвера получить текущую раскладку клавиатуры (LCID)

Тема в разделе "WASM.WIN32", создана пользователем Guest, 8 сен 2006.

  1. Miller Rabin

    Miller Rabin New Member

    Публикаций:
    0
    Регистрация:
    4 янв 2006
    Сообщения:
    185
    И все-таки код не работает. В режиме пользователя вызов функции по int 2E проходит прекрасно, вызов же из драйвера заканчивается бсодом.

    Какое еще условие должно быть выполнено?
     
  2. rain

    rain New Member

    Публикаций:
    0
    Регистрация:
    22 апр 2006
    Сообщения:
    976
    вовсе нет, как по номеру получить ссылку? да очень просто в KeServiceDescriptorTable есть SerivceTable - массив из функций указателей, всё что нужно это взять дворд по смещению id*4 (в х64 ещё нада добавить офсет самой таблици сервисов), кроме того для W32pServiceTable у id нада отбросить всё что старше 0xfff. В этом нет ничего сложного это подробно расписано во многих источниках
    ну это уже вы что-то намудрили, в ядре (w2k) есть функции Zw переходники которые работают именно через int 2eh и если бы они не работали...
     
  3. Miller Rabin

    Miller Rabin New Member

    Публикаций:
    0
    Регистрация:
    4 янв 2006
    Сообщения:
    185
    Хм. Вот такой код
    Код (Text):
    1. __declspec(naked) KiStubCall()
    2. {
    3.     __asm
    4.     {
    5.         lea edx,[esp+4]
    6.         int 0x2E
    7.         retn 2*4
    8.     }
    9. }
    10.  
    11. ULONG GetKeyboardLayout(ULONG ThreadId)
    12. {
    13.     __asm
    14.     {
    15.         push 28h
    16.         push ThreadId
    17.         mov eax, 1143h
    18.         call KiStubCall
    19.     }
    20. }
    В приципе ничем не отличается от приводимого ранее.
    Дальше в DriverEntry вызываю GetKeyboardLayout(ThreadID) ThreadID беру у Notepad.exe. И получаю бсод.
    Вызываю эту же функцию из режима пользователя и получаю текущую раскладку указанного потока.

    Я и сам понимаю что это какой-то глюк. Но что я упустил?
     
  4. rain

    rain New Member

    Публикаций:
    0
    Регистрация:
    22 апр 2006
    Сообщения:
    976
    Это не глюк. Скорее всего упущенно то что вы вызываете этот код из обычного ядерного потока.
    Коротко в системе есть 2 типа потоков одни ГУЁвые вторые нет, в ядре существеут неэкспортируемая функция конвертирования потоков PsConvertToGuiThread, найти её я незнаю как. Отличия потоков:
    - KTHREAD.SystemService = KeServiceDescriptorTableShadow (в х86, в х64 другие поля)
    - в АП промапленные у них гуевые библиотеки (хотя если юзить int 2eh а не напрямую вызывать их по адресам то пофигу)
    - превиус мод обычно у них юзермод
    - расширенный стек
    - .. ещё что-то уже не помню
    короче в сети можно найти её сорци

    Зачастую в некоторых юзер функциях просто чекаются адреса передаваемые им адреса с помошью ProbeForWrite/Read соответственно частный случай обхода этого всего состоит просто в банальном RtlAllocateHeap и передача адресов из юзерского пространства функциям, но если функция проверяет что-то больше чем это то тут ессесно мы обламываемся. Я до конца ещё не разобрался как замутить нормальный гуевый поток по уму.

    Обычно поступают проще просто хукают юзерские функции, при чём получают уже готовые нормальные ГУЁвые потоки и делают нужные манипуляции там.

    Короче 2 выхода:
    - нахождение и вызов функции напрямую а не через int23h (не во всех случаях)
    - хук какой-нить какой нить функции и выполнение этой работы там
     
  5. Miller Rabin

    Miller Rabin New Member

    Публикаций:
    0
    Регистрация:
    4 янв 2006
    Сообщения:
    185
    Да что же это такое получается
    Дык в чем же тогда заключается решение? Как тогда получить из драйвера раскладку клавиатуры потока активного окна?
     
  6. Miller Rabin

    Miller Rabin New Member

    Публикаций:
    0
    Регистрация:
    4 янв 2006
    Сообщения:
    185
    А если заменить IA32_SYSENTER_EIP?

    mov ecx, 0x176
    rdmsr
    mov [OriginalSysEnterEip], eax
    mov eax, MySysEnterEipDispatch
    wrmsr

    proc MySysEnterEipDispatch
    Здесь вызываем нашу GetKeyboardLayout
    и получаем раскладку клавиатуры
    jmp [OriginalSysEnterEip]
    ret
    endp

    Сам допер :)
     
  7. rain

    rain New Member

    Публикаций:
    0
    Регистрация:
    22 апр 2006
    Сообщения:
    976
    мы поклоняемся тебе о великий! напиши статью

    Только имей в виду что поток там может быть ещё не гуёвый так что вероятной поймать бсод имеется
     
  8. Miller Rabin

    Miller Rabin New Member

    Публикаций:
    0
    Регистрация:
    4 янв 2006
    Сообщения:
    185
    Написать статью говоришь. А это мысль :) Я начну готовить материал. Посмотрим что получится.