Перехват обработчика прерывания

Тема в разделе "WASM.NT.KERNEL", создана пользователем diombre, 31 мар 2009.

  1. diombre

    diombre New Member

    Публикаций:
    0
    Регистрация:
    18 янв 2009
    Сообщения:
    18
    Доброго времени суток!

    1. Перехватывается обработчик прерывания IRQ8 в WindowsXP. Каким образом корректно подменить
    регистры, сохраненные в стеке, чтобы после возврата из обработчика начал выполняться
    мой user-mode код? И ещё
    2. Как выйти из моего обработчика корректно, не передавая управления
    оригинальному обработчику тем самым не запуская процесс переключения контекстов
    в Винде (вроде как iretd но почему-то не работает).
     
  2. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Расплывчатый вопрос.
    1. Какой твой юзермодный код ??
    DPL(CS) не известно заранее. Прерывание в контексте любого процесса произойти может..
    2. Восстановить всё, что было изменено(например сегментные регистры, стек). Обычно планировщик запускается по выходу из прерывания в HalEndSystemInterrupt().
     
  3. diombre

    diombre New Member

    Публикаций:
    0
    Регистрация:
    18 янв 2009
    Сообщения:
    18
    Пытаюсь сделать вот что. В обработчике определяю, какой код выполнял процессор
    в момент наступления прерывания r0 или r3 (при помощи анализа сохраненных в
    стеке cs и flags. Если r0 - то ничего не делаю и передаю управление
    оригинальному обработчику. Если r3 - то по fs:[0x20] (TEB) определяю ID процесса
    и если это мой процесс то заменяю значение eip в стеке на адрес процедуры в контексте
    главного потока моего процесса.
    Процедура-то вызывается, но: хотелось бы, во-первых, передавать управление моей процедуре таким образом из любого контекста, в котором сработало прерывание и, во-вторых, не дать
    Windows переключить задачу на время выполнения (1-2 тика таймера) user-mode процедуры.
    Есть у кого мнение на этот счет?
    Прошу прощения за сумбур :)
     
  4. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Во первых процесс нужно определять через ядерные структуры, виртуальная память выгружаемая, дабы избежать голубого огонька следует вызвать PsGetCurrentProcessId(), либо из ETHREAD.Cid считать вручную.
    Значит тебе нужно переключить адресное пространство, тоесть аттачиться к необходимому процессу.
    Планировщик вызывается не только по таймеру. Все их запрети(cli) и планирование выполняться не будет. Только в этом случае не будет вызван менеджер памяти при возникновении исключения(для подкачки), также нельзя будет обращаться к системе, вызывая сервисы, даже стек наверно расширен не будет при срабатывании сторожевой страницы..
    Вобжем так не делается, нельзя выполнять юзермодный код с запрещёнными прерываниями.
     
  5. Zufyxe

    Zufyxe New Member

    Публикаций:
    0
    Регистрация:
    13 авг 2004
    Сообщения:
    137
    Адрес:
    Russia
    Верно, в Винде нет никакой возможности позволить юзермодному thread-у гарантировано не быть вытесненым втечение какого-то промежутка времени.
     
  6. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Zufyxe
    Ошибаешся, блокировать планирование не проблема, другое когда код с DPL=3 вызывается на высоких IRQL.
     
  7. Zufyxe

    Zufyxe New Member

    Публикаций:
    0
    Регистрация:
    13 авг 2004
    Сообщения:
    137
    Адрес:
    Russia
    Поделись, пожалуиста, как сделать, чтобы мой "хелловорлд" гарантировано отработал одну секунду и не был ничем вытеснен.
    Варианты на тему "пропатчить ядро" и "есть такое недокументированное поле" не предлагать.
     
  8. SashaTalakin

    SashaTalakin New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2008
    Сообщения:
    261
    Для начала надо знать что это за код. Может быть он в принципе не может не быть не вытеснен.
     
  9. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Zufyxe
    Знаешь ли, ядро не расчитано чтоб юзать "вторичный" код прямо из аппаратных ISR. И документированной функции KiDisableSwapContext ты не найдёшь :lol:
    Пошли DPC и уже из него когда IRQL будет понижен бокси мессагу, например через ядерный калбэк, или в классическом варианте APC поставь в очередь.
     
  10. Zufyxe

    Zufyxe New Member

    Публикаций:
    0
    Регистрация:
    13 авг 2004
    Сообщения:
    137
    Адрес:
    Russia
    SashaTalakin, Мы не рассматриваем код, который периодически чего-то там ждет (если ты об этом). Скажем, есть некая "математика" в юзермоде, есть драйвер.
    Я лично, утверждаю в 5-м посте, что в ОС Виндовз нету легитимной возможности гарантировать, что наша "математика" будет считаться на процессоре какое-то разумное время N, и за этот период не будет вытеснена. Нету таких средств.
    Конечно, можно похучить несколько функций диспатчера и запретить вытеснять определенный thread. Но это будет сложное, и сильно зависимое от версии и архитектуры системы, решение.
    Вполне возможно, что я не прав, и что-то упустил: именно это и хотелось бы услышать.

    Clerk, я не особо много понял из твоего поста.
    В особенно непонятно про "Пошли DPC и уже из него когда IRQL будет понижен...".
    Когда это при обработке DPC понижается IRQL?
    Полностью согласен с тобой на счет того, что вызывать узермодный код на высоком IQRL, - полный ахтунг :)
     
  11. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Zufyxe
    DPC доставляется когда происходит понижение IRQL до DISPATCH_LEVEL. А в аппаратных прерываниях IRQL слишком высокий, на котором высокоуровневый функционал ядра не доступен. Повторяю, напрямую вызвать юзермодный код ты можешь, например закрепив страницу в памяти и передать через Iret на неё управление, но максимум что ты можешь сделать там - это выполнить код не выходящий за пределы этой страницы и не вызывая сервисы(не обращаясь к ядру), например просто увеличить значение какихто счётчиков и вернуться.
     
  12. Zufyxe

    Zufyxe New Member

    Публикаций:
    0
    Регистрация:
    13 авг 2004
    Сообщения:
    137
    Адрес:
    Russia
    Это я знаю прекрасно, и понимаю :)
    Просто не верно понял твою фразу.

    Спор то о другом. См. 5-й пост :)
     
  13. diombre

    diombre New Member

    Публикаций:
    0
    Регистрация:
    18 янв 2009
    Сообщения:
    18
    Всем большое спасибо!
    Действительно, так просто передать управление на юзер-моду не получится в Windows:)
    Спасибо Clerk направил на путь истинный.
    Зреет вопрос: как из-под юзверя залочить память чтобы не свопилась? и чтобы её драйвер "видел"?
    Но это уже совсем другая история ...
     
  14. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Код (Text):
    1. NTSTATUS
    2. NtLockVirtualMemory(
    3.     __in HANDLE ProcessHandle,
    4.     __inout PVOID *BaseAddress,
    5.     __inout PSIZE_T RegionSize,
    6.     __in ULONG MapType
    7.     )
    8.  
    9. /*++
    10.  
    11. Routine Description:
    12.  
    13.     This function locks a region of pages within the working set list
    14.     of a subject process.
    15.  
    16.     The caller of this function must have PROCESS_VM_OPERATION access
    17.     to the target process.  The caller must also have SeLockMemoryPrivilege.
    18.  
    19. Arguments:
    20.  
    21.    ProcessHandle - Supplies an open handle to a process object.
    22.  
    23.    BaseAddress - The base address of the region of pages
    24.                  to be locked. This value is rounded down to the
    25.                  next host page address boundary.
    26.  
    27.    RegionSize - A pointer to a variable that will receive
    28.                 the actual size in bytes of the locked region of
    29.                 pages. The initial value of this argument is
    30.                 rounded up to the next host page size boundary.
    31.  
    32.    MapType - A set of flags that describe the type of locking to
    33.              perform.  One of MAP_PROCESS or MAP_SYSTEM.
    34.  
    35. Return Value:
    36.  
    37.     NTSTATUS.
    38.  
    39.     STATUS_PRIVILEGE_NOT_HELD - The caller did not have sufficient
    40.                                 privilege to perform the requested operation.