kernel exception: анализ крешей

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

  1. dmk

    dmk New Member

    Публикаций:
    0
    Регистрация:
    25 мар 2006
    Сообщения:
    20
    Адрес:
    Russia
    доброго времени суток!



    есть драйвер. он падает на единственном компе у клиента. доступа к тому компу доступа не имею, но мне присылают crash dumps.

    после анализа этих дампов обнаружилось, что проблема

    KMODE_EXCEPTION_NOT_HANDLED

    STATUS_ACCESS_VIOLATION

    + некоторый stack trace:

    f2de55c8 804e36d5 f2de5a40 00000000 feae64c0 nt+0x92eb5

    f2de55ec f3461f27 feae64c0 8226ed90 00de5624 nt+0xc6d5

    f2de5a4c 804e37f7 821c7030 feae64b0 feae64b0 MyDriver+0x3f27

    так вот вопрос:

    как мне найти где именно падает драйвер (т.е. как найти в исходнике что соответствует MyDriver+0x3f27)?



    кто-нибудь может подсказать ка решить проблему?



    Заранее благодарен!
     
  2. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Если сохранился pdb и исходники в том виде как они были на момент компиляции, то самое простое влить дамп в WinDbg и набрать .ecxr - WinDbg встанет на нужную строку прямо в исходнике (исходники должны лежать в каталоге где они были при компиляции). Если pdb нет, то 0x3f27 - это смещение от начала образа драйвера или File Offset. Нужно преобразовать его в Virtual Address. Если руками не умеешь, то во многих PE-редакторах есть такая функция. Например в PE Tools есть FLC - File Locator Calculator. Поимев RVA, вливаешь драйвер в дизассемблер и идёшь по нужному RVA (в IDA клавиша G). Строку в исходнике в этом случае получишь путём анализа дизасма.



    А вообще, WinDbg должен сам показать нужную строку (дизасм), по крайней мере, по команде !analyze -v



    ЗЫ: Судя по стеку падает внутри ядра, после вызова драйвером какой-то функции.
     
  3. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Ммм... по .ecxr может и не встанет на исходник, т.к. исключение всё-таки не внутри образа драйвера.
     
  4. dmk

    dmk New Member

    Публикаций:
    0
    Регистрация:
    25 мар 2006
    Сообщения:
    20
    Адрес:
    Russia
    спасибо!

    но что-то не сильно полчилось... :dntknw:

    .ecxr выдаёт кучу ошибок вида:

    ERROR: Module load completed but symbols could not be loaded for NAVENG.Sys

    и в конце:

    Couldn't resolve error at 'cxr'



    pdb и исходники лежат там же где и копилились, но windbg их почему-то не подхватывает... :dntknw:
     
  5. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Извиняюсь, забыл что .ecxr - только для юзер-модной отладки.



    Имея файловое смещение MyDriver+0x3f27 можно однозначно и просто найти это место в дизассемблере. В IDA, оказывается, можно перемещаться прямо по File Offset. Вливай драйвер в IDA, Jump->Jump to file offset... и вводи свои 0x3f27. Окажешься в нужном месте. Положи рядом pdb - когда ида спросит вливать его или нет, скажи да - увидишь имена функций вместо sub_xxxx.



    На худой конец, если хочешь и секретов нет, можешь мне на мыло (<мой ник> собака mail.ru) скинуть драйвер (без исходников, разумеется, - голый sys) - я посмотрю.



    Если опыта анализа крэшдампов нет, то для начала почитай kernel_debugging_tutorial.doc (лежит в каталоге с WinDbg). Потом поброди по debugger.chm (лежит там же). Затем набросай драйвер, который вызовет крах системы... нет... лучше слей готовый Notmyfault http://www.sysinternals.com/windowsinternals.html и поанализируй дампы. В книжке по ссылке, кстати, есть хорошая вводная статья по анализу крэшдампов.



    Тут на словах трудно помочь. Я прошёлся по тем ядрам, что у меня есть, но зацепить ничего не удалось - адреса не совпадают. Какая у клиета система? Если не знаешь, то WinDbg должен показать в самом верху. Или лучше приаттачь сюда, то что WinDbg говорит. Сделай...

    !analyze -v

    lmnt

    kd

    ...хотя kd без символов мало что даст. Какой у тя дамп? Мини (64К)?



    Вобщем "Делайте что-нибудь, Шарапов, делайте - не сидите сиднем!" (с) Груздев
     
  6. dmk

    dmk New Member

    Публикаций:
    0
    Регистрация:
    25 мар 2006
    Сообщения:
    20
    Адрес:
    Russia
    Four-F, огромное спасибо за помощь! я обязательно почитаю, то ты мне посоветовал!



    но проблему уже и так удалось решить (надеюсь...) в IDA я что-то не нашел Jump to file offset. может она у меня сильно старая...зато если пойти по 00013f27 то полученный блок исходников один в один совпадает с тем, что говорит windbg...



    а проблема была в том, что остался кусок кода с незапамятных времен...и если файла !!!!test5.txt не находит, то падает :) вот такие вот косяки :)



    хотя, если это не поможет, буду еще спрашивать :)



    Огромнейшее спасибо за помощь!!!
     
  7. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    Four-F



    Чтобы исследовать аварийный дампы, надо почитать то что ты предложил, т.к. у Касперски это очень мало! А на русском кроме Криса мало кто пишет, толково! Хотелось бы чтобы ты написал такую статью, вопросами обеспечим! :)))



    Я конечно предполжу твою рекомендацию: учите английский, но ведь бывает, что человеку Именно сейчас надо! А язык он только еще учит, как быть такому челу?
     
  8. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    В принципе, можно было бы подумать, но в четвёртом издании "Внутреннее устройство Microsoft Windows" этому посвещена целая глава на 28 страниц. Всё по-русски. Если писАть статью, то минимум на 50% это будет копирка.



    ЗЫ: А вопросы давайте, интересно ;)



    ЗЗЫ: А где у Криса про это?
     
  9. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Four-F

    написал бы маленький тутор по WinDbg в режиме ядра (судя по ответам, знаешь его) на русском :) А то сколько искал - ни одной ссылки не видел :dntknw: Приходится отлаживать путем бсодов :dntknw:
     
  10. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Этого точно не будет. Во-первых, для ядерной отладки нужны две машины: отлаживаемая и отлаживающая. Хотя это и жутко удобно и производительнее чем в айсе, но много тут людей имеющих такую связку? Во-вторых, WinDbg я знаю но, честно говоря, плохо. В-третьих, был тут один человек, который обещал написАть такой тутор ;)
     
  11. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
  12. n2k

    n2k kris kaspersky

    Публикаций:
    0
    Регистрация:
    22 янв 2005
    Сообщения:
    102
    Адрес:
    Russia
  13. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    <font color="gray][ cresta</font><!--color--><font color="gray]: написал бы маленький тутор по WinDbg в режиме ядра на русском :) ]</font><!--color-->



    Вот вам, типа, первая часть ;)



    ------------------------------



    >> На худой конец, если хочешь и секретов нет, можешь мне на мыло...



    > посмотри плиз...а то у меня уже совсем урыша съезжает :dntknw:





    100% ты переполняешь стек.


    Код (Text):
    1. kd> !analyze -v
    2.  
    3. ********************************************************************** *********
    4. *                                                                             *
    5. *                        Bugcheck Analysis                                    *
    6. *                                                                             *
    7. ********************************************************************** *********
    8.  
    9. UNEXPECTED_KERNEL_MODE_TRAP_M (1000007f)
    10.  
    11. Arguments:
    12. Arg1: 00000008, EXCEPTION_DOUBLE_FAULT
    13. Arg2: 80042000
    14. Arg3: 00000000
    15. Arg4: 00000000
    16.  
    17. STACK_TEXT:  
    18. WARNING: Stack unwind information not available. Following frames may be wrong.
    19. f392385c 804e37f7 83370020 f9e26008 02c03000 Driver+0xf79
    20. f3923880 804f552f 83370020 82a7520a 82a752c8 nt+0xc7f7
    21. f39238a0 804f5194 83372810 82a752e8 82a752c8 nt+0x1e52f
    22. ...
    23. f3925d6c 012cea68 f66de54a 00000000 00000000 0xbadb0d00
    24. f3925d70 f66de54a 00000000 00000000 00000000 0x12cea68
    25. f3925d74 00000000 00000000 00000000 00000000 somename+0x54a
    26.  
    27. FOLLOWUP_IP:
    28. Driver+f79
    29. f1fb9f79 56   push esi


    Первым делом идем в DDK и смотрим описание UNEXPECTED_KERNEL_MODE_TRAP_M, которое гласит, что одной из вероятных причин падения может быть A kernel stack overflow.



    К сожалению, в минидампе команда !thread не работает, а то можно было бы сразу увидеть начало и конец стека. Придётся по трассе стека разбирать.



    Стек ядра очень мал - всего 3 страницы, т.е. 12Кб. Из первой (нижней) строки трассы можно заключить, что вершина стека равна 0xF3926000-1. Нужно просто округлить 0xF3925D74 до максимального адреса в пределах страницы: 0xF3925D74+0x28B=0xf3926000-1. Если вершина стека 0xF3926000-1, то его дно 0xF3926000-3*0x1000=0xF3923000.



    Когда ты входишь в свою Driver!DispatchRead (верхняя строка по трассе), esp уже равен 0xF392385C, т.е. до дна стека остаётся 0xF392385C-0xF3923000=0x85C байт.


    Код (Text):
    1. .text:00010F70 DispatchRead    proc near
    2.  
    3. .text:00010F70    push  ebp
    4. .text:00010F71    mov   ebp, esp
    5. .text:00010F73    sub   esp, 918h  <-- выделяшь на стеке 2328 (много!) байт для локальных переменных
    6. .text:00010F79    push  esi        <-- UNEXPECTED_KERNEL_MODE_TRAP_M
    7. .text:00010F7A    push  edi


    В Driver!DispatchRead ты выделяешь на стеке 0x918 байт, что болше остатка равного 0x85C, и таким образом выходишь за границы стека. Когда процессор пытается затолкнуть esi в стек, происходит кирдык, т.к. указатель стека esp равен 0xF3922F44, что ниже дна.


    Код (Text):
    1. kd> r
    2. eax=00000003 ebx=82a752c0 ecx=83370020 edx=f9e26008 esi=8322e490 edi=83372810
    3. eip=f1fb9f79 esp=[b]f3922f44[/b] ebp=f392385c iopl=0         nv up ei ng nz na po nc
    4. cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00010286


    Мораль: не нужно использовать в дровах много локальных переменных и буферов. Если требуется большой локальный буфер, то юзайте системные пулы.



    Решение: вытекает из морали. Исправить процедуру Driver!DispatchRead так, чтобы она не использовала так много стека. После этого, скорее всего, всё заработает нормально, т.к. драйвер, похоже последний в цепочке, т.е. стек больше никому не потребуется. Если клиент, у которого падает, продвинут и морально устойчив, то можно пихнуть в драйвер вызовы IoGetStackLimits и IoGetInitialStack, вывести в лог и попросить прислать лог. При этом можно воспользоваться IoGetRemainingStackSize (враппер над IoGetStackLimits) для определения остатка стека, и если стека не хватает - уходить.
     
  14. ksu_ant

    ksu_ant New Member

    Публикаций:
    0
    Регистрация:
    28 сен 2005
    Сообщения:
    273
    Вот не я тему заводил, а за первую часть ;) - спасибо.

    Очень понятно, особенно для новичков - все объяснено, показано.

    Понятно, что это в доках есть, - но тут объяснения человека, реально использующего продукт, практика. Очень часто страничка таких объяснений (не важно на каком языке) заменяет целые главы в книгах (многие любят так книги писАть, наверное, чтобы можно было, с помощью объема, в глазах читателя цену книги оправдать ;0)). А новичку бывает просто страшно лезть в изучение, потому как по мануалам, хелпу и т.д. не все сразу понятно (в силу отсутствия опыта).

    Думаю, не ошибусь, если скажу, что народ жаждет второй части :0).

    Извините за некоторый оффтопик.
     
  15. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
  16. IceStudent

    IceStudent Active Member

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

    Долго ждать перевода придётся — быстрее выучишь английский :)
     
  17. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    /offtop

    В книге Руссиновича(новой 2005 г.) на стр.92 внизу, указывается понятие "Стек ядра" в www.ya.ru Чаще встречается "Стек режима ядра", я до ответа Гуру думал, что это разные понятия. Вобщем такой разброд, Может уважаемый Four-F дал бы понятие, я бы принял его слова за стандарт!
     
  18. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    <font color="gray][ ksu_ant</font><!--color--><font color="gray]: Думаю, не ошибусь, если скажу, что народ жаждет второй части :0). ]</font><!--color-->



    Кидайтесь в меня минидампами с sys'ами ( только не все сразу :) ), может и будет вторая.





    <font color="gray][ EvilsInterrupt</font><!--color--><font color="gray]: Может уважаемый Four-F дал бы понятие, я бы принял его слова за стандарт! ]</font><!--color-->



    Обратимся к первоисточнику:



    "Using the Kernel Stack



    The size of the kernel-mode stack is limited to approximately three pages. Consequently, when passing data to internal routines, drivers cannot pass large amounts of data on the kernel stack.



    To avoid running out of kernel-mode stack space, use the following design guidelines:



    Avoid making deeply nested calls from one internal driver routine to another, if each routine passes data on the kernel stack.

    Take care to limit the number of recursive calls that can occur, if you design a driver with a recursive routine.



    In other words, the call-tree structure of a driver should be relatively flat. You can call the IoGetStackLimits and IoGetRemainingStackSize routines to determine the amount of kernel stack space that is available. Note that the size of the kernel-mode stack can vary among different hardware platforms and different versions of the operating system.



    Running out of kernel stack space causes a fatal system error. Therefore, it is better for a driver to allocate system-space memory than to run out of kernel stack space. However, nonpaged pool is also a limited system resource."




    Как видно, используются оба понятия, но kernel stack в DDK используется чаще.



    У любого потока (кроме чисто ядерных) - два стека. Один используется, когда поток работает в режиме пользователя (user mode). Когда поток переходит в режим ядра (kernel mode), система переключает стеки и поток начинает использовать свой стек ядра. Отсюда и происходит kernel-mode stack.



    Так что "cтек ядра" и "cтек режима ядра" - это просто дословные переводы соответствующих англоязычных словосочетаний и означают они абсолютно одно и то же.
     
  19. ksu_ant

    ksu_ant New Member

    Публикаций:
    0
    Регистрация:
    28 сен 2005
    Сообщения:
    273
    EvilsInterrupt

    http://www.sysinternals.com/Publications.html

    ХАчу ВСЕ и на Русском! :)


    Там все ссылки на windowsitpro, где требуется регистрация и, как я понял, она не совсем бесплатная :)

    Можно ли где-нибудь почитать то же самое, но более "пролетарским" способом?
     
  20. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    Four-F

    Хорошо что рад учить народ ловить рыбку, все же лучше чем давать ему уже пойманную!

    Когда страницы в памяти нет, возникает возникает исключение с номером 0xe, так? Значит запись в IDT с этим номером и есть системный обработчик. Судя потому, что прочитал в Руссиновиче это так, теперь наберу:
    Код (Text):
    1. kd> !idt
    2.  
    3. Dumping IDT:
    4.  
    5. 37:     806ed728 hal!PicSpuriousService37
    6. 3d:     806eeb70 hal!HalpApcInterrupt
    7. 41:     806ee9cc hal!HalpDispatchInterrupt
    8. 50:     806ed800 hal!HalpApicRebootService
    9. 62:     823aedd4 Unknown_Module_f8451000!IdePortInterrupt (KINTERRUPT 823aed98)
    10. 63:     81e5d2cc USBPORT!USBPORT_InterruptService (KINTERRUPT 81e5d290)
    11. 73:     81fdddd4 VIDEOPRT!pVideoPortInterrupt (KINTERRUPT 81fddd98)
    12.                  USBPORT!USBPORT_InterruptService (KINTERRUPT 82103008)
    13.                  USBPORT!USBPORT_InterruptService (KINTERRUPT 81ddd008)
    14. 82:     8236ddd4 Unknown_Module_f8451000!IdePortInterrupt (KINTERRUPT 8236dd98)
    15. 83:     81ffd044 portcls!CKsShellRequestor::`vector deleting destructor'+0x26
    16.                             (KINTERRUPT 81ffd008)
    17. 92:     821dd784 serial!SerialCIsrSw (KINTERRUPT 821dd748)
    18. 93:     8220f704 i8042prt!I8042KeyboardInterruptService (KINTERRUPT 8220f6c8)
    19. 94:     820ce1fc NDIS!ndisMIsr (KINTERRUPT 820ce1c0)
    20. a3:     81e9e2cc i8042prt!I8042MouseInterruptService (KINTERRUPT 81e9e290)
    21. a4:     82082334 USBPORT!USBPORT_InterruptService (KINTERRUPT 820822f8)
    22. b1:     823cc044 ACPI!ACPIInterruptServiceRoutine (KINTERRUPT 823cc008)
    23. b4:     81dff2cc USBPORT!USBPORT_InterruptService (KINTERRUPT 81dff290)
    24. c1:     806ed984 hal!HalpBroadcastCallService
    25. d1:     806ecd34 hal!HalpClockInterrupt
    26. e1:     806edf0c hal!HalpIpiHandler
    27. e3:     806edc70 hal!HalpLocalApicErrorService
    28. fd:     806ee464 hal!HalpProfileInterrupt


    что-то я не могу понять, где здесь оно?