Вопрос для Chingachguk'а

Тема в разделе "WASM.WIN32", создана пользователем Wolfgang, 6 июл 2005.

  1. Wolfgang

    Wolfgang New Member

    Публикаций:
    0
    Регистрация:
    11 май 2005
    Сообщения:
    82
    Адрес:
    Russia
    В статье про HASP3 был очень интересный момент, до которого я никак не докопаюсь





    Тут несколько сложновато написано, но смысл такой: всякий раз при выполнении такого исключения все биты в DR7 скидываются, и мы получаем в исключении #1 его "чистым". Попытка проинициализировать его внутри обработчика приведет к краху системы...





    Это - выдержка из статьи. Так вот, уважаемый Chingachguk, почему dr7 нельзя инициализировать внутри оработчика?????

    В моей ХР SP2 регистр dr7 постоянно (почему-то при изменении размера любого окна) сбрасывает winlogon.exe, попытка восстановить его в драйвере ведет к заквисанию.
     
  2. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    Ну так там же далее пояснения - как это обойти. Необходимо "вернуться" из обработчика на свой код, затем восстановить DRx, затем уже вернуться в точку исключения:


    Код (Text):
    1. ; подпрограмма - ловушка #1 - debug
    2. BD equ 0010000000000000b
    3. B0 equ 0001b
    4. B1 equ 0010b
    5. B2 equ 0100b
    6. B3 equ 1000b
    7. CMD_IN_AL_DX equ 0ECh
    8. TrapPort proc
    9.   push ebp
    10.   mov  ebp,esp
    11. ...
    12. @@AfterDebugRegs:
    13.  
    14. ; Запоминаем адрес возврата и возвращаемся в наш код
    15.   mov  dword ptr RetAddr_UD01_EIP,ecx
    16.   mov  word ptr RetAddr_UD01_CS,es
    17.  
    18.   mov  [ebp+4],offset32 After_DebugRegisterUsed
    19.   mov  word ptr [ebp+8],cs
    20.  
    21.   popfd
    22.   pop  es
    23.   pop  ds
    24.   popad
    25.   pop  eax
    26.   pop  ebp
    27.   iretd
    28. TrapPort endp
    29.  
    30. ; Я знаю, что исключение (обращение к портам или сброс DR7)
    31. ; вызвано в драйвере защиты (VXD), поэтому я не забочусь о селекторе точки исключения (cs), а только о EIP:
    32. After_DebugRegisterUsed proc
    33.   pushad
    34.   pushfd
    35. ; Восстанавливаем cr4 & DR7
    36. ; Enable DE flag
    37.   mov  eax,cr4
    38.   or   eax,01000b
    39.   mov  cr4,eax
    40.   ;                   FEDCBA9876543210FEDCBA9876543210
    41.   mov  eax,TrapMask ; 01100110011001100010011111111111b
    42.   mov  dr7,eax
    43.   popfd
    44.   popad
    45. ; Возвращаемся [b]near[/b] jmp'ом:
    46.   jmp  dword ptr RetAddr_UD01_EIP
    47. ; Хотя на самом деле корректно писать jmp far (fword ptr)[Сохраненные cs:eip адреса возврата]
    48. After_DebugRegisterUsed endp
     
  3. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    Возможно, дело в том, что когда возникает исключение попытки сброса DRx, то при входе в обработчик исключения установлен бит DE в cr4. Если ты пытаешься его (DRx)восстановить внутри обработчика, то возникает повторное исключение или сразу GPF. Но, насколько я помню, мне не удалось найти другого решения.
     
  4. Wolfgang

    Wolfgang New Member

    Публикаций:
    0
    Регистрация:
    11 май 2005
    Сообщения:
    82
    Адрес:
    Russia
    Так ведь бит DE в cr4 запрещает только отладочные прерывания при обращении к портам, а я к портам пока и не обращаюсь, только пытаюсь перехватить модификацию DRx :-(
     
  5. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    Ну да, немного не так. Ты получаешь исключение по попытке сброса DRx, затем внутри исключения пытаешься его исправить. Видимо, в этом и проблема. Возможно, надо сначала какой-то битик скинуть/поставить, но я решил это через iretd (что разрешает видимо повторную инициализацию DRx) и уже затем инициализация DRx.
     
  6. Wolfgang

    Wolfgang New Member

    Публикаций:
    0
    Регистрация:
    11 май 2005
    Сообщения:
    82
    Адрес:
    Russia
    Шаманство какое-то... Специально нарыл интелловские доки, читал очень вниательно и выяснил, что GD в DR7 в обработчике первого прерывания сбрасывается, то есть доступ к отладочным регистрам разрешен и это так, ибо к DR6 доступаюсь спокойно без зацикливания. Кроме того, выяснил, что iretd не сбрасывает разрешающих битов, так что дело в чем-то еще...

    Попробовал делать так, как у тебя, то есть подменять реальный адрес возврата по iretd на адрес своей функи... так вот, выставление этого бита в DR7 уже в ней дает тот же эффект - зависает намертво. Очень бы хотелось разобраться, как с этим быть. Возможно, что где-то в системе есть код типа:
    Код (Text):
    1.  
    2. @1:
    3. xor  ebx, ebx
    4. mov  dr7, ebx
    5. ...
    6. mov  ebx, dr7
    7. test ebx, GD
    8. jnz  @1
    9.  


    но вряд ли... посоветуй, плиз, в какую сторону копать на эту тему?
     
  7. Chingachguk

    Chingachguk New Member

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



    Туда точно ты попадаешь ?



    > так вот, выставление этого бита в DR7 уже в ней дает

    > тот же эффект - зависает намертво.



    Ну у меня не совсем так, попробуй все же в точности как у меня.