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

如何在x86_64 Linux环境的Shellcode中获取数据绝对地址?

x86_64 Linux Shellcode获取字符串绝对地址解决方案

我的Shellcode如下:

xor rax, rax
    xor rdi, rdi
    xor rsi, rsi
    xor rdx, rdx

    ; 获取`pathname`的地址
    mov rdi, [something]
    mov al, 59
    mov rdi, rsp
    syscall

    xor rax,rax
    mov al, 60
    xor rdi, rdi
    syscall

_pathname:
    db "/usr/bin/shutdown",0

这只是简单的execve调用和退出操作。问题在于我无法获取访问pathname所需的绝对地址。我找到的“解决方案”是编写类似这样的代码:

call _end

_start:
    pop rdi ; _start的绝对地址
    ; 然后加上偏移量得到_end的地址

_end:
    call start
    db "/usr/bin/shutdown", 0

这对我来说毫无逻辑,而且也不生效。我还尝试过使用FPU指令,据说该方法可行,但同样没有效果。

操作系统:Linux
架构:amd64


可行解决方案:利用call指令特性直接获取地址

在x86_64架构中,call指令会把下一条指令的地址压入栈中,我们可以利用这个特性直接拿到字符串的绝对地址,无需手动计算偏移。

正确实现代码

global _start

_start:
    ; 调用get_str_addr,此时栈中会压入字符串的起始地址
    call get_str_addr
    ; 字符串数据,必须紧跟在call指令之后
    db "/usr/bin/shutdown", 0

get_str_addr:
    ; 弹出栈顶的字符串地址到rdi,正好作为execve的第一个参数
    pop rdi
    ; 设置execve系统调用参数
    xor rax, rax
    mov al, 59         ; execve的系统调用号
    xor rsi, rsi       ; argv = NULL
    xor rdx, rdx       ; envp = NULL
    syscall

    ; 退出系统调用
    xor rax, rax
    mov al, 60
    xor rdi, rdi
    syscall

代码逻辑说明

  1. call get_str_addr:执行这条指令时,CPU会把call之后的下一个地址(也就是字符串/usr/bin/shutdown的起始地址)压入栈,然后跳转到get_str_addr标签。
  2. pop rdi:直接把栈顶的字符串地址弹出到rdi寄存器,此时rdi就持有目标路径的绝对地址,完全满足execve对第一个参数的要求。
  3. 后续设置execve的系统调用号、清空rsi和rdx(对应argv和envp为NULL),调用syscall即可执行目标程序。

你之前代码失效的原因

你之前的代码存在标签命名混乱(start和_start不统一)、偏移计算逻辑错误的问题,导致无法正确定位字符串地址。上面的写法直接利用call指令的栈操作特性,逻辑简洁且可靠性高。

内容的提问来源于stack exchange,提问作者R-Rothrock

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 04:32:19