замена обработчика прерывания

Тема в разделе "WASM.BEGINNERS", создана пользователем Lenok____, 15 июн 2008.

  1. Lenok____

    Lenok____ New Member

    Публикаций:
    0
    Регистрация:
    15 июн 2008
    Сообщения:
    2
    привет всем :)

    мне очень нужна помощь: курсовик горит.
    нужна программка, которая "замаскирует" прерывания от клавиатуры до нажатия клавиши ESC. мне сказали, что нужно поменять обработчик прерывания, а я сама даже не знаю толком, что это такое :dntknw:

    один мой однокурсник этим сам занимался когда-то, дал мне вот это:

    Код (Text):
    1. cseg segment
    2.     assume cs:cseg,ds:cseg,es:cseg,ss:cseg
    3.     org 100h
    4. start:  jmp begin
    5.     old_int09h dw   '??'
    6.  
    7. begin: 
    8.     ;сохраняем адрес старого обработчика
    9.     push 0
    10.     pop es
    11.  
    12.     mov ax,es:[09h*4]
    13.     mov word ptr old_int09h,ax
    14.    
    15.     mov ax,es:[09h*4+2]
    16.     mov word ptr old_int09h+2,ax
    17.    
    18.     ;меняем обработчик
    19.     pushf
    20.     cli
    21.     mov es:[09h*4],offset hand_int09h
    22.     mov es:[09h*4+2],cs
    23.     popf
    24.     xor ax,ax
    25.     ;зацикливаемся
    26.     c1: jmp c1
    27.        
    28. hand_int09h proc far
    29.    
    30.             ;считываем скан-код из клавиатуры и сообщаем ей об этом
    31.     in al,60h
    32.     push ax
    33.     in al,61h
    34.     or al,80h
    35.     out 61h,al
    36.     pop ax
    37.    
    38.     ;если нажата не ESC, возвращаем управление программе
    39.     cmp al,01h
    40.     jne ccc
    41.            
    42.     ;если нажата ESC, возвращаем старый обработчик
    43.     pushf
    44.     cli
    45.     mov ax,word ptr [old_int09h]
    46.     mov es:[09h*4],ax
    47.     mov ax,word ptr [old_int09h+2]
    48.     mov es:[09h*4+2],ax
    49.     popf
    50.    
    51.         ;возвращаем управление операционной системе
    52.         mov ah,4ch
    53.         int 21h
    54.    
    55.     ccc: iret
    56. hand_int09h endp
    57. cseg ends
    58. end start
    он сказал, что он там что-то напутал, чтоб я сама ошибку нашла... у него вообще с чувством юмора плохо...
    помогите, кто-нибудь!!! ... а то ведь я помру за этим проклятым компом.

    я в долгу не останусь: расплачусь воздушными поцелуями :)
     
  2. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    Lenok____
    Код (Text):
    1. cseg segment
    2.     assume cs:cseg,ds:cseg,es:cseg,ss:cseg
    3.     org 100h
    4. start:  jmp begin
    5.     old_int09h dw   '??'
    6.  
    7. begin: 
    8.     ;сохраняем адрес старого обработчика
    9. ;;  push 0
    10. ;;  pop es
    11. xor ax,ax
    12. mov es,ax
    13.     mov ax,es:[09h*4]
    14.     mov word ptr old_int09h,ax
    15.    
    16.     mov ax,es:[09h*4+2]
    17.     mov word ptr old_int09h+2,ax
    18.    
    19.     ;меняем обработчик
    20.     pushf
    21.     cli
    22.     mov es:[09h*4],offset hand_int09h
    23.     mov es:[09h*4+2],cs
    24.     popf
    25.     xor ax,ax
    26.     ;зацикливаемся
    27.     c1: jmp c1
    28.        
    29. hand_int09h proc far
    30.    
    31.             ;считываем скан-код из клавиатуры и сообщаем ей об этом
    32.     in al,60h
    33.     push ax
    34.     in al,61h
    35.     or al,80h
    36.     out 61h,al
    37.     pop ax
    38.    
    39.     ;если нажата не ESC, возвращаем управление программе
    40.     cmp al,01h
    41.     jne ccc
    42.            
    43.     ;если нажата ESC, возвращаем старый обработчик
    44.     pushf
    45.     cli
    46.  
    47. push    es
    48. xor ax,ax
    49. mov es,ax
    50. ;;  mov ax,word ptr [old_int09h]
    51. mov ax,word ptr cs:[old_int09h]
    52.     mov es:[09h*4],ax
    53. ;;  mov ax,word ptr [old_int09h+2]
    54. mov ax,word ptr cs:[old_int09h+2]
    55.     mov es:[09h*4+2],ax
    56. pop es
    57.     popf
    58. mov al,20h
    59. out 20h,al
    60.         ;возвращаем управление операционной системе
    61.         mov ah,4ch
    62.         int 21h
    63.    
    64.     ccc:
    65. mov al,20h
    66. out 20h,al
    67.         iret
    68. hand_int09h endp
    69. cseg ends
    70. end start
     
  3. Lenok____

    Lenok____ New Member

    Публикаций:
    0
    Регистрация:
    15 июн 2008
    Сообщения:
    2
    *KISSED* *KISSED* *KISSED*
    ой, спасибо большое, все получилось, теперь еще отчет нужно написать, но эт я как-нибудь уж сама :).
    *KISSED* *KISSED* *KISSED*
     
  4. Vov4ick

    Vov4ick Владимир

    Публикаций:
    0
    Регистрация:
    8 окт 2006
    Сообщения:
    581
    Адрес:
    МО
    Вернее сам, тов. annufriy
    20 порт - программируемый конроллер прерываний.
     
  5. maverick

    maverick New Member

    Публикаций:
    0
    Регистрация:
    16 апр 2008
    Сообщения:
    148
    жесть... q_q мужик расцеловал :)
     
  6. Zhelezka

    Zhelezka New Member

    Публикаций:
    0
    Регистрация:
    21 июл 2008
    Сообщения:
    103
    А как тоже самое сделать под Windows на flat assembler?
     
  7. Freeman

    Freeman New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2005
    Сообщения:
    1.385
    Адрес:
    Ukraine
    убрать кучу убогих коментариев вида "cseg segment", немного подправить синтаксис
     
  8. Zhelezka

    Zhelezka New Member

    Публикаций:
    0
    Регистрация:
    21 июл 2008
    Сообщения:
    103
    Код (Text):
    1. org 100h
    2.  
    3. jmp begin
    4.  
    5. old_sint09h dw ?
    6. old_aint09h dw ?
    7.  
    8. begin:  
    9.  
    10. xor     ax,ax
    11. mov     es,ax
    12.         mov ax,[es:24h]
    13.         mov ax,[es:24h]
    14.         mov [cs:old_aint09h], ax
    15.        
    16.         mov ax,[es:26h]
    17.         mov [cs:old_sint09h],ax
    18.  
    19.         pushf
    20.         cli
    21.         mov [es:24h],word new_int09h
    22.         mov [es:26h],cs
    23.         popf
    24.         xor ax,ax
    25.         ;çàöèêëèâàåìñÿ  
    26.         c1: jmp c1
    27.                
    28. new_int09h:
    29.         in al,60h
    30.         push ax
    31.         in al,61h
    32.         or al,80h
    33.         out 61h,al
    34.         pop ax
    35.  
    36.         cmp al,01h
    37.         jne ccc
    38.  
    39.         pushf
    40.         cli
    41.  
    42. push    es
    43. xor     ax,ax
    44. mov     es,ax
    45. mov     ax,old_aint09h
    46. mov     ax, [cs:old_aint09h]
    47.         mov [es:24h],ax
    48. mov     ax,old_sint09h
    49. mov     ax, [cs:old_sint09h]
    50.         mov [es:26h],ax
    51. pop     es
    52.         popf
    53. mov     al,20h
    54. out     20h,al
    55.  
    56.                 mov ah,4ch
    57.                 int 21h
    58.        
    59.         ccc:
    60. mov     al,20h
    61. out     20h,al
    62.  
    63. iret
    Переделывал—не получилось, помогите
    (Для Windows)
     
  9. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Zhelezka
    Ты в Windows хочешь перехватить обработчик прерываний? Тогда придется писать драйвер.
     
  10. Zhelezka

    Zhelezka New Member

    Публикаций:
    0
    Регистрация:
    21 июл 2008
    Сообщения:
    103
    Меня просто друг попросил:
    Где множно такую найти, или как сделать?
    (другие подробности он не сказал)
     
  11. Nbt

    Nbt New Member

    Публикаций:
    0
    Регистрация:
    2 июл 2004
    Сообщения:
    11
    у руссиновича что-то похожее было. что-то вроде ctrl2caps. поищи на его сайте sysinternals.com
     
  12. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    Было дело - тоже интересовался. Через Native API получалось поставить обработчик только на системный таймер.

    IMHO это надо делать через SIDT и вручную модифицировать таблицу дескрипоров прерываний. Здесь на сайте есть руководство по защищённому режиму - его следует прочитать в первую очередь.

    Номера прерываний процессора и клавиатуры по-моему не изменны. Это 0 и 1 соответственно.
     
  13. CrystalIC

    CrystalIC New Member

    Публикаций:
    0
    Регистрация:
    26 июл 2008
    Сообщения:
    500
    Эмм.. Младшие вектора отведены под исключения, при старте ядра выполняется редирект прерываний.
    Не понимаю для чего они поступили так, но авторы ядра NT раскидали устройства по всей IDT, а не последовательно. Вобщем, чтобы создать шлюз прерывания проблема только одна - это нужно сделоть в каждой IDT(для каждого процессора она уникальна). В висте и Win7 нам помогли - в списке экспорта есть KeIpiGenericCall(). В остальных она не экспортируется. В принципе можно заюзать некоторые экспорты хал. Можно поступить иначе - перечислить все таблицы, с GDT проще, список их начинается одной их переменных ядра. Как вариант - подменить указатель на IDT в idtr каждого процессора, но это всё упирается в синхронизацию. Я делал это поиском/вызовом KeIpiGenericCall() что приводит к исполению кода последовательно на всех ядрах.
    С дескриптором всё просто, код для текущего процессора:
    Код (Text):
    1. INTERRUPT_GATE struct
    2. OffsetLo    WORD ?          ;Bits 0-15
    3. Selector        WORD ?          ;Bits 16-31
    4. AccessRights    WORD ?
    5. OffsetHi        WORD ?     
    6. INTERRUPT_GATE ends
    7. PINTERRUPT_GATE typedef ptr INTERRUPT_GATE
    8.  
    9. IDTR_FIELD struct
    10. _Limit  WORD ?
    11. _Base   PVOID ?
    12. IDTR_FIELD ends
    13. PIDTR_FIELD typedef ptr IDTR_FIELD
    14.  
    15. SetInterruptGate proc PrivilegeLevel:ULONG, InterruptNumber:ULONG, Vector:PVOID, Selector:ULONG
    16. Local Descriptor:IDTR_FIELD
    17.     cli
    18.     sidt Descriptor
    19.     mov eax,InterruptNumber
    20.     mov edx,Descriptor._Base
    21.     lea edx,[edx+eax*SizeOf INTERRUPT_GATE]
    22.     assume edx:PINTERRUPT_GATE
    23.     mov eax,Vector
    24.     mov [edx].OffsetLo,ax
    25.     shr eax,16
    26.     mov [edx].OffsetHi,ax
    27.     mov eax,Selector
    28.     mov [edx].Selector,ax
    29.     mov eax,PrivilegeLevel
    30.     mov [edx].AccessRights,1000111000000000b
    31.     .if Eax
    32.     or [edx].AccessRights,   0110000000000000b
    33.     .endif
    34.     sti
    35.     ret
    36. SetInterruptGate endp
    Номер прерывания для клавиатуры не помню, можно посмотреть. Документированный способ подвеситсо на прерывание - KeConnectInterrupt().
     
  14. CrystalIC

    CrystalIC New Member

    Публикаций:
    0
    Регистрация:
    26 июл 2008
    Сообщения:
    500
    Zhelezka
    Если нужно, могу шелкодес накидать..
     
  15. bugaga

    bugaga New Member

    Публикаций:
    0
    Регистрация:
    1 июл 2007
    Сообщения:
    361
    Под виндой (NTVDM, 32 bit) можно и так:
    Код (Text):
    1. var
    2.     irq0sel,irq0ofs,
    3.     myds : integer;
    4.     count: integer;
    5.  
    6. procedure irq0hand;
    7. asm push ds
    8.     mov  ds,cs:myds
    9.     inc  count
    10.     pop  ds
    11. // continue interupt
    12.     push cs:irq0sel
    13.     push cs:irq0ofs
    14.     retf
    15. end;
    16.  
    17. procedure main;
    18. var
    19.     tsc :int64;
    20.     irq0:integer;
    21. begin
    22.     write('Wait... '+n);
    23. // preserve data sel for interrupt routine
    24.     myds := DS;
    25. // get PIC0 (master) base interrupt
    26.     irq0 := GetDpmiVer and $FF;
    27. // store prev handler
    28.     irq0sel := GetPMInt(irq0) shr 32;
    29.     irq0ofs := GetPMInt(irq0);
    30. // hook int
    31.     SetPMInt (irq0,@irq0hand,CS);
    32. // do measure test
    33.     tsc := rdtsc;
    34.     count := 0;
    35.     repeat //1 sec delay
    36.     until count >= 18; //18hz - default timer clock
    37.     tsc := rdtsc-tsc;
    38. // restore vector
    39.     SetPMInt(irq0,pointer(irq0ofs),irq0sel);
    40. // print msg
    41.     write('CPU freq:'+DecStr( tsc div (1000 * 1000) )+' Mhz'+n);
    42. end;
    43. end.
    реализации ф-нкций

    Код (Text):
    1. function GetDpmiVer:integer;
    2. asm push ebx
    3.     mov eax, 400h // DPMI Get Version
    4.     int 31h
    5.     mov al,dh // DH = current value of master PIC base interrupt (low 8 IRQs)
    6.     mov ah,dl // DL = current value of slave  PIC base interrupt (high 8 IRQs)
    7.     pop ebx
    8. end;
    9.  
    10. procedure SetPMInt(vect:integer;proc:pointer;sel:integer);
    11. asm push ebx
    12.     mov  ebx,eax
    13.     mov  eax,205h //DPMI Set Protected Mode Interrupt Vector
    14.     int  31h
    15.     pop  ebx
    16. end;
    17.  
    18. function GetPMInt(vect:integer):int64;
    19. asm push ebx
    20.     mov  ebx,eax
    21.     mov  eax,204h //DPMI Set Protected Mode Interrupt Vector
    22.     mov  ecx,cs
    23.     int  31h
    24.     mov  eax, edx
    25.     mov  edx, ecx
    26.     pop  ebx
    27. end;
     
  16. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    CrystalIC
    А если на каждое ядро поставить свой обработчик клавиатуры они будут выполняться одновременно? Или существуют какие-то приоритеты?
     
  17. CrystalIC

    CrystalIC New Member

    Публикаций:
    0
    Регистрация:
    26 июл 2008
    Сообщения:
    500
    murder
    Хэндлер прерывания для любого ядра имеет одну и туже точку входа, адрес ISR в шлюзе одинаков. Контроллеры прерываний ведь последовательно включены. Поднимается IRQL для синхронизации, хэндлер начинается с HalBeginSystemInterrupt().
     
  18. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    1) номер прерывания процессора? круто
    2) не путай irq и номера векторов в таблице
     
  19. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    Код (Text):
    1. номер прерывания процессора?
    Ну в смыле исключение (неправильный опкод, деление на ноль)

    Не судите строго - я не программирую в режиме ядра, просто интересуюсь для общего развития.
     
  20. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    Не будут. Контроллер прерываний отпровляет прерывание только одному процессору(ядру).

    Есть IDT - таблица векторов прерываний.
    А есть IRQ номера входов в контроллер прерываний. Дальше они преобразовываются в вектора из IDT.
    В IDT первые 20h заняты под процессорные нужды.
    Что касается IRQ то
    IRQ0 в PIC режиме таймер. В APIC IRQ0 каскадно подключен к PIC0.
    IRQ1- клавиатура
    IRQ2 в PIC режиме каскадно подключен к PIC1. В APIC IRQ2 таймер.