Hello World Shellcode正确执行,但不输出任何内容到stdout

时间:2019-05-07 14:51:45

标签: gcc assembly x86-64 system-calls shellcode

我在hello.asm中有以下简单的汇编代码:

section .text:
    global _start

    _start:

    jmp short ender

    starter:

    ; clean registers
    xor rax, rax
    xor rbx, rbx
    xor rcx, rcx
    xor rdx, rdx

    ; writes 'hello\n' to stdout
    mov al, 0x04 ; 4 = syscall number of sys_write
    mov bl, 0x01 ; 1 = file descriptor of stdout
    pop rcx      ; points to 'hello\n'
    mov dl, 0x06 ; writes 6 characters
    int 0x80

    ; exits with status 5
    xor rax, rax
    mov al, 0x01 ; 1 = syscall number of sys_exit
    xor rbx, rbx
    mov bl, 0x05 ; 5 = exit status number
    int 0x80

    ender:

    call starter
    db 'hello',0x0a

an article on shellcoding的启发,汇编代码将hello\n压入堆栈,将其写入标准输出,然后以代码5退出。

我可以编译并成功运行它:

$ nasm -f elf64 hello.asm
$ ld hello.o -o hello
$ ./hello
hello

使用objdump -D hello和一个简短的python脚本,我可以提取相关的shellcode字符串并使用以下简单的C代码对其进行测试:

#include <stdio.h>
#include <string.h>
#include <unistd.h>

char* shellcode = "\xeb\x21\x48\x31\xc0\x48\x31\xdb\x48\x31\xc9\x48\x31\xd2\xb0\x04\xb3\x01\x59\xb2\x06\xcd\x80\x48\x31\xc0\xb0\x01\x48\x31\xdb\xb3\x05\xcd\x80\xe8\xda\xff\xff\xff\x68\x65\x6c\x6c\x6f\x0a";

void main() {
    (*(void(*)()) shellcode)();
}

问题

./test-shellcode的预期输出为hello\n,退出状态为5,就像运行编译的程序集时一样。但是,该程序根本不输出任何内容,但仍以5状态退出!

在使用GDB对其进行调试之后,我观察到该程序按预期执行了shellcode。特别是,应该将hello\n写到stdout的这一部分没有错误地执行,并且rcx的内容是hello\n字符串的地址:

   0x5555555546d6:  mov    $0x4,%al
   0x5555555546d8:  mov    $0x1,%bl
   0x5555555546da:  pop    %rcx
   0x5555555546db:  mov    $0x6,%dl
   0x5555555546dd:  int    $0x80

但是,尽管sys_write显然被正确调用并且没有错误地执行了,但 没有 被写入标准输出。

为什么?

0 个答案:

没有答案