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

如何在NASM汇编中正确使用execve系统调用执行cat命令输出文件?

正确调用x86_64 Linux下execve系统调用的方法

你的代码存在的核心问题

  • 字符串带多余双引号:execve要求的是原始ASCII路径字符串,不需要shell的引号。你写的"\"/bin/cat\""会让系统尝试寻找名为**"/bin/cat"(包含引号)**的程序,这显然不存在。
  • 文件名拆分错误:你把/file.txt拆成//file.t和xt,导致argv数组里的参数是两个无效的字符串指针,而非指向完整文件名的指针。
  • 寄存器赋值错误:直接用mov rdi, "\"/bin/cat\""是错误的——字符串字面量不能直接加载到64位寄存器,这行代码实际是把字符串的ASCII值当成64位整数加载,完全不是你需要的内存指针。
  • argv数组构造错误:execve的第二个参数rsi需要指向一个指针数组,每个元素是指向参数字符串的指针,最后必须以NULL指针结尾,你当前的栈结构完全不符合这个要求。

正确实现方式

方式1:使用.data段存储字符串(易读性高)

这种方式适合普通程序,把字符串和argv数组提前存在数据段:

section .data
    ; 程序路径,必须以NULL字节终止
    cmd     db  "/bin/cat", 0
    ; 要读取的文件路径,同样以NULL终止
    arg1    db  "/file.txt", 0
    ; argv数组:[程序路径指针, 参数指针, NULL]
    argv    dq  cmd, arg1, 0

section .text
global _start

_start:
    mov rax, 59          ; x86_64 Linux下execve的系统调用号
    mov rdi, cmd         ; 第一个参数:指向程序路径的指针
    mov rsi, argv        ; 第二个参数:指向argv数组的指针
    xor rdx, rdx         ; 第三个参数:环境变量数组(传NULL表示继承当前环境)
    syscall

方式2:纯栈构造(适合shellcode等无.data段场景)

如果需要不依赖数据段,完全在栈上构造所有内容:

section .text
global _start

_start:
    xor rax, rax        ; 清零rax,同时用来构造字符串的NULL终止符

    ; 构造"/file.txt"字符串到栈上(栈向下增长,所以从字符串末尾往前压)
    push rax            ; 压入NULL终止符
    mov rbx, 0x7478742e656c6966 ; 小端序对应"txt.elif",即"file.txt"的后8字节
    push rbx
    push byte 0x2f      ; 压入"/",此时栈顶就是指向"/file.txt"的指针
    mov rsi, rsp        ; 暂存文件名指针到rsi

    ; 构造"/bin/cat"字符串到栈上
    push rax            ; 压入NULL终止符
    mov rbx, 0x7461632f6e69622f ; 小端序对应"tac/nib/",即"/bin/cat"
    push rbx
    mov rdi, rsp        ; 把程序路径指针存入rdi

    ; 构造argv数组:[程序路径指针, 文件名指针, NULL]
    push rax            ; 压入NULL指针作为数组结尾
    push rsi            ; 压入文件名指针
    push rdi            ; 压入程序路径指针
    mov rsi, rsp        ; 让rsi指向argv数组的起始

    mov al, 59          ; 加载execve系统调用号(rax高56位已为0,用al更高效)
    xor rdx, rdx        ; 环境变量数组传NULL
    syscall

关键注意事项

  • 字符串必须以NULL终止:execve依赖C风格字符串的NULL终止符来确定字符串长度,缺少会导致读取垃圾数据。
  • x86_64系统调用参数约定:rax存系统调用号,rdi、rsi、rdx依次存前三个参数,这是Linux x86_64的固定规范。
  • 栈构造的小端序问题:因为push操作是将64位值压入栈,所以字符串需要以逆序的64位值压入,才能保证栈中字节顺序正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 21:24:53