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
Harus dijalankan sebagai root.
Ini sama dengan menekan tombol daya dan bukan cara yang aman untuk mematikan PC Anda. Pastikan Anda menutup semua aplikasi yang terbuka dan mengeksekusi sync
untuk menyiram semua buffer sistem file sebelum menjalankan program ini, untuk setidaknya meminimalkan risiko korupsi file.
Uji coba
$ 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:
Diikuti oleh kegelapan.
Bagaimana itu bekerja
int $0x80
meminta interupsi perangkat lunak. Ia bekerja pada x86 dan x64, tetapi telah ditinggalkan lebih dari satu dekade sekarang dan tidak boleh digunakan dalam kode produksi. kode x64 harus digunakan syscall
sebagai gantinya. x86 harus digunakan sysenter
, tetapi terlalu rumit untuk kode golf.
Tindakan yang dihasilkan dari syscall tergantung pada register EAX - EDX, ESI, dan EDI. The Linux SYSCALL Referensi menunjukkan semua syscalls yang tersedia melalui int $0x80
.
Ketika EAX memegang 0x58 (88) , reboot dinamai, yang juga dapat digunakan untuk mematikan, mematikan, atau hibernasi komputer, serta mengganti kernel dan menonaktifkan atau mengaktifkan kombo tombol Ctrl - Alt - Del .
Di awal program - dan dengan kompilasi dengan as
atau gcc -nostdlib
, kami dapat memastikan bahwa kami benar-benar berada di awal program - sebagian besar register diatur ke 0 . Ini termasuk EAX, jadi kita bisa gunakan mov $0x58, %al
untuk mengatur 8 bit EAX yang lebih rendah ke 0x58 , sehingga mengatur EAX sendiri ke 0x58 . Ini menghemat dua byte lebih dari nol secara manual dengan register xor %eax, %eax
dan satu lagi atas straighforward mov $0x58, %eax
yang mengkodekan 0x58 dalam 32 bit.
Dua argumen pertama untuk reboot adalah angka ajaib, mungkin untuk mencegah reboot tidak disengaja, dan dibaca dari register EBX dan ECX. Kecuali jika angka-angka ini sama dengan konstanta tertentu, reboot menolak untuk melakukan tindakan apa pun.
Angka ajaib pertama harus sama dengan 0xfee1dead ( merasa mati ), mungkin mengacu pada matikan / matikan PC.
Angka ajaib kedua dapat sama dengan empat konstanta yang berbeda, meskipun tiga yang terakhir tidak bekerja di versi Linux kuno. Semua dari mereka tampaknya merujuk pada kekuatan selanjutnya pada / kelahiran PC.
0x28121969 merupakan ulang tahun Linus Torvalds (28 Desember 1969).
0x05121996 melambangkan ulang tahun Patricia Torvalds (5 Desember 1996).
0x16041998 merupakan hari ulang tahun Daniela Torvalds (16 April 1998).
0x20112000 mewakili ulang tahun Celeste Torvalds (20 November 2000).
Patricia, Daniela, dan Celeste Torvalds adalah tiga putri Linus Torvalds.
Register EDX memilih jenis "reboot" yang kita inginkan. 0x4321fedc adalah RB_POWER_OFF , mematikan PC dan mematikannya.
Akhirnya, nilai register ESI diabaikan untuk RB_POWER_OFF ; nilai register EDI diabaikan sepenuhnya oleh reboot .
Versi alternatif, hanya x64, 19 byte
Pada x64, kita bisa menggunakan syscall yang tepat untuk jumlah byte yang sama.
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
Satu-satunya perbedaan terletak pada instruksi ( syscall
vs int $0x80
), nilai __NR_REBOOT ( 0xa9 vs 0x58 ), dan register yang terlibat.