Доброго времени суток. Собственно вопрос. Какие инструменты использовать при отладке драверов? Какие для анализа крэш дампа и где он находится (что это вообще такое)? Ну и вообщем-то ситуация которая меня вывела на этот вопрос - Код (Text): __try { ProbeForRead(ObjectAttributes->ObjectName, ObjectAttributes->ObjectName->Length, 1); } __except(EXCEPTION_EXECUTE_HANDLER) { DbgPrint("Exception occured while probe"); } Все равно вылезает бсод с криками о PAGE_FAULT_AT_NONPAGED_AREA. Почему? Я же вроде обрабатываю исключение. Или не правильно обрабатываю?
это точно здесь ошибка? и ты не пробовал вместо __try/__except делать try/except ? а по сабжу, юзай SI/Syser/WinDBG
Да, здесь Если закомментить эти строки, все отлично. Через черточку - это на выбор?) И про анализ крэш дампов можно чего нибудь почитать?
Vilco дык я тебе и написал, что вместо сишных __try/__except лучше заюзать try/except. а крешдампы тот же WinDBG анализирует неплохо.
SEH в ядре существенно отличается от юзер-моды. Например, обращение к невыделенной памяти в ядре приведет к краху, даже внутри SEH-фрейма. Очевидно это и происходит в твоём случае. Код (Text): __try { ProbeForRead(...); } __except(EXCEPTION_EXECUTE_HANDLER) { } Это только для защиты юзер-модных адресов! Для ядерных не работает. http://msdn2.microsoft.com/en-us/library/aa489870.aspx "Kernel-mode drivers must use ProbeForRead to validate read access to buffers that are allocated in user space.... Do not use this routine on kernel-mode addresses; it will raise an exception." http://msdn2.microsoft.com/en-us/library/ms809962(printer).aspx
+1 поэтому нужно делать проверку на PreviousMode. Да и на корректность ObjectAttributes тоже не увидел проверки. Код (Text): try{ if (KeGetPreviousMode() == UserMode) ProbeForRead(...); } except (EXCEPTION_EXECUTE_HANDLER) { } перепутал немного, try/except наоброт некошерно для msvc, а ddk кушает одинаково эти блоки.
С проверкой памяти на валидность всегда были проблемы в ядре. Для проверки юзермодных буферов, безусловно, рулит ProbeForRead. Для проверки ядерной памяти уже хуже. Если определить валидность неподкачиваемой памяти еще можно через MmIsAddressValid (которая возвращает TRUE если при доступе к памяти не возникнет #PF), то проверка подкачиваемых ядерных буферов, насколько я знаю, полная задница. Определить наличие буфера физической памяти еще можно через ту же MMIsAddressValid, а вот с определением вообще валидный ли это адрес дела плохи. Вообще странно, почему не предоставили такой полезной возможности. Как вариант, можно вручную прочесать Virtual Address Descriptors
Vilco И что тут непонятно? Все вполне логично. Код (Text): PUNICODE_STRING Name; __try { ProbeForRead( Name, sizeof( *Name ), 2 ); ProbeForRead( Name->Buffer, Name->Length, 1 ); } __except(EXCEPTION_EXECUTE_HANDLER) {} Для ядерных адресов это вызовет исключение, независимо от валидности, поскольку проверяется MmUserProbeAddress и генерится исключение ExRaiseAccessViolation(); если адрес в ядре. Так что если предполагается работа только с user-mode buffer дополнительно проверку KeGetPreviousMode() == UserMode делать не обязательно.
Если честно, я так и не понял как быть в такой ситуации. Разве что вообще не проверять, а сразу в try-except блоке читать ObjectAttributes->ObjectName...
Vilco Ты скажи, где у тебя используется эта структура, то есть кто её заполняет/читает/передает. Если она находится в адресном пространстве ядра - это одно дело, если в буффере кот. находится в user-mode - это другое дело. Если работаешь с чужим буфером - то любые проверки весьма скользкая вещь, поскольку ты можешь, допустим проверить валидность памяти, и сразу после этого кто-то другой ее освободит. Поэтому как правильнее поступить в той или иной ситуации зависит от многих обстоятельств
Обрабатываю функцию NtCreateSection, структера ObjectAttributes заполняется системой. Я так подозреваю, что нехороший буфер находится в адресном пространстве ядра