代码之家  ›  专栏  ›  技术社区  ›  Ricardo Pereira

为什么我的外壳代码在从C执行时会出错,而不是作为一个独立的可执行文件执行?

  •  0
  • Ricardo Pereira  · 技术社区  · 7 年前

    我正在尝试使用外壳代码执行一个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链接后,如果我执行该文件,则效果良好。问题是,如果我从中获取外壳代码并尝试使用此程序执行它:

    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 要使堆栈可执行,仍会出现分段错误

    1 回复  |  直到 7 年前
        1
  •  4
  •   sinkmanu    7 年前

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

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

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