You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

x86_64 Linux汇编获取argv[1]时尾部出现多余bash内容求助

问题:x86_64汇编获取argv[1]后输出尾部附带多余内容

在x86_64 Linux环境下用汇编编写程序获取argv[1]的值,输出时尾部会附加多余的bash相关内容。目前仅能通过减少预留字节临时消除,但argv[1]是动态值,无法固定长度。

原汇编代码

bits 64

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;          MACROS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

%define SYS_WRITE 1
%define SYS_EXIT 60
%define EXIT_SUCESS 0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;         SECTIONS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

section .bss
    filename: resb 32

section .data
    usage_msg: db "Usage: ./pac <filename>", 10, 0
    usage_msg_len: equ $-usage_msg

section .text
    global _start

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;    PROGRAM ENTRY POINT
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
_start:
    pop rax                 ; pop argc into rax
    cmp rax, 2              ; make sure <filename> has been passed
    jl .not_enough_args

    jmp .enough_args

.not_enough_args:
    call print_usage
    jmp .exit

.enough_args:
    pop rax
    pop rax                 ; pop argv[1] into rax
    mov [filename], rax     ; move argv[1] into filename

    ; print filename for testing
    mov rax, SYS_WRITE
    mov rdi, SYS_WRITE
    mov rsi, [filename]
    mov rdx, 32
    syscall

    jmp .exit

.exit:
    mov rax, SYS_EXIT
    mov rdi, EXIT_SUCESS
    syscall

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;          CALLS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

print_usage:
    mov rax, SYS_WRITE
    mov rdi, SYS_WRITE
    mov rsi, usage_msg
    mov rdx, usage_msg_len
    syscall
    ret

程序运行输出

$ ./pac file.txt
file.txtSHELL=/bin/bashSESSION

问题分析与修复

核心问题

  1. 固定长度输出导致垃圾数据:调用sys_write时硬编码了rdx=32,但argv[1]是以空字节(\0)结尾的字符串,实际长度远小于32,所以会把内存中字符串后面的随机数据(包括bash环境变量)一起输出。
  2. 文件描述符参数语义错误:mov rdi, SYS_WRITE虽然数值是1(stdout的文件描述符),但语义混淆,应该明确指向标准输出。
  3. 无用的内存存储:mov [filename], rax完全没必要,argv[1]本身就是字符串的指针,直接使用即可,不需要额外存到bss段。

修复方案

添加计算字符串长度的函数,获取argv[1]的实际长度再传给sys_write;同时修正参数错误,去掉冗余代码。

修复后的完整代码

bits 64

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;          MACROS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

%define SYS_WRITE 1
%define SYS_EXIT 60
%define EXIT_SUCCESS 0
%define STDOUT 1

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;         SECTIONS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

section .data
    usage_msg: db "Usage: ./pac <filename>", 10, 0
    usage_msg_len: equ $-usage_msg
    newline: db 10

section .text
    global _start

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;    PROGRAM ENTRY POINT
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
_start:
    pop rax                 ; pop argc into rax
    cmp rax, 2              ; check if filename is provided
    jl .not_enough_args

.enough_args:
    pop rax                 ; pop argv[0] (program name)
    pop rsi                 ; pop argv[1] pointer into rsi

    call strlen             ; calculate length of argv[1], result in rax
    mov rdx, rax            ; pass length to sys_write

    ; print the filename
    mov rax, SYS_WRITE
    mov rdi, STDOUT
    syscall

    ; print newline to match usual terminal output
    mov rax, SYS_WRITE
    mov rdi, STDOUT
    mov rsi, newline
    mov rdx, 1
    syscall

    jmp .exit

.not_enough_args:
    call print_usage
    jmp .exit

.exit:
    mov rax, SYS_EXIT
    mov rdi, EXIT_SUCCESS
    syscall

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;          CALLS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; strlen: calculate length of string pointed to by rsi, returns length in rax
strlen:
    xor rax, rax            ; initialize length counter to 0
.str_loop:
    cmp byte [rsi + rax], 0 ; check if current byte is null terminator
    je .str_done
    inc rax                 ; increment counter
    jmp .str_loop
.str_done:
    ret

print_usage:
    mov rax, SYS_WRITE
    mov rdi, STDOUT
    mov rsi, usage_msg
    mov rdx, usage_msg_len
    syscall
    ret

修复说明

  1. strlen函数:遍历字符串直到遇到空字节,返回实际长度,确保sys_write只输出有效内容。
  2. 修正文件描述符:用STDOUT宏明确指定标准输出,代码可读性更强。
  3. 去掉冗余存储:直接使用rsi存储argv[1]的指针,无需中转到bss段。
  4. 新增换行输出:让输出符合终端常规格式,可选保留。

现在运行程序,输出只会显示file.txt(带换行),不会附带多余内容。

内容的提问来源于stack exchange,提问作者joshjkk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 08:24:57