Вообщем такая лажа - не могу подкачать страницу из драйвера, т.е. страница всеже подкачивается но управление мне не возвращается! Вот смотрите Код (Text): push dwAddr <- нужная мне страница call GetPte mov eax, [eax] <- беру соотв. PTE и проверяю сброшена ли страница на диск test al, 1 jnz page_in_memory ;если страница сброшена, то ставлю свой обработчик ;и обращаюсь к странице, но назад управление не ;получаю!!!! push fs push ds mov ax, 23h <- на всякий случай mov ds, ax mov ax, 30h mov fs, ax push offset ExceptionHandler push dword ptr fs:[0] mov dword ptr fs:[0], esp mov SafeEip, offset SafePlace mov PrevEbp, ebp mov PrevEsp, esp sti <- поднимаю флаг прерывания, т.к. все это происходит в другом обработчик прерывания - 0xD SafePlace: add already_patched, 2 mov eax, dwAddr mov eax, [eax] <- генерирую исключение add already_patched, 0x100 pop dword ptr fs:[0] add esp, 4 pop ds pop fs cli jmp page_in_memory nop nop nop ExceptionHandler: push ds <- управления даже не попадает сюда! mov ax, 23h mov ds, ax add already_patched, 0x10000000 pop ds mov eax, dword ptr [esp + 0Ch] //pContext push SafeEip push PrevEsp push PrevEbp pop dword ptr [eax + 0B4h] pop dword ptr [eax + 0C4h] pop dword ptr [eax + 0B8h] xor eax, eax ret page_in_memory:
процедура GetPte взята из исходников IceExt, в ней можно не сомневатся Как уже писал управления даже не попадает в установленный мной обработчик исключений! :-\ Вот такая лажа! Что может быть не так? И как это вообще сделать?
staier Да уж - точно не шариш Шестнадцатиразрядные регистры тут не причем, это я ж там сегменты настраиваю... Там я мелким почерком написал, что вся эта байда выполняется в обработчике 0xD прерывания, из него то мне и нужно подкачать страницу. Народ, ну скажите что нибудь умное! - таво и гляди и мне шонибудь умное придет в голову ~|
Я подумал что IRQL слишком высокий, но это врядле, т.к. система то не падает, а вот управления я не получаю назад! Да и вызов GetCurrentIRQL из обработчика, чето приводит к краху
хм ... я не претендую на звание .. но всеже .. скажу\спрошу вы пишите test al, 1 jnz page_in_memory а вы уверены что нужно именно так проверять биты в структуре PTE ?? там же струтура типа : 31 ---- 12 --биты-- 0 Также надо проверять битовый флаг Valid .. Ну ладно страница подкачивается - это хорошо ... И еще Зачем в fs помещать 30h. Да и вопрос - уверн что исключение вызывается ? может эта страница присутствует и в нее нормально записываются данные и никаких исключений.
TermoSINteZ на "вы" не надо! мне то всего ничего - 24 года, так что на вы не надо именно нулевой бит в PTE определяет присутствие страницы, это стопудово, и та проверка совершенно правильна тут даже сомниватся не приходится. в fs заношу 30h, т.к. этот код является обработчиком прерывания 0xD и соответственно может быть вызван в любой ситуации, а fs=30h стандартное его состояния для режима ядра - ...ну я ж исключение через него обрабатываю Да и вопрос - уверн что исключение вызывается ? может эта страница присутствует и в нее нормально записываются данные и никаких исключений. если страница присутствует, то управление передается на метку page_in_memory, и там я с ней нормально работаю - это проверено ужо 15000 раз. По сути то дела (насколько я понимаю), обращение к сброшеной странице не должно являтся исключением (т.е. мне воовсе не обязательно ставить обработчик, как я это делаю), но просто уже я настолько за#бался, что даже просто нету слов - одни... это, как говорится - нех#й матерится
Вообще-то суть общей проблемы в следующем имеется код ринг3 вот такой nop nop int 6 nop nop При выполнении данного кода возникает исключение #GP т.е. инт0xD (все же int 6 просто так ему выполнить нельзя). На инт0xD сидит мой обработчик, который пытается поставить в обработчике исключений этой проги бряк 0xCC, дабы знать де остановится (...ну надо мне так) ну делаю я так, сначала получаю адресс обработчика Код (Text): pushad push fs mov ax, 38h mov fs, ax mov eax, dword ptr fs:[0] mov eax, [eax + 4] mov dwAddr, eax pop fs push dwAddr call GetPte mov eax, [eax] mov SavedPTE, eax test al, 1 jnz page_in_memory тут тоже все нормально. и потом смотрю, что если он в памяти, то ставлю бряк 0xCC и все путем, а если же нет - то вот такая вот лажа
Отвечать, как подкачать страницу в память из обработчика прерывания, воовсе не обязательно... Ну, просто скажите что нибудь умное!
Существуют механизмы для работы с памятью в режиме прерывания (высокий IRQL). Для примера: списки, фиксация... Чем это тебе не подходит ?