如何在不写空字节的情况下在nasm中写入?

时间:2013-04-21 17:03:22

标签: file null byte nasm

非常简单的问题。

该nasm应该将用户编写的消息(即hello)写入文件,再次由参数的用户输入确定。它做得很好,但问题是,它写了以后没有使用的所有空字节。例如,如果我为用户输入保留32个字节,并且用户仅使用4个字节作为输入,那么将打印那些字节,以及28个空字节。

如何停止打印空字节?

使用的代码:

global _start

section .text
_start:

    mov rax, 0 ; get input to write to file
    mov rdi, 0
    mov rsi, msg
    mov rdx, 32
    syscall

    mov rax, 2 ; open the file at the third part of the stack
    pop rdi
    pop rdi
    pop rdi
    mov rsi, 1
    syscall

    mov rdi, rax

    mov rax, 1 ; write message to file
    mov rsi, msg
    mov rdx, 32
    syscall

    mov rax, 3 ; close file
    syscall

    mov rax, 1 ; print success message
    mov rdi, 1
    mov rsi, output
    mov rdx, outputL
    syscall

    mov rax, 60 ; exit
    mov rdi, 0 
    syscall

section .bss
    msg: resb 32

section .data
    output: db 'Success!', 0x0A
    outputL: equ $-output

1 个答案:

答案 0 :(得分:0)

好吧,在对头文件和实验进行一些挖掘后,我自己想出来了。

基本上,它的工作方式是你必须将用户的字符串放在一个字节计数过程中,该过程沿着字符串计数,直到它找到一个空字节,然后存储那个非空字节数。

我会发布我正在使用的解决方法,以便与我有同样问题的人使用。请记住,此解决方案适用于64位nasm, NOT 32

对于32位编码器,请更改:

  • “rax”与“eax”的所有实例
  • “rdi”与“ebx”的所有实例
  • “rsi”与“ecx”的所有实例
  • “rdx”与“edx”的所有实例
  • “syscall”与“int 80h”(或equivelant)的所有实例
  • “r8”与“edx”的所有实例(你必须兼顾这个和rdx)

以下是我使用的解决方案:

global _start

; stack: (argc) ./a.out input filename

section .text
_start:

getInput:
    mov rax, 0   ; syscall for reading user input
    mov rdi, 0  
    mov rsi, msg ; store user input in the "msg" variable
    mov rdx, 32  ; max input size = 32 bytes
    xor r8, r8   ; set r8 to zero for counting purposes (this is for later)

getInputLength:
    cmp byte [msg + r8], 0 ; compare ((a byte of user input) + 0) to 0
    jz open                ; if the difference is zero, we've found the end of the string
                           ; so we move on. The length of the string is stored in r9.
    inc r8                 ; if not, onto the next byte...
    jmp getInputLength     ; so we jump back up four lines and repeat!

open:
    mov rax, 2 ; syscall for opening files
    pop rdi
    pop rdi
    pop rdi    ; get the file to open from the stack (third argument)
    mov rsi, 1 ; open in write mode
    syscall

    ; the open syscall above has made us a full file descriptor in rax

    mov rdi, rax ; so we move it into rdi for later

write:
    mov rax, 1   ; syscall for writing to files
                 ; rdi already holds our file descriptor
    mov rsi, msg ; set the message we're writing to the msg variable
    mov rdx, r8  ; set write length to the string length we measured earlier
    syscall

close:
    mov rax, 3 ; syscall for closing files
               ; our file descriptor is still in fd
    syscall

exit:
    mov rax, 60 ; syscall number for program exit
    mov rdi, 0  ; return 0

请记住,这不是一个完整的计划。它完全没有错误处理,不提供用户指令等。这只是方法的说明。