Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Changing interrupt code....

MainForzeMainForze Member Posts: 36
For example: I'd like to change INT 10h AX=0013h (set mode 13)
to set Mode-X. How should i go about this? Should i change the interrupt address in the Interrupt Vector Table??? This could be very cool to do... I could also implement my own keyboard handler or something!! Could someone give me a web-address or just send me some docs???

Thanks in advance, MainForze

(Sorry for my bad English, it's not my native language, you know :-))

Comments

  • blipblip Member Posts: 756
    To be able to change an int's code, you need to begin with the interrupt vector table. It is located in the first 1K (1024 bytes) of your PC's memory. There are 256 interrupts and each has its own 4 byte entry.
    Example code:

    start:
    jmp install
    cmp ax,13h ;Are they trying to go into mode 13h
    jne caller ;If not, call the real int 10h and return to
    ;the calling program. If so, execute your code (remember to
    ;save any changed registers!)

    ;Resident code here (Your ModeX stuff)
    jmp return
    caller:
    pushf
    call 1234:5678
    return:
    iret ;This returns from an interrupt, like RET it returns to the
    ;original CS:IP, but this also pops the saved flags
    install:
    xor ax,ax
    mov ds,ax ;Point DS to the Interrupt Vector Table
    mov si,10h*4
    push cs
    pop es
    mov di,offset caller + 1
    movsw
    movsw ;Save the original int 10h address
    mov ax,offset start
    cli ;Clear interrupts; don't want to be called and screw up!
    mov ds:[10h*4],ax ;Write IP for int 10h
    mov ax,cs
    mov ds:[10h*4+2],ax ; Write CS for int 10h
    sti ;Enable them
    push cs
    pop ds
    mov ds:[100h],9090h ;Write NOPs over the JMP so this doesn't
    ;try to reinstall itself whenever it's called
    mov ax,3100h ;Terminate stay resident
    mov dx,offset (install + 100h) / 16 ;Paragraphs, not bytes for
    ;mem allocation and you must remember to include the PSP
    int 21h
    end start

    E-mail me any questions or comments: bthompson67665@yahoo.com
    Also, e-mail me if you want a much better TSR (one that doesn't let you install it multiple times!)

  • MainForzeMainForze Member Posts: 36
    Thanks for the info!!!

    One little question though.... Is this what they call "Interrupt Hooking"?? Or is that something else?

    MainForze

    : To be able to change an int's code, you need to begin with the interrupt vector table. It is located in the first 1K (1024 bytes) of your PC's memory. There are 256 interrupts and each has its own 4 byte entry.
    : Example code:
    :
    : start:
    : jmp install
    : cmp ax,13h ;Are they trying to go into mode 13h
    : jne caller ;If not, call the real int 10h and return to
    : ;the calling program. If so, execute your code (remember to
    : ;save any changed registers!)
    :
    : ;Resident code here (Your ModeX stuff)
    : jmp return
    : caller:
    : pushf
    : call 1234:5678
    : return:
    : iret ;This returns from an interrupt, like RET it returns to the
    : ;original CS:IP, but this also pops the saved flags
    : install:
    : xor ax,ax
    : mov ds,ax ;Point DS to the Interrupt Vector Table
    : mov si,10h*4
    : push cs
    : pop es
    : mov di,offset caller + 1
    : movsw
    : movsw ;Save the original int 10h address
    : mov ax,offset start
    : cli ;Clear interrupts; don't want to be called and screw up!
    : mov ds:[10h*4],ax ;Write IP for int 10h
    : mov ax,cs
    : mov ds:[10h*4+2],ax ; Write CS for int 10h
    : sti ;Enable them
    : push cs
    : pop ds
    : mov ds:[100h],9090h ;Write NOPs over the JMP so this doesn't
    : ;try to reinstall itself whenever it's called
    : mov ax,3100h ;Terminate stay resident
    : mov dx,offset (install + 100h) / 16 ;Paragraphs, not bytes for
    : ;mem allocation and you must remember to include the PSP
    : int 21h
    : end start
    :
    : E-mail me any questions or comments: bthompson67665@yahoo.com
    : Also, e-mail me if you want a much better TSR (one that doesn't let you install it multiple times!)
    :


  • blipblip Member Posts: 756
    Yes, this is what they call "Interrupt Hooking" except that this is a non-standard way to do this because I wrote over some of my own code instead of changing the IP entry to 102h instead of 100h (that's what [italic]really[/italic] happens in the CPU).

    Any other questions, anyone?

  • AsmGuru62AsmGuru62 Member Posts: 6,519
    : Yes, this is what they call "Interrupt Hooking" except that this is a non-standard way to do this because I wrote over some of my own code instead of changing the IP entry to 102h instead of 100h (that's what [italic]really[/italic] happens in the CPU).
    :
    : Any other questions, anyone?
    :

    You should change INT code only if you cannot overcome it another way. If you just want to set a graph mode - just write a routine and call it... Full control over keyboard is another matter - without replacing INT 9h you cannot achieve it...


  • MainForzeMainForze Member Posts: 36
    Yeah, I know but the mode-setting thing was just an example. The TSR would be pretty useless anyway because when a program would try to change to mode13h, it'd expect a linear addressing mode, and NOT an unchained mode. But I see what you mean...

    Installing my own keyboard handler would indeed be a good (and faster?) idea. Thank fer the tip!!!

    Regards, MainForze

    : : Yes, this is what they call "Interrupt Hooking" except that this is a non-standard way to do this because I wrote over some of my own code instead of changing the IP entry to 102h instead of 100h (that's what [italic]really[/italic] happens in the CPU).
    : :
    : : Any other questions, anyone?
    : :
    :
    : You should change INT code only if you cannot overcome it another way. If you just want to set a graph mode - just write a routine and call it... Full control over keyboard is another matter - without replacing INT 9h you cannot achieve it...
    :
    :


  • DariusDarius Member Posts: 1,666
    : Yeah, I know but the mode-setting thing was just an example. The TSR would be pretty useless anyway because when a program would try to change to mode13h, it'd expect a linear addressing mode, and NOT an unchained mode. But I see what you mean...
    :
    : Installing my own keyboard handler would indeed be a good (and faster?) idea. Thank fer the tip!!!
    :
    : Regards, MainForze
    :
    : : : Yes, this is what they call "Interrupt Hooking" except that this is a non-standard way to do this because I wrote over some of my own code instead of changing the IP entry to 102h instead of 100h (that's what [italic]really[/italic] happens in the CPU).
    : : :
    : : : Any other questions, anyone?
    : : :
    : :
    : : You should change INT code only if you cannot overcome it another way. If you just want to set a graph mode - just write a routine and call it... Full control over keyboard is another matter - without replacing INT 9h you cannot achieve it...
    : :
    : :
    :
    :

    This is pretty much an extension to what AsmGuru62 said. Typically, there are only two cases when you want to hook an int.

    The more typical one is when you are are writing a TSR. You'd hook an arbitrary software interrupt or the multiplexor interrupt (see Art of Assembly (as always)) so that any program that used your TSR would have a defined way of accessing it. You don't typically overwrite software interrupts unless you are going to EXTEND they're functionality, and even that not frequently. You rarely overwrite the functionality of an existing interrupt. The most common case of this is if you need to change a specific function to (once again) extend the capabilities, but of a specific function. A good example of this is a Hard disk BIOS overwriting the old BIOS int 13h handler to handle a larger or unusual harddrive. In almost all of these cases you should call the previous handler, either before or after your code, unless you completely reimplement that particular function, which should be in a way that is still compatible with the normal usage of that function.

    The other case which is less typical (with the exception of INT 8 and INT 9) is hooking hardware interrupts. In DOS these are 8-F and 70h-77h. These are _real_ interrupts. They are called when the IRQ line for that device transitions. These require a little special handling in both code and policy. The code change is fairly minimal, you simply need to out 20h,20h (or out A0h, 20h) before iretting. The policy change is major, though if ignored it's changes may be subtle. Hardware interrupts can happen at ANY time, and will be handled immediately after the last opcode the processor was currently decoding is executed. Your programs now run asychronously and are subject to the pitfalls of that condition. Anyways, these hooks are rarely made. The interrupts created by devices are typically simply to signal that data is ready to be read or that an operation has completed. An example of the first is the Keyboard INT, and example of the latter is the Hard disk INT.

    As I said earlier, the commonly hooked hardware interrupts are 8 and 9. These correspond to IRQ0 and IRQ1. These are the Timer INT and the Keyboard INT respectively, and these are about the only two hardware interrupts that most application would find any interest in. The timer interrupt is good for establishing a pulse to your program. If you change the the timer's speed via the PIT, you should hook this INT to maintain the BIOS clock correctly, though not doing so will only result in it being wrong until a reset. Another VERY interesting use is to use it to dispatch threads in your program. You can either implement a very specific, but simple threading system on a per-program basis, or you can generalize it and make it into a library. The other IRQ (INT 9) is the keyboard int. AsmGuru62 is wrong when he says you'll need to hook this int to have complete control of the keyboard, technically. However, to efficiently have complete control. You would have to hook it. Interrupts keep you from having to use a polling loop which is very wasteful of processor time. This interrupt is hooked often to provide a higher degree of control, functionality, response, and, yes, SPEED to real-time application (technical jargon for game, hehe). Chances are you aren't gonna be slower than BIOS, if you are shoot yourself right now! Not only is BIOS slow in and of itself, but pretty much the extent of it's functions are a blocking call to get input, or a call that let's you do the polling, only now you're polling BIOS instead of the keyboard, all for an xlat to ASCII. As I said earlier, polling is usually terribly inefficient.




Sign In or Register to comment.