【问题标题】:Using write() to output string on stack使用 write() 在堆栈上输出字符串
【发布时间】:2021-02-25 02:09:55
【问题描述】:

在 Ubuntu 20 上,在 x86-assembly 中,我尝试使用 write 系统调用将字符串 pushed 输出到堆栈中。堆栈中的小端十六进制字节push 是 ASCII 中的 "hello world"。我的目标是仅从堆栈中输出字符串。为什么?进一步了解堆栈以及参数如何通过寄存器传递给系统调用/函数。

根据我的基本理解,我应该将push 的参数放入堆栈,movesp 寄存器(指向堆栈的顶部)按write 所需参数的顺序放入寄存器。

这是我的尝试(没有输出):

; compile: nasm -f elf32 -g test.asm && ld -melf_i386 test.o -o test
section .text
global  _start

_start:
    xor  eax, eax

    push 0xc
    mov  ebx, esp

    push eax
    push 0x00646c72
    push 0x6f77206f
    push 0x6c6c6568

    mov  ecx, esp
    mov  edx, 1
    mov  eax, 4
    int  0x80

    mov  eax, 1
    int  0x80

预期输出:

hello world

如何更正我的代码以显示预期的输出?我做错了什么?

【问题讨论】:

  • 作为开始,stackoverflow.com/questions/2535989/…。您将所有参数都放在错误的寄存器中。您应该在 eax 中具有系统调用号 (4),在 ebx 中具有文件描述符 (1),在 ecx 中具有数据指针(您正确的那个),以及 edx 中的字节数 (11)。我不知道你从哪里得到你所拥有的信息,但这完全是假的。
  • 另外,你可能想在写完之后调用exit系统调用,否则你的程序接下来要做的就是执行垃圾和崩溃。
  • 我看到了,我修改了代码,还是没有输出。
  • 你现在打电话给write(crazy number, buffer, 1)。你还没有把文件描述符放到ebx里面,edx里面的字节数是1。
  • 哦,push 0xc 应该是长度计数吗?它根本不属于堆栈。系统调用遵循与函数调用不同的约定;一切都在寄存器中,而不是在堆栈中。不过,我认为它应该是 11 或 0xb,因为写入尾随空字节没有意义。

标签: string assembly x86 system-calls write


【解决方案1】:

我建议阅读What are the calling conventions for UNIX & Linux system calls (and user-space functions) on i386 and x86-64。您需要eax 中的系统调用号和ebxecxedxesiediebp 中的参数。 write 需要三个参数,所以你需要:

  • eax中的系统调用号 (4)

  • ebx 中的文件描述符(标准输出为 1)

  • 指向 `ecx 中的缓冲区 (esp) 的指针,这是正确的

  • edx 中要写入的字节数(11,因为没有理由写入空字节)。

没有必要在堆栈上放任何东西。内核不在那里寻找参数,一切都在寄存器中。这与正常的函数调用约定有所不同。

此外,您可能想在之后调用exit 系统调用,否则您的程序将在其代码末尾运行并因执行垃圾而崩溃。那是系统调用编号 1,它在 ebx 中接受一个参数,这是一个退出代码。

以下作品:

section .text
global  _start

_start:
    push 0x00646c72
    push 0x6f77206f
    push 0x6c6c6568

    mov  ecx, esp
    mov  edx, 11
    mov  ebx, 1
    mov  eax, 4
    int  0x80

    mov  eax, 1
    xor  ebx, ebx
    int  0x80

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-15
    • 1970-01-01
    • 2011-07-22
    • 2016-01-12
    • 2012-09-28
    • 2021-06-25
    • 1970-01-01
    • 2020-12-04
    相关资源
    最近更新 更多