我正在尝试加密二进制文件。但程序不加密任何东西,它会在磁盘上写入文件时出错。所以我没有得到加密文件的磁盘和程序卡住无限循环打印未知的符号。你能帮我修改一下代码吗?
.286
.model small
.stack 100h
.DATA
bufferSize EQU 255
keyword db bufferSize DUP (0)
fileContent db bufferSize DUP (0)
fileNameIn db "INPUT.DOC", 0
fileNameOut db "OUTPUT.DOC", 0
fileNameDec db "DECRYPTED.DOC", 0
bytesCountReadWrite dw 0
inputms db "Please enter keyword", 0
emptyinputmsg db "Console input is empty", 0
cantCreateFileMsg db "Can't create file", 0
cantWriteFileMsg db "Can't write file", 0
cantReadFileMsg db "Can't read file", 0
cantOpenFileMsg db "Can't open file", 0
handler_input dw 0
handler_output dw 0
handler_decrypt dw 0
.CODE
InitSet MACRO
mov ax, @data ; Load the segment address of the data segment into AX
mov ds, ax ; Set the data segment register (DS) to the value in AX
mov es, ax ; Set the extra segment register (ES) to the value in AX
; xor ax, ax ; Clear the value in AX by performing an XOR operation with itself
ENDM
GetStrLen MACRO string, strlen
LOCAL count_bytes, end_count
pusha
push si ; Save SI register on the stack
mov si, OFFSET string ; SI = offset of the string
; Calculate the number of bytes to write
mov cx, 0 ; Initialize byte count to 0
count_bytes:
cmp byte ptr [si], 0 ; Check if end of string
je end_count ; If end of string, jump to end_count
add cx, 1 ; Increment byte count by 1
add si, 1 ; Move to the next byte
jmp count_bytes ; Jump back to count_bytes to process the next character
end_count:
mov strlen, cx ; Store the byte count in the memory location pointed by strlen
pop si ; Restore SI register from the stack
popa
ENDM
PrintString MACRO string
LOCAL strlen
.data
strlen dw 0
.code
GetStrLen string, strlen
pusha
mov dx, offset string ; Load the offset of the string to print into DX
mov cx, strlen ; Load the length of the string into CX
mov ah, 40h ; Set AH to 40h for writing to file or device
mov bx, 1 ; Set BX to 1 for standard output handle
int 21h ; Call MS-DOS interrupt 21h to write the string
popa
ENDM
ReadFileGetReadMsgLen MACRO filename, bytesRead, s, handler_input
LOCAL readcontent, rt, closeFile, exit_readingfile
pusha
; check opened file
mov ax, [handler_input]
test ax, ax
jnz readcontent
; getting filename
lea bx, filename
inc bx
mov al, [bx]
xor ah, ah
add bx, ax
inc bx
xor al, al
mov [bx], al
; open file
lea dx, filename
add dx, 2
mov ah, 3dh
xor al, al
int 21h
; ax - filehandler or error num
jnc readcontent ; check open error
PrintString cantOpenFileMsg
jmp exit_readingfile
readcontent:
mov [handler_input], ax
mov bx,ax ; read file
mov ah, 3fh
mov cx, bufferSize ; count
lea dx, s
int 21h
jnc rt ; - open,write,read
PrintString cantReadFileMsg
jmp exit_readingfile
rt: ; if we read less than buffersize we can close file
cmp ax, bufferSize
jne closeFile
closeFile:
mov bytesRead, ax
xor ax, ax
mov ah, 3eh ; closing file handle
int 21h
mov [handler_input], ax
exit_readingfile:
popa
ENDM
WriteFileGetWriteMsgLen MACRO keyword, filename, bytesWrote, str_chunk, handler_output
LOCAL writecontent, encodeContent, rtwrt, closeOutFile
pusha
push si
; Check opened file
mov ax, [handler_output]
test ax,ax
jnz writecontent
; Getting filename
lea bx, filename
inc bx
mov al, [bx]
xor ah,ah
add bx, ax
inc bx
xor al,al
mov [bx], al
; Create File
lea dx, filename
add dx, 2
mov ah, 3Ch
xor cx, cx
int 21h
jnc writecontent
PrintString cantCreateFileMsg
jmp closeOutFile
writecontent:
mov [handler_output], ax
lea si, str_chunk
;mov cx, word ptr [str_chunk]
encrypt keyword, str_chunk
mov bx, [handler_output] ; Write file
mov ah, 40h
;mov cx, [str_chunk]
GetStrLen str_chunk, cx
lea dx, str_chunk
int 21h
jnc rtwrt
PrintString cantWriteFileMsg
jmp closeOutFile
rtwrt:
cmp ax, bufferSize
jne closeOutFile
closeOutFile:
mov bytesWrote, ax
xor ax, ax
mov ah, 3eh ; Close file
mov bx, [handler_output]
int 21h
xor ax, ax
mov [handler_output], ax
popa
ENDM
findX0 MACRO keyword, key0
LOCAL search_loop, strlen
.data
strlen dw 0
.code
pusha
GetStrLen keyword, strlen
mov al, 0 ; Initialize AL register to 0
mov bl, 0 ; Initialize BL register to 0
mov cx, strlen ; Load the length of the keyword into CX
mov bx, offset keyword ; Load the offset of the keyword into BX
search_loop:
mov al, [bx] ; Move the byte at memory location pointed by BX into AL
add key0, ax ; Add the value of AX to key0
rol key0, 8 ; Rotate the bits of key0 to the left by 8 positions
inc bx ; Increment BX to point to the next character in the keyword
loop search_loop ; Decrement CX and repeat the loop until CX becomes 0
popa
ENDM
encrypt MACRO keyword, message
LOCAL encrypt_loop, X0, Xi, strlen, encryptedMessage, A, B, M ; Define local labels for the loop and Xi variable
.data
encryptedMessage db bufferSize DUP (0)
strlen dw 0
Xi dw ? ; Define a word-sized variable Xi
X0 dw 0
A EQU 12
B EQU 25
M EQU 56
.code
findX0 keyword, X0
GetStrLen message, strlen
pusha
push si ; Save SI register on the stack
push di ; Save DI register on the stack
mov ax, X0 ; Move the value of X0 into AX
mov Xi, ax ; Move the value of AX into Xi variable
mov cx, strlen
mov si, offset message ; Load the offset of the message into SI
mov di, offset encryptedMessage ; Load the offset of the encrypted message into DI
encrypt_loop:
mov ax, [si] ; Move the word at memory location pointed by SI into AX
xor ax, Xi ; XOR the word with Xi
mov [di], byte ptr ax ; Move the result byte by byte into the encrypted message
mov ax, Xi ; Move the value of Xi into AX
mov bl, A ; Move the value of Akey into BL
mul bl ; Multiply AX by BL
xor bx, bx ; Clear BX register
mov bl, B ; Move the value of Bkey into BL
add ax, bx ; Add BX to AX
xor bx, bx ; Clear BX register
mov bl, M ; Move the value of Mkey into BL
div bl ; Divide AX by BL
xor bx, bx ; Clear BX register
mov byte ptr Xi, ah ; Move the remainder into Xi
xor ax, ax ; Clear AX register
inc si ; Increment SI to point to the next word in the message
inc di ; Increment DI to point to the next byte in the encrypted message
loop encrypt_loop ; Decrement CX and repeat the loop until CX becomes 0
xor ax, ax
mov al, encryptedMessage ; Swap messages to return encrypted message
mov message, al ; Being stored into origin
pop di ; Restore DI register from the stack
pop si ; Restore SI register from the stack
popa
ENDM
ReadString MACRO str
LOCAL ReadStringLoop, EndReadString, RetryInput, EndInputLabel
RetryInput:
mov cx, bufferSize ;max input length for string limited to 255 due
mov dx, offset str ;place string itself
push cx ; save registers
push si
push cx ; save digit count again
mov si,dx ; point to input buffer
dec cx ; save room for null byte
ReadStringLoop:
mov ah, 1 ; function: keyboard input
int 21h ; DOS returns char in AL
cmp al, 0Dh ; end of line?
je EndReadString ; yes: exit
mov [si], al ; no: store the character
inc si ; increment buffer pointer
loop ReadStringLoop ; loop until CX=0
EndReadString:
mov byte ptr [si], 0 ; end with a null byte
pop ax ; original digit count
sub ax, cx ; AX = size of input string
dec ax
pop si ; restore registers
pop cx
; Check if zero length str
xor ch, ch
mov cl, [str+1]
test cl, cl
jnz EndInputLabel
PrintString emptyinputmsg
jmp RetryInput
EndInputLabel:
ENDM
ReadingFile PROC
ReadFileGetReadMsgLen fileNameIn, bytesCountReadWrite, fileContent, handler_input
RET
ENDP
WritingFile PROC
WriteFileGetWriteMsgLen keyword, fileNameOut, bytesCountReadWrite, fileContent, handler_output
RET
ENDP
start:
InitSet
PrintString inputms
ReadString keyword
encryptFileLoop:
CALL ReadingFile
CALL WritingFile
cmp bytesCountReadWrite, bufferSize
je encryptFileLoop
mov ah, 4Ch ; Exit program
int 21h
end start
我试图只读文件,但它停留在无限循环没有写任何东西回来。
1条答案
按热度按时间toe950271#
程序如何工作:
a)从控制台读取到缓冲区
keyword
B)尝试打开
input.doc
,但文件夹中没有此文件。在ah = 3dh
、ax = 2
之后,未找到文件c)从
fileContent
缓冲区写入output.doc
,该缓冲区仅包含零。1.第一个问题发生在
ReadFileGetReadMsgLen MACRO
。bx
包含文件名偏移量,但之后还有inc bx
。文件名为(I)NPUT.DOC
。这段代码只是将0
放入消息中。所以只有部分文本会出现在屏幕上,因为0
标记字符串的结尾。Can't creat
和Can't wri
。同样的代码在WriteFileGetWriteMsgLen MACRO
中。1.程序无法打开
INPUT.DOC
,因为没有文件。程序应该在ReadFileGetReadMsgLen MACRO
的开头使用服务5bh
来创建文件或打开现有文件。1.服务
3dh
现在工作正常,因为文件是用5bh
创建的dx
包含(IN)PUT.DOC
。不存在此类文件。1.服务
3fh
读取0字节,因为文件input.doc
中没有数据。也许想法是从控制台读取到keyword
缓冲区和保存这到文件input.doc
。我添加了proc,它可以执行Keyword2InputFile
。1.然后从
INPUT.DOC
读取到fileContent
缓冲区。程序可以把keyword
复制到fileContent
。WriteFileGetWriteMsgLen MACRO
.和上面一样的问题。Encrypt MACRO
,mov al, encryptedMessage
,mov message, al
,这只是插入一个字节4b
,我认为代码应该返回偏移到dx
中的encryptedMessage
,因为我们加密后使用dx服务40h
。1.在
GetStrLen str_chunk, cx
、cx = 6
内部,但popa
恢复旧值。因此,只有2个字节将保存到OUTPUT.DOC
。我在这里使用di
来存储str_chunk
长度。代码: