这个程序是为 x86 Linux 系统上的 Gnu Assembler 编写的,应该会导致三重错误,然后重新启动。
.text
.global _start
_start:
# write our string to stdout
movl $len,%edx # third argument: message length
movl $msg,%ecx # second argument: pointer to message to write
movl $1,%ebx # first argument: file handle (stdout)
movl $4,%eax # system call number (sys_write)
int $0x80 # call kernel
# Triple Fault -- reboot
movq $1, %rsp # Load the stack pointer with a one
pushq %rax # Push the A register, should cause a triple fault.
# and exit
movl $0,%ebx # first argument: exit code
movl $1,%eax # system call number (sys_exit)
int $0x80 # call kernel
.data # section declaration
msg:
.ascii "Will reboot by triple fault!\n" # our dear string
len = . - msg # length of our dear string
相反,它会导致分段错误。如果以 root 身份运行,是否可以使其在用户模式下工作?
答案1
Linux 内核不允许用户空间执行此类可能影响其他用户的操作。作为 root,您可能能够执行类似的操作,但内核可能仍然会阻止这种直接控制;毕竟,根进程仍然是用户态进程,但可以不受限制地访问内核的系统调用。
更正确的/UNIXy 方法是在内核中执行此类操作,并公开用户态进程可以用来调用它的接口。然后您的代码将在内核的上下文中执行,并且可以完全访问用户通常不应访问的硬件/系统功能。
答案2
此类 CPU 故障由内核模式中断处理程序处理。内核代码很好,如果发生用户空间故障(如除以零或访问无效内存),第一个中断处理程序应该可以正确处理。其他任何事情都是内核中的错误 - 如果中断处理程序中存在故障,基本上唯一明智的做法是转储寄存器和堆栈,然后放到调试器(如 OpenBSD 所做的)或 HCF 中,以便可以记录恐慌消息。存在三重故障是因为到那时,您的代码已经无法正常工作。
TL;DR:要使其发挥作用,您必须在 Linux 的故障处理代码中找到错误。
您也许可以在故意破坏中断处理程序的内核模块中执行此操作,但也很可能导致系统崩溃。和效果不一样啊shutdown -r now
!
答案3
在Linux上,您可以使用reboot
系统调用:
#include <unistd.h>
#include <sys/reboot.h>
int main(void) {
return reboot(LINUX_REBOOT_CMD_RESTART);
}
答案4
如果您确实需要汇编程序(?!),这曾经可以从 root 运行(我认为使用 nasm):
BITS 32
mov eax, 88
mov ebx, 0xfee1dead
mov ecx, 85072278
mov edx, 0x01234567
int 0x80