【问题标题】:x86_64 assembly execve *char[] syscallx86_64 程序集 execve *char[] 系统调用
【发布时间】:2026-02-08 14:00:01
【问题描述】:

我试图在不使用标准库的情况下进入一些 Linux 64 位 x86 程序集,但是在处理呈现给我的程序 (argv) 的参数时遇到了一些问题。我认为(基于文档)rsp 标志着 argc qword 的开始,而[rsp + 8] 将是 argv。不幸的是,情况并非如此,以下(删节)程序导致EFAULT (Bad address)

sys_execve equ 59
sys_exit equ 60

section .data
    child db "/bin/sh", 0

global _start

section .text
    _start:
        mov rdi, child      ; #1 filename
        mov rsi, [rsp + 8]      ; #2 argv
        mov rdx, 0      ; #3 envp = 0

        mov rax, sys_execve ; execve
        syscall
        mov rax, rdi        ; #1 Return value
        mov rax, sys_exit   ; exit
        syscall

有关 amd64 调用约定和将 *char[] 传递到内核的帮助将不胜感激。

谢谢

【问题讨论】:

  • 如果我将相关代码更改为xor rsi, [esp + 4],strace 会显示一个基于 exec 的有用 argv,耶!然而,该程序随后出现段错误。传递空指针 (0) 允许 sh 正常运行。
  • 以上内容应为mov rsi, [esp+4]
  • 没关系,我完全错误地阅读 strace 并看着我执行测试。上面的代码实际上直接导致了段错误

标签: linux pointers assembly nasm system-calls


【解决方案1】:

rsp+8,您会找到带有程序路径的字符串地址。指向第一个参数的指针位于[rsp+16]。但是对于execve,您需要一个指向字符串指针数组的指针,该数组以指向程序路径的指针开头(您可以(ab)使用[rsp+8])。

所以改变

mov rsi, [rsp + 8]

lea rsi, [rsp + 8]

【讨论】:

  • 像魅力一样工作,谢谢!出于兴趣,是否还有一种简单的方法可以传入 envp,我认为 rsi + argc*8 就足够了。
  • @md_5:参数和环境之间有一个空指针。这有效:mov rdx, [rsp] --- lea rdx, [rsp+8 + rdx*8 + 8].
  • 对了,忘了第二个空指针了。感谢您的所有帮助!