Win2003 Server + Access violation when executing on RE page

Тема в разделе "WASM.WIN32", создана пользователем gribodemon, 25 апр 2010.

  1. gribodemon

    gribodemon New Member

    Публикаций:
    0
    Регистрация:
    17 июн 2009
    Сообщения:
    138
    Ну, у меня нет слов.
    Вызывается, функция из библиотеки wininet.dll внутри explorer.exe
    При этом возникает Acceess violation when executing хотя под отладчиком видно, что атрибуты страницы стоят RE.

    [​IMG]

    Готов выслушать любые идеи. Как это могло произойти?
     
  2. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    EXCEPTION_RECORD в студию.
     
  3. gribodemon

    gribodemon New Member

    Публикаций:
    0
    Регистрация:
    17 июн 2009
    Сообщения:
    138
    Вроде Olly отображает её полностью на этом скрине:

    [​IMG]
     
  4. gribodemon

    gribodemon New Member

    Публикаций:
    0
    Регистрация:
    17 июн 2009
    Сообщения:
    138
    Хм. А вообще, я просто не могу её найти в стеке.
    Регистр ESP у меня указывает не на структуру EXCEPTION_POINTERS, а на адрес, позади инструкции CALL, откуда текущая функция (из либы wininet.dll) вызывалась.
     
  5. gribodemon

    gribodemon New Member

    Публикаций:
    0
    Регистрация:
    17 июн 2009
    Сообщения:
    138
    Или там для этого нужно хукнуть ntdll!KiUserExceptionDispatcher ?
     
  6. gribodemon

    gribodemon New Member

    Публикаций:
    0
    Регистрация:
    17 июн 2009
    Сообщения:
    138
    Хм... А вообще, мысль интересная.
    Сделать отсылку отчётов к себе на сервачок об исключениях.
    Можно будет мониторить стабильность работы, оперативно устранять баги, по идее.
    Плюсом ещё идейка интересная:
    http://www.packetstormsecurity.org/NT/
     
  7. gribodemon

    gribodemon New Member

    Публикаций:
    0
    Регистрация:
    17 июн 2009
    Сообщения:
    138
    Подскажите плз код для выдергивания имени DLL'ки по определённому адресу (ну, как в RKU реализовано).
    Просто, ведь, если ошибка произошла не в самом приложении, а в DLL, то нам как минимум нужно знать имя этой DLL и базовый адрес модуля.
     
  8. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    gribodemon
    Если средствами нэйтива, то LdrFindEntryForAddress().
    Если проекцию связать с файлом, то MemoryMappedFilenameInformation:
    http://wasm.ru/forum/viewtopic.php?pid=362651#p362651
    В ядре через VAD определяется.
    -
    Запускаете процесс под отладчиком, добавляете все сепшены в игнор, потом брейк на диспетчер http://wasm.ru/forum/viewtopic.php?pid=309734#p309734
    Далее смотрите атрибуты памяти утилитой типо VmMap от сисинтерналс и отписываете сюда найденную инфу, далее видно будет.
     
  9. gribodemon

    gribodemon New Member

    Публикаций:
    0
    Регистрация:
    17 июн 2009
    Сообщения:
    138
    Хм...

    Попытался хукнуть её.
    Прямо в начало ставлю:
    Код (Text):
    1. OutputDebugString(__FUNCTION__);
    И система крэшится (WinXP SP2). Возможно, это из-за внедрения в winlogon.exe
    Убираю kerlnel32!OutputDebugString. Смотрю в RKU - всё хукнулось отлично.

    Подскажите, в чём может быть причина крэша при использовании OutputDebugString ?
     
  10. gribodemon

    gribodemon New Member

    Публикаций:
    0
    Регистрация:
    17 июн 2009
    Сообщения:
    138
    Глянул в DbgView - крэш происходит после внедрения в services.exe (при исп. OutputDebugString).
    М... ?
     
  11. gribodemon

    gribodemon New Member

    Публикаций:
    0
    Регистрация:
    17 июн 2009
    Сообщения:
    138
    Вот я даю вообще.
    Код (Text):
    1. MY_NAKED void filter_handler() {
    2.     __asm {
    3.                 mov ecx,[esp+4]            
    4.                 mov ebx,[esp]              
    5.                 pushad
    6.                 cmp dword ptr [ebx],0xc0000005
    7.                 jne _leave_it
    8.                 mov ebp,esp
    9.                 push ecx
    10.                 push ebx
    11.                 call filter_exceptions
    12.                 mov esp,ebp
    13.  
    14.     _leave_it:  popad
    15.                 push _KiUserExceptionDispatcher
    16.                 add [esp],7
    17.                 ret
    18.     }
    19. }
     
  12. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    gribodemon
    Если после ваших непонятных манипуляций система рушится со STATUS_SYSTEM_PROCESS_TERMINATED то явно изза возникновения необработанного исключения или разрушения контекста, в частности стека(Esp).
    filter_handler() это хэндлер сплайса диспетчера исключений ?
    Нормально это делается получением куков целевого процесса, необходимых для шифрования поинтера на VEH в списке RtlpCalloutEntryList, либо непосредственно вызовом RtlAddVectoredExceptionHandler() в контексте целевого процесса.
     
  13. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Какой я догадливый http://rsdn.ru/forum/winapi/3789528.1.aspx :)
    Функа DbgPrint() проверяет PEB.BeingDebugged. В зависимости от него направляет вывод в ядро, либо генерирует #DBG_PRINTEXCEPTION_C, которое должен обработать отладчик. Если порта нет, то исключение доставляется, после чего выполняется возврат из DbgPrint() вне зависимости обработано оно или нет. Доставка исключения локальна, тоесть в таком случае будет рекурсивный вызов диспетчера исключений(изза перехвата), пока весь стек не исчерпается и далее ядро прибьёт процесс. У вас иное, вы используете OutputDebugString(), которая не использует ядерный вывод, а доставляет локально #DBG_PRINTEXCEPTION_C, вне зависимости от PEB.BeingDebugged. Вот и исчерпывается стек. Под отладчиком разумеется будет работать ;)
     
  14. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    gribodemon
    мб так попробовать:
    Код (Text):
    1. DBGPRINT macro pStr, StrLen
    2.     push ebx
    3.     push edi
    4.     xor eax,eax
    5.     mov ecx,pStr
    6.     mov edx,StrLen  ; OPT.
    7.     inc eax ; BREAKPOINT_PRINT
    8.     xor ebx,ebx
    9.     xor edi,edi
    10.     Int 2DH
    11.     nop
    12.     pop edi
    13.     pop ebx
    14. endm
    [​IMG]
     
  15. gribodemon

    gribodemon New Member

    Публикаций:
    0
    Регистрация:
    17 июн 2009
    Сообщения:
    138
    Clerk
    Благодарю за инфо.
    Попутно вопрос - могут ли возникнуть какие-нибудь проблемы, если я буду в коде перехвачечнной KiUserExceptionDispatcher вызывать функции из библиотеки kernel32.dll. Например, СreateThread -- думаю, создать поток, и в нём отправлять данные через сокет, на свой серв, с использованием библиотеки ws2_32.dll.
    Например, может возникнуть какое-нибудь исключение. Скажем, тот же Aceess Violation, в моём коде. В этом случае, произойдёт рекурсия.

    Сейчас, я эту потенциальную проблему решаю так:

    Код (Text):
    1. DWORD gl_dwLastExceptionTicks;
    2.  
    3. void STDAPICALLTYPE xKiUserExceptionDispatcher ( EXCEPTION_RECORD *er, CONTEXT *con )
    4. {
    5.     // Not more then 1 report per 10 sec.  
    6.     DWORD dwCurrentTicks = GetTickCount();
    7.     if (dwCurrentTicks > gl_dwLastExceptionTicks + 10 * 1000)
    8.     {
    9. #ifdef _DEBUGLITE
    10.         OutputDebugString("Exception was skipped by time interval");
    11. #endif
    12.         Real_KiUserExceptionDispatcher(er, con);
    13.         return;
    14.     }
    15.  
    16.     // *** My report here ... calling funcs. from ws2_32.dll & etc. ***
    17.  
    18.     Real_KiUserExceptionDispatcher(er, con);
    19. }
     
  16. gribodemon

    gribodemon New Member

    Публикаций:
    0
    Регистрация:
    17 июн 2009
    Сообщения:
    138
    Clerk:
    o0 Угумс, так и сделаю.
     
  17. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    gribodemon
    Извращениям нету конца, да.. зачем это Ki* сплайсить, если можно поставить VEH ?
     
  18. gribodemon

    gribodemon New Member

    Публикаций:
    0
    Регистрация:
    17 июн 2009
    Сообщения:
    138
    Млин. В моём коде ещё не хватает:

    Код (Text):
    1. gl_dwLastExceptionTicks = dwCurrentTicks;
    Плюс, OutputDebugString нужно заменить на int 2d прерывание.
    Но, в этом случае (в случае с таймером), рекурсии как раз произойти не должно. Хотя, там же минимальная едиинца - 1 МС.
    М... Ок. Точно int 2d использовать надо.

    Хорошо - тогда только остаётся вопрос - как будет реагировать эта функция (или процессы, которые её используют) на вызов CreateThread ?
     
  19. gribodemon

    gribodemon New Member

    Публикаций:
    0
    Регистрация:
    17 июн 2009
    Сообщения:
    138
    Clerk
    М... И действительно.
    Ок. Иду курить MSDN по этому поводу.
     
  20. ptr

    ptr New Member

    Публикаций:
    0
    Регистрация:
    14 мар 2009
    Сообщения:
    130
    не пойму почему не работает код
    Код (Text):
    1. var
    2.   ldr: TLDR_DATA_TABLE_ENTRY;
    3.   buf: array[BYTE] of char;
    4.   procedure dummy; begin end;
    5. begin
    6.   ZeroMemory(@ldr, sizeof(TLDR_DATA_TABLE_ENTRY));
    7.   LdrFindEntryForAddress(pointer(@dummy), @ldr);
    8.   wsprintf(@buf, 'EP=%x', DWORD(ldr.EntryPoint));
    9.   MessageBox(0, @buf, '', 0);
    результат всегда нулевой для любого поля в структуре _LDR_DATA_TABLE_ENTRY