Turbo Assembler 16 BIT 加密二进制文件

问题描述 投票:0回答:1

我正在尝试加密二进制文件。但程序不会加密任何内容,并且在磁盘上写入文件时会出错。因此,我没有在磁盘上获得加密文件,并且程序因无限循环打印未知符号而卡住。您能帮我修复代码吗?

.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

我试图只读取文件,但它陷入无限循环而没有写回任何内容。

assembly tasm dosbox 16-bit
1个回答
0
投票

程序如何运作:

a) 从控制台读取到缓冲区

keyword

b) 尝试打开

input.doc
,但文件夹中没有该文件。
ah = 3dh
ax = 2
之后,找不到文件

c) 从

output.doc
缓冲区写入
fileContent
,该缓冲区仅包含零。


  1. 第一个问题出现在

    ReadFileGetReadMsgLen MACRO
    bx
    包含文件名偏移量,但之后有
    inc bx
    。所以文件名将是
    (I)NPUT.DOC
    。此代码只是将
    0
    放入消息中。因此屏幕上只会显示部分文本,因为
    0
    标记字符串结尾。
    Can't creat
    Can'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
    
  2. 程序无法打开

    INPUT.DOC
    ,因为没有文件。程序应在
    5bh
    开头使用服务
    ReadFileGetReadMsgLen MACRO
    来创建文件或打开现有文件。

  3. 服务

    3dh
    现在工作正常,因为文件是用
    5bh

    创建的
  4. dx
    包含
    (IN)PUT.DOC
    。不存在这样的文件。

    lea dx, filename    ; dx = 0202h
    add dx, 2       ; dx = 0204h
    mov ah, 3dh
    xor al, al
    int 21h
    
  5. 服务

    3fh
    读取0字节,因为文件
    input.doc
    中没有数据。也许想法是从控制台读取到
    keyword
    缓冲区并将其保存到文件
    input.doc
    。我添加了 proc 来做到这一点
    Keyword2InputFile

  6. 然后从

    INPUT.DOC
    读取到
    fileContent
    缓冲区。好吧,程序可以将
    keyword
    复制到
    fileContent

  7. WriteFileGetWriteMsgLen MACRO
    。和上面一样的问题。

  8. Encrypt MACRO
    mov al, encryptedMessage
    mov message, al
    ,只是插入一个字节
    4b
    ,我认为代码应该 返回
    encryptedMessage
    dx
    的偏移量,因为我们在加密后使用dx服务
    40h

  9. GetStrLen str_chunk, cx
    内部,
    cx = 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
© www.soinside.com 2019 - 2024. All rights reserved.