From:	AITGW::"MACRO32@WKUVX1.BITNET" 20-FEB-1992 05:11:07.89
To:	MACRO32@WKUVX1.BITNET, gavron@vesta.sunquest.com
CC:	
Subj:	New and Improved fixup_prcnam (with new and improved FIND_VECTOR)

Received: by AITGW.DECnet (utk-mail11 v1.5) ; Thu, 20 Feb 92 05:08:21 EST
Received: from ukcc.uky.edu by aitgw.ge.com (5.65/GE Gateway 1.4)
	id AA04193; Thu, 20 Feb 92 05:08:08 -0500
Received: from ukcc.uky.edu by UKCC.uky.edu (IBM VM SMTP V2R2)
   with BSMTP id 1191; Thu, 20 Feb 92 05:03:40 EST
Received: from UKCC by ukcc.uky.edu (Mailer R2.08) with BSMTP id 6420; Thu, 20
 Feb 92 05:03:26 EST
Received: from WKUVX1.BITNET by ukcc.uky.edu (Mailer R2.08) with BSMTP id 6332;
 Thu, 20 Feb 92 05:01:29 EST
Errors-To: MacroMan@WKUVX1.BITNET
X-Listname: "VMS Internals, MACRO, and BLISS Discussions"
    <MACRO32@WKUVX1.BITNET>
Received: from CUNYVM.BITNET (MAILER) by WKUVX1 (MX V3.0A) with BSMTP; Thu, 20
          Feb 1992 04:01:14 EST
Received: from CUNYVM by CUNYVM.BITNET (Mailer R2.08) with BSMTP id 9243; Thu,
          20 Feb 92 04:53:53 EST
Received: from optima.cs.arizona.edu by CUNYVM.CUNY.EDU (IBM VM SMTP V2R2) with
          TCP; Thu, 20 Feb 92 04:53:50 EST
Received: from ALPHA.SUNQUEST.COM by optima.cs.arizona.edu (4.1/15) id AA07865;
          Thu, 20 Feb 92 02:53:47 MST
Date: Thu, 20 Feb 1992 2:53:41 -0700 (MST)
From: <GAVRON@alpha.sunquest.com>
Reply-To: MACRO32@WKUVX1.BITNET
Message-Id: <920220025341.2f40ac81@ALPHA.SUNQUEST.COM>
Subject: New and Improved fixup_prcnam (with new and improved FIND_VECTOR)
To: MACRO32@WKUVX1.BITNET, gavron@vesta.sunquest.com
X-Vmsmail-To: MACRO32@WKUVX1.BITNET
 
        Enclosed is the latest version of the program which patches
        exe$setprn and exe$nampid so that process names ignore UIC groups.
 
        Thanks to Nick De Smith's comment, this version improves the
        FIND_VECTOR routine.  Other macros have been added to make a
        future in-memory-patcher simple.
 
        This and other things are availabe for anonymous ftp from:
                vesta.sunquest.com::[anonymous.files.macro_hacks.*]
 
 
        Ehud
 
--
Ehud Gavron        (EG76)
gavron@vesta.sunquest.com
"The world bores you when you're cool."
 
$! ------------------ CUT HERE -----------------------
$ v='f$verify(f$trnlnm("SHARE_VERIFY"))'
$!
$! This archive created by VMS_SHARE Version 7.2-007  22-FEB-1990
$!   On 20-FEB-1992 02:41:58.50   By user GAVRON
$!
$! This VMS_SHARE Written by:
$!    Andy Harper, Kings College London UK
$!
$! Acknowledgements to:
$!    James Gray       - Original VMS_SHARE
$!    Michael Bednarek - Original Concept and implementation
$!
$! TO UNPACK THIS SHARE FILE, CONCATENATE ALL PARTS IN ORDER
$! AND EXECUTE AS A COMMAND PROCEDURE  (  @name  )
$!
$! THE FOLLOWING FILE(S) WILL BE CREATED AFTER UNPACKING:
$!       1. FIXUP_PRCNAM.MAR;7
$!
$set="set"
$set symbol/scope=(nolocal,noglobal)
$f=f$parse("SHARE_TEMP","SYS$SCRATCH:.TMP_"+f$getjpi("","PID"))
$e="write sys$error  ""%UNPACK"", "
$w="write sys$output ""%UNPACK"", "
$ if f$trnlnm("SHARE_LOG") then $ w = "!"
$ ve=f$getsyi("version")
$ if ve-f$extract(0,1,ve) .ges. "4.4" then $ goto START
$ e "-E-OLDVER, Must run at least VMS 4.4"
$ v=f$verify(v)
$ exit 44
$UNPACK: SUBROUTINE ! P1=filename, P2=checksum
$ if f$search(P1) .eqs. "" then $ goto file_absent
$ e "-W-EXISTS, File ''P1' exists. Skipped."
$ delete 'f'*
$ exit
$file_absent:
$ if f$parse(P1) .nes. "" then $ goto dirok
$ dn=f$parse(P1,,,"DIRECTORY")
$ w "-I-CREDIR, Creating directory ''dn'."
$ create/dir 'dn'
$ if $status then $ goto dirok
$ e "-E-CREDIRFAIL, Unable to create ''dn'. File skipped."
$ delete 'f'*
$ exit
$dirok:
$ w "-I-PROCESS, Processing file ''P1'."
$ if .not. f$verify() then $ define/user sys$output nl:
$ EDIT/TPU/NOSEC/NODIS/COM=SYS$INPUT 'f'/OUT='P1'
PROCEDURE Unpacker ON_ERROR ENDON_ERROR;SET(FACILITY_NAME,"UNPACK");SET(
SUCCESS,OFF);SET(INFORMATIONAL,OFF);f:=GET_INFO(COMMAND_LINE,"file_name");b:=
CREATE_BUFFER(f,f);p:=SPAN(" ")@r&LINE_END;POSITION(BEGINNING_OF(b));
LOOP EXITIF SEARCH(p,FORWARD)=0;POSITION(r);ERASE(r);ENDLOOP;POSITION(
BEGINNING_OF(b));g:=0;LOOP EXITIF MARK(NONE)=END_OF(b);x:=ERASE_CHARACTER(1);
IF g=0 THEN IF x="X" THEN MOVE_VERTICAL(1);ENDIF;IF x="V" THEN APPEND_LINE;
MOVE_HORIZONTAL(-CURRENT_OFFSET);MOVE_VERTICAL(1);ENDIF;IF x="+" THEN g:=1;
ERASE_LINE;ENDIF;ELSE IF x="-" THEN IF INDEX(CURRENT_LINE,"+-+-+-+-+-+-+-+")=
1 THEN g:=0;ENDIF;ENDIF;ERASE_LINE;ENDIF;ENDLOOP;t:="0123456789ABCDEF";
POSITION(BEGINNING_OF(b));LOOP r:=SEARCH("`",FORWARD);EXITIF r=0;POSITION(r);
ERASE(r);x1:=INDEX(t,ERASE_CHARACTER(1))-1;x2:=INDEX(t,ERASE_CHARACTER(1))-1;
COPY_TEXT(ASCII(16*x1+x2));ENDLOOP;WRITE_FILE(b,GET_INFO(COMMAND_LINE,
"output_file"));ENDPROCEDURE;Unpacker;QUIT;
$ delete/nolog 'f'*
$ CHECKSUM 'P1'
$ IF CHECKSUM$CHECKSUM .eqs. P2 THEN $ EXIT
$ e "-E-CHKSMFAIL, Checksum of ''P1' failed."
$ ENDSUBROUTINE
$START:
$ create 'f'
X`09.TITLE`09FIXUP_PRCNAM`09Make process names ignore UIC groups
X`09.IDENT`09/V2.1.0-20feb92/
X
X;++
X;
X; FIXUP_PRCNAM.MAR            02-Feb-1992`09Ehud Gavron
X;
X; For those times you want process control functionality to be independent
X; of UIC groups, this image patches the executive routines EXE$NAMPID and
X; EXE$SETPRN to ignore the group UIC check.
X;
X; Although no merchantability is expressed or implied, this
X; code was developed for and will work under V5.4-2.
X;
X;       Ehud Gavron             gavron@Spades.ACES.COM
X;
X;--
X; V1.0.0        Created because I'm not getting enough interesting
X;               kernel-coding to do in my regular job.
X;
X;
X; V2.0.0`09Modified to have FIND_VECTOR be a generalized routine
X;`09`09I can call from anywhere.  Do EXE$NAMPID.  Fix page-
X;`09`09protection bug which caused JOB_CONTROL to accvio.
X;`09`09
X; V2.0.1`09Added macros to create the command definitions, and
X;`09`09other things...
X;
X; V2.1.0 `09Nick De Smith pointed out I wasn't catching the fourth
X;`09`09type of executive vector.  Corrected.  According to Nick's
X;`09`09MWAIT program (good stuff!) the four types are:
X;`09`09`091. Base image vectored system routine:
X;`09`09`09`09jmp @#address
X;`09`09`092. Base vectored system service:
X;`09`09`09`09.entry `5Em<...>
X;`09`09`09`09jmp`09@#address
X;`09`09`093. Chamge mode kernel system service:
X;`09`09`09`09.entry `5Em<...>
X;`09`09`09`09chmk`09#nnnn
X;`09`09`094. Change mode executive system service
X;`09`09`09`09.entry `5Em<...>
X;`09`09`09`09chme`09#nnnn`09
X;`09`09Modified code to use built in opcodes where appropriate.
X;`09`09The only place this is not modified is where I use the
X;`09`09cmd_store macro to create a descriptor; this is to make
X;`09`09future changes easy to do - just grab listings code and
X;`09`09plug in.
X;
X;`09`0920-feb-1992`09Ehud Gavron`09Gavron@ACES.COM
X;
X; Definitions
X;
X        .library        "sys$Library:lib.mlb"                   ; find $xxxd
Vefs
X        .link           "sys$system:sys.stb"/selective_search   ; find xxx$x
V_xs
X
X`09$opdef`09`09; Opcode definitions (for op$_jmp...)
X`09$pcbdef`09`09; Process Control Block offsets (to get PCB$W_GRP)
X`09$prtdef`09`09; Page Protection definitions (for PRT$C_URKW)
X`09$ptedef`09`09; Page Table Entry definitions (to get PTE$x_PROT)
X        $ssdef          ; System Service status values (for normal status)
X
X;
X; Offsets I stole from the VAX Architecture manual:
X;
XSCB_L_CMKRNL`09=`09`5EX40
XSCB_L_CMEXEC`09=`09`5EX44
X
X;
X; Location of vector symbol and addresses:
X;
Xfv_symbol:`09.blkl`091`09; The global symbol to find the code for
Xfv_vector:`09.blkl`091`09; The address of the code
X;
X; Argument list to pass it to FIND_VECTOR:
X;
Xfv_arglst:`09.long`092
X`09`09.address fv_symbol
X`09`09.address fv_vector
X;
X; Macros:
X;
X`09.macro`09cmd_store`09cmd,cmdargs`09; Store a command as a string
X'cmd'_inst: 'cmd' 'cmdargs'`09`09`09; Descriptor.  Eventually this
X'cmd'_len = . - 'cmd'_inst`09`09`09; will lead to a generic patch-
X'cmd'_desc:`09.long`09'cmd'_len`09`09; in-memory routine.
X`09`09.address 'cmd'_inst
X`09.endm
X
X`09.macro`09FIND_AND_DESTROY symb`09`09; A temporary macro to avoid
X`09movl`09#symb,fv_symbol`09`09`09; Having repetitious-looking
X`09$cmkrnl_s`09routin=find_vector,-`09; source-code.  This one will
X`09`09`09arglst=fv_arglst`09; find a symbol, and call the
X`09$cmkrnl_s`09routin=fixup_k,-`09; fixup routine.
X`09`09`09arglst=fv_arglst
X`09.endm
X
X;
X; Start of user-mode code:
X;
X`09.Entry`09Fixup,`5Em<>
X`09find_and_destroy exe$nampid`09`09; Patch exe$nampid
X`09find_and_destroy exe$setprn`09`09; Patch exe$setprn
X`09Ret`09`09`09`09`09; End!
X
X;
X; Start of kernel-mode code:
X;
X`09.entry`09FIND_VECTOR,`5Em<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11>
X;
X; Find out which system service or jump vector it is today...
X;
X`09movl`09@4(ap),r7`09`09; Address of vector requested
X`09cmpw`09(r7),#op$_jmp!<`5Ex9f00>`09; Check for JMP @#
X`09beql`0910$`09`09`09; It is, go use it
X`09addl`09#2,r7`09`09`09; Move past the entry mask
X`09cmpw`09(r7),#op$_jmp!<`5Ex9f00>`09; Is it a JMP @#
X`09beql`0910$`09`09`09; Yup, go deal with it
X`09movl`09#SCB_l_cmkrnl,r10`09; Prepare for it being a CHMK
X`09cmpb`09(r7),#op$_chmk`09`09; Is it a CHMK #n
X`09beql`0920$`09`09`09; Yup, go deal with it
X`09movl`09#SCB_l_cmexec,r10`09; Prepare for it being a CHME
X`09cmpb`09(r7),#op$_chme`09`09; Is it a CHME #n
X`09beql`0920$`09`09`09; Yup, go deal with it
X`09movl`09#ss$_unsupported,-`09; Eeek, don't know what it is...
X`09`09r0`09`09`09; So tell user it's unsupported
X`09ret`09`09`09`09; and go back to user mode!
X
X;
X; So now we extract the address from the JMP instruction:
X;
X10$:
X`09addl2`09#2,r7`09`09`09; Get nn from JMP @#nn
X`09movl`09(r7),@8(ap)
X`09movl`09#ss$_normal,r0
X`09ret
X;
X; So now we get the number of the exception...
X;
X20$:
X`09addl2`09#2,r7`09`09`09; Get address of #nn from CHMx #nn
X`09movzbl`09(r7),r8`09`09`09; Get nn into R8
X;
X; So now we find the dispatcher address
X;
X`09movl`09@#exe$gl_scb,r1`09`09; Get address of System Control Block
X`09addl2`09r10,r1`09`09`09; Get address of correct dispatcher
X`09movl`09(r1),r1`09`09`09; Get address of exe$cmodxxxx where
X`09`09`09`09`09; xxxx is either krnl or exec
X;
X; We look in its code for the dispatch vector table
X;
X`09movab`09movaq_inst,r2`09`09; Address of our MOVAQ instruction`09
X`09movzwl`09(r2),r5
X`09addl3`09#`5Exff,r1,r3`09`09; Address past MOVAQ fer shure
X30$:
X`09movzwl`09(r1),r6
X`09cmpw`09r6,r5`09`09`09; Have we found a MOVAQ?
X`09beql`0940$`09`09`09; Yup!
X`09aobleq`09r3,r1,30$
X`09movl`09#ss$_nodata,r0`09`09; Whoops, couldn't find it...
X`09ret`09`09`09`09; So go back to user mode... sigh
X
X;
X; Ok, here R1 points to the start of a MOVAQ instruction that looks like:
X; `09MOVAQ CMOD$AR_mode_DISPATCH_VECTOR`5BR1`5D,R1
X; which translates to bytes:`0951hhllCF417E with hhll being the offset
X; from the last byte (51).  We first save this current R1
X;
X40$:
X`09movl`09r1,r9`09`09`09; Address of MOVAQ
X`09movl`09r1,r7`09`09`09; Saved
X;
X; Then we find the offset
X;
X`09addl2`09#3,r9`09`09`09; Address of hhll (word)
X`09movzwl`09(r9),r3`09`09`09; R3 = offset
X;
X; Then we add get the address of the end of the instruction
X;
X`09addl2`09#5,r7`09`09`09; Address of last byte of instruction
X;
X; Then we add the offset
X;
X`09addl2`09r3,r7`09`09`09; R7 = CMOD$AR_mode_DISPATCH_VECTOR
X;
X; Then we take our CHMn code and multiply by 8 (quadword vectors) and add
X;
X`09ashl`09#3,r8,r6`09`09; Vector offset
X`09addl2`09r6,r7`09`09`09; Our vector
X`09addl2`09#4,r7`09`09`09; The address `5B2nd longword of vector`5D
X`09movl`09(r7),@8(ap)`09`09; Return this address
X`09movl`09#ss$_normal,r0
X`09ret
X
X
X`09.entry FIXUP_K,`5Em<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11>
X;++
X; Make EXE$SETPRN ignore UIC groups
X;--
X`09movl`09@8(ap),r1`09`09; Get address of code
X;
X; Now we need to search this code for the instructions:
X;`09CMPW`09PCB$W_GRP(R4),PCB$W_GRP(R7)
X;`09BNEQ`09offset
X;
X; and change them to NOPs...
X;
X`09movab`09cmpw_inst,r2`09`09; Address of our CMPW instruction
X`09movzbl`09(r2),r5`09`09`09; Address of CMPW (1B)
X`09addl3`09#`5Ex64,r1,r3`09`09; Address past CMPW fer shure
X10$:
X`09movzbl`09(r1),r6`09`09`09; Current instruction
X`09cmpl`09r6,r5`09`09`09; Have we found a CMPW?
X`09beql`0920$`09`09`09; Yup!
X15$:
X`09aobleq`09r3,r1,10$
X`09movl`09#ss$_nodata,r0`09`09; Whoops, couldn't find it...
X`09ret`09`09`09`09; So go back to user mode... sigh
X;
X; Here we make sure we got the right CMPW.  The way we do that is twofold.
X; First we make sure that the offset to the register is C6 (PCB$W_GRP).
X; Then we make sure there is a BNEQ afterwards.
X20$:
X`09addl3`09#2,r1,r2`09`09; Address of PCB$W_GRP
X`09cmpw`09#pcb$w_grp,(r2)
X`09cmpl`09r5,r6
X`09bneq`0915$`09`09`09; Nope, keep looking
X`09addl3`09#7,r1,r2
X`09movzbl`09(r2),r3
X`09movab`09bneq_inst,r4
X`09movzbl`09(r4),r4
X`09cmpl`09r3,r4
X`09beql`0930$`09`09`09; passed sanity check
X`09brw`0915$`09`09`09; go find another CMPW...
X;
X; Set page for URKW protection:
X;
X30$:
X`09movl`09r1,r2`09`09`09; Get start address
X`09movl`09#prt$c_urkw,r9`09`09`09; Set for URKW
X`09moval`09nop_inst,r7`09`09; Put address of NOP in R7
X`09movzbl`09(r7),r7`09`09`09; Put NOP instruction in R7
X`09addl3`09#9,r1,r8`09`09; Get end address
X`09lock`09lockname=MMG,-`09`09; Raise IPL, acquire spinlock
X`09`09lockipl=#IPL$_MMG,-
X`09`09preserve=NO
X`09jsb`09g`5Emmg$svaptechk`09`09; Get SVAPTE in R3
X`09extzv`09#pte$v_prot,-`09`09; Get old page protection in R10
X`09`09#pte$s_prot,-
X`09`09(r3),r10
X;
X; Now we NOP out the bytes...
X;
X`09insv `09r9,#pte$v_prot,-`09; Make page kernel writeable
X`09     `09#pte$s_prot,(r3)
X`09invalidate_tb`09`09`09; Translation Buffer Invalidate All
X40$:
X`09movb`09r7,(r1)
X`09aoblss`09r8,r1,40$
X`09invalidate_tb`09`09`09; Translation Buffer Invalidate All
X`09unlock`09lockname = MMG,-`09; Release spinlock, lower IPL
X`09`09condition = RESTORE,-
X`09`09newipl = #0,-
X`09`09preserve = NO
X`09movl`09#ss$_normal,r0
X`09ret`09`09`09`09; and return
X
X;
X; Note: We use the CMD_STORE macro and actually store instructions
X;`09as opposed to using the OP$_xxx method of using them because
X;`09we cannot be sure that these will remain constant.  As they
X;`09may change from time to time, it is easier to leave them in
X;`09this format, and then vary it from the listings.
X;
X;`09At least that much was true for MOVAQ.
X;
X;`09We leave the CMPW and BNEQ and NOP instructions in this
X;`09format (and even create descriptors for them) in anticipation
X;`09of the day I write a generic patch-in-memory routine that
X;`09will expect descriptors of what-to-look-for and what-to-
X;`09replace-it-with.  This is easier in a descriptor format
X;`09than an OP$_xxx format.
X;
X`09cmd_store`09movaq`09<w`5E10`5Br1`5D,r1>
X`09cmd_store`09cmpw`09<pcb$w_grp(r4),pcb$w_grp(r7)>
X`09cmd_store`09bneq`09<bneq_inst+1>
X`09cmd_store`09nop`09<>
X`09.end`09Fixup
$ CALL UNPACK FIXUP_PRCNAM.MAR;7 1195601267
$ v=f$verify(v)
$ EXIT
 
