Копирование памяти из обработчика int 1

Тема в разделе "WASM.WIN32", создана пользователем Ms Rem, 17 апр 2005.

  1. Ms Rem

    Ms Rem New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2005
    Сообщения:
    1.057
    Адрес:
    С планеты "Земля"
    Я пытаюсь в обработчике первого прерывания (генерируется аппаратно при отладке) изменить память процесса, выскакивает синий экран IRQL_NOT_LESS_OR_EQUAL.

    KeGetCurrentIrql возвращает PASSIVE_LEVEL.

    Что делать?

    мне нужно копировать вытесняемую память синхронно, я не могу использовать apc, mdl создать тоже не могу.
     
  2. CARDINAL

    CARDINAL Member

    Публикаций:
    0
    Регистрация:
    23 янв 2004
    Сообщения:
    551
    Адрес:
    Moscow
    ПРОСТО CLI, и правь свою память, потому как в обработчиках исключений аппаратно программные прерывания не запрещаются. Другого делать не советую
     
  3. Ms Rem

    Ms Rem New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2005
    Сообщения:
    1.057
    Адрес:
    С планеты "Земля"
    Я копирую вытесняемую память, которая может оказаться и в файле подкачки. На irql = PASSIVE_LEVEL система может выполнить подкачку по страничному сбою, а большем чем DISPATCH_LEVEL нет. Вот и вылетает синий экран. Понижать irql нельзя. CLI мне здесь ничего не дает.
     
  4. CARDINAL

    CARDINAL Member

    Публикаций:
    0
    Регистрация:
    23 янв 2004
    Сообщения:
    551
    Адрес:
    Moscow
    тогда есть такое понятие как dpc for isr, правда , не могу сказать, насколько данная техника здесь уместна, но, описание её есть помоему в ддк да и вообще можно поискать. Или, можно поднять irql до уровня dpc\dispatch, что бы запретить свитчинг контекстов, но, не запретить обработчик #PF и затем делать свое грязное дело
     
  5. Ms Rem

    Ms Rem New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2005
    Сообщения:
    1.057
    Адрес:
    С планеты "Земля"
    Во первых: уровень irql насколько я понял итак выше dpc\dispatch, что мне и не дает работать с памятью.

    Во вторых: dpc использовать нельзя по двум причинам: они тоже выполняются на dpc\dispatch и вызов dpc асинхронный, тоесть я могу поставить dpc в очередь, но выполнен вызов будет только после понижения irql до dpc\dispatch, а мне нужно вернуть управление из обработчика прерывания только после завершения копирования памяти. Использовать ожидание внутри обработчика прерывания не предлагать, т.к. ожидание на таком уровне irql приводит к повисанию системы.
     
  6. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    Идея извращенная, но все же я ее выскажу.



    Насколько я понял, ты втыкаешь int 1 в некий модуль, дожидаешься прерывания и копируешь некие данные из него.



    Но у тебя нет стопроцентного доступа к памяти, так как она может быть сброшена в своп или вообще не закачана (еще не было обращений), а настраивать irql и взаимодействие с драйвером файла подкачки тяжело.



    Однако если бы само приложение обратилось к эти данным непосредственно перед int 1, то таких проблем бы не было. Если бы память была бы неподгружена, то дернется page fault и система все сама подгрузит.



    Предлагаю следующее. Ты ловишь первый int 1, вставляешь сразу по адресу возврата такие команды (сохранив старые):



    mov eax,ds:CryticalData_Begin

    int 1



    Второй int 1 даст тебе управление после прочитанных данных и вроде как можно копировать...
     
  7. Ms Rem

    Ms Rem New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2005
    Сообщения:
    1.057
    Адрес:
    С планеты "Земля"
    Этот метод не годится по трем причинам:

    1) Ненадежность (никто не гарантиркет на 100%, что процесс не бкдет прерван и память не будет выгружена в файл подкачки, а значит будут появляться синие экраны при большой загрузке системы).

    2) Копирование памяти идет в сторониий процесс неожиданно для него, и я не могу его заставить подгрузить свою память в нужный момент.

    3) Прерывание вызывать с помощью комманды int 1 не получится, так как оно имеет DPL=0, можно конечно изменить DPL и тогда такой проблемы вообще не будет, но будут проблемы с запуском программ отлавливающих Soft Ice по 1 прерыванию. Я вызываю 1 прерывание путем установки аппаратного брекпоинта через DR регистры в SEH, а в обработчике прерывания сбрасываю бит трассировки.



    В общем, не все так просто как кажется. Можно было бы подгрузить память в обработчике прерывания на irql>dispatch_level, может кто-нибудь знает как?
     
  8. CARDINAL

    CARDINAL Member

    Публикаций:
    0
    Регистрация:
    23 янв 2004
    Сообщения:
    551
    Адрес:
    Moscow
    _KiTrap0D proc







    ;

    ; Did the trap occur in a VDM in V86 mode? Trap0d is not critical from

    ; performance point of view to native NT, but its super critical to

    ; VDMs. So here we are doing every thing to make v86 mode most efficient.

    ;

    test dword ptr [esp]+0ch,EFLAGS_V86_MASK

    jz Ktdi





    if FAST_V86_TRAP



    FAST_V86_TRAP_D

    endif





    KtdV86Slow:

    ENTER_TRAPV86 kitd_a, kitd_v



    KtdV86Slow2:



    ; Raise Irql to APC level, before enabling interrupts

    mov ecx, APC_LEVEL

    fstCall KfRaiseIrql

    push eax ; Save OldIrql

    sti



    stdCall _Ki386DispatchOpcodeV86

    KtdV86Exit:

    test al,0FFh

    jnz short Ktdi2



    stdCall _Ki386VdmReflectException,<0dh>

    test al,0fh

    jnz short Ktdi2

    pop ecx ; (TOS) = OldIrql

    fstCall KfLowerIrql

    jmp Kt0d105

    Ktdi2:

    pop ecx ; (TOS) = OldIrql

    fstCall KfLowerIrql

    cli

    test dword ptr [ebp]+TsEFlags,EFLAGS_V86_MASK

    jz Ktdi3



    EXIT_TRAPV86

    ;

    ; EXIT_TRAPv86 does not exit if a user mode apc has switched

    ; the context from V86 mode to flat mode (VDM monitor context)

    ;



    Ktdi3:

    jmp _KiExceptionExit



    Ktdi:

    ENTER_TRAP kitd_a, kitd_t





    ...........



    так белые люди поступают :))
     
  9. CARDINAL

    CARDINAL Member

    Публикаций:
    0
    Регистрация:
    23 янв 2004
    Сообщения:
    551
    Адрес:
    Moscow
    звиняюсь, это я про креатеров сего кода
     
  10. Ms Rem

    Ms Rem New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2005
    Сообщения:
    1.057
    Адрес:
    С планеты "Земля"
    Какой-то мутный код не имеющий отношения к этому вопросу.
     
  11. CARDINAL

    CARDINAL Member

    Публикаций:
    0
    Регистрация:
    23 янв 2004
    Сообщения:
    551
    Адрес:
    Moscow
    Ms Rem

    как раз таки и имеющий самое непосредственное :))
     
  12. _BC_

    _BC_ БЦ

    Публикаций:
    0
    Регистрация:
    20 янв 2005
    Сообщения:
    759
    Ms Rem

    Вот за что я люблю 9х -- за то что она "cracker friendly". Там таких проблем никогда не возникало. По-моему твоя проблема имеет простое решение, т.к. тот же ntice при трассировке без проблем подгружает paged-out страницы (и не теряет контроль при этом). А ntice скорее всего просто работает на IRQL <= DISPATCH_LEVEL.

    Почему бы тебе не работать на IRQL пониже, и юзать что-нибудь типа MmProbeAndLockPages ?
     
  13. _BC_

    _BC_ БЦ

    Публикаций:
    0
    Регистрация:
    20 янв 2005
    Сообщения:
    759
    Вообще с точки зрения винды это твое обращение из int1 (DPL=0) ничем не отличается от обращения к pageable памяти из обработчика аппаратного прерывания. Едва ли тут есть другое легальное решение для IRQL > dispatch, кроме как DPC. Можно конечно от души напатчить ядро (например, так, чтобы commit pages всегда были present ;))... но потеряется совместимость...

    Если сильно хочется вы$%нуться (вывернуться), можно написать свой pager, который будет работать с винтом на уровне I/O (притом ч/з PIO и с запрещенными прерываниями), обрабатывать FAT32/NTFS/etc и делать вручную page in. И всё это для того, чтобы не потерять контроль при своппинге в обработчике прерывания. ;)))
     
  14. Ms Rem

    Ms Rem New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2005
    Сообщения:
    1.057
    Адрес:
    С планеты "Земля"
    Да ты прав, обращение из int1 (DPL=0) ничем не отличается от обращения к pageable памяти из обработчика аппаратного прерывания.

    Хотелось бы иметь возможность скопировать память оттуда, DPC не подходит, так как он работает на DISPATCH_LEVEL.

    Вы$%нуться мне не хочется, потому-что гиморно сильно.

    Наверно эта задача не имеет прямого решения. В связи с этим возникает вопрос: что бы такое жизненно необходимое для протектора повесить на вызов int 1?
     
  15. _BC_

    _BC_ БЦ

    Публикаций:
    0
    Регистрация:
    20 янв 2005
    Сообщения:
    759
    Ещё вдогонку... Самое элегантное и красивое решение -- это спуститься с заоблачных небес ring0 int1 на грешную землю отлаживаемой программы. Если твой int1 отлаживает, например, обычную ring3-прогу, то идея такая: записать в адр. пространство отлаживаемого процесса код, который будет работать на уровне отлаживаемой проги и все функции которого будут сводится к примерно следуещему:
    Код (Text):
    1.     pushad/pushfd
    2.     mov edi, mem_to_read
    3.     cld
    4.     for all_pages_in_mem do
    5.       lodsb
    6.       add   edi, 0FFFh
    7.     end;
    8.     popfd/popad
    9.     вызвать какой-нить exception;


    И передать управление на этот код.

    Т.е. сделать page in для вываленных в своп страниц на уровне самой проги. Exception -- чтобы привлечь внимание трэйсера. А в обработчике exception'a уже соответственно считывать память процесса и корректировать адрес возврата. Этот же метод и для kernel code с IRQL<dispatch. А код, который выполняется с irql>dispatch, по идее не должен обращаться к pageable памяти, и ейная память должна без проблем дампиться из обработчика int1.



    что бы такое жизненно необходимое для протектора повесить на вызов int 1?

    А оно тебе надо? Один х, всё равно заломают. ;)
     
  16. CARDINAL

    CARDINAL Member

    Публикаций:
    0
    Регистрация:
    23 янв 2004
    Сообщения:
    551
    Адрес:
    Moscow
    _BC_

    кстати, в некотром ты прав, я не могу понять для чего весь этот огород городить. В интелловских мануалах чёрным по белому писано, что в обработчиках исключений аппаратные прерывания не запрещаются, а следовательно, они разрешены, и , если на этапе обработчика исключения возникает какое либо прерывание, и, при условии, что последнее явно не запрещено командой cli или маскированием контроллера прерываний, то, собственно, вложенное прерывание имеет место быть выполненым без всяких проблем, если конечно нет рекурсии, но, вопрос прост и с тем же успехом решаем в данном случае.

    Загвоздка здесь может быть в другом, а точнее - в свитчинге контекстов. То есть, если он самостоятельно обрабатывает #DB и явно не запретил прерываня, то механизм свитчинга по прежнему продолжает работать (это при условии, что #DB возник по уровню > dpc/dispatch), и "его память" может оказаться недоступной. Если же обработчик возник на уровне равном тому, что я указал выше - механизм свитчинга будет приостановлен, до тех пор , пока не текущий поток не передаст управление

    , поскольку оба находятся на одном уровне. Так вот , для данной проблемы мне видны два пути решения:

    1. Поднять уровень Irql до dpc\dispatch, поскольку, если я не ошибаюсь, обработчик #PF находится где то этажом выше, и тем самым закрепим контекст прерывания.



    2. Замаскировать прерывание уровня CLOCK, при этом все остальные теоретически должны продолжить свою работу в том же порядке, единственное, что не будет работать при этом - наш любимый свитчинг контекстов.



    Так что, проблема решаема :))
     
  17. _BC_

    _BC_ БЦ

    Публикаций:
    0
    Регистрация:
    20 янв 2005
    Сообщения:
    759




    Совсем необязательно. Если исключение вызывается ч/з IntGate, то апп. прерывания как раз таки запрещены by default (что не мешает правда их обработчикам пользовать STI).







    BSOD, BSOD, ...., BSOD.
     
  18. CARDINAL

    CARDINAL Member

    Публикаций:
    0
    Регистрация:
    23 янв 2004
    Сообщения:
    551
    Адрес:
    Moscow
    _BC_

    в том то все и дело, что в винде все шлюзы выполнены как шлюзы прерываний, кроме, не помню каково конкретно.

    а вот насчет второго, это ты поторопился, я применял его и на ура. Да ой, щас сам залезу... чё то тут не так !
     
  19. CARDINAL

    CARDINAL Member

    Публикаций:
    0
    Регистрация:
    23 янв 2004
    Сообщения:
    551
    Адрес:
    Moscow
    _BC_

    а вообще, смареть исходники винды
     
  20. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    _BC_



    Так нечестно ;) Вариант с врезкой кода, читающего свою память, я написал раньше.