为什么我的 shellcode 在从 C 执行时会出现段错误,而不是作为独立的可执行文件执行?

Why does my shellcode segfault when executed from C, but not as a stand-alone executable?

我正在尝试使用 shell 代码执行 shell。我在 64 位机器上编写了这段代码:

section .text
    global _start

_start:
    xor rax, rax
    push rax
    mov rbx, "/bin//sh"
    push rbx
    mov rdi, rsp
    mov al, 59
    syscall

    mov al, 60
    xor rdi, rdi
    syscall

在使用 nasm 并与 ld 链接后,如果我执行该文件,效果很好。问题是如果我从这里得到 shell 代码并尝试用这个程序执行它:

int main(){
    char *shellcode = "\x48\x31\xc0\x50\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x89\xe7\xb0\x3b\x0f\x05\xb0\x3c\x48\x31\xff\x0f\x05";

    (*(void(*)()) shellcode)();
}

它给我一个分段错误。我看不出这里出了什么问题。任何帮助将不胜感激。

编辑:已经尝试 gcc -z execstack 使堆栈可执行,仍然给出分段错误

这是正常的,因为你的shellcode没有设置寄存器rsi和rdx,当你的C程序执行时shellcode会在寄存器rdi和rdx中产生垃圾。这是因为系统调用 execve 需要更多参数。

int execve (const char *filename, const char *argv [], const char *envp[]);

作为额外信息,分段错误是因为在您的 execve 系统调用之后,您将在 rax 中遇到错误,您将移动 60 到 rax 的最后 8 位并调用这个不存在的系统调用。