home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / os2sdk / os2sdk12 / spy / spyhstrt.asm < prev    next >
Encoding:
Assembly Source File  |  1989-11-20  |  5.6 KB  |  237 lines

  1. ;  SPYHOOK library initialization routine
  2. ;  Created by Microsoft Corporation, 1989
  3.  
  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
  16.  
  17. sBegin    DATA
  18. assumes DS,DATA
  19. public    __acrtused
  20. __acrtused = 1
  21. sEnd    DATA
  22.  
  23. sBegin    CODE
  24. assumes cs,CODE
  25. assumes ds,DATA
  26.  
  27. EXTRN    Init:NEAR
  28. .286p
  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. ;
  37. cProc    LoadProc,<FAR,PUBLIC>
  38. cBegin    LoadProc
  39.  
  40.     push di
  41.     call Init          ; Init( hmod );
  42.  
  43. cEnd    LoadProc
  44.  
  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
  235.  
  236. end    LoadProc
  237.