home *** CD-ROM | disk | FTP | other *** search
- ;
- ; GRDP
- ;
- ; Copyright(c) LADsoft
- ;
- ; David Lindauer, camille@bluegrass.net
- ;
- ;
- ; EXEC.ASM
- ;
- ; Function: Handle T,G,P commands
- ;
- ;MASM MODE
- .model small
- .386
-
-
- include eprints.inc
- include einput.inc
- include emtrap.inc
- include ebreaks.inc
- include edos.inc
- include eints.inc
- include eregs.inc
- include eswift.inc
-
- TRAPFLAG = 100h ; 80386 trap enable flag
-
- PUBLIC go,trap, proceed, ReTrap, TrapCount, callcheck, cmpstring, wadeprefix
-
-
- .data
- trapcount dd 0 ;number of traps left to do or zero for none
- pfx67flag dw 0 ;flag if 67h prefix found during call check
-
- ;All possible prefixes
-
- pretab db 0f0h,0f2h,0f3h,026h,02eh,036h,03eh,064h,065h,066h,067h
-
- ;String functions
-
- stringtab db 0a6h,0a7h,6ch,6dh
- db 0ach,0adh,0a4h,0a5h
- db 06eh,06fh,0aeh,0afh
- db 0aah,0abh
-
- .code
- ;
- assume ds:nothing ; going to call from where DS is moot
- ;
- callcheck proc
- mov ah,fs:[bx] ; Load the first byte of the instruction
- cmp ah,0ceh ; into?
- mov al,1
- jz chx
- cmp ah,0cdh ; Interrupt ?
- mov al,2 ; two bytes
- jz chx ; I do this because some int calls are
- ; misbehaved and won't restore the trap flag
- cmp ah,0e8h ; Near Call?
- mov al,3 ; Yes, this is 3 bytes
- jz chx ; And execute it
- cmp ah,09ah ; Far call
- mov al,5 ; This one is 5 bytes
- jz chx ; Not either of these, just trap
- mov ax,fs:[bx]
- and ax,038FFH
- cmp ax,010ffh
- jz gotind
- cmp ax,018ffh
- jz gotind
- ret
- gotind:
- mov al,2 ; two bytes base
- mov ah,fs:[bx+1]
- and ah,0c7h
- cmp ah,0c0h ; mod 3, through reg is 2 bytes
- jnc chx
- test [pfx67flag],0ffh ; check 16/32 address mode flag
- jnz call32
- cmp ah,8 ; 16 bit, MOD=0
- jnc chk16m1
- cmp ah,6 ; yes, direct offset?
- jnz chx
- add al,2 ; yes 4 bytes total
- jmp chx
- chk16m1:
- and ah,0c0h ; check for mod 1 or 2
- js is16m2
- inc al ; mod 1, add a byte for offset
- jmp chx
- is16m2:
- add al,2 ; else mod 2, two byte offset
- jmp chx
- call32:
- cmp ah,6 ; 32 bit mode, check for 32-bit offset
- jnz ch32m0
- add al,4 ; yep, add 4
- jmp ch32sib
- ch32m0:
- cmp ah,8 ; MOD = 0?
- jc ch32sib ; yep, check for sib
- ch32m1:
- or ah,ah ; MOD = 1?
- js ch32m2
- add al,1 ; yep, 1 byte offset
- jmp ch32sib
- ch32m2:
- add al,4 ; else mod 2
- ch32sib:
- and ah,7
- cmp ah,4
- jnz chx
- inc al ; add in the SIB byte
- mov ah,byte ptr fs:[bx+1] ; test for MOD 3
- and ah,0c0h
- cmp ah,0c0h
- jz chx ; yep, no further bytes
- mov ah,byte ptr fs:[bx+2] ; get SIB byte
- and ah,7 ; check for EBP special cases
- cmp ah,5
- jnz chx
- inc al
- test byte ptr fs:[bx+1],40h ; check if one or 4 bytes disp
- jz chx
- add al,3 ; MOD 1,3, need 4 bytes
- chx:
- add al,dl ; fix for prefixes
- sub ah,ah ; clear Z flag...
- ret
- callcheck endp
- ; used by P command to wade through prefixes to find out if
- ; we have a string instruction
- ;
- wadeprefix:
- mov [pfx67flag],0
- sub dx,dx
- wp_lp:
- mov al,fs:[bx]
- mov di,offset pretab
- mov cx,11
- repnz scasb
- jnz wp_done
- inc bx
- inc dx
- cmp al,67h
- jnz wp_lp
- bts [pfx67flag],0 ; flag the addrsiz in case of call
- jmp wp_lp
- wp_done:
- ret
-
- cmpstring:
- mov al,fs:[bx]
- mov di,offset stringtab
- mov cx,14
- repnz scasb
- ret
- ;
- assume ds:dgroup ; DS ok again
- ;
- ; Execute program
- ;
- go PROC
- Call WadeSpace ; Wade till address
- jz dogo
- cmp al,'='
- jnz checkbreak
- inc si
- call ReadAddress
- jc goerr
- mov word ptr [RegdumpEIP],bx ; Fix CS:EIP for new routine
- call defCS ; get CS
- checkbreak:
- call WadeSpace ; Wade
- jz short dogo ;
- call ReadAddress ; Read break address
- jc goerr ; Quit if errir
- dogo2:
- sub ax,ax ; Break 0
- call SetBreak ; Set the break
- dogo:
- call EnableBreaks ; Enable breaks
- xor ax,ax ; Not trapping
- jmp gotrap ; Run the code
- goerr:
- stc
- ret
- go ENDP
- ;
- ;
- ; Limited and semi-buggy proced function
- ;
- PROCEED PROC
- call WadeSpace
- jz pok
- cmp al,'r'
- jnz perr
- inc si
- call WadeSpace
- jnz perr
- mov cs:[traceon],1
- jmp gotrap
- pok:
- movzx ebx,word ptr [RegdumpEIP] ;
- mov fs,[RegdumpCS] ;
- call wadeprefix ; wade through all prefixes
- call callcheck ; noew check for near & far calls
- jz short pgo ; and execute it
- mov ah,fs:[bx]
- mov al,2
- cmp ah,0e0h ; Check for loop instructions
- jz short pgo
- cmp ah,0e1h
- jz short pgo
- cmp ah,0e2h
- jz short pgo
- call cmpstring ; see if is string instruction or loop
- jnz short dotrap ; Not either of these, just trap
- mov ax,dx
- inc ax
- pgo:
- sub ah,ah
- movzx ebx,word ptr [RegdumpEIP] ;
- add bx,ax ; Ebx = breakpoint
- mov dx,[RegdumpCS] ; DX:EBX = position to break at
- sub ax,ax ; Use the scratch breakpoint
- call SetBreak ; Set a break
- call EnableBreaks ; Enable breakpoints
- sub ax,ax ; No trapping
- jmp gotrap ; Run the code
- perr:
- stc
- ret
- PROCEED ENDP
- ;
- ; Trap command
- ;
- trap PROC
- call WadeSpace
- jz dotrap
- call ReadNumber
- jc terr
- push eax
- call WadeSpace
- pop eax
- jz tnerr
- terr:
- stc
- ret
- tnerr:
- or eax,eax
- jz dotrap
- dec eax
- mov [trapcount],eax
- trap ENDP
- dotrap PROC
- mov fs,[RegdumpCS] ;
- mov bx,word ptr [RegdumpEIP] ;
- mov ah,fs:[bx] ; Load the first byte of the instruction
- cmp BYTE PTR fs:[bx],0cdh
- jnz ReTrap
- mov al,byte ptr fs:[bx+1]
- cmp al,20h
- jz dosvec
- cmp al,21h
- jnz stepvec
- mov ebx,cs:[int21adr]
- jmp gotadr
- stepvec:
- push 0 ; other int instructions do a step
- pop fs
- jmp gotadr
- dosvec:
- mov fs,[intpage]
- gotadr:
- movzx bx,al ; trying to trace through a DOS
- shl bx,2
- mov ebx,fs:[bx]
- push es ; vector bypasses our hook
- mov es,[RegdumpSS]
- mov di,word ptr [RegdumpESP]
- sub [RegdumpESP],6
- std
- scasw
- mov ax,word ptr [RegdumpFLAGS]
- stosw
- mov ax,[RegdumpCS]
- stosw
- mov ax,word ptr [RegdumpEIP]
- add ax,2
- stosw
- cld
- pop es
- mov word ptr [RegdumpEIP],bx
- shr ebx,16
- mov [RegdumpCS],bx
- call DisplayRegisters; Display registers
- clc
- ret
- dotrap ENDP
- ReTrap PROC
- mov ax,TRAPFLAG ; Are trapping on instruction
- gotrap PROC
- push ax
- mov si,offset dgroup : veclist ; enable ints
- call SetRMInts
- pop ax
- mov ss,[RegdumpSS]
- mov esp,[RegdumpESP] ; Load toss
- or ax,word ptr [RegdumpFLAGS] ; Fill stack frame with FLAGS , CS:EIP
- push ax ;
- call SetUserPSP
- push [RegdumpCS]
- push word ptr [RegdumpEIP]
- push [RegdumpDS]
- mov es,[RegdumpES]
- mov fs,[RegdumpFS]
- mov gs,[RegdumpGS]
- mov eax,[RegdumpEAX] ; Load regs
- mov ebx,[RegdumpEBX] ;
- mov ecx,[RegdumpECX] ;
- mov edx,[RegdumpEDX] ;
- mov esi,[RegdumpESI] ;
- mov edi,[RegdumpEDI] ;
- mov ebp,[RegdumpEBP] ;
- pop ds ; Load DS
- test cs:[traceon],1 ; if PR go handle first instruction
- jz doiret
- call swiftrace
- call DisplayRegisters; if it was an int 3 come back
- clc
- ret
- doiret:
- iret
- gotrap ENDP
- Retrap ENDP
- end