Механизм обработки прерываний в NT

Тема в разделе "WASM.BEGINNERS", создана пользователем Sholar, 4 фев 2012.

  1. Sholar

    Sholar New Member

    Публикаций:
    0
    Регистрация:
    16 окт 2011
    Сообщения:
    189
    Никак не могу разобраться с механизмом обработки прерываний в NT. Руссинович утверждает, что адресс сопоставленный в IDT с конкретным прерыванием указывает на код диспетчирезации, копирующийся при создании объекта прерывания в буфер KINTERRUPT::lol: ispatchCode из KiInterruptTemplate:
    [​IMG]
    Далее управление должно передаваться в KiInterruptDispatch или KiChainedDispatch, которые в свою очередь передают его конкретной ISR. Но эксперименты с трассировкой различных прерываний показали, что
    1) Начало "кода диспетчирезации" у разных прерываний может быть одинаковым или разным
    2) Ни в одном из случаев это не код из KiInterruptTemplate.
    Подскажите, чего я не понял, или понял не правильно в словах Руссиновичи и как со всем этим хозяйством разобраться.
     
  2. Sholar

    Sholar New Member

    Публикаций:
    0
    Регистрация:
    16 окт 2011
    Сообщения:
    189
    UP
    Неужели никто не может сказать, где зарыта собака? Кстати, некоторые прерывания вообще не трассируются: после нажатия F8 на инструкции, к примеру int 11h(мышь), Syser просыпаетсся где-то в районе RtlExitUserThread
     
  3. PSR1257II

    PSR1257II New Member

    Публикаций:
    0
    Регистрация:
    25 июн 2011
    Сообщения:
    228
    Sholar

    // Не силен в этой NT

    Вы как-то имхо странновато трассируите: зовете int (из User-mode?!) вместо честно поставленного bpx/bpm x (SoftIce) на элемент из idt и аппаратного прерывания (шевелите мышь если вам нужна мышь).

    User-mode int'ы с большой вероятностью будут проэмулированы/проскипаны на другом уровне.
     
  4. Sholar

    Sholar New Member

    Публикаций:
    0
    Регистрация:
    16 окт 2011
    Сообщения:
    189
    Да, я просто писал int 3h/ int XXh и запускал это на выполнение. Сделал так, как вы говорите, если поставить бряк на обработчик мыши или клавиатуры, то это не срабатывает, а вот, к примеру, c int 2Eh работает. Но int 2Eh я мог и так трассировать старым способом. Возможно Syser не хочет трассировать аппаратные прерывания. Но трассировка обработчика в отладчике мне на самом деле ничего не дает(ибо вообще мало что там понимаю), интересует как и через какие обработчики проходит программа(ведь должен сохраняться трап-фрейм и т.д.?). Вот в книге Руссиновича, как я писал выше, говорится о том, что при любом прерывании сначала должен выполняться код диспетчирезации, скопированный из KiInterruptTemplate, но ни один из обработчиков не содержит ничего подобного.
     
  5. Sholar

    Sholar New Member

    Публикаций:
    0
    Регистрация:
    16 окт 2011
    Сообщения:
    189
    Двойной пост. Del
     
  6. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    PSR1257II
    Не выйдет при входе в прерывание все другие прерывания запрещаются. Единственный метод это трассировка int при условии, что отладчик умеет эмулировать int иначе опять таки прерывания будут запрещены.

    Так что дизассемблер в руки и вперёд изучать развилки.

    Sholar
    Отладчик вещь хорошая, но я человек ленивый и посмотрел бы в исходных кодах.

    Даже близко не мышь. Во-вторых явная путаница IRQ и INT.
     
  7. TSS

    TSS New Member

    Публикаций:
    0
    Регистрация:
    13 апр 2009
    Сообщения:
    494
    На самом деле трассировать можно, просто это надо делать после того, как сформирован трап фрейм и разрешены прерывания.
     
  8. Sholar

    Sholar New Member

    Публикаций:
    0
    Регистрация:
    16 окт 2011
    Сообщения:
    189
    Точно.

    Смотрю уже третьи сутки, изучил огромное количество кода, но до "того самого" докопаться не могу. В данный момент смотрю KeConnectInterrupt/KeDisconnectInterrupt в WRK.
    Подскажите где именно изучать, к примеру, как называется обработчик того же int 2Eh?
     
  9. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Sholar
    В WRK обработчики прерываний находятся в файле trap.asm (их два, для 32битного и 64битного режима). Например, для int 0x2E есть обработчик:

    IDTEntry _KiSystemService, D_INT332 ;2E: system service calls

    В общем, начать, думаю, стоит с этого файла.
     
  10. Sholar

    Sholar New Member

    Публикаций:
    0
    Регистрация:
    16 окт 2011
    Сообщения:
    189
    Посмотрел этот обработчик, создается трап-фрейм и совершается прыжок в KiFastCallEntry, ранее изученную досконально. То есть никаких KiInterruptTemplate или KiInterruptDispatch. Пришла в голову мысль, что я жестко туплю и все написанное в #1 относится только к аппаратным прерываниям. Можно ли как-то узнать, за каким устройством закреплено конкретное прерывание? Отладчик эту инфу не показывает.
     
  11. TSS

    TSS New Member

    Публикаций:
    0
    Регистрация:
    13 апр 2009
    Сообщения:
    494
    Отладчик все прекрасно показывает:

    Код (Text):
    1. kd> !idt
    2.  
    3. Dumping IDT:
    4.  
    5. 37: 806d1728 hal!PicSpuriousService37
    6. 3d: 806d2b70 hal!HalpApcInterrupt
    7. 41: 806d29cc hal!HalpDispatchInterrupt
    8. 50: 806d1800 hal!HalpApicRebootService
    9. 62: 81780404 atapi!IdePortInterrupt (KINTERRUPT 817803c8)
    10. 63: 815a2044 USBPORT!USBPORT_InterruptService (KINTERRUPT 815a2008)
    11. 73: 817aa664 SCSIPORT!ScsiPortInterrupt (KINTERRUPT 817aa628)
     
  12. Sholar

    Sholar New Member

    Публикаций:
    0
    Регистрация:
    16 окт 2011
    Сообщения:
    189
    Кажется Syser такую информацию не выдает.
     
  13. totimoud

    totimoud New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2012
    Сообщения:
    78
    Чтоб трейсить IRQ нужно воспользоваться windbg.

    А Int в юзермодах, какой нить инвалидный(или на который прав не хватает), к примеру диспетчер IPI(0xE1) дёрнуть не получится. Это приведёт к срабатыванию защиты и будет вызвано системное исключение(#GP), далее вы попадается в системный диспетчер исключений(KiTrap0D() -> STATUS_ACCESS_VIOLATION).
     
  14. Sholar

    Sholar New Member

    Публикаций:
    0
    Регистрация:
    16 окт 2011
    Сообщения:
    189
    Трассирую сисером прерывание 0xE1, в KiTrap0D не попадаю, управление передается на адресс указаный в IDT
     
  15. totimoud

    totimoud New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2012
    Сообщения:
    78
    Sholar
    И как вы его вызываете, в смысле прерывание ?

    Это не INT, а IRQ. Есть есчо тип векторов - исключения. IRQ хардварно вызываются, а не через INT из ядра. Хотя эмулировать вызов можно.
     
  16. Sholar

    Sholar New Member

    Публикаций:
    0
    Регистрация:
    16 окт 2011
    Сообщения:
    189
    Код (Text):
    1. .code
    2.    start:
    3.         int 3h
    4.         int 0E1h
    5.    .end start
    Отладчик всплывает на int 0E1h, дальше жму F8
    Хмм, то есть потрейсить код, который выполняется при хардверном прирывании у меня не получится?
     
  17. PSR1257II

    PSR1257II New Member

    Публикаций:
    0
    Регистрация:
    25 июн 2011
    Сообщения:
    228
    Pavia

    Отладчегу должно быть пофигу на все остальные прерывания (если только его собственные - int 1/3 в случае bpx == int 3 или bpm X == int 1 не вырублены).

    При входе (например) в мышиное IRQ N запрещаются только все менее приоритетные, e.g. >N. Клава и таймер должны работать. Фактически ставя bmp/bpx на элемент idt вы просто ставите jmp Debugger. Если перехваченное прерывание используется отладчегом - тогда да, он повиснет но он всплывет. Sice работал у меня. Единственное что винда может перезагрузить idt и тогда вы не увидите никакого прерывания. Или если обработчик делает cli а вы поставили bpx после.

    Sholar

    By my humble opinion you should start your research from Processor architechture (e.g. idt, interrupts, etc) and only after some express study try some Windows-related features.
     
  18. totimoud

    totimoud New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2012
    Сообщения:
    78
    Sholar
    Попробуйте в олли это заюзать. Сиська это если и вызывает, то вызывает in silico. Защита не позволяет такое дёргать, у вас нет прав на это(CPL/IOPL). Там в дескрипторе указан !DPL, посему такие вектора не доступны в юзермоде.
     
  19. PSR1257II

    PSR1257II New Member

    Публикаций:
    0
    Регистрация:
    25 июн 2011
    Сообщения:
    228
    Sholar

    Процессор при получении хардварного прерывания извлекает соответствующий ему элемент из таблицы idt и передает ему управление. Оформляется контекст нулевого уровня (стек - ядерный и так далее) и процессор работает в ring0. Все попытки вызывать прерывание программно не из нулевого кольца приводят к исключению защиты (примерно, нужно глянуть мануал) и обрабатываются соответствующим обработчиком системы а вовсе не соответствующим элементом из idt.

    int 2Eh (Windows) или int 80h (Linux) - специально оговоренный интерфейс ядра для связи с пользовательскими приложениями. Поэтому вы иногда (для некоторых прерываний) можете "программно" их "трассировать".

    Если хотите трассировать программно вызванное - пишите себе sys-драйвер и уже зовите из 0-кольца (или ищите соответствующий ядерный интерфейс как заметили выше).
     
  20. Sholar

    Sholar New Member

    Публикаций:
    0
    Регистрация:
    16 окт 2011
    Сообщения:
    189
    Всем спасибо. Попробую таки вариант с драйвером.