|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.