;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *; ;* This is a demonstration program that shows how to encrypt *; ;* a file with a password using the XOR operator. *; ;* Compiled by TASM 3.1 for 8086 CPU under DOS (small memory). *; ;* *; ;* Written by Zsolt Nagy Perge in October 2000, Pensacola, FL. *; ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *; CODE SEGMENT ASSUME CS:CODE, DS:CODE, ES:CODE, SS:CODE ORG 00100h ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *; ;* INITIALIZATION *; ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *; ENTRY: ; PSP PARAMETER STRING ANALYZATION XOR BL,BL ; tells if we are reading letters or spaces XOR CL,CL ; counts the number of parameter strings MOV DI,OFFSET ParamPtr ; points to the parameter ptr table MOV SI,00081h ; points to the parameter string CLD GetParam: ; Read one character from the parameter string. LODSB ; Identify it... CMP AL,00Dh ; END OF PARAMETER? JE GetParam_Exit CMP AL,020h ; SPACE? JE GetParam_Space CMP AL,009h ; TAB? JE GetParam_Space ; If AL was not a space, neither a TAB character, ; then it must be the character of a parameter. ; Did we previously save this parameter? ; If yes, then continue the loop. OR BL,BL JNE GetParam ; If no, then we'll save its address in the parameter ptr table now. MOV AX,SI DEC AX STOSW ; Increment the parameter counter, ; and then set the flag because we have saved this parameter. INC CL GetParam_SetState: ; We change the flag now. ; This helps us remember what we just did before this loop... NOT BL JMP GetParam GetParam_Space: ; Have we just read a parameter? ; Let's check the flag if it is zero. ; If no, then continue the loop. OR BL,BL JE GetParam ; If yes, then we must put a NULL character at its end, ; and then clear the flag because we are done with this parameter. MOV BYTE PTR [SI-01],00 JMP GetParam_SetState GetParam_Exit: ; Finally, we are finished, ; but we still have to put one NULL character ; at the end of the parameter string to close it. MOV BYTE PTR [SI-01],00 ; Now, CL contains the number of parameter strings given, ; and ParamPtr contains the pointers to each parameter string. ; PARAMETER CHECKING ; Here, we want to make sure that we got all the needed parameters. ; Only two parameters are required. ; If we got less, then we jump to Error and display Usage. CMP CL,002h MOV DX,OFFSET Usage JB Error ; Assume that the password was given as a parameter. MOV AX,[ParamPtr[4]] MOV [PWP],AX ; Make sure that we have the password... JA HavePassword ; Unfortunately the user forgot to give us the password, ; but we will remind him now. MOV AH,009h MOV DX,OFFSET AskPassword INT 021h ; Ask the user to enter the password. MOV AH,00Ah MOV DX,OFFSET Buffer INT 021h MOV AH,009h MOV DX,OFFSET CRLF INT 021h ; Put a NULL character at the end of the password string. MOV AL,[Buffer[1]] CBW MOV SI,AX ADD SI,OFFSET Password MOV [SI],AH ; Store the password pointer at PWP. ; Originally PWP was pointing to the thrid parameter in ParamPtr. MOV [PWP],OFFSET Password HavePassword: ; Equal PWC to PWP. MOV AX,[PWP] MOV [PWC],AX ; Now that we have the password, ; we may go ahead and open the files. ; Open input file for read-only access... MOV AX,03D00h MOV DX,[ParamPtr[0]] INT 021h MOV [InFile],AX MOV DX,OFFSET InFileErr JC Error ; Create normal output file... MOV AH,03Ch MOV CX,00000h MOV DX,[ParamPtr[2]] INT 021h MOV [OutFile],AX MOV DX,OFFSET OutFileErr JC Error ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *; ;* MAIN LOOP *; ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *; MainLoop: ; Fill the buffer when necessary. ; This function will never return when we reach the end of file. CALL Read ; Load password character and do the encryption... MOV DI,[PWC] MOV AL,[DI] ; We are not removing the character; we just XOR it in the buffer. ; The write function will be called by the read function before ; it wants to read in a new buffer, therefore the buffer ; will flush itself whenever it is necessary. XOR [SI],AL ; Increment PWC. INC [PWC] ; Reset PWC if it points to the end of the password. MOV SI,[PWC] LODSB OR AL,AL JNE MainLoop MOV SI,[PWP] MOV [PWC],SI JMP MainLoop ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *; ;* Displays an error message and terminates the program *; ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *; Error: ; Print a message to stdout. MOV AH,009h INT 021h ; Close all files and exit with error code 1. MOV AX,04C01h INT 021h ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *; ;* Writes each byte from the buffer to the output file *; ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *; WriteBuffer: ; Write resulting byte to the output file. MOV AH,040h MOV BX,[OutFile] MOV CX,SI MOV DX,OFFSET DATABUFFER INT 021h ; Check for errors... CMP AX,[BFULL] MOV DX,OFFSET WritingErr JNE Error RET ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *; ;* Reads one byte of data *; ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *; Read: ; If we do not have any leftovers in the data buffer, ; then we'll have to fill it up again. MOV SI,[BPTR] CMP SI,[BFULL] JAE ReadBuffer ; Return the pointer to the new character in SI. ADD SI,OFFSET DATABUFFER INC [BPTR] RET ReadBuffer: ; We have to flush the buffer before we read. ; Nothing will be written when SI is zero. ; So, we don't have to worry about what's going to happen on the first round. CALL WriteBuffer ; Now, we'll try to read in a buffer. MOV AH,03Fh MOV BX,[InFile] MOV CX,BUFFERSIZE MOV DX,OFFSET DATABUFFER INT 021h MOV [BFULL],AX MOV [BPTR],0000 ; If were not able to read anything, ; then certainly we've reached the end of file. OR AX,AX JNE Read ; Close all files and exit with error code 0. MOV AX,04C00h INT 021h ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *; ;* DATA AREA *; ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *; InFileErr DB "Cannot open input file.", 13, 10, 36 OutFileErr DB "Cannot open output file.", 13, 10, 36 WritingErr DB "Cannot write to output file.", 13, 10, 36 AskPassword DB "Password: $" ; The following two lines must stay in this order! Usage DB "Usage: XOR [password]" CRLF DB 13, 10, 36 BPTR DW 0 ; number of bytes read from data buffer BFULL DW 0 ; number of bytes read into data buffer ; The following two lines must stay in this order! Buffer DB 128, ? ; password buffer size & password length Password DB 128 DUP(?) ; password buffer PWP DW ? ; password pointer PWC DW ? ; password character pointer ParamPtr DW 64 DUP(?) ; parameter ptr table InFile DW ? ; input file handle OutFile DW ? ; output file handle BUFFERSIZE EQU 08000h ; size of data buffer DATABUFFER DB BUFFERSIZE DUP(?) ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *; CODE ENDS END ENTRY ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *;