Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1200 lines
23 KiB

;
;
; SaveRest.asm
;
; This file contains the two function SaveRegs() and RestoreRegs().
; These functions save/restore AX, BX, CX, DX, DS, ES, and flags to/from
; the stack. For each SaveRegs() call there should be a matching
; RestoreRegs() call to cleanup the stack.
;
; Please note that no local variables is used here since we are dealing
; with the app's DS.
;
;
.MODEL LARGE
PUBLIC _SaveRegs
PUBLIC _RestoreRegs
PUBLIC _GrovelDS
PUBLIC _UnGrovelDS
PUBLIC _HookAdd
PUBLIC _HookFind
PUBLIC _HookSearch
PUBLIC _Hooks
PUBLIC HOOKCALL
PUBLIC HookTable
PUBLIC _HookProc
PUBLIC HookCount
.CODE
_SaveRegs PROC FAR
;
; This is how the stack looks like upon entering this routine:
;
; +-------+-------+---
; |Ret Seg|Ret Off|
; +-------+-------+---
; SP+4 SP+2 SP+0
;
; <- popping makes sp go <-
; -> pushing makes sp go ->
;
push bp ; Remeber where we are during this stuff
mov bp,sp ; BP = Original SP - 2
push ax
push bx
push cx
push dx
push si
push di
push ds
push es
push ss
pushf
mov bx,[bp+4] ; Grab Ret Seg
mov ax,[bp+2] ; Grab Ret Off
push bx ; Put Ret Seg on Stack
push ax ; Put Ret Off on Stack
mov bp,[bp+0] ; Restore original BP
;
; This is how the stack looks like just before executing RET:
;
; +------+------+------+--+--+--+--+--+--+--+--+--+-----+-------+-------+--
; |Dummy1|Dummy2|Dummy3|AX|BX|CX|DX|SI|DI|DS|ES|SS|FLAGS|Ret Seg|Ret Off|
; +------+------+------+--+--+--+--+--+--+--+--+--+-----+-------+-------+--
;30 SP+28 SP+26 SP+24 22 20 18 16 14 12 10 8 6 SP+4 SP+2 SP+0
;
; <- popping makes sp go <-
; -> pushing makes sp go ->
;
; First Dummy location actually contains the Ret Seg
; Second Dummy location actually contains the Ret Off
; Third Dummy location actually contains a copy of the original BP
;
ret
_SaveRegs ENDP
_RestoreRegs PROC FAR
;
; This is how the stack looks like upon entering this routine:
;
; +------+------+------+--+--+--+--+--+--+--+--+--+-----+-------+-------+--
; |Dummy1|Dummy2|Dummy3|AX|BX|CX|DX|SI|DI|DS|ES|SS|FLAGS|Ret Seg|Ret Off|
; +------+------+------+--+--+--+--+--+--+--+--+--+-----+-------+-------+--
;30 SP+28 SP+26 SP+24 22 20 18 16 14 12 10 8 6 SP+4 SP+2 SP+0
;
; <- popping makes sp go <-
; -> pushing makes sp go ->
;
; First Dummy location actually contains the Old Ret Seg
; Second Dummy location actually contains the Old Ret Off
; Third Dummy location actually contains an old copy of original BP
;
pop ax ; Get Ret Off
pop bx ; Get Ret Seg
push bp ; Save a temporary copy of original BP
mov bp,sp ; BP = Original SP + 2
mov [bp+26],bx ; Put Ret Seg on Stack
mov [bp+24],ax ; Put Ret Off on Stack
pop ax ; Get Original BP
mov [bp+22],ax ; Put it in the original BP place
popf
pop ss
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
pop bp
;
; This is how the stack looks like just before executing RET:
;
; +-------+-------+---
; |Ret Seg|Ret Off|
; +-------+-------+---
; 0 2 4
;
ret
_RestoreRegs ENDP
_GrovelDS PROC FAR
;
; This is how the stack looks like upon entering this routine:
;
; +-------+-------+---
; |Ret Seg|Ret Off|
; +-------+-------+---
; SP+4 SP+2 SP+0
;
; <- popping makes sp go <-
; -> pushing makes sp go ->
;
push bp ; Remeber where we are during this stuff
mov bp,sp ; BP = Original SP - 2
push ax ; save original ax
push ds ; save original ds
mov ax, [bp+4] ; get return segment
push ax
mov ax, [bp+2] ; get return offset
push ax
mov ax, [bp-2] ; restore ax
mov bp, [bp+0] ; restore original bp
mov ds, [bp-2] ; get apps ds
;
; This is how the stack looks like just before executing RET:
;
; +------+------+------+--+--+-------+-------+--
; |Dummy1|Dummy2|Dummy3|AX|DS|Ret Seg|Ret Off|
; +------+------+------+--+--+-------+-------+--
;14 SP+12 SP+10 8 6 4 SP+2 SP+0
;
; <- popping makes sp go <-
; -> pushing makes sp go ->
;
; First Dummy location actually contains the Ret Seg
; Second Dummy location actually contains the Ret Off
; Third Dummy location actually contains a copy of the original BP
;
ret
_GrovelDS ENDP
_UnGrovelDS PROC FAR
;
; This is how the stack looks like upon entering this routine:
;
; +------+------+------+--+--+-------+-------+--
; |Dummy1|Dummy2|Dummy3|AX|DS|Ret Seg|Ret Off|
; +------+------+------+--+--+-------+-------+--
;14 SP+12 SP+10 8 6 4 SP+2 SP+0
;
; <- popping makes sp go <-
; -> pushing makes sp go ->
;
; First Dummy location actually contains the Ret Seg
; Second Dummy location actually contains the Ret Off
; Third Dummy location actually contains a copy of the original BP
;
push bp ; Remeber where we are during this stuff
mov bp,sp ; BP = Original SP - 2
mov [bp+8], ax ; save ax
pop ax ; save original BP
mov [bp+10], ax
pop ax ; save return offset
mov [bp+12], ax
pop ax ; save return segment
mov [bp+14], ax
pop ds ; get DLLs ds back
pop ax ; get ax
pop bp ; get original bp
;
; This is how the stack looks like just before executing RET:
;
; +-------+-------+---
; |Ret Seg|Ret Off|
; +-------+-------+---
; 0 2 4
;
ret
_UnGrovelDS ENDP
.DATA
HookCount dw 0000h
HookTable dd 00000000h ;
dd 00000000h ;
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
dd 00000000h
.CODE
HOOKCALL PROC
push bp
mov bp,sp
mov dx,[bp+4] ; Get Return Segment
mov ax,[bp+2] ; Get Return Offset
mov bx,[bp+10] ; Get Segment to call
mov cx,[bp+8] ; Get Offset to call
mov [bp+10],dx ; Put Return Segment in nice place
mov [bp+8],ax ; Put Return Offset in nice place
mov ax,[bp+6] ; Get that AX value
mov [bp+6],bx ; Put Segment to call in nice place
mov [bp+4],cx ; Put Offset to call in nice place
pop bp
add sp,+2
ret ; Phony jmp
HOOKCALL ENDP
_HookProc PROC
; Original Return Address 4 BP+6/BP+8
; Table Lookup Return Address 4 BP+2/BP+4
push bp ; BP+0
mov bp,sp ;
push ax ; These two locations are used to store
push ax ; the return address for phony jumping
push ax ; A place to store the BP
push ax ; The real saved AX value
push ds
mov ax,[bp] ; Get Original BP
mov [bp-6],ax ; Save it in its place
mov ds,[bp+4] ; Set DS = CS
mov bx,[bp+2] ; Get Return address
mov dx,[bx] ; Get the Table Index #
mov ax,_DATA
mov ds,ax
mov bx,offset HookTable
mov cl,3
shl dx,cl
add bx,dx ; BX = Address of Table entry #
mov ax,[bp+6] ; Get original return address
mov dx,[bp+8]
mov [bp+2],dx ; Put it on as the new return address
mov [bp],ax
mov ax,[bx]
mov dx,[bx+2]
mov [bp+8],dx ; Put another parameter on the stack
mov [bp+6],ax ; trashing the phony pointer
mov ax,[bp-8] ; Get one of the pushed AX values
mov [bp+4],ax ; Put it in a spot as a parameter
add bx,+4
mov ax,[bx]
mov dx,[bx+2]
mov [bp-2],dx ; Phony return address (for ret'f ing)
mov [bp-4],ax ;
pop ds
pop ax ; Restore, incase anybody cares
pop bp ; Restore to original value
ret
pop bx ; Get Return Address
pop dx
push di
push si
mov di,ax ; Save passed AX
mov si,ds ; Save old DS
mov ds,dx ; DS = Code Segment of Caller
mov dx,[bx] ; Get Table #
mov cx,_DATA
mov ds,cx ; DS = _DATA
assume ds: _DATA
mov bx,offset HookTable
mov cl,3
shl dx,cl
add bx,dx ; BX = address of table entry #
pop cx ; Get Real Return Address of caller
pop dx
mov ax,[bx+2]
push ax ; Push parameter
mov ax,[bx]
push ax
push dx ; Re-Put down Real Return Address
push cx
add bx,+4
mov ax,[bx]
mov dx,[bx+2]
push dx
push ax ; Push address to Jmp to (Jmp via push/ret)
mov ds,si ; Restore original DS
mov ax,di
ret
_HookProc ENDP
_Hooks PROC
call FAR PTR _HookProc
dw 0000h
db 0h
call FAR PTR _HookProc
dw 0001h
db 0h
call FAR PTR _HookProc
dw 0002h
db 0h
call FAR PTR _HookProc
dw 0003h
db 0h
call FAR PTR _HookProc
dw 0004h
db 0h
call FAR PTR _HookProc
dw 0005h
db 0h
call FAR PTR _HookProc
dw 0006h
db 0h
call FAR PTR _HookProc
dw 0007h
db 0h
call FAR PTR _HookProc
dw 0008h
db 0h
call FAR PTR _HookProc
dw 0009h
db 0h
call FAR PTR _HookProc
dw 000Ah
db 0h
call FAR PTR _HookProc
dw 000Bh
db 0h
call FAR PTR _HookProc
dw 000Ch
db 0h
call FAR PTR _HookProc
dw 000Dh
db 0h
call FAR PTR _HookProc
dw 000Eh
db 0h
call FAR PTR _HookProc
dw 000Fh
db 0h
call FAR PTR _HookProc
dw 0010h
db 0h
call FAR PTR _HookProc
dw 0011h
db 0h
call FAR PTR _HookProc
dw 0012h
db 0h
call FAR PTR _HookProc
dw 0013h
db 0h
call FAR PTR _HookProc
dw 0014h
db 0h
call FAR PTR _HookProc
dw 0015h
db 0h
call FAR PTR _HookProc
dw 0016h
db 0h
call FAR PTR _HookProc
dw 0017h
db 0h
call FAR PTR _HookProc
dw 0018h
db 0h
call FAR PTR _HookProc
dw 0019h
db 0h
call FAR PTR _HookProc
dw 001Ah
db 0h
call FAR PTR _HookProc
dw 001Bh
db 0h
call FAR PTR _HookProc
dw 001Ch
db 0h
call FAR PTR _HookProc
dw 001Dh
db 0h
call FAR PTR _HookProc
dw 001Eh
db 0h
call FAR PTR _HookProc
dw 001Fh
db 0h
call FAR PTR _HookProc
dw 0020h
db 0h
call FAR PTR _HookProc
dw 0021h
db 0h
call FAR PTR _HookProc
dw 0022h
db 0h
call FAR PTR _HookProc
dw 0023h
db 0h
call FAR PTR _HookProc
dw 0024h
db 0h
call FAR PTR _HookProc
dw 0025h
db 0h
call FAR PTR _HookProc
dw 0026h
db 0h
call FAR PTR _HookProc
dw 0027h
db 0h
call FAR PTR _HookProc
dw 0028h
db 0h
call FAR PTR _HookProc
dw 0029h
db 0h
call FAR PTR _HookProc
dw 002Ah
db 0h
call FAR PTR _HookProc
dw 002Bh
db 0h
call FAR PTR _HookProc
dw 002Ch
db 0h
call FAR PTR _HookProc
dw 002Dh
db 0h
call FAR PTR _HookProc
dw 002Eh
db 0h
call FAR PTR _HookProc
dw 002Fh
db 0h
call FAR PTR _HookProc
dw 0030h
db 0h
call FAR PTR _HookProc
dw 0031h
db 0h
call FAR PTR _HookProc
dw 0032h
db 0h
call FAR PTR _HookProc
dw 0033h
db 0h
call FAR PTR _HookProc
dw 0034h
db 0h
call FAR PTR _HookProc
dw 0035h
db 0h
call FAR PTR _HookProc
dw 0036h
db 0h
call FAR PTR _HookProc
dw 0037h
db 0h
call FAR PTR _HookProc
dw 0038h
db 0h
call FAR PTR _HookProc
dw 0039h
db 0h
call FAR PTR _HookProc
dw 003Ah
db 0h
call FAR PTR _HookProc
dw 003Bh
db 0h
call FAR PTR _HookProc
dw 003Ch
db 0h
call FAR PTR _HookProc
dw 003Dh
db 0h
call FAR PTR _HookProc
dw 003Eh
db 0h
call FAR PTR _HookProc
dw 003Fh
db 0h
call FAR PTR _HookProc
dw 0040h
db 0h
call FAR PTR _HookProc
dw 0041h
db 0h
call FAR PTR _HookProc
dw 0042h
db 0h
call FAR PTR _HookProc
dw 0043h
db 0h
call FAR PTR _HookProc
dw 0044h
db 0h
call FAR PTR _HookProc
dw 0045h
db 0h
call FAR PTR _HookProc
dw 0046h
db 0h
call FAR PTR _HookProc
dw 0047h
db 0h
call FAR PTR _HookProc
dw 0048h
db 0h
call FAR PTR _HookProc
dw 0049h
db 0h
call FAR PTR _HookProc
dw 004Ah
db 0h
call FAR PTR _HookProc
dw 004Bh
db 0h
call FAR PTR _HookProc
dw 004Ch
db 0h
call FAR PTR _HookProc
dw 004Dh
db 0h
call FAR PTR _HookProc
dw 004Eh
db 0h
call FAR PTR _HookProc
dw 004Fh
db 0h
call FAR PTR _HookProc
dw 0050h
db 0h
call FAR PTR _HookProc
dw 0051h
db 0h
call FAR PTR _HookProc
dw 0052h
db 0h
call FAR PTR _HookProc
dw 0053h
db 0h
call FAR PTR _HookProc
dw 0054h
db 0h
call FAR PTR _HookProc
dw 0055h
db 0h
call FAR PTR _HookProc
dw 0056h
db 0h
call FAR PTR _HookProc
dw 0057h
db 0h
call FAR PTR _HookProc
dw 0058h
db 0h
call FAR PTR _HookProc
dw 0059h
db 0h
call FAR PTR _HookProc
dw 005Ah
db 0h
call FAR PTR _HookProc
dw 005Bh
db 0h
call FAR PTR _HookProc
dw 005Ch
db 0h
call FAR PTR _HookProc
dw 005Dh
db 0h
call FAR PTR _HookProc
dw 005Eh
db 0h
call FAR PTR _HookProc
dw 005Fh
db 0h
call FAR PTR _HookProc
dw 0060h
db 0h
call FAR PTR _HookProc
dw 0061h
db 0h
call FAR PTR _HookProc
dw 0062h
db 0h
call FAR PTR _HookProc
dw 0063h
db 0h
call FAR PTR _HookProc
dw 0064h
db 0h
call FAR PTR _HookProc
dw 0065h
db 0h
call FAR PTR _HookProc
dw 0066h
db 0h
call FAR PTR _HookProc
dw 0067h
db 0h
call FAR PTR _HookProc
dw 0068h
db 0h
call FAR PTR _HookProc
dw 0069h
db 0h
call FAR PTR _HookProc
dw 006Ah
db 0h
call FAR PTR _HookProc
dw 006Bh
db 0h
call FAR PTR _HookProc
dw 006Ch
db 0h
call FAR PTR _HookProc
dw 006Dh
db 0h
call FAR PTR _HookProc
dw 006Eh
db 0h
call FAR PTR _HookProc
dw 006Fh
db 0h
call FAR PTR _HookProc
dw 0070h
db 0h
call FAR PTR _HookProc
dw 0071h
db 0h
call FAR PTR _HookProc
dw 0072h
db 0h
call FAR PTR _HookProc
dw 0073h
db 0h
call FAR PTR _HookProc
dw 0074h
db 0h
call FAR PTR _HookProc
dw 0075h
db 0h
call FAR PTR _HookProc
dw 0076h
db 0h
call FAR PTR _HookProc
dw 0077h
db 0h
call FAR PTR _HookProc
dw 0078h
db 0h
call FAR PTR _HookProc
dw 0079h
db 0h
call FAR PTR _HookProc
dw 007Ah
db 0h
call FAR PTR _HookProc
dw 007Bh
db 0h
call FAR PTR _HookProc
dw 007Ch
db 0h
call FAR PTR _HookProc
dw 007Dh
db 0h
call FAR PTR _HookProc
dw 007Eh
db 0h
call FAR PTR _HookProc
dw 007Fh
db 0h
_Hooks ENDP
_HookSearch PROC
push bp
mov bp,sp ; Set a nice example
push ds ; Save old DS
mov ax,_DATA
mov ds,ax ; DS = _DATA
assume ds: _DATA
mov cx,HookCount
or cx, cx
jz notfound ; nothing to do if no entries
again2:
push cx
mov bx,offset HookTable
mov ax,cx ; Get Index
dec ax
mov cl,3 ; * sizeof record
shl ax,cl
add bx,ax ; ds:bx = &HookTable[ax]
mov di,[bp+10] ; compare old hook entry
mov si,[bp+12]
cmp di,[bx]
jnz nope2
cmp si,[bx+2]
jnz nope2
mov di,[bp+6] ; compare new hook entry
mov si,[bp+8]
cmp di,[bx+4]
jnz nope2
cmp si,[bx+6]
jnz nope2
mov si,offset _Hooks
mov di,seg _Hooks
add ax,si
mov dx,di ; Return &Hooks[HookCount]
pop cx
jmp getout2
nope2:
pop cx
loop again2
notfound:
mov ax, 0
mov dx, 0
getout2:
pop ds ; Restore old DS
pop bp ; Nice C stack frame
ret
_HookSearch ENDP
_HookAdd PROC
push bp
mov bp,sp ; Set a nice example
push ds ; Save old DS
mov ax,_DATA
mov ds,ax ; DS = _DATA
assume ds: _DATA
; Call HookSearch to see if this hook already exists
mov ax,[bp+12]
push ax
mov ax,[bp+10]
push ax
mov ax,[bp+8]
push ax
mov ax,[bp+6]
push ax
call FAR PTR _HookSearch
add sp, 8
; If hook already exists just return it.
cmp dx, 0
jne LeaveHookAdd
mov ax,HookCount ; ax = HookCount++
inc HookCount
cmp ax,0080h
jae stopit
mov si,offset _Hooks
mov di,seg _Hooks
mov bx,offset HookTable
mov cl,3
shl ax,cl
add bx,ax ; ds:bx = &HookTable[ax]
add si,ax ; di:si = &Hooks[ax]
mov ax,[bp+10]
mov dx,[bp+12]
mov [bx],ax
mov [bx+2],dx ; *ds:bx = *ss:bp+4
add bx,+4
mov ax,[bp+6]
mov dx,[bp+8]
mov [bx],ax
mov [bx+2],dx ; *(ds:bx+4) = *(ss:bp+8)
mov ax,si
mov dx,di ; Return &Hooks[HookCount]
LeaveHookAdd:
pop ds ; Restore old DS
pop bp ; Nice C stack frame
ret
stopit:
int 3
db 'Out of available hooks',0
_HookAdd ENDP
_HookFind PROC
push bp
mov bp,sp ; Set a nice example
push ds ; Save old DS
mov ax,_DATA
mov ds,ax ; DS = _DATA
assume ds: _DATA
mov di,[bp+6]
mov si,[bp+8]
mov cx,HookCount
again:
push cx
mov bx,offset HookTable
mov ax,cx ; Get Index
mov cl,3 ; * sizeof record
shl ax,cl
add bx,ax ; ds:bx = &HookTable[ax]
cmp di,[bx]
jnz nope
cmp si,[bx+2]
jnz nope
mov si,offset _Hooks
mov di,seg _Hooks
add ax,si
mov dx,di ; Return &Hooks[HookCount]
pop cx
jmp getout
nope:
pop cx
loop again
mov ax, 0
mov dx, 0
getout:
pop ds ; Restore old DS
pop bp ; Nice C stack frame
ret
_HookFind ENDP
END