File:  [OS/2 SDKs] / pmsdk / samples / spy / spyhstrt.asm
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs
Thu Aug 9 12:28:20 2018 UTC (7 years, 9 months ago) by root
Branches: msft, MAIN
CVS tags: pmsdk-1989, HEAD
Microsoft OS/2 SDK PM 02-24-1989

;  SPYHOOK library initialization routine
;  Created by Microsoft Corporation, 1989

?WIN=1	    ; Use Windows prolog/epilog
?PLM=1	    ; Use PLM calling convention
DOS5=1
.xlist
include cmacros.inc
.list

; Define some constants to help build stack trace
savedCS = 4
savedIP = 2
savedBP = 0
savedDS = -2

sBegin	DATA
assumes DS,DATA
public	__acrtused
__acrtused = 1
sEnd	DATA

sBegin	CODE
assumes cs,CODE
assumes ds,DATA

EXTRN	Init:NEAR
.286p

;
; Registers set up by DosLoadModule...
;
;   SI = heap size
;   DI = module ID
;   DS = library's automatic data segment
;
cProc	LoadProc,<FAR,PUBLIC>
cBegin	LoadProc

	push di
	call Init	      ; Init( hmod );

cEnd	LoadProc



; CopyStruct
;
; CopyStruct(pbSrc, pbDst, cb)
;
cProc	CopyStruct,<NEAR,PUBLIC>,<DS,SI,DI>
ParmD  pbSrc
ParmD  pbDest
ParmW  cb
cBegin

	mov	cx,cb
	jcxz	lcopydone	    ; all done if cb == 0

	mov	bx,seg_pbDest
	lar	ax,bx		    ; make sure we have access
	jnz	lcopyDone	    ; no access
	les	di,pbDest

	lsl	ax,bx		    ; get the segment limit
	mov	bx,di		    ; check range
	add	bx,cx		    ; ending byte to copy
	jc	lcopyDone	    ; overflowed
	cmp	ax,bx
	jc	lcopyDone	    ; no room at destination

	mov	bx,seg_pbSrc
	lar	ax,bx		    ; make sure we have access
	jnz	lcopyDone	    ; no access

	lds	si,pbSrc
	lsl	ax,bx		    ; get the segment limit
	mov	bx,si		    ; check range
	add	bx,cx		    ; ending byte to copy
	jc	lcopyDone	    ; overflowed
	cmp	ax,bx
	jc	lcopyDone	    ; Source is not big enough

	cmp	si,di
	jae	lcopyok
	mov	ax,cx
	dec	ax
	add	si,ax
	add	di,ax
	std
	rep	movsb
	cld
	jmp	short lcopydone
lcopyok:
	cld
	rep	movsb
lcopydone:
cEnd




cProc	BuildStackTrace,<NEAR,PUBLIC>,<SI,DI>
ParmD	pStackSave
ParmW	cCallsIgnore
ParmW	cCallsSave

cBegin
	les	di,pStackSave		; where to save away stack info
	mov	bx,bp
	mov	dx,ss
	lsl	dx,dx
;
; First we need to ignore the defined number of entries
	mov	cx,cCallsIgnore
	jcxz	SaveLoop		; Dont ignore any?
NextBPToIgnore:
	and	bx,0FFFEh		; Flush any INC BP bit
	jz	SaveLoop		; End of chain if zero
	cmp	bx,dx			; BP outside of stack segment?
	jae	SaveLoop		; Yes, end of chain
	mov	si,bx			; Save current BP
	mov	bx,ss:[bx].savedBP	; SS:BX -> next frame in BP chain
	and	bl,0FEh 		; Flush any INC BP bit
	cmp	bx,si			; savedBP valid?
	jbe	SaveLoop		; No, end of chain
	dec	cx			; decrement count of calls to ignore
	jnz	NextBPToIgnore		; Process the next one

;
; This loop will save away the specified number of calls into the
; passed in save area

SaveLoop:
	mov	cx,cCallsSave		; get count of calls to save

NextBPToSave:
	and	bx,0FFFEh		; Flush any INC BP bit
	jz	EndBPChain		    ; End of chain if zero
	cmp	bx,dx			; BP outside of stack segment?
	jae	EndBPChain		    ; Yes, end of chain
; see if short or long call and setup selLast
	mov	si,ss:[bx].savedCS	; Get the code segment
	lar	ax,si			; get the access rights
	jnz	CSNotValid		; No access assume not selector
	and	ah,018h 		; see if code segment
	cmp	ah,018h 		;
	jz	CSValid 		; code segment, so  save it

CSNotValid:
	xor	si,si			; Not valid, set selector to NULL
CSValid:
	mov	ax,ss:[bx].savedIP	; save away IP of caller
	stosw
	mov	ax,si			; and save away the code selector
	stosw
	dec	cx			; decrement count of how many to save

	mov	si,bx			; Save current BP
	mov	bx,ss:[bx].savedBP	; SS:BX -> next frame in BP chain
	and	bl,0FEh 		; Flush any INC BP bit
	cmp	bx,si			; savedBP valid?
	jbe	EndBPChain		; No
	jcxz	StackOverflowsSave	; Stack is deeper than save area

	jmp	NextBPToSave
;
; We reached the end of the BP chain before we saved the specified number
; of stack items.  zero out the next item to signal caller how many items
; were filled in

EndBPChain:
	jcxz	FillInSelectors
	xor	ax,ax			; Ended BP Chain Before count
	stosw				; Put A 0:0 to signal end
	stosw
	sub	di,4			; realign DI to last saved call
	mov	ax,es:[di-2]		; ax = Selector of last saved call
	jmp	FillInSelectors 	;

;
; We saved the specified number of items, before we reached the end of the
; BP chain.  If the last item we saved was a local call, we should continue
; to go through the stack until we find a valid far return address.

StackOverflowsSave:
	or	ax,ax			; Was last call local?
	jnz	FillInSelectors 	;

; loop to locate a FAR return address
NextBPToCheck:
	and	bx,0FFFEh		; Flush any INC BP bit
	jz	FarReturnNotFound	; End of chain if zero
	cmp	bx,dx			; BP outside of stack segment?
	jae	FarReturnNotFound	; Yes, end of chain
; see if short or long call and setup selLast
	mov	ax,ss:[bx].savedCS	; Get the code segment
	lar	cx,ax			; get the access rights
	jnz	CSNotValid2		; No access assume not selector
	and	ch,018h 		; see if code segment
	cmp	ch,018h 		;
	jz	FillInSelectors 	; ax has valid code selector, use it

CSNotValid2:
	mov	si,bx			; Save current BP
	mov	bx,ss:[bx].savedBP	; SS:BX -> next frame in BP chain
	and	bl,0FEh 		; Flush any INC BP bit
	cmp	bx,si			; savedBP valid?
	jg	NextBPToCheck
FarReturnNotFound:
	mov	ax,0ffffh		; use special value to show

;
; Loop through and convert all Short return addresses into long return
; addresses
;
FillInSelectors:
	mov	cx,off_pStackSave
FillInLoop:
	cmp	di,cx			; have we back tracked all the way?
	jz	FillInEnd		; Yes
	sub	di,4			; point back to previous item
	cmp	WORD PTR es:[di+2],0	; is the selector zero?
	jz	LocalReturn		; Yes, local return
	mov	ax,es:[di+2]		; No FAR return, save CS selector
	jmp	FillInLoop
LocalReturn:
	mov	es:[di+2],ax		; Make long return using saved CS
	jmp	FillInLoop

FillInEnd:
cEnd

sEnd	CODE

end	LoadProc

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.