Nasm x86-64的Hello World程序不断打印Hello World

时间:2015-03-03 12:23:41

标签: assembly nasm

你能帮我解释一下这段代码吗?执行时,程序会连续打印Hello World并且不会退出。我也希望在C程序中将此代码用作shellcode,因此我没有在数据部分中定义Hello String。请告诉我问题在哪里。

SECTION .text       ; Code section
    global _start       ; Make label available to linker 

_start:             ; Standard ld entry point

jmp callback    ; Jump to the end to get our current address

dowork:

    pop     rsi     ;
    mov rax,4       ; System call number for write
    mov     rdi,1   ; 1 for stdout
    mov     rdx,12  ; length of Hello World
    syscall         ; Switch to the kernel mode

    mov     rax,1   ;
    xor rdi,rdi     ;
    syscall         ;

callback:
   call dowork        ; Pushes the address of "Hello World" onto the stack
   db 'Hello World',0xA  ; The string we want to print

2 个答案:

答案 0 :(得分:2)

说明

  • 您使用的错误的系统调用号码用于x86-64 Linux。因此,exit()调用失败,而doworkcallback最终导致相互递归,从而导致循环。
  • 有关正确的系统调用号,请参阅Linux源代码中的arch/x86/syscalls/syscall_64.tbl

1 common write sys_write 231 common exit_group sys_exit_group

  • 如果您愿意接受AT&amp; T x86汇编语法和C预处理器,您可以#include <sys/syscall.h>并使用例如SYS_write作为write的系统调用号。请参阅下面的hello-att.S。通过这种方式,您可以不再担心查找系统调用号码。

hello.asm

    SECTION .text   ; Code section
    global _start   ; Make label available to linker 

_start:             ; Standard ld entry point    
    jmp callback    ; Jump to the end to get our current address

dowork: 
    pop     rsi     ;
    mov rax,1       ; System call number for write
    mov     rdi,1   ; 1 for stdout
    mov     rdx,12  ; length of Hello World
    syscall         ; Switch to the kernel mode

    mov   rax,231   ; exit_group(0)
    xor rdi,rdi     ;
    syscall         ;

callback:
    call dowork     ; Pushes the address of "Hello World" onto the stack
    db 'Hello World',0xA  ; The string we want to print

你好-att.S

#include <sys/syscall.h>

    .global _start
_start:
    jmp callback
dowork:
    /* write(1, "Hello World\n", 12) */
    pop %rsi /* "Hello World\n" */
    mov $SYS_write, %rax
    mov $1, %rdi
    mov $12, %rdx
    syscall

    /* exit_group(0) */
    mov $SYS_exit_group, %rax
    xor %rdi, %rdi
    syscall

callback:
    call dowork
    .ascii "Hello World\n"

了解AT&amp; T x86汇编程序语法使得阅读Linux内核和glibc源变得更加容易;)

答案 1 :(得分:1)

显然,在最后syscall之后你必须退出,返回或跳转到其他地方,否则你会有一个无限循环,它会在一段时间后崩溃。

mov     rax,1   ;   sys_write
xor rdi,rdi     ;
syscall         ;

要么是这样,要么必须使用不同的系统调用,因为这里执行sys_write操作。也许你想要#60