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
Kök olarak çalıştırılmalıdır.
Bu, güç düğmesine basmaya eşittir ve PC'nizi kapatmak için güvenli bir yol değildir. Tüm açık uygulamaları kapattığınızdan ve çalıştırdığınızdan emin olun.sync
bu programı yürütmeden önce tüm dosya sistemi arabelleklerini yıkadığınızdan , en azından dosya bozulması riskini en aza indirin.
Test sürüşü
$ 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:
Karanlığın ardından.
Nasıl çalışır
int $0x80
bir yazılım kesintisini çağırır. Hem x86 hem de x64'te çalışır, ancak on yıldan beri kullanımdan kaldırılmıştır ve üretim kodunda kullanılmamalıdır. x64 kodu kullanmalısyscall
Bunun yerine . x86 kullanmalı sysenter
, ancak kod golf için çok zahmetlidir.
Sistemden kaynaklanan sonuç, EAX - EDX, ESI ve EDI kayıtlarına bağlıdır. Linux syscall Referans yoluyla ulaşılabilir tüm syscalls gösterir int $0x80
.
EAX tuttuğunda (88) 0x58 , yeniden da kapatmak için kullanılabilecek adlandırılan yatırmak, veya bilgisayar gibi hazırda bekleme çekirdek anahtarlama ve devre dışı bırakma veya etkinleştirme Ctrl - Alt - Del anahtar açılan.
Programın başında - ve as
veya ile derleyerek gcc -nostdlib
, aslında programın başında olduğumuzdan emin olabiliriz - çoğu kayıt 0 olarak ayarlanmıştır . Bu, EAX'i içerir , böylece EAX'inmov $0x58, %al
8 bitini 0x58'ye ayarlamak, böylece EAX'in kendisini 0x58'e ayarlamak için kullanabiliriz . Bu, iki bayttan xor %eax, %eax
daha fazlasını 0x58'imov $0x58, %eax
kodlayan düze üzerine kayıt defterine bir kez daha el ile sıfırlama ile kazandırır 32 bit olarak .
Yeniden başlatılacak ilk iki argüman , muhtemelen yanlışlıkla yeniden başlatmayı önlemek için sihirli sayılardır ve EBX ve ECX kayıtlarından okunur. Bu sayılar belirli sabitlere eşit değilse, yeniden başlatma işlemi herhangi bir işlem gerçekleştirmeyi reddeder.
İlk sihirli sayı , büyük olasılıkla PC'nin kapanması / ölümü anlamına gelen 0xfee1dead ( ölü hissediyorum ) ile aynı olmalıdır .
İkinci sihirli sayı dört farklı sabite eşit olabilir, ancak son üçü Linux'un eski sürümlerinde çalışmadı. Bunların hepsi, bilgisayarın daha sonraki açılışı / doğumuna atıfta bulunuyor gibi görünüyor.
0x28121969 , Linus Torvalds'ın doğum gününü temsil eder (28 Aralık 1969).
0x05121996 , Patricia Torvalds'ın doğum gününü temsil ediyor (5 Aralık 1996).
0x16041998 , Daniela Torvalds'ın doğum gününü temsil ediyor (16 Nisan 1998).
0x20112000 , Celeste Torvalds'ın doğum gününü temsil ediyor (20 Kasım 2000).
Patricia, Daniela ve Celeste Torvalds, Linus Torvalds'ın üç kızıdır.
EDX kaydı, istediğimiz "yeniden başlat" türünü seçer. 0x4321fedc , bilgisayarı kapatıp kapatan , RB_POWER_OFF .
Son olarak, ESI kaydının değeri RB_POWER_OFF için yoksayılır ; EDI kaydının değeri tamamen yeniden başlatma ile göz ardı edilir .
Alternatif sürüm, yalnızca x64, 19 bayt
X64'te, aynı bayt sayısı için uygun bir sistem kullanabiliriz.
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
Tek fark talimat ( syscall
vs int $0x80
), __NR_REBOOT ( 0xa9 - 0x58 ) ve ilgili kayıtların değerleridir.