Есть ли способ проверить валидность хэндла в user mode?

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

  1. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    IceStudent
    Насколько я понял, с твоей подачи #11 сюда переместилось обсуждение примера защиты, в котором первым делом делается явный вызов RaiseException. Поэтому я полагал что тебе с Asterix'ом должно быть понятно о чем идет речь ;)

    PS: Кстати, проверил ради интереса реализацию обработки INVALID_HANDLE в MiniDebugger'е с анализом адреса на принадлежность KiRaiseUserExceptionDispatcher - полет нормальный ;) Но выявился интересный факт - оказывается в простом самопальном дебагере время реакции на INVALID_HANDLE под отладчиком увеличивается всего раз в 20 (по сравнению с безотладочным режимом), а не в тысячи раз как в OllyAdvanced. Т.е. получается, что эти тысячи тиков на обработку\необработку исключения связаны не с виндовыми тормозами при вызове отладчика, а тормозами обработки DebugEvent в самом отладчике (?!)
     
  2. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Да, ответил не в ту ветку :)

    Вполне возможно. DebugEvent передаётся всем плагинам, да ещё и её обработка в OllyAdvanced весьма нетривиальна.
     
  3. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    что делать с CloseHandle мне понятно, а вот с RaiseException пока не ясно

    мне показалось что Olly спокойно пропускает исключение вызванное RaiseException
    по Shift-F9 и здесь в принципе поймать можно только по времени обработки
     
  4. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Asterix
    Ес-но, ручками можно все обойти - жмем Shift+F8/F9 в случае явных вызовов RaiseException или RtlRaiseException и просто F8/F9 в случае инвалидных CloseHandle и т.п. В пошаге понятно где что, а если исключение происходит во время Run, то явные вызовы можно определить по View\CallStack, а вот при неявных исключениях Оля в окне CallStack ничего не показывает (по кр.мере под XP), нужно смотреть сам стек или просто адрес исключения, т.к. останов происходит всегда внутри KiRaiseUserExceptionDispatcher.

    Ну а если делать автоматический игнор, то можно различать случаи явного и неявного вызова исключения по ExceptionAddress. В обоих случаях исключение генерится вызовом call ntdll.RtlRaiseException и ExceptionAddress указывает на следующую после call инструкцию (адрес возврата из call). Поэтому при явном вызове RtlRaiseException адрес будет соотв.коду самой проги, при вызове RaiseException - адресу в kernel32.RaiseException, а при виндовом автовызове - адресу внутри ntdll.KiRaiseUserExceptionDispatcher. Поэтому при EXCEPTION_DEBUG_EVENT смотрим принадлежит ли ExceptionAddress диапазону адресов (KiRaiseAdr,KiRaiseAdr+KiRaiseSize), если принадлежит то ставим признак обрабатки исключения (DBG_CONTINUE), если нет то пропускаем (DBG_EXCEPTION_NOT_HANDLED). Таким образом явные Raise\RtlRaise будут передаваться проге, а виндовые INVALID_HANDLE - не будут.
    Тут для защиты останется еще лазейка явно вызывать KiRaise, поэтому в качестве дополнения можно усложнить анализ, посмотрев реализацию KiRaise в разных виндах. Например, в XP возврат из KiRaise осуществляется на KiFastSystemCallRet и на момент исключения регистр EBP соответствует стандартному эпилогу (mov esp,ebp + pop ebp + ret), поэтому можно просто взять из контекста значение EBP и сравнить [EBP+4] c KiFastSystemCallRet - если совпадает, то это виндовый вызов.
     
  5. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    мне кажется все гораздо проще, ставим в игнор исключение 0xC0000008 средствами Olly
    чтоб защититься от явных RaiseException
    + обрабатываем вызовы CloseHandle с несуществующим хэндлом,
    мне кажется метод рабочий