Annotation of pmsdk/samples/spy/spyhstrt.asm, revision 1.1.1.2

1.1       root        1: ;  SPYHOOK library initialization routine
1.1.1.2 ! root        2: ;  Created by Microsoft Corporation, 1989
1.1       root        3: 
1.1.1.2 ! root        4: ?WIN=1     ; Use Windows prolog/epilog
        !             5: ?PLM=1     ; Use PLM calling convention
        !             6: DOS5=1
        !             7: .xlist
        !             8: include cmacros.inc
        !             9: .list
        !            10: 
        !            11: ; Define some constants to help build stack trace
        !            12: savedCS = 4
        !            13: savedIP = 2
        !            14: savedBP = 0
        !            15: savedDS = -2
1.1       root       16: 
1.1.1.2 ! root       17: sBegin DATA
        !            18: assumes DS,DATA
1.1       root       19: public __acrtused
                     20: __acrtused = 1
1.1.1.2 ! root       21: sEnd   DATA
1.1       root       22: 
1.1.1.2 ! root       23: sBegin CODE
        !            24: assumes cs,CODE
        !            25: assumes ds,DATA
1.1       root       26: 
                     27: EXTRN  Init:NEAR
1.1.1.2 ! root       28: .286p
1.1       root       29: 
                     30: ;
                     31: ; Registers set up by DosLoadModule...
                     32: ;
                     33: ;   SI = heap size
                     34: ;   DI = module ID
                     35: ;   DS = library's automatic data segment
                     36: ;
1.1.1.2 ! root       37: cProc  LoadProc,<FAR,PUBLIC>
        !            38: cBegin LoadProc
1.1       root       39: 
                     40:        push di
                     41:        call Init             ; Init( hmod );
                     42: 
1.1.1.2 ! root       43: cEnd   LoadProc
1.1       root       44: 
1.1.1.2 ! root       45: 
        !            46: 
        !            47: ; CopyStruct
        !            48: ;
        !            49: ; CopyStruct(pbSrc, pbDst, cb)
        !            50: ;
        !            51: cProc  CopyStruct,<NEAR,PUBLIC>,<DS,SI,DI>
        !            52: ParmD  pbSrc
        !            53: ParmD  pbDest
        !            54: ParmW  cb
        !            55: cBegin
        !            56: 
        !            57:        mov     cx,cb
        !            58:        jcxz    lcopydone           ; all done if cb == 0
        !            59: 
        !            60:        mov     bx,seg_pbDest
        !            61:        lar     ax,bx               ; make sure we have access
        !            62:        jnz     lcopyDone           ; no access
        !            63:        les     di,pbDest
        !            64: 
        !            65:        lsl     ax,bx               ; get the segment limit
        !            66:        mov     bx,di               ; check range
        !            67:        add     bx,cx               ; ending byte to copy
        !            68:        jc      lcopyDone           ; overflowed
        !            69:        cmp     ax,bx
        !            70:        jc      lcopyDone           ; no room at destination
        !            71: 
        !            72:        mov     bx,seg_pbSrc
        !            73:        lar     ax,bx               ; make sure we have access
        !            74:        jnz     lcopyDone           ; no access
        !            75: 
        !            76:        lds     si,pbSrc
        !            77:        lsl     ax,bx               ; get the segment limit
        !            78:        mov     bx,si               ; check range
        !            79:        add     bx,cx               ; ending byte to copy
        !            80:        jc      lcopyDone           ; overflowed
        !            81:        cmp     ax,bx
        !            82:        jc      lcopyDone           ; Source is not big enough
        !            83: 
        !            84:        cmp     si,di
        !            85:        jae     lcopyok
        !            86:        mov     ax,cx
        !            87:        dec     ax
        !            88:        add     si,ax
        !            89:        add     di,ax
        !            90:        std
        !            91:        rep     movsb
        !            92:        cld
        !            93:        jmp     short lcopydone
        !            94: lcopyok:
        !            95:        cld
        !            96:        rep     movsb
        !            97: lcopydone:
        !            98: cEnd
        !            99: 
        !           100: 
        !           101: 
        !           102: 
        !           103: cProc  BuildStackTrace,<NEAR,PUBLIC>,<SI,DI>
        !           104: ParmD  pStackSave
        !           105: ParmW  cCallsIgnore
        !           106: ParmW  cCallsSave
        !           107: 
        !           108: cBegin
        !           109:        les     di,pStackSave           ; where to save away stack info
        !           110:        mov     bx,bp
        !           111:        mov     dx,ss
        !           112:        lsl     dx,dx
        !           113: ;
        !           114: ; First we need to ignore the defined number of entries
        !           115:        mov     cx,cCallsIgnore
        !           116:        jcxz    SaveLoop                ; Dont ignore any?
        !           117: NextBPToIgnore:
        !           118:        and     bx,0FFFEh               ; Flush any INC BP bit
        !           119:        jz      SaveLoop                ; End of chain if zero
        !           120:        cmp     bx,dx                   ; BP outside of stack segment?
        !           121:        jae     SaveLoop                ; Yes, end of chain
        !           122:        mov     si,bx                   ; Save current BP
        !           123:        mov     bx,ss:[bx].savedBP      ; SS:BX -> next frame in BP chain
        !           124:        and     bl,0FEh                 ; Flush any INC BP bit
        !           125:        cmp     bx,si                   ; savedBP valid?
        !           126:        jbe     SaveLoop                ; No, end of chain
        !           127:        dec     cx                      ; decrement count of calls to ignore
        !           128:        jnz     NextBPToIgnore          ; Process the next one
        !           129: 
        !           130: ;
        !           131: ; This loop will save away the specified number of calls into the
        !           132: ; passed in save area
        !           133: 
        !           134: SaveLoop:
        !           135:        mov     cx,cCallsSave           ; get count of calls to save
        !           136: 
        !           137: NextBPToSave:
        !           138:        and     bx,0FFFEh               ; Flush any INC BP bit
        !           139:        jz      EndBPChain                  ; End of chain if zero
        !           140:        cmp     bx,dx                   ; BP outside of stack segment?
        !           141:        jae     EndBPChain                  ; Yes, end of chain
        !           142: ; see if short or long call and setup selLast
        !           143:        mov     si,ss:[bx].savedCS      ; Get the code segment
        !           144:        lar     ax,si                   ; get the access rights
        !           145:        jnz     CSNotValid              ; No access assume not selector
        !           146:        and     ah,018h                 ; see if code segment
        !           147:        cmp     ah,018h                 ;
        !           148:        jz      CSValid                 ; code segment, so  save it
        !           149: 
        !           150: CSNotValid:
        !           151:        xor     si,si                   ; Not valid, set selector to NULL
        !           152: CSValid:
        !           153:        mov     ax,ss:[bx].savedIP      ; save away IP of caller
        !           154:        stosw
        !           155:        mov     ax,si                   ; and save away the code selector
        !           156:        stosw
        !           157:        dec     cx                      ; decrement count of how many to save
        !           158: 
        !           159:        mov     si,bx                   ; Save current BP
        !           160:        mov     bx,ss:[bx].savedBP      ; SS:BX -> next frame in BP chain
        !           161:        and     bl,0FEh                 ; Flush any INC BP bit
        !           162:        cmp     bx,si                   ; savedBP valid?
        !           163:        jbe     EndBPChain              ; No
        !           164:        jcxz    StackOverflowsSave      ; Stack is deeper than save area
        !           165: 
        !           166:        jmp     NextBPToSave
        !           167: ;
        !           168: ; We reached the end of the BP chain before we saved the specified number
        !           169: ; of stack items.  zero out the next item to signal caller how many items
        !           170: ; were filled in
        !           171: 
        !           172: EndBPChain:
        !           173:        jcxz    FillInSelectors
        !           174:        xor     ax,ax                   ; Ended BP Chain Before count
        !           175:        stosw                           ; Put A 0:0 to signal end
        !           176:        stosw
        !           177:        sub     di,4                    ; realign DI to last saved call
        !           178:        mov     ax,es:[di-2]            ; ax = Selector of last saved call
        !           179:        jmp     FillInSelectors         ;
        !           180: 
        !           181: ;
        !           182: ; We saved the specified number of items, before we reached the end of the
        !           183: ; BP chain.  If the last item we saved was a local call, we should continue
        !           184: ; to go through the stack until we find a valid far return address.
        !           185: 
        !           186: StackOverflowsSave:
        !           187:        or      ax,ax                   ; Was last call local?
        !           188:        jnz     FillInSelectors         ;
        !           189: 
        !           190: ; loop to locate a FAR return address
        !           191: NextBPToCheck:
        !           192:        and     bx,0FFFEh               ; Flush any INC BP bit
        !           193:        jz      FarReturnNotFound       ; End of chain if zero
        !           194:        cmp     bx,dx                   ; BP outside of stack segment?
        !           195:        jae     FarReturnNotFound       ; Yes, end of chain
        !           196: ; see if short or long call and setup selLast
        !           197:        mov     ax,ss:[bx].savedCS      ; Get the code segment
        !           198:        lar     cx,ax                   ; get the access rights
        !           199:        jnz     CSNotValid2             ; No access assume not selector
        !           200:        and     ch,018h                 ; see if code segment
        !           201:        cmp     ch,018h                 ;
        !           202:        jz      FillInSelectors         ; ax has valid code selector, use it
        !           203: 
        !           204: CSNotValid2:
        !           205:        mov     si,bx                   ; Save current BP
        !           206:        mov     bx,ss:[bx].savedBP      ; SS:BX -> next frame in BP chain
        !           207:        and     bl,0FEh                 ; Flush any INC BP bit
        !           208:        cmp     bx,si                   ; savedBP valid?
        !           209:        jg      NextBPToCheck
        !           210: FarReturnNotFound:
        !           211:        mov     ax,0ffffh               ; use special value to show
        !           212: 
        !           213: ;
        !           214: ; Loop through and convert all Short return addresses into long return
        !           215: ; addresses
        !           216: ;
        !           217: FillInSelectors:
        !           218:        mov     cx,off_pStackSave
        !           219: FillInLoop:
        !           220:        cmp     di,cx                   ; have we back tracked all the way?
        !           221:        jz      FillInEnd               ; Yes
        !           222:        sub     di,4                    ; point back to previous item
        !           223:        cmp     WORD PTR es:[di+2],0    ; is the selector zero?
        !           224:        jz      LocalReturn             ; Yes, local return
        !           225:        mov     ax,es:[di+2]            ; No FAR return, save CS selector
        !           226:        jmp     FillInLoop
        !           227: LocalReturn:
        !           228:        mov     es:[di+2],ax            ; Make long return using saved CS
        !           229:        jmp     FillInLoop
        !           230: 
        !           231: FillInEnd:
        !           232: cEnd
        !           233: 
        !           234: sEnd   CODE
1.1       root      235: 
                    236: end    LoadProc

unix.superglobalmegacorp.com

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