home *** CD-ROM | disk | FTP | other *** search
- ; title 'PASSWORD.ASM'
- ; page 60
- ;
- ;
- ; PASSWORD.ASM
- ; Version 3.0
- ; By Bo McCormick 8/6/81
- ;
- ; This is a program that adds password protection
- ; to programs. Format:
- ;
- ; PASSWORD name_of_file
- ;
- ; Then answer the prompt with the password to be
- ; applied to the program:
- ;
- ; Password? enter password here
- ;
- ; If everything goes well, the program will be saved to disk.
- ; If not, a message is printed and control is passed
- ; to the CCP.
- ;
- ; The good part of this is, when you type in the program
- ; program name next time, instead of running the program
- ; right away, the program asks you for the password. If you
- ; reply with something other than the original password, the
- ; program doesn't run, and it returns to the ccp.
- ;
- ; 2/10/82: Set DMA before open because 1.4 CP/M uses buffer at 80H
- ; Removed "$" from labels so other assemblers can be used. Fixed
- ; "offset" to use tpa instead of 100H so it would work with
- ; modified CP/M. Added encryption of password so dumping .COM
- ; file will not reveal it. (Thanks to author of XYZZY.COM)
- ; Fixed test of supplied password to check all characters.
- ; Ted Shapin
- ;
- ; 12/10/81: changed ot$pw routine to input password one character
- ; at a time invisibly from BIOS rather than using BDOS's string input
- ; function. This allows password to be typed in without anyone
- ; seeing what it was that was typed. Jim Mills
- ;
- ;EQUATES
- rdchar: equ 1
- mesout: equ 9 ;BDOS functions
- incon: equ 10
- open: equ 15
- close: equ 16
- delete: equ 19
- read: equ 20
- write: equ 21
- setdma: equ 26
- ;
- cr equ 0dh ;ascii values
- lf equ 0ah
- eos equ '$'
- ;
- boot equ 0;4200H ;0 for standard CP/M
- ;4200H for ALT. CP/M;
- bdos equ boot+5
- fcb equ boot+5ch
- defbuf equ boot+80h
- tpa equ boot+100h
- stack equ tpa ;out of way of tpa
- ;
- org tpa
-
- ;
- ;
- start: lxi h,0 ;save stack pointer
- dad sp ;put stack in hl
- shld oldstack-offset ;save it
- lxi sp,stack ;get new stack
- ;
- ; stack saved so program can return to CCP without
- ; intervening warm start.
- ;
- lda fcb+9 ;get first char of extension
- cpi ' ' ;if ' ' then change to .COM
- jz notype
- cpi 'C' ;If there is an extension,
- jnz notright ;make sure it's .COM
- lda fcb+10 ;check second letter
- cpi 'O'
- jnz notright
- lda fcb+11
- cpi 'M' ;last letter
- jz iscom ;if it is a COM, then cont.
- notright:
- call endmes ;it's not a com file, so tell
- ;
- db cr,lf,'Must be a command (.COM) file'
- db cr,lf,eos
- ;
- endmes:
- pop d ;get address of message
- mvi c,mesout ;PRINT STRING command
- call bdos ;print error message
- ;
- finish: lhld oldstack-offset ;get old stack
- sphl ;put it in HL
- ret ;return to CP/M
- ;
- notype: mvi a,'C' ;if there was space, change
- sta fcb+9 ;to COM
- mvi a,'O'
- sta fcb+10
- mvi a,'M'
- sta fcb+11
- ;
- iscom: lxi d,buffer-offset ;point to where program goes
- mvi c,setdma ;SET DMA command
- push d ;save it
- call bdos ;and tell CP/M
- mvi a,0 ;zero record count
- sta fcb+32
- mvi c,open ;OPEN file command
- lxi d,fcb ;load address of FCB in DE
- call bdos ;Open file
- inr a ;successful?
- jnz openok ;if so, then continue
- call endmes ;if not, then tell
- ;
- db cr,lf,'Cannot open file',cr,lf,eos
- ;
- openok: pop d ;get starting dma back
- rloop: mvi c,setdma ;and set it in loop
- push d ;save it
- call bdos
- lxi d,fcb ;point to FCB
- mvi c,read ;READ sector command
- call bdos ;do it
- pop d ;get DMA address back
- ana a ;EOF?
- jnz doneread ;if so, then ask for password
- lxi h,80h ;length of sector
- dad d ;bump DMA
- xchg ;put new address in DE
- jmp rloop ;and read some more
- ;
- doneread:
- xchg ;dma ==> hl
- shld endprog-offset ;save last address
- gpasag call getpas ;print password message
- ;
- pasmes db 'Password? ',eos
- ;
- getpas pop d ;get address of message
- mvi c,mesout ;PRINT STRING function
- call bdos ;print it
- lxi d,defbuf ;point to default buffer
- mvi a,8 ;tell CP/M max chars
- stax d ;put it there
- mvi c,incon ;READ LINE command
- call bdos ;do it
- lxi h,defbuf+1 ;point to length
- lxi d,password-offset ;point to storage
- mov a,m ;get length
- ana a ;set flags
- jz gpasag ;if 0 then ask again
- inr a ;plus 1 for length byte
- mov b,a ;put length in B
- xra b ;cancel first xra in loop
- mov m,a ;and put it back
- mploop mov a,m ;get char
- xra b ;encrypt it
- stax d ;save it
- inx h ;increment pointer
- inx d ; " "
- dcr b ;decrement length
- jnz mploop ;if not zero, then next char
- xra a ;zero a
- sta fcb+12 ;zero bytes in FCB
- sta fcb+14
- sta fcb+32
- mvi c,open ;OPEN file command
- lxi d,fcb ;point to FCB
- call bdos ;open the file
- lxi d,nstart ;point to new program start
- ;
- push d
- wloop1 pop d ;get DMA
- push d ;put it back on stack
- mvi c,setdma ;SET DMA command
- call bdos ;tell CP/M
- lxi d,fcb ;point to FCB
- mvi c,write ;WRITE SECTOR command
- call bdos ;do it
- pop h ;get DMA address from stack
- lxi d,80h ;length of sector
- dad d ;HL has new DMA
- push h ;put it on stack
- mov a,h ;this is to get 2's complement
- cma ;of address. We are subtracting
- mov d,a ;the current address from the
- mov a,l ;high address. If the high byte
- cma ;<1 , we are done
- mov e,a ;
- inx d ;Now 2's comp. of address in DE
- lhld endprog-offset ;get ending address
- dad d ;Subtract (add 2's comp)
- mov a,h ;get high byte
- inr a ;is it FF (-1)?
- ana a ;set flags
- jnz wloop1 ;if not, write another sector
- ;
- mvi c,close ;That's it. Close the file
- lxi d,fcb ;point to FCB
- call bdos ;do it
- jmp finish ;goto finish
- ;
- ;
- nstart:
- offset equ tpa-nstart
- ;
- ; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- ; %% WARNING - %%
- ; %% From now on, all labels are in %%
- ; %% the form: %%
- ; %% LABEL EQU $+OFFSET %%
- ; %% This is to allow the program to run at100H %%
- ; %% when it is saved by the earlier portion. %%
- ; %% ALL new labels added MUST be in the form %%
- ; %% LABEL EQU $+OFFSET for this program to work %%
- ; %% properly. %%
- ; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- ;
- ;This is portion of the program is placed at the beginning
- ;of the program to be PASSWORDed. When it is executed, it will
- ;ask for a password. If the password is incorrect, the program
- ;warm starts. If the password is correct, the program is moved
- ;to the TPA and executed.
- ;
- lxi h,0 ;save stack pointer
- dad sp ;stack is in HL
- shld oldstack ;save it
- lxi sp,stack ;get new stack
- call otpw ;print password message
- ;
- db cr,lf,'Password? '
- db eos
- ;
- otpw equ $+offset
- pop d ;get address of message
- mvi c,mesout ;PRINT STRING command
- call bdos ;print it
-
- lxi d,newbuf+1 ;point to storage area
- xra a
- mov b,a ;init counter
- stax d ;# of chars typed (for compare)
- inx d ;and point to string
- ;
- ; we don't want to allow 'lookers' to see the password, so call
- ; bios instead of bdos to prevent echo. also allows control chars.
- ;
- lhld boot+1 ;get addr of warm start routine
- push d
- lxi d,6 ;+ offset to kbd input routine
- dad d
- pop d
- shld bconin+1 ;now init'd to bios conin
-
- otpw1 equ $+offset
- push b ;save counter..
- push d ;..& pointer
- bconin equ $+offset
- call $-$ ;to be filled in by above routine
- pop d ;restore pointer..
- pop b ;..& counter
- stax d ;store char
- inx d ;bump pointer..
- inr b ;..& counter
- cpi cr
- jnz otpw1 ;loop until cr typed
- ; B has the length of password furnished + 1 for count.
- lxi h,password ;point to actual password
- lxi d,newbuf+1 ;point to user's input
- xra a ;this 0 xra with length in B
- stax d ;should equal count in passwd
- ;
- ; first char compared is a count of # of chars in password,
- ; followed by password itself.
- ;
- clp equ $+offset
- ldax d ;get char
- xra b ;encrypt it
- cmp m ;are they the same?
- jnz boot ;if not, restart
- inx h ;point to next characters
- inx d ; " " " "
- dcr b ;decrement length
- jnz clp ;if not done, then loop
- ;
- ; Now we move a segment of code to a part of the default
- ; buffer. This segment moves the actual program down to the
- ; TPA
- ;
- lxi h,nmv ;point to code
- lxi d,defbuf+20h ;point to new postion
- mvi b,nmlen ;length
- ;
- move equ $+offset
- mov a,m ;get byte
- stax d ;save it
- inx d ;point to next addresses
- inx h ; " " " "
- dcr b ;decrement length
- jnz move ;if not done, loop
- jmp defbuf+20h ;go to segment
- ;
- nmv equ $+offset ;segment that gets moved
- lhld oldstack ;get stack pointer
- push h ;save it on stack
- lxi h,buffer ;get start of actual program
- mov a,h ;We have to compute the length
- cma ;and because X-Y equals
- mov d,a ;X + Two's complent(Y), we have
- mov a,l ;to find the 2's comp. of the
- cma ;first address
- mov e,a ;
- inx d ;Y is in DE
- lhld endprog ;get last address
- dad d ;subtract (add 2's comp)
- mov b,h ;put length in BC
- mov c,l ; " " " "
- lxi d,tpa ;point to TPA
- lxi h,buffer ;point to first address
- nmlp equ defbuf+20h+$+offset-nmv
- mov a,m ;get byte
- stax d ;save byte
- inx h ;increment address
- inx d ; " "
- dcx b ;decrement length
- mov a,b ;check for zero left
- ora c ;Are we done?
- jnz nmlp ;if not, loop some more
- pop h ;get stack from stack
- sphl ;put stack in SP
- jmp tpa ;run program
- ;
- nmlen equ $+offset-nmv ;length of segment
- ;
- ;
- password equ $+offset ;password storage
- db 0,' '
- ;
- ;12/10/81 changed to allow use of tbuf as input area
- ;
- newbuf equ $+offset ;Users input buffer
- db 10H,0,' '
- ;
- oldstack equ $+offset ;place for stack
- ds 2
- ;
- endprog equ $+offset ;place for address
- ds 2
- ;
- buffer equ $+offset ;where actual program goes
- end