Только начал изучение r0. Как написано в msdn, функция проверяет произойдет ли ошибка страницы при чтении\записи Также её опасность при проверках на валидность ядерного указателя описана: - http://blogs.msdn.com/doronh/archive/2006/03/09/547793.aspx - http://www.wasm.ru/forum/viewtopic.php?id=19547 Те по любому должно бсодонуть при передаче ей невалидного ядерного указателя. Но во многих исходниках она применялась с этой целью. Собственный эксперимент также показал, что для невалидного указателя возвращается FALSE (те все правильно). Раскопки wrk (WRK-v1.2\base\ntos\mm\pagfault.c : MmIsAddressValid->MiIsAddressValid) показали, что она практически сводится (за исключением ещё пары проверок на макросах, ктр не стал раскручивать) к проверки флага Valid в PTE. Из Руссиновича: Те все в принципе верно и её можно использовать для проверки валидности ядерного указателя, но инфа в вышеприведенных ссылках исходит от достаточно опытных людей и меня берут сомнения =\ Возможно при какихто обстоятельствах она таки выдает неверные результаты ( Valid = 1 для невалидного указателя или какие то проблемы в MiGetPteAddress/MiGetPdeAddress 0___0)? Или я чегото серьёзно недопонимаю (что намного реальнее ^____^)?
Booster Нужно скопировать буфер; буфер не мой и в общем случае я не могу сказать валиден ли он в данный момент. Мне надо быть уверенным, что при передаче невалидного указателя она не вернет TRUE или сбсоднет. И конечно верно ли я её понимаю вообще >___>. >>В каких? Ну даже на этом форуме советовали в старых темах =)
Ну вроде бы всё верно написали, что ты ещё хочешь-то? Реально MmIsAddressValid() может сказать тебе, валиден ли адрес или нет, но тебе это ничего не даст, т.к. уже через мгновение после проверки адрес может стать невалидным и ты всё равно свалишь систему при последующем обращении по этому адресу. Подобные проверки следует использовать тогда, когда у тебя есть гарантия, что в данный момент ты монопольно владеешь проверяемым виртуальным адресом, иначе в этом просто нет смысла. Для тебя специально там же в исходнике пометка:
x64 да, мне понятно, что ниже DISPATCH_LEVEL поток может быть вытеснен после проверки, что возможно сделает результат недействительным. Но мне интересно понимание самой функции =) в принципе все понятно стало, и в приведенных ссылках (да, сознаюсь, невнимательно прочитал) ненадежность функции выводят из вытеснения потоков и нахождении страницы в файле подкачки =) (млин, надо же так туманно написать). Хотя в принципе это не её проблемы - на момент проверки - результаты корректны и говорят о том, что на данный адрес отображена физическая память =). Всем спасибо за вопросы и ответы )
Позволю себе вставить свои пять копеек. Функция лишь проверяет бит Pte->Hard.Valid, что ровным счетом ничего не говорит о том, можно ли обращаться по данному VA в данный конкретный момент. Она может вернуть TRUE, а реально страница выгрузится через мгновение. С тем же успехом она может вернуть FALSE для вполне корректных адресов (корректных длянизких IRQL) - например, для вида секции (прототипные PTE невалидные), для только что выделенной через ZwAllocateVirtualMemory памяти (demand-zero PTE тоже невалидные), для выгруженной в своп памяти (paged-out PTE и transition PTE тка же невалидные). Но обращение к этим страницам на низких IRQL (<DISPATCH_LEVEL) вполне корректно и не вызовет ошибки (#PF будет корректно обработан). Она годится лишь для проверки доступности адреса на высоких IRQL - тогда "валидность адреса" тождественно равно "Pte->Hard.Valid == TRUE". В противном случае обращаться к странице нельзя (при IRQL >= DISPATCH_LEVEL). Для проверки обращения на низких IRQL функция не годится.
>ниже DISPATCH_LEVEL поток может быть вытеснен после проверки, что возможно сделает результат недействительным Кроме того, процессоров много