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
जड़ के रूप में चलाया जाना चाहिए।
यह पावर बटन दबाने के बराबर है और आपके पीसी को बंद करने का सुरक्षित तरीका नहीं है। सुनिश्चित करें कि आप सभी खुले अनुप्रयोगों को बंद करते हैं और sync
इस कार्यक्रम को निष्पादित करने से पहले सभी फ़ाइल सिस्टम बफ़र्स को फ्लश करने के लिए निष्पादित करते हैं, कम से कम फ़ाइल भ्रष्टाचार के जोखिम को कम करने के लिए।
परीक्षण चालन
$ 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:
अंधेरे से पीछा किया।
यह काम किस प्रकार करता है
int $0x80
एक सॉफ्टवेयर रुकावट को आमंत्रित करता है। यह x86 और x64 दोनों पर काम करता है, लेकिन अब एक दशक से अधिक के लिए पदावनत कर दिया गया है और इसका उपयोग उत्पादन कोड में नहीं किया जाना चाहिए। syscall
इसके बजाय x64 कोड का उपयोग करना चाहिए । x86 का उपयोग करना चाहिए sysenter
, लेकिन यह कोड गोल्फ के लिए बहुत बोझिल है।
Syscall से परिणामी कार्रवाई रजिस्टरों EAX - EDX, ESI और EDI पर निर्भर करती है। लिनक्स syscall संदर्भ सभी syscalls कि माध्यम से उपलब्ध हैं पता चलता int $0x80
।
जब EAX 0x58 (88) रखता है , तो रिबूट को कहा जाता है, जिसका उपयोग बिजली बंद करने, सोने के लिए, या कंप्यूटर को हाइबरनेट करने के साथ-साथ गुठली स्विच करने और Ctrl - Alt - Del keybo को सक्षम या सक्षम करने के लिए भी किया जा सकता है ।
कार्यक्रम की शुरुआत में - और as
या के साथ संकलन करके gcc -nostdlib
, हम यह सुनिश्चित कर सकते हैं कि हम वास्तव में कार्यक्रम की शुरुआत में हैं - अधिकांश रजिस्टर 0 पर सेट हैं । यह EAX भी शामिल है, इसलिए हम उपयोग कर सकते हैं mov $0x58, %al
करने के लिए EAX के निचले 8 बिट सेट करने के लिए 0x58 इस प्रकार EAX ही स्थापित करने के लिए, 0x58 । यह दो बाइट्स को मैन्युअल रूप से रजिस्टर को शून्य करने से बचाता है xor %eax, %eax
और स्ट्रेचेफोवर्ड पर एक और अधिक है mov $0x58, %eax
जो 32 बिट्स में 0x58 को एन्कोड करता है ।
रिबूट करने के लिए पहले दो तर्क जादू की संख्या हैं, संभवतः आकस्मिक रिबूट को रोकने के लिए, और रजिस्टर ईबीएक्स और ईसीएक्स से पढ़ा जाता है। जब तक ये संख्या कुछ स्थिरांक के बराबर नहीं होती, रिबूट किसी भी कार्रवाई को करने से इनकार करता है।
पहले मैजिक नंबर को 0xfee1dead ( मृत महसूस करना) के बराबर होना चाहिए , शायद पीसी की पावर ऑफ / डेथ का जिक्र हो।
दूसरी मैजिक संख्या चार अलग-अलग स्थिरांक के बराबर हो सकती है, हालांकि बाद के तीन लिनक्स के प्राचीन संस्करणों में काम नहीं करते थे। उन सभी को पीसी के जन्म के बाद की शक्ति का उल्लेख लगता है।
0x28121969 लिनस टॉर्वाल्ड्स के जन्मदिन (28 दिसंबर, 1969) का प्रतिनिधित्व करता है।
0x05121996 पेट्रीसिया टॉर्वाल्ड्स के जन्मदिन (5 दिसंबर, 1996) का प्रतिनिधित्व करता है।
0x16041998 डैनियल टोरवाल्ड्स के जन्मदिन (16 अप्रैल, 1998) का प्रतिनिधित्व करता है।
0x20112000 सेलेस्ट टॉर्वाल्ड्स के जन्मदिन (20 नवंबर, 2000) का प्रतिनिधित्व करता है।
पेट्रीसिया, डेनिएला और सेलेस्टे टॉर्वाल्ड्स लिनुस टॉर्वाल्ड्स की तीन बेटियां हैं।
EDX रजिस्टर "रिबूट" के प्रकार का चयन करता है जिसे हम चाहते हैं। 0x4321fedc है RB_POWER_OFF , पीसी नीचे बंद और इसे बंद शक्ति।
अंत में, ESI रजिस्टर के मूल्य को RB_POWER_OFF के लिए अनदेखा किया जाता है ; EDI रजिस्टर के मूल्य को पूरी तरह से रिबूट द्वारा अनदेखा किया गया है ।
वैकल्पिक संस्करण, x64- केवल, 19 बाइट्स
X64 पर, हम एक ही बाइट काउंट के लिए एक उचित syscall का उपयोग कर सकते हैं।
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
केवल अंतर निर्देश ( syscall
बनाम int $0x80
), __NR_REBOOT ( 0xa9 बनाम 0x58 ), और शामिल रजिस्टरों के मूल्य में निहित है ।