Retro video games delivered to your door every month!
Click above to get retro games delivered to your door ever month!
X-Hacker.org- Dos Protected Mode Interface - <b>allocate real mode call-back address</b> http://www.X-Hacker.org [<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]
        Allocate Real Mode Call-Back Address


                 This service  is used  to obtain  a  unique  real  mode
                 SEG:OFFSET that will transfer control from real mode to
                 a protected mode procedure.

                 At times  it is necessary to hook a real mode interrupt
                 or device  call-back in  a protected  mode driver.  For
                 example, many  mouse drivers  call an  address whenever
                 the mouse is moved.  Software running in protected mode
                 can use  a real  mode call-back  to intercept the mouse
                 driver calls.

            To Call

                 AX = 0303h
                 DS:(E)SI = Selector:Offset of procedure to call
                 ES:(E)DI = Selector:Offset of real mode call structure

            Returns

                 If function was successful:
                 Carry flag is clear.
                 CX:DX = Segment:Offset of real mode call address

                 If function was not successful:
                 Carry flag is set.

            Call-Back Procedure Parameters

                 Interrupts disabled
                 DS:(E)SI = Selector:Offset of real mode SS:SP
                 ES:(E)DI = Selector:Offset of real mode call structure
                 SS:(E)SP = Locked protected mode API stack
                 All other registers undefined

            Return from Call-Back Procedure

                 Execute an IRET to return
                 ES:(E)DI =  Selector:Offset of real mode call structure
                      to restore (see note)


            Programmer's Notes

                 o    Since the  real mode call structure is static, you
                      must be  careful when  writing code  that  may  be
                      reentered.     The  simplest  method  of  avoiding
                      reentrancy  is   to  leave   interrupts   disabled
                      throughout the  entire  call.    However,  if  the
                      amount of  code executed by the call-back is large
                      then you  will need  to copy  the real  mode  call
                      structure into  another  buffer.    You  can  then
                      return with  ES:(E)DI pointing  to the  buffer you
                      copied the data to -- it does not have to point to
                      the original real mode call structure.
                 o    The called  procedure is responsible for modifying
                      the real mode CS:IP before returning.  If the real
                      mode CS:IP  is left  unchanged then  the real mode
                      call-back will  be executed  immediately and  your
                      procedure will be called again.  Normally you will
                      want to  pop a return address off of the real mode
                      stack and  place it  in the  real mode CS:IP.  The
                      example code  in  the  next  section  demonstrates
                      chaining  to   another   interrupt   handler   and
                      simulating a real mode iret.
                 o    To return  values to the real mode caller you must
                      modify the real mode call structure.
                 o    Remember that  all segment values in the real mode
                      call structure  will contain  real mode  segments,
                      not selectors.    If  you  need  to  examine  data
                      pointed to  by a  real mode seg:offset pointer you
                      should not  use the segment to selector service to
                      create  a  new  selector.    Instead,  allocate  a
                      descriptor during  initialization and  change  the
                      descriptor's  base  to  16  times  the  real  mode
                      segment's  value.     This   is  important   since
                      selectors allocated though the segment to selector
                      service can never be freed.
                 o    DPMI hosts  should provide  a minimum  of 16 call-
                      back addresses per task.



            Example Code

                 The following code is a sample of a real mode interrupt
                 hook.   It hooks  the DOS  Int 21h and returns an error
                 for the delete file function (AH=41h).  Other calls are
                 passed through  to DOS.  This example is somewhat silly
                 but it  demonstrates the techniques used to hook a real
                 mode  interrupt.     Note  that  since  DOS  calls  are
                 reflected  from   protected  mode  to  real  mode,  the
                 following code  will intercept  all DOS calls from both
                 real mode and protected mode.

                 ;******************************************************
                 ; This procedure gets the current Int 21h real mode
                 ; Seg:Offset, allocates a real mode call-back address,
                 ; and sets the real mode Int 21h vector to the call-
                 ; back address.
                 ;******************************************************
                 Initialization_Code:
                 ;
                 ; Create a code segment alias to save data in
                 ;
                         mov     ax, 000Ah
                         mov     bx, cs
                         int     31h
                         jc      ERROR
                         mov     ds, ax
                         ASSUMES DS,_TEXT
                 ;
                 ; Get current Int 21h real mode SEG:OFFSET
                 ;
                         mov     ax, 0200h
                         mov     bl, 21h
                         int     31h
                         jc      ERROR
                         mov     [Orig_Real_Seg], cx
                         mov     [Orig_Real_Offset], dx
                 ;
                 ; Allocate a real mode call-back
                 ;
                         mov     ax, 0303h
                         push    ds
                         mov     bx, cs
                         mov     ds, bx
                         mov     si, OFFSET My_Int_21_Hook
                         pop     es
                         mov     di, OFFSET My_Real_Mode_Call_Struc
                         int     31h
                         jc      ERROR
                 ;
                 ; Hook real mode int 21h with the call-back address
                 ;
                         mov     ax, 0201h
                         mov     bl, 21h
                         int     31h
                         jc      ERROR



                 ;******************************************************
                 ;
                 ; This is the actual Int 21h hook code.  It will return
                 ; an "access denied" error for all calls made in real
                 ; mode to delete a file.  Other calls will be passed
                 ; through to DOS.
                 ;
                 ; ENTRY:
                 ;    DS:SI -> Real mode SS:SP
                 ;    ES:DI -> Real mode call structure
                 ;    Interrupts disabled
                 ;
                 ; EXIT:
                 ;    ES:DI -> Real mode call structure
                 ;
                 ;******************************************************

                 My_Int_21_Hook:
                         cmp     es:[di.RealMode_AH], 41h
                         jne     Chain_To_DOS
                 ;
                 ; This is a delete file call (AH=41h).  Simulate an
                 ; iret on the real mode stack, set the real mode
                 ; carry flag, and set the real mode AX to 5 to indicate
                 ; an access denied error.
                 ;
                         cld
                         lodsw                   ; Get real mode ret IP
                         mov     es:[di.RealMode_IP], ax
                         lodsw                   ; Get real mode ret CS
                         mov     es:[di.RealMode_CS], ax
                         lodsw                   ; Get real mode flags
                         or      ax, 1           ; Set carry flag
                         mov     es:[di.RealMode_Flags], ax
                         add     es:[di.RealMode_SP], 6
                         mov     es:[di.RealMode_AX], 5
                         jmp     My_Hook_Exit
                 ;
                 ; Chain to original Int 21h vector by replacing the
                 ; real mode CS:IP with the original Seg:Offset.
                 ;
                 Chain_To_DOS:
                         mov     ax, cs:[Orig_Real_Seg]
                         mov     es:[di.RealMode_CS], ax
                         mov     ax, cs:[Orig_Real_Offset]
                         mov     es:[di.RealMode_IP], ax

                 My_Hook_Exit:
                         iret

Online resources provided by: http://www.X-Hacker.org --- NG 2 HTML conversion by Dave Pearson