【问题标题】:Segmentation Fault when shutting down Linux with assembly application使用汇编应用程序关闭 Linux 时出现分段错误
【发布时间】:2023-03-30 16:12:01
【问题描述】:

以下应用程序在执行时会生成一个分段错误

.set __NR_reboot, 169
.set LINUX_REBOOT_CMD_POWER_OFF, 0x4321FEDC

.section .text
.globl _start
_start:
   movl $LINUX_REBOOT_CMD_POWER_OFF, %ebx
   movl $__NR_reboot, %eax
   int $0x80

这是一个非常简单的应用程序,我一定遗漏了一些非常明显的东西。有人可以帮我吗?

编译时使用:

as shutdown.s -o shutdown.o
ld shutdown.o -o shutdown

编辑:

即使是只调用系统调用 sync() 的简单应用程序也会产生分段错误

.set __NR_sync, 36

.section .text
.globl _start
_start:
   movl $__NR_sync, %eax
   int $0x80

   movl $1, %eax         #syscall exit
   movl $0, %eax
   int $0x80

【问题讨论】:

  • 第二个movl不应该是%ebx吗?
  • @user786653 完美。将其添加为答案,以便我投票。

标签: linux assembly segmentation-fault gnu shutdown


【解决方案1】:

警告:记得在拨打reboot(2)之前先sync(2)

reboot(2) 系统调用需要 4 个参数。您将它与 libc 混淆了 包装。

警告:记得在拨打reboot(2)之前先sync(2)

(它实际上需要 magic* 参数,因此人们必须重新阅读文档并且不要忘记调用sync(2)。)

警告:我有没有说过你必须先sync(2),然后才能调用reboot(2)

【讨论】:

  • 这个 sync 答案让 SYNC 每一次 sync SYNC 我读到 >记得同步!它。
【解决方案2】:

我正在添加最终和工作源代码,因为这个问题将来可能会引起某些人的兴趣:

                                     # For the right sys_call numbers on your arch,
                                     # check <asm/unistd_32.h> (or unistd_64.h)

.set __NR_sync, 36                   # sys_call sync()    
.set __NR_reboot, 88                 # sys_call reboot()

.set LINUX_REBOOT_MAGIC1, 0xfee1dead # flags are specified in: <linux/reboot.h>
.set LINUX_REBOOT_MAGIC2, 672274793
.set LINUX_REBOOT_CMD_POWER_OFF, 0x4321fedc
.set LINUX_REBOOT_CMD_RESTART, 0x01234567

.section .text
.globl _start
_start:
   movl $__NR_sync, %eax             # call sync()
   int $0x80

   movl $__NR_reboot, %eax
   movl $LINUX_REBOOT_MAGIC1, %ebx
   movl $LINUX_REBOOT_MAGIC2, %ecx
   movl $LINUX_REBOOT_CMD_RESTART, %edx
   #movl $0, %esi
   int $0x80                         # call reboot()

   movl $1, %eax
   movl $0, %ebx
   int $0x80                         # call exit()

【讨论】:

  • 当然,这段代码需要root执行才能工作。如果普通用户尝试执行它,程序将静默失败。
【解决方案3】:

来自linux/i386/syscall.S:函数号应按顺序放置在 %eax 和以下寄存器中的任何参数中:%ebx、%ecx、%edx、%esi、%edi 和 %ebp。

这就是为什么代码中最后一个movl %eax,0应该改为movl %ebx, 0

【讨论】:

  • NP。添加了指向我查找应该是哪个寄存器的链接。
猜你喜欢
  • 2020-03-10
  • 2021-02-25
  • 1970-01-01
  • 1970-01-01
  • 2019-03-27
  • 2021-07-18
  • 2022-01-04
  • 2020-05-30
  • 1970-01-01
相关资源
最近更新 更多