assembly Turbo汇编16位加密二进制文件

ltskdhd1  于 2023-10-19  发布在  其他
关注(0)|答案(1)|浏览(117)

我正在尝试加密二进制文件。但程序不加密任何东西,它会在磁盘上写入文件时出错。所以我没有得到加密文件的磁盘和程序卡住无限循环打印未知的符号。你能帮我修改一下代码吗?

.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

我试图只读文件,但它停留在无限循环没有写任何东西回来。

toe95027

toe950271#

程序如何工作:
a)从控制台读取到缓冲区keyword
B)尝试打开input.doc,但文件夹中没有此文件。在ah = 3dhax = 2之后,未找到文件
c)从fileContent缓冲区写入output.doc,该缓冲区仅包含零。
1.第一个问题发生在ReadFileGetReadMsgLen MACRObx包含文件名偏移量,但之后还有inc bx。文件名为(I)NPUT.DOC。这段代码只是将0放入消息中。所以只有部分文本会出现在屏幕上,因为0标记字符串的结尾。Can't creatCan't wri。同样的代码在WriteFileGetWriteMsgLen MACRO中。

lea bx, filename    ; 0202h
 inc bx          ; 0203h
 mov al, [bx]        ; al = 4eh = 'N'
 xor ah, ah      ; ah = 0
 add bx, ax      ; bx = 0203h + 004eh = 0251h
 inc bx          ; bx = 0252h    
 xor al,al       ; al = 0
 mov [bx], al        ; [0251] = 0

1.程序无法打开INPUT.DOC,因为没有文件。程序应该在ReadFileGetReadMsgLen MACRO的开头使用服务5bh来创建文件或打开现有文件。
1.服务3dh现在工作正常,因为文件是用5bh创建的

  1. dx包含(IN)PUT.DOC。不存在此类文件。
lea dx, filename    ; dx = 0202h
add dx, 2       ; dx = 0204h
mov ah, 3dh
xor al, al
int 21h

1.服务3fh读取0字节,因为文件input.doc中没有数据。也许想法是从控制台读取到keyword缓冲区和保存这到文件input.doc。我添加了proc,它可以执行Keyword2InputFile
1.然后从INPUT.DOC读取到fileContent缓冲区。程序可以把keyword复制到fileContent

  1. WriteFileGetWriteMsgLen MACRO .和上面一样的问题。
  2. Encrypt MACROmov al, encryptedMessagemov message, al,这只是插入一个字节4b,我认为代码应该返回偏移到dx中的encryptedMessage,因为我们加密后使用dx服务40h
    1.在GetStrLen str_chunk, cxcx = 6内部,但popa恢复旧值。因此,只有2个字节将保存到OUTPUT.DOC。我在这里使用di来存储str_chunk长度。
    代码:
.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 
  
  ;fileNameIn, bytesCountReadWrite, fileContent, handler_input
  
  pusha
  ; check opened file
  mov ax, [handler_input]
  test ax, ax
  jnz readcontent
  
  mov ah, 5bh                   ; create file
  lea dx, offset filename
  mov cx,2
  int 21h
  
  cmp ax,50h                    ; file exists?
  jne save_file_handle          ; new file created
  jmp file_exists
  
  save_file_handle:
    mov [handler_input], ax
  
    mov bx,ax
    mov ah, 3eh ; closing file handle
   int 21h
   
   file_exists: 
  ; getting filename
;  lea bx, filename             ; INPUT.DOC
;  inc bx                       ; NPUT.DOC
;  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             ; read to fileContent
  int 21h
  jnc closeFile     ; data saved in input.doc, close file

  PrintString cantReadFileMsg
  jmp exit_readingfile
  
closeFile: 
  mov bytesRead, ax
  mov bx,[handler_input]
  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
    
    ;keyword, fileNameOut, bytesCountReadWrite, fileContent, handler_output

  pusha
  ; check opened file
  mov ax, [handler_output]
  test ax, ax
  jnz writecontent
  
  mov ah, 5bh                   ; create file
  lea dx, offset filename
  mov cx, 2
  int 21h
  
  cmp ax,50h                    ; file exists?
  jne save_file_handle          ; new file created
  jmp file_exists
  
  save_file_handle:
    mov [handler_output], ax
  
    mov bx, ax
    mov ah, 3eh ; closing file handle
   int 21h
   
   file_exists: 
  ; getting filename
;  lea bx, filename             ; OUTPUT.DOC
;  inc bx                       ; UTPUT.DOC
;  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, 3ch
  mov cx, 2
  int 21h

    jnc writecontent 
    PrintString cantCreateFileMsg
    jmp exit_writingfile
    
writecontent:
    mov [handler_output],ax
    lea si, str_chunk           ;filecontent buffer
    ;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, di
    mov cx, di
    ;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, ax
    int 21h
    xor ax, ax
    mov [handler_output], ax
    
    exit_writingfile:
    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          ;1
    LOCAL encrypt_loop, X0, Xi, strlen, encryptedMessage, A, B, M   ; Define local labels for the loop and Xi variable
    .data
    
    ;keyword, str_chunk
    
    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], al            ; or ax ah ??  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 dx, offset encryptedMessage ; Swap messages to return encrypted message
;    mov msg_off, dx          ; 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                    ; First element of keyword is 0dh 
    mov cl, [str+1]
    test cl, cl
    jnz EndInputLabel
    PrintString emptyinputmsg 
    jmp RetryInput
    
    EndInputLabel:
ENDM

ReadingFile PROC
  ReadFileGetReadMsgLen fileNameIn, bytesCountReadWrite, fileContent, handler_input
  RET
ReadingFile ENDP

WritingFile PROC
  WriteFileGetWriteMsgLen keyword, fileNameOut, bytesCountReadWrite, fileContent, handler_output
  RET
WritingFile ENDP

start:
  InitSet                                   ; ok
  PrintString inputms                       ; ok
  ReadString keyword                        ; ok
  
  call Keyword2InputFile
  
  encryptFileLoop:
    CALL ReadingFile
    CALL WritingFile 
    cmp bytesCountReadWrite, bufferSize 
    je encryptFileLoop
  mov ah, 4Ch ; Exit program
  int 21h
  
Keyword2InputFile proc  
    pusha
    
    mov ah, 5bh                     ; create file
    lea dx, offset fileNameIn       ; INPUT.DOC
    mov cx, 2                       ; attrib rw
    int 21h
  
    cmp ax,50h                      ; file exists?
    jne new_file_created            ; new file created
    jmp open_input_file ; file already exits
  
    new_file_created:
        mov [handler_input], ax     ; save handle
        jmp copy_keyword_2_input_doc
        
   open_input_file:     
        mov ah, 3dh                 ; open file
        mov al, 2                   ; attrib rw     
        lea dx, fileNameIn
        int 21h
       mov [handler_input], ax     
   
   copy_keyword_2_input_doc:
        mov bx, ax 
        mov ah, 40h
        mov cx, bufferSize
        lea dx, keyword
        int 21h

    mov bx, [handler_input]
    mov ah, 3eh                     ; close file
    int 21h

    xor ax,ax
    mov [handler_input], ax
    popa
    ret
Keyword2InputFile endp  
end start

相关问题