          <<< NOTED::DISK$NOTES7:[NOTES$LIBRARY_7OF4]HACKERS.NOTE;1 >>>
                               -< ** Hackers ** >-
================================================================================
Note 751.17               Need to force a process dump                  17 of 17
CSC64::BLAYLOCK "If at first you doubt,doubt again" 239 lines   6-FEB-1996 16:51
--------------------------------------------------------------------------------


It seems that on V7 of OpenVMS Alpha, SS$_IMGDMP does work.  The same
code on V6.1 fails to do anything useful.  $FORCEX does not do anything
for you because it does not cause a signal in the receiving process.

Here is something that I have used that works pretty well for
VAX systems and will cause a dump on a Alpha system.  The latter
systems image dump analyzer has problems with the system PC
in the first exception frame so it is not useful until V7
where ANALYZE /PROCESS seems to be working on these kinds of
dumps.  This code does not work (but could be made to) on
images installed with privileges.  I have tested this on a V7
OpenVMS Alpha system, but not recently on a V6 or V5 system.

        .TITLE  Cross_Signal Signal an exception in another process
        .IDENT  /V01.005/
;
;       COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1993,1996.
;       ALL RIGHTS RESERVED.
;
;       THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE
;       USED AND COPIED ONLY IN ACCORDANCE WITH THE TERMS OF
;       SUCH LICENSE AND WITH THE INCLUSION OF THE ABOVE
;       COPYRIGHT NOTICE.  THIS SOFTWARE OR ANY OTHER COPIES
;       THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE
;       TO ANY OTHER PERSON OR ENTITY.  NO TITLE TO AND OWNERSHIP 
;       OF THE SOFTWARE IS HEREBY TRANSFERRED.
;
;       THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE
;       WITHOUT NOTICE AND SHOULD NOT BE CONSTRUED AS A 
;       COMMITMENT BY DIGITAL EQUIPMENT CORPORATION.
;
;++
; Abstract:
;
;       This program queues an AST to a specified process and
;       and requests a signal of SS$_ABORT. The process is
;       marked with the image dump turned on, so if the image
;       has traceback and can write out the dump file, it
;       will.
;
; Environment:
;       Local and target process - kernel mode
;       Requires WORLD and CMKRNL privileges
;
; Build:
;
;       $ IF f$getsyi("arch_name") .eqs. "VAX"
;       $ THEN
;       $   MACRO /LIST /SHOW=BINARY CROSS_SIGNAL
;       $   LINK /MAP/CROSS/FULL CROSS_SIGNAL+SYS$SYSTEM:SYS.STB/SELECTIVE
;       $ ELSE
;       $   MACRO /LIST /MACHINE/SHOW=BINARY /OBJ=CROSS_SIGNAL -
;               SYS$SHARE:ARCH_DEFS + SYS$DISK:[]CROSS_SIGNAL
;       $   LINK /SYSEXE /MAP/CROSS/FULL CROSS_SIGNAL
;       $ ENDIF
;
; Limitations:
;
;       It's a hack. The resulting image dump file needs to have an
;       analyzer that will read through a system space PC for the
;       exception.
;
;
; Author:
;
;       Kenneth G. Blaylock             07-Jan-1993
;
;               From original code to set remote user prompt
;               written by author way back when ...
;
; Modification History
;
;       V01.001 Kenneth G. Blaylock     07-Jan-1993
;               new entry.
;
;       V01.002 Kenneth G. Blaylock     10-Jun-1993
;               Clear the NODELET bit on the target process.
;       V01.003 Kenneth G. Blaylock     29-Mar-1994
;               Fix to run on Alpha and VAX.  This is
;               done by calling the locally, but switching
;               the JIB address temporarily.
;       V01.004 Kenneth G. Blaylock     25-Oct-1994
;               Generalize this to use SS$_ABORT and to
;               set the IMGDMP bit in the target process.
;       V01.005 Kenneth G. Blaylock     06-Feb-1996
;               Clean up for Alpha/VAX system builds and
;               add some more comments.
;
; Usage:
;
;       $ ABORT :== $SYS$DISK:[]CROSS_SIGNAL
;       $ ABORT <user_pid>
;
;--

        .LIBRARY        /SYS$LIBRARY:LIB/
        $ACBDEF                         ; AST control block
        $DYNDEF                         ; Dynamic memory descriptor
        $JIBDEF                         ; JIB block definitions.
        $JPIDEF                         ; JPI defintions
        $IPLDEF                         ; IPL levels
        $PCBDEF                         ; Process control block definition
        $PHDDEF                         ; Process header stuff
        $PRDEF                          ; processor register defs
        $PSLDEF                         ; PSL defs
        $SSDEF                          ; System Service Status

        .SUBTITLE       LOCALDATA - Local user data
        .PSECT  $DATA, NOEXE, WRT, PAGE
PID:    .LONG   0                       ; Pid to disconnect
PID2:   .LONG   0                       ; Conferm existing process
PROMPT: .ASCID  /Processes ID to Abort: /
RESPONSE:
        .word
        .byte   dsc$k_dtype_t
        .byte   dsc$k_class_d
        .long

ITMLST: .WORD   4                       ; JPI itm list, get target PID
        .WORD   JPI$_PID
        .ADDRESS PID2
        .QUAD   0                       ; End of list
get_flags:
        .long

        .SUBTITLE       CODE - Main routine to set up to send AST
        .PSECT  $USER_CODE, EXE, LONG, RD, NOWRT
        .ENTRY  Cross_Signal, ^M<>
10$:    PUSHAB  GET_FLAGS               ; First try the command line
        PUSHAB  RESPONSE                ; Actual string length
        PUSHAB  PROMPT                  ; Prompt
        PUSHAB  RESPONSE                ; Input string
        CALLS   #4, G^LIB$GET_FOREIGN   ; Get command line
        BLBS    R0, 15$                 ; Check for error
        RET
15$:
        PUSHL   #3              ; do not interpret blanks and tabs
        PUSHL   #4              ; 4 bytes return
        PUSHAB  PID             ; Return address
        PUSHAB  RESPONSE        ; Input string
        CALLS   #4, G^OTS$CVT_TZ_L; Convert string Hex to INT
        BLBC    R0, 10$

        $GETJPIW_S PIDADR=PID,- ; make sure there is a process
                ITMLST=ITMLST
        BLBS    R0, 20$
        RET
20$:
        CMPL    PID, PID2       ; And its the right one
        BEQL    25$
21$:    MOVL    #SS$_NONEXPR, R0
        RET
25$:
        $CMKRNL_S -
                ROUTIN=SIGPRC     ; Start the queuing ...
        RET
        .SUBTITLE       SIGPRC - Signal target process
;
;       In kernel mode, look for the process again and
;       verify it's existence (and get its PCB address).
;       Save the current process JIB address and then
;       stuff the target JIB address and call the signaling
;       routine.
;
;       In V6 of VMS there is the flag
;       C2$V_ALLOW_SPAN_JOB_TREES in EXE$GL_SECURITY_POLICY
;       that we could set to call this.  We do not
;       have that luxury on V5 (or AXP V1.5).
;
;       REALITY CHECK: CODE SHOULD BE HOLDING THE SCHED SPINLOCK
;

        .PSECT  $DATA, NOEXE, WRT, PAGE
SAVED_JIB:
        .LONG   0
        .PSECT  $USER_CODE, EXE, LONG, RD, NOWRT
        .ENTRY  SIGPRC, ^M<R2, R3, R4, R5, R6>    ; Entry mask
        MOVL    G^CTL$GL_PCB, R4
        BISL    #PCB$M_NODELET, PCB$L_STS(R4)
        MOVL    PCB$L_JIB(R4), SAVED_JIB
;
; From this point on, code must proceed through
; 100$ before returning to user mode.
;
        MOVL    PID, R0
.IF DF, EVAX
        JSB     G^EXE$CVT_EPID_TO_PCB
.IFF
        JSB     G^EXE$EPID_TO_PCB
.ENDC
        MOVL    R0, R3                  ; Save the PCB address.
        BEQL    110$                    ; Zero is none
;
; We have the process.  Set the JIB address.  The alternative to this is
; to save and set the C2$V_ALLOW_SPAN_JOB_TREES bit.
;
;       clrl    r6
;       bbcc    #C2$V_ALLOW_SPAN_JOB_TREES, g^EXE$GL_SECURITY_POLICY, 10$
;       movl    #<1@C2$V_ALLOW_SPAN_JOB_TREES>, r6 ; KEEP THE BIT IF SET
; 10$:   
;
;
        BICL    #PCB$M_NODELET, PCB$L_STS(R3) ; Clear no DELETE on remote
process
        MOVL    PCB$L_JIB(R3), PCB$L_JIB(R4)  ; Set the JIB address
        MOVL    PCB$L_PHD(R3), R2             ; Get the remote PHD
.IF DF, EVAX
        BISL2   #PHD$M_IMGDMP, PHD$L_FLAGS(R2); Set the image dump bit
.IFF
        BISW2   #PHD$M_IMGDMP, PHD$W_FLAGS(R2); Set the image dump bit
.ENDC
;
;       $SIGPRC_S -
;               PIDADR=PID, -
;               SIGNAL=#SS$_ABORT
;
; Signal the remote process to do something.
;
        PUSHL   #SS$_ABORT              ; SIGNAL THIS ERROR
        PUSHL   #0                      ; PROCESS NAME ADDRESS
        PUSHAL  PID                     ; PID ADDRESS
        CALLS   #3, G^SYS$SIGPRC        ; SIGNAL THE TARGET PROCESS
;
;       BISL2   R6, g^EXE$GL_SECURITY_POLICY    ; RESET THE C2 BIT IF SET
;
        MOVL    SAVED_JIB, PCB$L_JIB(R4)        ; RESTORE THE USERS ORG JIB
100$:   MOVL    G^CTL$GL_PCB, R4
        BICL    #PCB$M_NODELET, PCB$L_STS(R4)
        SETIPL  #0                      ; Reset IPL.  Now we're deletable
        RET                             ; Leave Kernel routine
110$:   MOVL    #SS$_NONEXPR, R0
        BRB     100$

        .END    Cross_Signal            ; Program Cross Signal



