У меня проблемы с WaitForDebugEvent EXCEPTION_DEBUG_EVENT - PullRequest
1 голос
/ 26 сентября 2010

Я запускаю экземпляр Explorer.exe с CreateProcess (флаги NORMAL_PRIORITY_CLASS + DEBUG_PROCESS + DEBUG_ONLY_THIS_PROCESS), а затем я делаю это:

procedure FakeDebugProcess; 
var 
  wDebugEvent : DEBUG_EVENT; 
begin 
  fillchar( wDebugEvent, sizeof( wDebugEvent ), 0 ); 
  repeat 
    if WaitForDebugEvent( wDebugEvent, INFINITE ) 
      then 
        begin 
          if wDebugEvent.dwDebugEventCode = EXIT_PROCESS_DEBUG_EVENT 
            then break; 
          ContinueDebugEvent( wDebugEvent.dwProcessId, wDebugEvent.dwThreadId, DBG_CONTINUE ); 
        end;
  until false; 
end;

Все почти работает нормально, кроме какмного EXCEPTION_DEBUG_EVENTs из того, что кажется "C: \ Windows \ System32 \ rpcrt4.dll"

(AdditionalDetails: EXCEPTION_ACCESS_VIOLATION)

77ea3c00 sub_77ea3c00:                    ; function entry point
77ea3c00 >>mov     [ecx+4], eax
77ea3c03   movsx   eax, bx
77ea3c06   cdq
77ea3c07   sub     eax, edx
77ea3c09   sar     eax, 1
77ea3c0b   mov     [ecx], ax
77ea3c0e   xor     eax, eax
77ea3c10   pop     edi
77ea3c11   pop     esi
77ea3c12   pop     ebx
77ea3c13   pop     ebp
77ea3c14   ret     8

Что я делаю не так?Как мне это исправить?

Я использую Delphi 7, кстати.

Ответы [ 3 ]

4 голосов
/ 26 сентября 2010

Ваш код в порядке, тестирование с использованием других отладчиков, таких как ollydbg, rpcrt4.dll по-прежнему сообщает об исключениях при подключении к некоторым приложениям.Единственный способ обойти это - определить фильтры (что позволяет пользователю ollydbg) на основе кода исключения, а затем на основе модуля.Таким образом, если вы получаете 0xC0000005 (EXCEPTION_ACCESS_VIOLATION), вы проверяете: EIP >= (UINT_PTR)GetModuleHandle("rpcrt.dll") && EIP <= (UINT_PTR)GetModuleHandle("rpcrt.dll") + getModuleSize("rpcrt.dll") (конечно, getModuleSize - это настраиваемая функция для получения виртуализированного размера модулей из PE, а UINT_PTR - тип, достаточно большой для размещения указателя на вашей целевой системе), вы игнорируете его, иначе обрабатываете событие, хотя может потребоваться перехватывать KiDispatchUserException (это должно быть правильным, иначе проверьте NTInternals)

3 голосов
/ 01 ноября 2011

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

Если запустить процесс и ожидать отладки с помощью вызовов Windows API, вы должны знать,что Windows отправит один EXCEPTION_BREAKPOINT (INT3) при первой загрузке.Вы должны DEBUG_CONTINUE это первое исключение точки останова ... если вы DBG_EXCEPTION_NOT_HANDLED, вы получите всплывающее окно сообщения: приложение не удалось правильно инициализировать (0x80000003).

Теперь, для всех других исключений, вы хотите вернуть DBG_EXCEPTION_NOT_HANDLED, так чтоони возвращаются назад и обрабатываются.После первого исключения точки останова, созданного окнами, вы можете свободно устанавливать дополнительные точки останова по своему усмотрению.

Действительно упрощенный код для цикла отладки выглядит следующим образом:

// debug loop...  while(debugging) or whatever you want to do.

DEBUG_EVENT DebugEvent;
DWORD ContinueStatus = DBG_CONTINUE;

WaitForDebugEvent(&DebugEvent, INFINITE);

switch (DebugEvent.dwDebugEventCode) {

    case EXCEPTION_DEBUG_EVENT:

        switch(DebugEvent.u.Exception.ExceptionRecord.ExceptionCode) { 

            case EXCEPTION_BREAKPOINT:
                // stay with DBG_CONTINUE at least for the first breakpoint. 
                // continue, don't pass this back to process being debugged.   
                break;
            default:
                // handles all other stuff like EXCEPTION_ACCESS_VIOLATION
                // pass these back to the process being debugged... 
                ContinueStatus = DBG_EXCEPTION_NOT_HANDLED;
                break;
        }
        break;

    default: 
        break;
}

ContinueDebugEvent(DebugEvent.dwProcessId, DebugEvent.dwThreadId, ContinueStatus);

Основы:

  • Windows при запуске создает точку останова, которую нужно перехватить и не передавать обратно.
  • В больших программах Windows есть множество других исключений, которые они обрабатывают, поэтому передайте их обратно.
  • Передача обратной точки останова при запуске приводит к следующему: «Приложению не удалось правильно инициализироваться (0x80000003)» *
  • Перехват исключений памяти / SEH и отказ от их возврата вызывает бесконечные циклы в цикле отладчика, поскольку исключения никогда не выполняютсяесть шанс очиститься от кода.
1 голос
/ 26 сентября 2010

Почему вы предполагаете, что что-то не так с вашим кодом? Отладчик получает уведомления первого шанса для любого исключения SEH. Вы отлаживаете огромное количество кода. Не только Explorer.exe, вы также получаете все обработчики расширения оболочки. Вокруг много грязи, Explorer делает все возможное, чтобы остаться в живых, даже если в этих расширениях есть ошибки.

Если вы действительно хотите решить эту проблему, это неплохая идея, тогда используйте утилиту автозапуска SysInternals и отключите любой обработчик расширения оболочки, который не был создан Microsoft, и вам это не нужно. Если вы хотите проверить свой отладчик, попробуйте что-нибудь более невинное, например Notepad.exe. Хотя File + Open возвращает эти расширения оболочки обратно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...