home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 September
/
Simtel20_Sept92.cdr
/
msdos
/
sysutl
/
passwrd5.arc
/
PASSWRD5.ASM
< prev
next >
Wrap
Assembly Source File
|
1988-09-20
|
12KB
|
383 lines
PAGE 60,132
TITLE PASSWRD5.ASM - PASSWRD5.SYS DEVICE DRIVER
;------------------------------------------------------------
;[from SIMTEL20's PD:<MSDOS.SYSUTL>PASSWORD.ARC, tweaked]
;PASSWRD5.ASM (CREATES PASSWRD5.SYS, DEVICE DRIVER)
;DOS 2.00 DEVICE DRIVER FORCES USER TO ENTER PASSWORD ON BOOTING UP
;AND DISABLES Ctrl-Break.
;
;v1.5 19 Sep 88
; - Got a msg from Bernie Eiben, explaining what's going on with the Init
; procedure and why the code got overlaid/garbaged on installation.
; Turns out I did good in moving Ask_Off up in the code (even tho
; I didn't know why). Comments edited and clarified.
; - Added version number to the device_name
; - Let the compiler compute password length, password space padding
;David Kirschbaum
;v1.4 Toad Hall Tweak, 7 Aug 88
; - Tightened code a little.
; - changed "ESC" to "ESCP" so MASM 5.0 wouldn't complain.
; - Reorganized to put things more inline, keep FAR things FAR.
;David Kirschbaum
;Toad Hall
;kirsch@braggvax.ARPA
; REV by JOHN R. PETROCELLI 02/25/85
;
; ADDITIONAL CODE HAS BEEN ADDED TO INITIALIZE INT 66h WITH THE
; SEGMENT AND OFFSET OF THE "RECALL" CODE (Ask_Off). USING THE
; PROGRAM "LOCK.COM" WILL ENABLE THE USER TO DISABLE THE USE OF THE
; PC UNTIL THE CORRECT PASSWORD IS SUPPLIED.
;
;AFTER ASSEMBLY: LINK PASSWRD5 (ignore "no STACK" error)
; EXE2BIN PASSWRD5 PASSWRD5.SYS
; (Or use one of the public domain EXE2COM utilities,
; insuring any product is a .SYS type.)
; Place DEVICE=PASSWRD5.SYS in CONFIG.SYS file
; Reboot system with Ctrl-Alt-Del
; Answer prompt with : Password <ENTER>
; **** BEWARE OF UPPER VS LOWER CASE ****
;
DEV_SEG SEGMENT
ASSUME CS:DEV_SEG, DS:DEV_SEG, ES:DEV_SEG
org 0 ;TH
Pword_Device PROC FAR
;---------------------------------------------------------------
;The following lines are the device header, which must exist for
;every device. This file has only one device, and it works with
;character I/O. It doesn't actually handle any I/O services,
;but it's easier to create a character device.
pword_dev_header label byte ;start of the device driver
next_dev_ptr DD -1 ;only 1 device is defined in this file
dev_attribute DW 1000000000000000B
strategy_ptr DW Strategy ;the installation procedure
interupt_ptr DW Interupt ;the proc that handles all services
device_name DB 'PWORD15' ;device name string (up to 8 bytes)
; -- This is the storage area for the password --
; -- The first byte is the length (0-16) --------
; -- The following characters are the password --
; -- Only an exact match will allow the system --
; -- to continue the boot process ---------------
;TH 1.5 A note to operators: If you just HAVE to find the password in
;the installed driver or PASSWRD5.SYS file .. use DEBUG or a binary file
;editor like FM (or even Buerg's LIST.COM in hexidecimal mode). Look
;immediately after the device_name "PWORD15" (8 bytes altogether), and
;you should see the hardcoded password.
;THIS is what makes this sucker "not so very secure."
;So don't tell the users!
;
password_store DB LEN ;v1.5 actual password length
db 'plan' ;actual password (case matters!)
;(replace with yours, up to 16 chars)
;Leave room for a 16-character password
LEN equ $-password_store-1 ;v1.5
DB 16-LEN DUP(' ') ;v1.5 pad with spaces (unused)
inbuf_max DB 16 ;max password length allowed
inbuf_len DB 0 ;actual keyboard entry length
inbuf DB 16 DUP(0) ;TH buffer for keyboard input
break_off DW 0 ;TH save old Int 1BH vector
break_seg DW 0 ;TH
; -- The Strategy proc stores ES:BX request header pointer here
; -- The Interupt proc retrieves it
request_ptr LABEL DWORD
req_ptr_off DW 0 ;TH
req_ptr_seg DW 0 ;TH
;dummy_iret DB 207 ;Ctrl-Break vector is pointed here, so it
;does nothing. Break is not recognized!
;TH this is actually an IRET instruction.
dummy_iret: IRET ;TH v1.5
;---------------------- Messages ----------------------------------
;These messages are expected to be output via the ANSI.SYS device,
;so it should be installed (named in the CONFIG.SYS file) before
;this PWORD device.
;If you don't want to use ANSI.SYS, remove the ESCP sequences in the
;messages.
ANSI EQU 1 ;v1.5 make 0 for non-ANSI display
LF EQU 0AH
CR EQU 0DH
ESCP EQU 1BH
IF ANSI ;v1.5
msg_1 DB CR,LF,ESCP,'[0m' ;make output visible
DB 'Enter '
DB ESCP,'[5m' ;make output blink
DB 'Password: '
DB ESCP,'[8m$' ;make input invisible
msg_2 DB CR,LF,ESCP,'[0m' ;make output visible
DB 'Password accepted.',CR,LF,'$'
ELSE ;v1.5
msg_1 DB CR,LF,'Enter Password: $'
msg_2 DB CR,LF,'Password accepted.',CR,LF,'$'
ENDIF ;v1.5
Pword_Device endp ;TH
;====================================================================
;Strategy procedure
;Just saves the request header pointer for the Interupt proc
Strategy PROC FAR
ASSUME CS:DEV_SEG
MOV CS:req_ptr_off,BX
MOV CS:req_ptr_seg,ES
RET
Strategy ENDP
;====================================================================
No_Break PROC NEAR
;The following 8 lines eliminate Ctrl-Break from having any effect
;on the system, unless another program KEYBOARD_BREAK vector is
;altered (BASIC does that).
; OLD BREAK VECTOR IS STORED SO THAT IT MAY BE RESET
ASSUME DS:DEV_SEG,ES:Nothing ;TH a reminder
xor ax,ax ;TH
MOV ES,AX
MOV AX,WORD PTR ES:[1Bh*4] ;save old Int 1BH
MOV break_seg,AX
MOV AX,WORD PTR ES:[1Bh*4+2]
MOV break_off,AX
MOV WORD PTR ES:[1Bh*4],OFFSET dummy_iret ;reset to our function
MOV WORD PTR ES:[(1Bh*4)+2],CS ;(a dummy IRET)
RET
No_Break ENDP
Break_On PROC NEAR
; THE FOLLOWING 6 LINES RESTORE THE CTL-BREAK VECTOR
xor ax,ax ;TH
MOV ES,AX
MOV AX,break_seg ;Restore the Int 1BH seg
cli ;TH let's try this
MOV WORD PTR ES:[1Bh*4],AX ;restore the segment
MOV AX,break_off ; and offset
MOV WORD PTR ES:[(1Bh*4)+2],AX
sti ;TH restore ints
RET
Break_On ENDP
;====================================================================
Ask_Pwrd PROC NEAR
;
; This code prompts the user for the correct password
;
mov ax,CS
mov ES,ax ;TH for string comparisons
ASSUME DS:DEV_SEG, ES:DEV_SEG ;TH a reminder
Try_Again:
mov ax,0E07H ;TH write a beep TTY
INT 10H
MOV DX,OFFSET msg_1 ;"Enter Password: "
MOV AH,9 ;DOS display msg
INT 21H
MOV DX,OFFSET inbuf_max ;TH keyboard input buffer
mov ax,0C0AH ;TH buffered kbd input
INT 21H
MOV SI,OFFSET inbuf_len ;nr chars he typed
MOV DI,OFFSET password_store ;our password length
xor ch,ch ;clear msb
MOV CL,[SI] ;compare his input length..
CMP CL,[DI] ;.. to our password length
JNE Try_Again ;not the same .. gotta be wrong
INC DI ;bump past length bytes
INC SI
REP CMPSB ;do a comparison
JNE Try_Again ;not the same .. dummy
MOV DX,OFFSET msg_2 ;"Password accepted"
MOV AH,9 ;DOS display msg
INT 21H
RET
Ask_Pwrd ENDP
Ask_Off proc far ;TH
push ax ;TH do this same order as Init_Fn above
push bx
push ES
push cx
push dx
push si
push di
push DS
MOV AX,CS
MOV DS,AX
CALL No_Break ;turn Ctrl C function off
CALL Ask_Pwrd ;Try for the password
CALL Break_On ;turn Ctrl C function back on
Exit:
pop DS ;clean up the stack
pop di
pop si
pop dx
pop cx
pop ES ;the ones we first pushed
pop bx
pop ax
ret ;RET FAR from drivers
Ask_Off endp ;TH
;=====================================================================
;Interupt procedure
;Processes the command indicated in the request header.
Interupt PROC FAR
ASSUME CS:DEV_SEG, DS:NOTHING, ES:NOTHING
push ax ;TH save only what we need
push bx ;TH for first test
push ES
LES BX,request_ptr ;vector to our request flag
MOV AL,ES:[BX+2] ;check the init byte
or al,al ;TH 0 means not initialized
je Init_Fn ;TH so go initialize
OR WORD PTR ES:[BX+3],8003H ;the word right after
pop ES ;TH restore those we disturbed
pop bx
pop ax
ret ;RET FAR from drivers
Interupt endp ;TH
;TH An explanation .. When I first tweaked PASSWRD, it would compile,
;load, run on system boot, and even prompt for and process the password.
;However, the LOCK.COM utility (which calls Ask_Off) would lock up!
;Turned out Ask_Off was low in the original code (below Init_Fn), and its
;code space was being released and overwritten after PASSWRD initialized.
;LOCK.COM had no Ask_Off to call!
;
;I fixed this in PASSWRD4 by moving Init_Fn higher in the code
;(but I didn't understand what was going on).
;Thanks to Bernie Eiben for explaining what was happening with the
;Init process. (See his message at the end of this source code.)
Init_Fn PROC FAR ;was NEAR
push cx ;TH already pushed ax,bx,ES
push dx ;TH so gotta save the rest now
push si
push di
push DS
PUSH ES ;TH yep, save ES again since the
; Break fiddling'll blast it
;TH I'm assuming DOS initialized DS to CS on loading.
CALL No_Break ;Turn Ctrl C function off
CALL Ask_Pwrd ;Get user password
CALL Break_On ;Turn Ctrl C function back on
POP ES ;restore ES vector to installed driver
;TH v1.5: I'm not exactly sure what's happening here .. I THINK we're
;leaving information for DOS to release everything from Init_Fn on (e.g.,
;FREEMEM equivalent). The Init_Fn function is only used once, and then
;will be overlaid by later drivers, DOS, whatever. (Again, thanks to
;Bernie Eiben for the explanation. No, STILL haven't done a thorough
;study of DOS device drivers .. sigh ..)
MOV WORD PTR ES:[BX+0EH],OFFSET Init_Fn ;release from here on
MOV WORD PTR ES:[BX+10H],CS
OR WORD PTR ES:[BX+3],0100H ;flag we're initialized?
; THE FOLLOWING 6 LINES SET THE REFERENCE FOR RECALL.
; LOCATION AT INT 66H IS USED FOR ADDRESS STORE
;TH: I donno about this .. isn't anyone else using Int 66H?
;I'd rather have LOCK.COM search through memory for THIS particular
;driver (by finding its name or something).
;Think about that later if anything conflicts.
xor ax,ax ;TH
MOV ES,AX ;page 0
MOV AX,CS
MOV DS,AX
ASSUME DS:DEV_SEG, ES:Nothing ;TH a reminder
;Point Int 66H to our Ask_Off routine.
MOV AX,OFFSET Ask_Off
MOV WORD PTR ES:[66H*4],AX
MOV WORD PTR ES:[66H*4+2],CS ;TH
jmp Exit ;TH common pop, return
Init_Fn ENDP
DEV_SEG ENDS
END Pword_Device
From EIBEN@TOPS20.DEC.COM Mon Sep 5 10:54:15 1988
Date: 5 Sep 1988 1053-EDT
From: EIBEN@TOPS20.DEC.COM
To: David Kirschbaum <kirsch@braggvax.arpa>
Message-Id: <"MS11(6041)+GLXLIB6(0)" 12428147514.13.41.10070 at TOPS20.DEC.COM>
References: Message from David Kirschbaum <kirsch@braggvax.arpa>
of 27-Jul-88 1039-EDT
In-Reply-To: <8807271223.AA22884@braggvax.arpa>
Just saw Your PASSWRD4.ARC - and the 'dunno' comment in INIT_FN [or something
close].. Thats standard documented DOS behaviour.
to quote..
One of the functions defined for each device is INIT. This routine is called
only once when the device is installed and never again. The INIT routine
returns the following:
A location to the first free byte of memory after the device driver,
like a terminate and stay resident that is stored in the ending address
field. This way the initialization code can be used once and thrown
away to save space.
After setting the ending address field, a character device driver can
set the status word and return.
[quoted without permission from Technical Reference, Disk Operating System
Version 3.30 , IBM]
Rgds,
Bernie - You might want to 'remove' Your comments - the code does the
'correct' thing - it removes the INIT piece by letting DOS
're-use' the space... maybe a comment BEFORE INIT should warn,
that the 'following' is overlaid 'once-only' code.
--------