home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 June
/
SIMTEL_0692.cdr
/
msdos
/
sysutl
/
passwrd9.arc
/
PASSWORD.ASM
< prev
next >
Wrap
Assembly Source File
|
1989-03-15
|
17KB
|
575 lines
Title pw9.asm
;Originally titled PW.8
;Rev by John R. Petrocelli 02/25/85
;Rev by John R. Petrocelli 04/30/85
;Rev by Durrell Drummond 10/10/86
;Re-written by Bob Montgomery 01/10/87
;Re-written by John Jaeger 03/12/89
;Major changes include ready for assembly by MASM.
;Use without the ANSI.SYS driver for reasonable CRT
;displays.
;Corrected source code. The original dated 01/10/87
;worked as stated when using the supplied object code,
;However when I added all the necessary items to compile
;with MASM, things didn't work so well. That may be due
;to the fact I am not acquainted with A86!
;Coding of the ASCII Password string so that if
;viewed by such things as XTREE, nothing jumps out
;and indicates a readable password.
;Coding of the "Prompt Strings" for the same reason
;as noted above. There is no evidence that this file
;is the one to cause the Password Check to appear on the
;screen.
code segment public 'CODE'
assume cs:code,ds:code,es:code
driver proc near
org 0 ;Required for Device Driver
;======== Driver Device Header Area ========
header: dd -1 ;One device in this file
dw 8000h ;Defines character device
dw strategy ;Pointer to install routine
dw interrupt ;pointer to proc that handles
;the services
db 'PWXYZQPR' ;8 byte string that names the
;device. Do not attempt to
;type from the Keyboard or
;anything could happen!!!!
;============================================================================
;======== Storage for header offset and segment ========
rhoffset dw 0
rhseg dw 0
;============================================================================
;============================================================================
;Area below is for some variables used by the program that installs
;PASSWORD.SYS. DO NOT change the relationship of the variable "area_length"
;to the DEVICE HEADER, or the location of the PASSWORD area! You may add
;or delete to the Screen Message area, but do not move or remove the
;"tries_left" variable in relation to the message area.
;============================================================================
area_length dw tries_left-$
password db 0
password_len equ $-password
padd db 16-password_len dup(20h)
;============================================================================
;======== Screen message character area (Encrypted) ========
msg_1 db 'Enter Password:',15 dup(20h) ;Enter Password
msg_1_len dw $-msg_1
msg_2 db '****** Password Accepted *****';Password Accepted
msg_2_len dw $-msg_2
msg_3 db '** Wrong Password Try Again **';Wrong Password
msg_3_len dw $-msg_3
msg_4 db '******** ACCESS DENIED *******';Access Denied
msg_4_len dw $-msg_4
msg_5 db 201,32 dup(205),187 ;Screen Box
msg_6 db 186,32 dup(20h),186 ;Screen Box
msg_7 db 200,32 dup(205),188 ;Screen Box
;============================================================================
;Miscellaneous Variable Storage
;============================================================================
Tries_left db 0
wordlen db 0
wordbuff db 15 dup(0)
tries db 3
breakoff dw 0
breakseg dw 0
video_location dw 0
cursor_location dw 0
;============================================================================
dummyret: iret ;Pointer to Ctrl-Break vector
;inserted by this program to
;disable the Ctrl-Break
;============================================================================
;======== main portion of program to get the user password ========
ask_password:
push cs
pop ds ;Set ds=cs
mov ax,351bh ;Get break vector (Int 1Bh)
int 21h ;from DOS
mov breakoff,bx ;Save it for later
mov breakseg,es
push cs
pop es ;Set es=cs
mov dx,offset dummyret ;Set Break vector to dummyret
mov ax,251bh
int 21h ;via DOS
check_video: ;See where video RAM is
mov ah,0fh ;via video ROM
int 10h
cmp al,07h ;See if Mono card installed
jz set_mono ;Jump to monochrome routine
mov video_location,0b800h ;If not mono then Color RAM
jmp video_done ;Exit routine
set_mono:
mov video_location,0b000h ;Set location to Mono RAM
video_done:
call clear_screen ;Self explanatory
call box ;Routine to build entry
;box on screen
xor cx,cx ;Set cx=0
mov cl,tries ;Store the number of tries
mov tries_left,cl ;for later
;======== Prompt the user for the correct password ========
set_prompt:
cmp cl,0 ;See if tries has expired
jz go_lock_out ;Jump to routine to lock
;system if tried 3 times
;with wrong password!
mov tries_left,cl ;Store the tries left
mov bx,offset msg_1 ;Point to input prompt
mov cx,msg_1_len ;Prep for display
mov ah,0fh ;Set ah with the attribute
;that write_crt uses
;You may change this for
;different colors or intensity
mov dx,0c19h ;Load dx for start location
call write_crt ;to print on CRT and write it
mov dx,0b27h ;Set CRT location for input
;field start
xor bx,bx ;Set bx to 0 (Page 0)
call position_cursor ;Set cursor to start of input
;line on CRT
mov si,offset wordlen ;Point to number of char. in
mov byte ptr [si],0 ;entry and initialize to 0
mov di,offset wordbuff ;Point to number of char. in
;stored password
;======== Character input routine ========
in_char: ;Lets go get some input
mov ah,07h ;Use none echoing input
int 21h ;from DOS
cmp al,08h ;See if backspace?
jz back_space ;Jump to routine to del Char.
cmp al,0dh ;See if input is done?
jz check_password ;Check it out
cmp byte ptr [si],15 ;See if password length has
jz bell ;been exceeded and ring bell
mov [di],al ;Store char in wordbuff and
inc di ;increment pointer
mov al,0h ;Store special char for the
call write_cursor ;display of an '*' on the CRT
jmp in_char ;Loop for the next Character
;======== Intermediate launching point to lock the machine ========
go_lock_out:
call lock_out ;Go lock up the machine
;======== Routine to back space and erase on the crt ========
back_space:
cmp byte ptr [si],0 ;See if there are no char to
jz bell ;erase and sound bell if none
dec byte ptr [si] ;Set char count to one less
dec di ;Move pointer back one in
;wordbuff
mov al,0ffh ;Set erase code for erasing
call write_cursor ;'*' at cursor position
jmp in_char ;Loop back for next char
;======== Ring the bell routine ========
Bell: mov al,07h ;Ring the bell with DOS
mov ah,0eh
int 10h
jmp in_char ;Back to input
;============================================================================
;End of input routines, now lets go check what was entered!
;============================================================================
Check_password:
mov di,offset password ;Point to length of our pre-
cmpsb ;set word and see if the
jne next_try ;length is the same and spare
;the trouble if it is not
xor cx,cx ;cx=0
mov cl,wordlen ;Total char. entered into cl
call convert_up ;Convert char. to upper case
repe cmpsb ;compare pointers si & di
cmp cl,0 ;See if all matched
je ok ;Jump to exit if they were
;Fall through if not
;======== Routine to display wrong word and reset for another word ========
next_try:
call off_screen ;Move curser out of the box
mov dx,0c19h ;Cursor location for message
mov bx,offset msg_3 ;Wrong Password message
mov cx,msg_3_len ;Message length
mov ah,8fh ;Blinking attribute
call write_crt ;Display message
mov ax,0e07h ;Ring bell
int 10h
mov ah,07h ;Ask for character input to
int 21h ;hold screen. Any char allows
;continuation of the program
mov cl,tries_left ;Set up to reduce the number
dec cl ;of tries left and go back
jmp set_prompt ;for another turn
;======== This is where we prepare to exit this program ========
ok:
call off_screen ;Move cursor out of the box
mov dx,0c19h ;Location of message
mov bx,offset msg_2 ;Point to Password Accepted
mov cx,msg_2_len ;Length of message
mov ah,8fh ;Set attribute
call write_crt ;Display successful message
mov ds,breakseg ;Restore original Ctrl Break
mov dx,breakoff ;vectors through DOS
mov ax,251bh
int 21h
ret ;And return
;============================================================================
;This subroutine converts all characters to upper case
;============================================================================
convert_up:
push ax ;Save all registers
push cx
push ds
push es
push si
push di
push ds ;es=ds
pop es
mov di,si ;make di & si point to the
;same location
check_char:
lodsb ;Get char at si and inc si
cmp al,'a' ; < a ?
jl store_byte ; It's ok - store it
cmp al,'z' ; > z ?
jg store_byte ; It's ok - store it
sub al,20h ; Make it caps
Store_byte:
stosb ;Store the byte at di
loop Check_char ;Do all until cx=0
pop di ;Restore all registers
pop si
pop es
pop ds
pop cx
pop ax
ret ;And return
;============================================================================
driver endp
;============================================================================
;This routine locks up the machine completely. If the program gets this far
;you will need to press the reset button ( If you have one ) or
;turn the power off!!
;============================================================================
lock_out proc near
cli ;Disable any interrupts
mov dx,0c19h ;Location on CRT for message
mov bx,offset msg_4 ;Sad message !!!
mov cx,msg_4_len ;Message length
mov ah,8fh ;Blinking Attribute
call write_crt ;Print Sad message
call off_screen ;Get cursor out of box
; and
locked: jmp locked ; die !
lock_out endp
;============================================================================
;The following routines are the direct CRT display code
;============================================================================
write_crt proc near
push es ;Save original es
push dx ;Save location to write
push ax ;Save the attribute
push cx ;Save the character count
push dx ;Save for the moment
mov cx,02h ;Set the multiplier
mov ax,video_location ;Get the address of video RAM
mov es,ax ;Set the es register to RAM
mov si,bx ;Point si to the message
xor ax,ax ;Zero the ax
mov al,dl ;Move to al the column
sub al,1 ;Adjust the al
imul cx ;Times to for actual column
pop dx ;Get the original location
mov dl,al ;Store column in dl
mov al,dh ;Move into ax the row
push dx ;Save for the moment
sub ax,1 ;Adjust the ax
mov cx,160 ;80 times 2 for actual offset
imul cx
pop dx ;Get dx back
and dh,00h ;Zero the dh
add ax,dx ;Add the column offset to the
mov di,ax ;row and move di to the actual
;memory position
pop cx ;Restore character count
pop ax ;Restore the attribute
write_crt_1:
lodsb ;Load a byte of message
stosw ;Store byte & attribute to RAM
loop write_crt_1 ;Loop until cx=0
pop dx ;Restore original dx
pop es ;restore original es
ret ;And return
write_crt endp
write_cursor proc near
mov bx,0fh ;Load attribute in bl
mov cx,1 ;Load # of characters
cmp al,0ffh ;See if back space
jz erase_char ;If so then erase prev char
mov al,'*' ;Set to display an * on CRT
mov ah,09h ;Call DOS to display '*'
int 10h
mov dx,cursor_location ;Where in the input string
inc dl ;the cursor resides and inc
inc byte ptr [si] ;Increase character count
xor bx,bx ;Zero the bx
jmp position_cursor ;Move cursor to the next pos
erase_char:
mov dx,cursor_location ;Get the last position of the
dec dl ;cursor and back it up
call position_cursor
mov ah,09h ;Set up to output a space
mov al,' ' ;character over the last *
int 10h ;Have DOS do it
ret ;And return
off_screen:
xor bx,bx ;Zero bx (page 0) and set
xor dx,dx ;position to upper left corner
position_cursor:
mov cursor_location,dx ;Store the position for later
mov ah,02h ;Have DOS reset the cursor
int 10h ;where we want it
ret ;And return
clear_screen:
mov ax,0600h ;Use DOS scroll to clear CRT
mov bh,07 ;Set attribute
xor cx,cx ;Upper left corner 0,0
mov dx,184fh ;Lower right 24,79
int 10h
ret ;And return
write_cursor endp
;============================================================================
;This routine draws a box for an entry window
;============================================================================
box proc near
mov ah,04h ;Set attribute for box
mov bx,offset msg_5 ;Point to Upper portion
mov cx,34 ;Horizontal Length
mov dx,0b17h ;Start at line 11, col 23
call write_crt ;Draw it
mov bx,offset msg_6 ;Middle portion
mov cx,34 ;Length
mov dx,0c17h ;Start next at 12 and 23
call write_crt ;Draw it
mov bx,offset msg_7 ;Bottom portion
mov cx,34 ;length
mov dx,0d17h ;Start next at 13 and 23
call write_crt ;Draw it
ret ;And return
box endp
;============================================================================
;The following procedure is where "Lock.Com" makes its entry
;It is far procedure ending with a Interrupt Return as Lock.Com
;gets here using an int 66.
;============================================================================
lock proc far
push ds ;Save Everything
push es
push ax
push bx
push cx
push dx
push si
push di
call ask_password ;Ask user for password
pop di ;Restore Everything
pop si
pop dx
pop cx
pop bx
pop ax
pop es
pop ds
iret ;And return from interrupt
;============================================================================
;This is the routine called by DOS to process the command in the request
;header. Preserve the environment and restore when done
;============================================================================
interrupt:
push ds
push es
push ax
push bx
push cx
push dx
push si
push di
push cs
pop ds ;Set ds=cs
mov bx,rhoffset ;Get request header and
mov es,rhseg ;segment loaded
cmp es:byte ptr [bx+2],0 ;Command 0? (Initialize)
je init ;Yes jump & initialize
exit: or es:word ptr [bx+3],100h ;No Set status done
pop di ;Restore environment
pop si
pop dx
pop cx
pop bx
pop ax
pop es
pop ds
ret
;============================================================================
;The following code is the initialize code run once when DOS originally
;loads this device driver. A code is passed back to DOS showing the
;beginning location of this code. Once initialized, this code is
;discarded.
;============================================================================
init: mov dx,offset lock ;Point to entry of int 66
mov ax,2566h ;and save it through DOS
int 21h
push es ;Save es & bx received
push bx ;from DOS
;============================================================================
;This is the area to restore the display and password area to their
;original ASCII numbers.
;============================================================================
xor cx,cx ;Zero the counter
mov cx,area_length ;Get the char count to decode
mov al,40h ;Set the al to the decode #
mov bx,offset password ;Point to the start position
in_loop: ;
add byte ptr [bx],al ;Start decoding
inc bx ;Increment pointer
loop in_loop ;Do until done
;============================================================================
xor cx,cx ;Prep for conversion to
mov si,offset password ;Uppercase. Point to length
lodsb ;of password and move to al
mov cl,al ;Move char count to cl
call convert_up ;Convert to upper case
call ask_password ;Ask user for Password
pop bx ;Restore bx & es
pop es
mov es:[bx+14],offset init ;Save pointer to init as
mov es:[bx+16],cs ;start of free memory
jmp exit ;And return to DOS
lock endp
;============================================================================
;The following Strategy procedure stores the location of the request
;header (passed by DOS in the es:bx) here. The interrupt procedure
;gets it to find the request from DOS.
;Request header format:
; Offset Content
; 0 Byte-length (of request header)
; 1 Byte-unit code (If more than one device controlled)
; 2 Byte-command (0 thru 0ch; 0=Initialize)
; 3,4 Word-Status (Bit 8=done, bit 15=error, bits 0-3=error code)
; 5-D 8 Bytes - Reserved for DOS
; E- Data-Ending address if code=0, otherwise data to transfer
strategy proc far
mov cs:rhoffset,bx ;Save Request header offset
mov cs:rhseg,es ;Save request header segment
ret ;And do a far return
strategy endp
code ends
end