Skip to content

Instantly share code, notes, and snippets.

@zuchmanski
Created June 7, 2013 13:14
Show Gist options
  • Save zuchmanski/5729159 to your computer and use it in GitHub Desktop.
Save zuchmanski/5729159 to your computer and use it in GitHub Desktop.
.286
APP_DATA segment
; arguments
Arguments db 200 dup(?)
ArgsLengths db 128 dup(?)
; encrypt/decrypt mode
Mode db 0
; filename
InputFileName db 13 dup(?)
OutputFileName db 13 dup(?)
; filehandlers
InputFileHandler dw ?
OutputFileHandler dw ?
; passhase to code with
Passphrase db 100 dup (?)
PassphraseSize db 0
; buffer
Buffer db 4096 dup(?)
PassphraseBuffer db 4096 dup(?)
InputBufferPointer dw 0
OutputBufferPointer dw 0
BufferSize dw 0
; helper vars
Counter db 0
; errors
Error_InvalidArgs db "Please provide valid arguments! ", 10, 13, '$'
Error_Input db "Can not open input file", 10, 13, '$'
Error_Output db "Can not open output file", 10, 13, '$'
APP_DATA ends
APP_CODE segment
assume ss:APP_STACK, ds:APP_DATA
start:
mov ax, APP_DATA
mov ds, ax
mov ax, seg top1
mov ss, ax
mov sp, offset top1
main:
CALL loadArguments
CALL extractArguments
CALL setupFiles
CALL runCipher
CALL exit
; load arguments from command line
loadArguments:
pusha
; save number of arguments
mov bx, 0
; start loading args
mov si, 81h
mov di, offset Arguments
; is new line char last?
CALL loadArguments_skipWhiteChars
cmp al, 0
JNE Error_InvalidArgsRun
; main loop iterating each arg
loadArguments_loop:
; save arg and skip next white chars
CALL loadArgument
CALL loadArguments_skipWhiteChars
; inc number of args
inc bx
; last white char was not new line?
cmp al, 0
JE loadArguments_loop
; validate number of arguments
CALL checkNumberOfArguments
popa
ret
; validate length and number of arguments
checkNumberOfArguments:
pusha
mov si, offset ArgsLengths
cmp bx, 3
JE checkNumberOfArguments_encryptMode
cmp bx, 4
JE checkNumberOfArguments_decryptMode
CALL Error_InvalidArgsRun
checkNumberOfArguments_decryptMode:
; length
cmp byte ptr ds:[si], 2
JNE Error_InvalidArgsRun
CALL checkMode
inc si
checkNumberOfArguments_encryptMode:
; length
cmp byte ptr ds:[si], 10
JA Error_InvalidArgsRun
inc si
; length
cmp byte ptr ds:[si], 10
JA Error_InvalidArgsRun
popa
RET
; skip all white chars
; returns
; al 0 when there was new line char
loadArguments_skipWhiteChars:
; are all chars white?
mov al, 0
loadArguments_skipWhiteChars_start:
; store args in es:si
mov ah, byte ptr es:[si]
; space/tab/\n
cmp ah, ' '
JE loadArguments_skipWhiteChars_skip
cmp ah, 9d
JE loadArguments_skipWhiteChars_skip
cmp ah, 13
JE loadArguments_skipWhiteChars_newLine
JMP loadArguments_skipWhiteChars_end
loadArguments_skipWhiteChars_skip:
inc si
JMP loadArguments_skipWhiteChars_start
loadArguments_skipWhiteChars_newLine:
mov al, 1
loadArguments_skipWhiteChars_end:
ret
; parse and load one argument
loadArgument:
; last line?
mov al, 0
; length of current arg
mov cl, 0
loadArgument_start:
; all args are in es:si
mov ah, byte ptr es:[si]
cmp ah, ' '
JE loadArgument_end
cmp ah, 9d
JE loadArgument_end
cmp ah, 13
JE loadArgument_newLine
; ds:di - merged args
mov byte ptr ds:[di], ah
inc si
inc di
inc cl
JMP loadArgument_start
loadArgument_newLine:
mov al, 1
loadArgument_end:
push di
mov di, offset ArgsLengths
mov byte ptr ds:[di+bx], cl
pop di
RET
; validate mode (if == '-d')
checkMode:
push si
mov si, offset Arguments
cmp byte ptr ds:[si], '-'
JNE Error_InvalidArgsRun
inc si
cmp byte ptr ds:[si], 'd'
JNE Error_InvalidArgsRun
mov ds:[Mode], 1
pop si
RET
; read arguments and save in vars
extractArguments:
pusha
mov bx, 0
mov si, offset Arguments
cmp ds:[Mode], 1
JNE extractArguments_cont
; skip first two chars (if decrypt mode)
add si, 2
extractArguments_cont:
; extract file_name, inc index of ArgsLengths
mov di, offset InputFileName
CALL extractArgument
inc bx
; extract file_name, inc index of ArgsLengths
mov di, offset OutputFileName ;przepisujemy nazwe wyjscia
CALL extractArgument
inc bx
; extract Passphrase
mov di, offset Passphrase
CALL extractArgument
popa
RET
; rewrite filename and passphrase to memory
; in:
; di: given offset to write
extractArgument:
push ax
push cx
push di
mov di, offset ArgsLengths
cmp ds:[Mode], 1
JNE extractArgument_cont
; skip first arg (if dec mode)
inc di
extractArgument_cont:
; length of arg
mov cl, ds:[di+bx]
pop di
extractArgument_loop:
mov al, byte ptr ds:[si]
mov byte ptr ds:[di], al
inc di
inc si
dec cl ; length of arg
cmp cl, 0
JE extractArgument_end
JMP extractArgument_loop
extractArgument_end:
pop cx
pop ax
RET
; setup Handlers for input and output files
setupFiles:
pusha
; read only mode
mov al, 0
mov ah, 3dh
mov dx, offset InputFileName
int 21h
JC Error_InputRun
mov word ptr ds:[InputFileHandler], ax
; no attributes
mov cx, 0
mov ah, 3ch
mov dx, offset OutputFileName
int 21h
JC Error_OutputRun
mov word ptr ds:[OutputFileHandler], ax
popa
RET
; main function en/decoding given string
runCipher:
pusha
; skip en/de
mov bl, byte ptr ds:[Mode]
add bl, 2
; get length of passphrase
mov al, byte ptr ds:[ArgsLengths+bx]
mov di, offset PassphraseSize
mov byte ptr ds:[di], al
; main cypher loop
cipher_loop:
; read buffer from file
; set bx buffer pointer
CALL readToBuffer
mov bx, word ptr ds:[InputBufferPointer]
; iterate each char
cipher_char:
; save to al current char
mov al, byte ptr ds:[Buffer + bx]
; en/decrypt
CALL encryption
; save to output buffer
mov byte ptr ds:[PassphraseBuffer+bx], al
inc bx
; end of buffer?
cmp bx, ds:[BufferSize]
JB cipher_char
; save to file
CALL writeToBuffer
; repeat until buffer is not full
cmp ds:[BufferSize], 4096
JE cipher_loop
popa
RET
; helper method for reading to buffer
readToBuffer:
pusha
; buffer size - 2**12
mov bx, word ptr ds:[InputFileHandler]
mov cx, 4096
mov ah, 3Fh
mov dx, offset Buffer
int 21h
; ax - number of loaded bytes
mov word ptr ds:[BufferSize], ax
; position in buffer
mov word ptr ds:[InputBufferPointer], 0
popa
RET
encryption:
push bx
push cx
mov ah, 0
mov dh, 0
; make loop out of passphrase
mov bl, byte ptr ds:[Counter]
cmp bl, byte ptr ds:[PassphraseSize]
; start over if overflow
JB ety
mov bl, 0
mov byte ptr ds:[Counter], bl
ety:
mov bh, 0
mov dl, ds:[Passphrase+bx]
; CONVERT CODE TO BIG LETTERS
cmp dl, 'a'
jb ety_cont
sub dl, 32
ety_cont:
cmp ds:[Mode], 1
JE decryptMode
;; START ENCRYPT
encryptMode:
; check if given is char
pusha
mov dl, al
mov ah, 02h
int 21h
popa
pusha
mov ah, 02h
int 21h
popa
cmp al, 'A'
jb nat_break
; CONVERT TO BIG LETTER
cmp al, 'a'
jb nat_enc
sub dl, 32
nat_enc:
sub dl, 64 ; 20 - 1:A
sub al, 64 ; 20 - 1:A
add al, dl ; 40
sub al, 2
; al modulo 26
;
mov ah, 0
mov cx, 26
cmp al, 26
jl cont
sub al, 26
cont:
add al, 'A'
JMP nat
;; START DECRYPT
decryptMode:
; check if given is char
pusha
mov dl, al
mov ah, 02h
int 21h
popa
pusha
mov ah, 02h
int 21h
popa
cmp al, 'A'
jb nat_break
sub dl, 64;
sub al, 64
cmp al, dl
jl decrypt_with_mod
; without
sub al, dl
;mov al, dl
jmp decrypt_cont
decrypt_with_mod:
sub dl, al
mov al, 26
sub al, dl
;sub al, dl ; odejmujemy rejestry sa 8 bitowe wiec sam zmoduje
decrypt_cont:
add al, 'A'
nat:
pusha
mov dl, al
mov ah, 02h
int 21h
mov dl, 10
mov ah, 02h
int 21h
popa
inc byte ptr ds:[Counter]
jmp nat_cont
nat_break:
pusha
mov dl, '_'
mov ah, 02h
int 21h
mov dl, 10
mov ah, 02h
int 21h
popa
nat_cont:
pop cx
pop bx
RET
writeToBuffer:
pusha
pushf
; cx - how many chars to read (position in buffor)
mov cx, word ptr ds:[BufferSize]
; ds:dx - beginning of buffer
mov dx, offset PassphraseBuffer
; bx - output
mov bx, ds:[OutputFileHandler]
; run
mov ah, 40h
int 21h
mov word ptr ds:[OutputBufferPointer], 0
popf
popa
RET
exit:
pusha
; close files
mov bx, word ptr ds:[InputFileHandler]
mov ah, 3eh
int 21h
mov bx, word ptr ds:[OutputFileHandler]
mov ah, 3eh
int 21h
popa
mov ax,04c00h
int 21h
;; ERRORS HELPERS
Error_InvalidArgsRun:
mov dx, offset Error_InvalidArgs
CALL errors
Error_InputRun:
mov dx, offset Error_Input
CALL errors
Error_OutputRun:
mov dx, offset Error_Output
CALL errors
errors:
mov ah, 9
int 21h
CALL exit
APP_CODE ends
APP_STACK segment STACK
dw 1000 dup(?)
top1 dw ?
APP_STACK ends
end start
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment