mov $0x58, %al # 2 bytes: b0 58
mov $0xfee1dead, %ebx # 5 bytes: bb ad de e1 fe
mov $0x28121969, %ecx # 5 bytes: b9 69 19 12 28
mov $0x4321fedc, %edx # 5 bytes: ba dc fe 21 43
int $0x80 # 2 bytes: cd 80
Debe ejecutarse como root.
Esto es equivalente a presionar el botón de encendido y no es una forma segura de apagar su PC. Asegúrese de cerrar todas las aplicaciones abiertas y ejecutar sync
para vaciar todos los búferes del sistema de archivos antes de ejecutar este programa, para al menos minimizar el riesgo de corrupción de archivos.
Prueba de funcionamiento
$ as -o poweroff.o poweroff.s
$ ld -o poweroff poweroff.o
ld: warning: cannot find entry symbol _start; defaulting to 0000000000400078
$ sudo sh -c 'sync && ./poweroff'
root's password:
Seguido por la oscuridad.
Cómo funciona
int $0x80
invoca una interrupción de software. Funciona tanto en x86 como en x64, pero ha quedado en desuso durante más de una década y no debe usarse en el código de producción. el código x64 debería usar syscall
en su lugar. x86 debería usar sysenter
, pero es demasiado engorroso para el golf de código.
La acción resultante de la llamada al sistema depende de los registros EAX - EDX, ESI y EDI. La Referencia de llamadas al sistema Linux muestra todas las llamadas al sistema que están disponibles a través de int $0x80
.
Cuando EAX mantiene 0x58 (88) , se llama reiniciar , que también se puede usar para apagar, poner en suspensión o hibernar la computadora, así como para cambiar los núcleos y deshabilitar o habilitar la combinación de teclas Ctrl - Alt - Supr .
Al comienzo del programa, y compilando con as
o gcc -nostdlib
, podemos asegurarnos de que estamos realmente al comienzo del programa, la mayoría de los registros se establecen en 0 . Esto incluye EAX, por lo que podemos usarlo mov $0x58, %al
para configurar los 8 bits inferiores de EAX en 0x58 , configurando así EAX en 0x58 . Esto ahorra dos bytes sobre xor %eax, %eax
la puesta a cero manual del registro con y uno más sobre el sencillo mov $0x58, %eax
que codifica 0x58 en 32 bits.
Los primeros dos argumentos para reiniciar son números mágicos, presumiblemente para evitar reinicios accidentales, y se leen de los registros EBX y ECX. A menos que estos números sean iguales a ciertas constantes, reiniciar se niega a realizar cualquier acción.
El primer número mágico debe ser igual a 0xfee1dead ( sentirse muerto ), probablemente refiriéndose a la desconexión / muerte de la PC.
El segundo número mágico puede ser igual a cuatro constantes diferentes, aunque los últimos tres no funcionaron en versiones antiguas de Linux. Todos ellos parecen referirse al encendido / nacimiento posterior de la PC.
0x28121969 representa el cumpleaños de Linus Torvalds (28 de diciembre de 1969).
0x05121996 representa el cumpleaños de Patricia Torvalds (5 de diciembre de 1996).
0x16041998 representa el cumpleaños de Daniela Torvalds (16 de abril de 1998).
0x20112000 representa el cumpleaños de Celeste Torvalds (20 de noviembre de 2000).
Patricia, Daniela y Celeste Torvalds son las tres hijas de Linus Torvalds.
El registro EDX selecciona el tipo de "reinicio" que queremos. 0x4321fedc es RB_POWER_OFF , apaga la PC y la apaga.
Finalmente, el valor del registro ESI se ignora para RB_POWER_OFF ; el reinicio ignora por completo el valor del registro EDI .
Versión alternativa, solo x64, 19 bytes
En x64, podemos usar una llamada al sistema adecuada para el mismo recuento de bytes.
mov $0xa9, %al # 2 bytes: b0 a9
mov $0xfee1dead, %edi # 5 bytes: bf ad de e1 fe
mov $0x28121969, %esi # 5 bytes: be 69 19 12 28
mov $0x4321fedc, %edx # 5 bytes: ba dc fe 21 43
syscall # 2 bytes: 0f 05
Las únicas diferencias radican en la instrucción ( syscall
vs int $0x80
), el valor de __NR_REBOOT ( 0xa9 vs 0x58 ) y los registros involucrados.