Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Копирование памяти из обработчика int 1  (Прочитано 9008 раз)
0 Пользователей и 1 Гость смотрят эту тему.
_Ms-Rem_
Гость
« : 17-04-2005 04:41 » 

Я пытаюсь в обработчике первого прерывания (генерируется аппаратно при отладке) изменить память процесса, выскакивает синий экран IRQL_NOT_LESS_OR_EQUAL.
KeGetCurrentIrql возвращает PASSIVE_LEVEL.
Что делать?
мне нужно копировать вытесняемую память синхронно, я не могу использовать apc, mdl создать тоже не могу.
Записан
dachny
Гость
« Ответ #1 : 19-04-2005 07:44 » 

Странно все это
Вот это   "в обработчике первого прерывания"
Плюс вот это   "KeGetCurrentIrql возвращает PASSIVE_LEVEL"

По моему память процесса (Юзер мод я так понимаю) имеет нерезидентный стораж
и в полне законно что в "обработчике первого прерывания" ты получаешь заслуженную синьку с подписью IRQL_NOT_LESS_OR_EQUAL

Вот это только странно "KeGetCurrentIrql возвращает PASSIVE_LEVEL"

Записан
_Ms-Rem_
Гость
« Ответ #2 : 19-04-2005 08:13 » 

Может у меня система глючит, но KeGetCurrentIrql мне всегда возвращает PASSIVE_LEVEL.
В общем, я проблему уже решил (окольным путем), но если кто знает, то подскажите, а то я пока прямого решения этой проблемы нигде не нашел, подобные вопросы задавали многие на форумах, но никто ничего реального еще не предложил.
Записан
dimedrol
Помогающий

ru
Offline Offline

« Ответ #3 : 19-04-2005 16:27 » 

_Ms-rem_, мне вот что интересно:
1.
Цитата
Может у меня система глючит, но KeGetCurrentIrql мне всегда возвращает PASSIVE_LEVEL.
Это вообще всегда (даже после KeRaiseIrql(DISPATCH_LEVEL,..)) или только в обработчике прерывания. Если только в обработчике то
 это при входе в обработчик или вообще даже после попыток поднять IRQL?
2. Каким образом устанавливается обработчик прерывания? Если через IoConnectInterrupt, то при вызове вроде можно явно указать IRQL под которым будет исполнятся ISR.
Если подменой адреса в нужном элементе IDT, то мне кажется система не сможет сделать необходимые операции по синхронизации, установке IRQL итд и вполне может прерваться скажем на PASSIVE_LEVEL.
Записан

Как говориться, cемь бед - один Reset Улыбаюсь
dimedrol
Помогающий

ru
Offline Offline

« Ответ #4 : 19-04-2005 18:06 » 

Вот я задался вопросом: "А что же такое этот IRQL? Какая-то софтварьная выдумка или что-то еще?" Отдизасмил KeRaiseIrql, что в hal.dll:
Код:
....
80012258 dword_80012258  dd 41413D00h, 81716151h, 0B1B1A191h, 3 dup(0B1B1B1B1h)
80012258                                         ; DATA XREF: KfRaiseIrql+3r
80012258                                         ; KfLowerIrql+6r ...
80012258                 dd 0C1B1B1B1h, 0FFEFE1D1h

..........
         KfRaiseIrql     proc near               ; CODE XREF: sub_800122F8+5p
80012278                                         ; .text:80014C75p ...
80012278                 movzx   edx, cl
8001227B                 movzx   ecx, byte ptr ds:dword_80012258[edx]
80012282                 mov     eax, ds:0FFFE0080h
80012287                 mov     ds:0FFFE0080h, ecx
8001228D                 shr     eax, 4
80012290                 movzx   eax, byte ptr ds:unk_8001D088[eax]
80012297                 retn
80012297 KfRaiseIrql     endp
...........
Почитав Pentium4 Software Developers Manual с intel.com понял, что FFFE0080 - это адрес Task Priority Register APIC, который оперделяет приоритет текущей задачи и может млужить отсеивателем ненужных событий, прерываний. Формат:
0-3   - Task Priority SubClass
4-7   - Task Priority Class
8-31  - Reserved
Из дизасма видно, что для PASSIVE_LEVEL в TPR пишется 0x00, те все прерывания разрешены (IntPrioirty>TaskPriority чтобы сработало), APC_LEVEL - 0x3D, DISPATCH_LEVEL - 0x41,.... HIGHEST_LEVEL - 0xFF - процессор мертв для прерываний (проверял в SoftIce).
Это я все к чему - прерывание Int1 по умолчанию может иметь такой приоритет (при трассировке Kernel Debugger-ом он наверно искусственно повышается), что скажем при IRQL >=APC_LEVEL проц его проигнорирует.
Я конечно не утверждаю точно, тем более что еще не разобрался как эти приоритеты устанавливаются.. Но все же это вполне возможно. Так и получится что в обработчике int1 всегда PASSIVE_LEVEL (в обработчике на который указывает адрес в IDT).
« Последнее редактирование: 19-04-2005 18:19 от dimedrol » Записан

Как говориться, cемь бед - один Reset Улыбаюсь
_Ms-Rem_
Гость
« Ответ #5 : 20-04-2005 00:26 » 

Прерывание перехватывается изменением IDT,  KeGetCurrentIrql всегда возвращает 0, даже после KeRaiseIrql.
Irql при возникновении прерывания устанавливается аппаратно процессором, так как к памяти обратиться не удается.
Записан
dimedrol
Помогающий

ru
Offline Offline

« Ответ #6 : 20-04-2005 10:30 » 

Цитата
Прерывание перехватывается изменением IDT,  KeGetCurrentIrql всегда возвращает 0, даже после KeRaiseIrql.
Опробовал у себя в драйвере:
Код:
__asm
{
      pushad
      sidt [idtr]
      lea ebx, [idtr]
      mov ebx,[ebx+2] //adddress if IDT
      add ebx,8       //address of INT 1 descriptor
      lea eax,[irq1]
      mov edi,[ebx]
      mov esi,[ebx+4]
      mov [eax],edi
      mov [eax+4], esi
      //setup new idt entry
      lea eax, __int1
      mov [ebx],ax
      shr eax,16
      mov [ebx+6],ax
      push cs
      pop eax
      mov [ebx+2],ax
      mov byte ptr[ebx+4],0
      mov byte ptr[ebx+5],10001111b
      pushfd
      or dword ptr ss:[esp],100h //TF set
      popfd
      nop       //int1
      jmp __over
///int1 handler begin
__int1:
      nop
    }
    KeRaiseIrql(DISPATCH_LEVEL, &irql_old);
    irql_now = KeGetCurrentIrql();
__asm{
      cmp [irql_now], PASSIVE_LEVEL
      je _endbeep

//Do beep begin
      mov al, 7
      out 61h, al
      mov eax, 0FFFFFFFh
_lp:  dec eax
      nop
      nop
      nop
      jnz _lp
      out 61h, al
//do beep end
_endbeep:   
      nop
}
    KeLowerIrql(irql_old);
__asm{
      mov eax,[esp+8]
      and ah,0FEh //tf clear
      mov [esp+8], eax
      iretd
///int1 handler end
      nop
__over: //restore old vector
      lea eax, [irq1]
      mov esi,[eax]
      mov edi,[eax+4]
      mov [ebx],esi
      mov [ebx+4],edi
      popad
};
Бип слышу всегда..
Цитата
Irql при возникновении прерывания устанавливается аппаратно процессором, так как к памяти обратиться не удается.
Не знаю, не знаю.. Вот я проверил и точно установил, что по крайней мере у меня IRQL внутри обработчика будет такой же какой в момент возникновения прерывания. Так-что если оно генерится под юзермодом то кроме PASSIVE_LEVEL ничего и не будет, это проверено (немного видоизменил код: DPL=3+елемент IDT не восстанавливается)..

А как ты вообще смотрел что возвращает KeGetCurrentIrql (уж не отладчиком ли?)? Может тут какая ошибка затесалась?
« Последнее редактирование: 20-04-2005 11:00 от dimedrol » Записан

Как говориться, cемь бед - один Reset Улыбаюсь
SlavaI
Главный специалист

ru
Offline Offline

« Ответ #7 : 22-04-2005 10:19 » 

И зачем столько мучался- тебе же точно сказали-  IRQL_NOT_LESS_OR_EQUAL, это значит что ты на IRQL>APC_LEVEL трогаешь вытесняемую память, это определил обработчик ошибок страниц путем проверки IRQL при возникновении ошибки. Вобще то при вызове обработчиков прерываний IRQL повышают, если обработчик прерывания зарегистрирован стандартным способом. Если пропатчить IDT, то по моему действительно IRQL при вызове ф-ции, указанной в IDT, будет тот на котором работал прерванный поток( кстати он не обязвтельно PASSIVE, может быть и DISPATCH и выше )
« Последнее редактирование: 22-04-2005 14:09 от SlavaI » Записан
dimedrol
Помогающий

ru
Offline Offline

« Ответ #8 : 23-04-2005 15:07 » 

SlavaI, ты указал мне на такую статью http://www.osronline.com/article.cfm?article=374, ее полная версия(зарегаться надо)http://www.osronline.com/article.cfm?article=380, там описывается
случай, когда при исполнении кода под IRQL==PASSIVE_LEVEL выскакивало IRQL_NOT_LESS_OR_EQUAL при сбросе флага прерываний(cli?), что оказалось эквивалентно IRQL==HIGHEST_LEVEL. Вполне возможно, что здесь как раз этот случай.
« Последнее редактирование: 23-04-2005 15:11 от dimedrol » Записан

Как говориться, cемь бед - один Reset Улыбаюсь
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines