Привет! Как из kernel-mode изменить атрибуты защиты страниц, например, на PAGE_EXECUTE_READWRITE? Какая функция для этого нужна? ПАМАГИТЕ! Заранее благодарю.
Если под ХР+, то MmProtectMdlSystemAddress. Если ниже, то вроде никак. В смысле через функции. Руками по PTE лазить надо. ЗЫ: PAGE_EXECUTE_READWRITE это обманка для юзера. На x86 это просто PAGE_READWRITE.
Все вроде у меня получилось, но когда делаю MDL для виртуального адреса user-mode процесса и если попадаю на секцию .rdata (только для чтения), то MmProbeAndLockPages() дает исключение, которое я даже на PASSIVE_LEVEL не могу обработать SEH’ом! Почему так происходит? Код (Text): ULONG * pu = NULL; PMDL pmdl; pu = (ULONG*)(*(ULONG*)ioBuffer); pmdl = MmCreateMdl(0, pu, sizeof(ULONG)); if(pmdl) { __try{ MmProbeAndLockPages(pmdl, KernelMode, IoModifyAccess); pu = MmGetSystemAddressForMdl(pmdl); if(pu && NT_SUCCESS(MmProtectMdlSystemAddress(pmdl, PAGE_READWRITE))) { *pu = 13; } MmUnlockPages(pmdl); } __except(EXCEPTION_EXECUTE_HANDLER){ } IoFreeMdl(pmdl); }
Four-F Да, но ZwProtectVirtualMemory экспортируется ntdll.dll, которая находится в user-mode, а мне надо бы все делать из kernel-mode!
Глянь таблицу экспорта в ntdll - там она уходит в SDT. А так как принцип вызова эдентичен везде, то просто глянь чё ложится в EAX перед Int 2Eh. И сам вызови её уже из ntoskrnl. Не очень то уж и геморно. Если уж прям суждено юзать только ZwProtectVirtualMemory.
Four-F Если бы не BSOD MmProbeAndLockPages() на секции токо для чтения, то MmProtectMdlSystemAddress() выручила бы меня! PavPS Но Руссинович пишет о том, что номера сервисов зависят от номера build’a Windows (их номера генерируются автоматически при компиляции ядра!) и поэтому мне int 2Eh (или SYSENTER) ничего не даст.
Да нет, именно это я и имел ввиду, что ты сам должен малец дизасеммблить тот кусок кода, который стоит перед Int 2Eh. Ты должен глянуть, чё ложится в EAX ZwProtectVirtualMemory proc near ; CODE XREF: sub_0_77F5A981+69p .text:77F7EC43 ; sub_0_77F5A981+106p ... .text:77F7EC43 mov eax, 89h ; NtProtectVirtualMemory .text:77F7EC48 mov edx, 7FFE0300h .text:77F7EC4D call edx .text:77F7EC4F retn 14h .text:77F7EC4F ZwProtectVirtualMemory endp разбираешь опкод этого mov eax, 89h и вперед... Например я так вызаваю некоторые ф-ии сам, и пока - пашет на разных build-ах. А в то что вызов этой ф-ии изменит свою _сруктуру_, так это вроде революций никаких в MS нет. Вроде не должен. Ну для гарантии можно проверять по каким-нить сигнатурам. Короче, у меня пашет.
PavPS Смотри, плз, у Руссиновича на стр. 100 Примечание! У меня тоже eax=89h, но если так сделать, то потом у кого-то мой драйвер может вызвать BSOD!!!!
rsrc, а какова конечная цель? Если просто писАть из драйвера в юзерную память, то можно сбросить WP. А если именно изменить атрибуты памяти юзерных адресов, то MmProtectMdlSystemAddress тут, IMHO, не поможет, т.к. она вроде только с системными адресами работает. MmGetSystemAddressForMdl вернет тебе адрес в ядре, куда будет отображена пользовательская память. Вот для этой проекции ты и поменяешь атрибуты, а юзерные страницы как были так и останутся со старыми атрибутами. Если я всё правильно понимаю.
Four-F Моя конечная цель это отображать (через MDL) в системное адресное пространство секции ресурсов (битмапы) user-модулей и потом из программных системных потоков выводить все это в видеопамять 25-кадром. И все хорошо, да вот только на секции только для чтения MmProbeAndLockPages() выдает BSOD и наверное придется при сборке exeшников эти секции делать RW. В user-mode невозможно сделать 25-кадр потому, что квант равен примерно 20 мс (показывать картинку надо примерно 42 мс и через 958 мс), а когда еще прога получит квант хз и поэтому возникает мерцание надписи типа “7 лет не пить!”.
Так а зачем атрибуты то менять? Тебе же картинки читать надо будет. Так и отображай себе спокойно. Код (Text): try { pMdl = IoAllocateMdl( Address, cb, FALSE, FALSE, NULL ); if ( pMdl != NULL ) { MmProbeAndLockPages( pMdl, KernelMode, IoReadAccess ); pBuffer = MmGetSystemAddressForMdlSafe( pMdl, NormalPagePriority ); if ( pBuffer != NULL ) { Value = * (ULONG*) pBuffer; MmUnlockPages( pMdl ); Status = STATUS_SUCCESS; } IoFreeMdl( pMdl ); } } except(EXCEPTION_EXECUTE_HANDLER) { if ( pMdl != NULL ) { IoFreeMdl( pMdl ); } Status = GetExceptionCode(); } Странно, что MmProbeAndLockPages у тя бсодит. Точно я не уверен, но вроде при любом из флагов IoWriteAccess или IoModifyAccess она тоже самое делает. А именно ProbeForWrite. А это должно обрабатываться SEH, иначе можно было бы любому драйверу послать контрол с METHOD_OUT_DIRECT и указателем на read-only буфер... и кирдык, даже не доходя до драйвера.
Four-F <font color="red]CПАСИБО!</font><!--color--> <font color="green]CПАСИБО!</font><!--color--> <font color="blue]CПАСИБО!</font><!--color--> MmProbeAndLockPages(,,IoReadAccess) уже c этим флагом не бсодит и что самое интересное так это то, что можно даже и писАть в read-only user-mode страницы закрепленные с таким IoReadAccess флагом!