Nasm x86-64 中的 Hello World 程序连续打印 Hello World
Hello World program in Nasm x86-64 prints Hello World continuously
你能帮我看看这段代码吗?执行时,程序会连续打印 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
显然在最后一个 syscall
之后你必须退出,return 或跳到其他地方,否则你有一个死循环,一段时间后它会崩溃堆栈。
mov rax,1 ; sys_write
xor rdi,rdi ;
syscall ;
要么,要么你必须使用不同的系统调用,因为你在这里做了一个 sys_write
操作。也许你想要 #60
?
说明
- 您为 x86-64 使用了错误的系统调用编号 Linux。因此,您的
exit()
调用失败,取而代之的是 dowork
和 callback
最终进入相互递归,导致循环。
- 有关正确的系统调用编号,请参阅 Linux 源代码中的 arch/x86/syscalls/syscall_64.tbl:
1 common write sys_write
231 common exit_group sys_exit_group
- 如果您愿意接受 AT&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 , %rdi
mov , %rdx
syscall
/* exit_group(0) */
mov $SYS_exit_group, %rax
xor %rdi, %rdi
syscall
callback:
call dowork
.ascii "Hello World\n"
了解 AT&T x86 汇编器语法使阅读 Linux 内核和 glibc 源代码变得容易得多;)
你能帮我看看这段代码吗?执行时,程序会连续打印 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
显然在最后一个 syscall
之后你必须退出,return 或跳到其他地方,否则你有一个死循环,一段时间后它会崩溃堆栈。
mov rax,1 ; sys_write
xor rdi,rdi ;
syscall ;
要么,要么你必须使用不同的系统调用,因为你在这里做了一个 sys_write
操作。也许你想要 #60
?
说明
- 您为 x86-64 使用了错误的系统调用编号 Linux。因此,您的
exit()
调用失败,取而代之的是dowork
和callback
最终进入相互递归,导致循环。 - 有关正确的系统调用编号,请参阅 Linux 源代码中的 arch/x86/syscalls/syscall_64.tbl:
1 common write sys_write
231 common exit_group sys_exit_group
- 如果您愿意接受 AT&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 , %rdi
mov , %rdx
syscall
/* exit_group(0) */
mov $SYS_exit_group, %rax
xor %rdi, %rdi
syscall
callback:
call dowork
.ascii "Hello World\n"
了解 AT&T x86 汇编器语法使阅读 Linux 内核和 glibc 源代码变得容易得多;)