
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>
[<<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