सबसे छोटा कोड SIGILL फेंकने के लिए


76

पृष्ठभूमि

हमारे पास पहले से ही SIGSEGV फेंकने के बारे में एक चुनौती है , तो SIGILL फेंकने के बारे में चुनौती क्यों नहीं है?

SIGILL क्या है?

SIGILL प्रोसेसर पर एक अवैध निर्देश के लिए संकेत है, जो बहुत कम ही होता है। SIGILL प्राप्त करने के बाद की गई डिफ़ॉल्ट कार्रवाई प्रोग्राम को समाप्त कर रही है और कोर डंप लिख रही है। SIGILL की सिग्नल आईडी है 4. आप SIGILL का सामना बहुत कम ही करते हैं, और मुझे बिलकुल भी अंदाजा नहीं है कि आपके कोड के माध्यम से इसे कैसे जनरेट करना है sudo kill -s 4 <pid>

नियम

आपके कार्यक्रमों में आपकी जड़ें होंगी, लेकिन यदि आप किसी भी कारण से नहीं चाहते हैं, तो आप एक सामान्य उपयोगकर्ता का भी उपयोग कर सकते हैं। मैं जर्मन लोकेल के साथ एक लिनक्स कंप्यूटर पर हूं और मुझे SIGILL पकड़ने के बाद प्रदर्शित होने वाले अंग्रेजी पाठ का पता नहीं है, लेकिन मुझे लगता है कि यह 'अवैध निर्देश' जैसा है। सबसे छोटा प्रोग्राम जो SIGILL जीतता है।


6
आप स्पष्ट करना चाहते हैं कि निर्देश कर्नेल द्वारा उत्पन्न किया जाना है या नहीं। विशेष रूप से, क्या आप प्रोग्राम को सीधे libc कॉल का उपयोग करके इसे उत्पन्न करने की अनुमति देना चाहते हैं raise(SIGILL)?

1
यह वास्तव में कहते हैं Illegal instruction (core dumped)
आउटगोल्फ

@ ais523 सब कुछ अनुमत है।
मेगा मैन

5
किसी भी हार्डवेयर के लिए जो SIGILL बढ़ा सकता है, इसका उत्तर अनुदेश की लंबाई के समान होगा। बस एक अवैध निर्देश को कहीं रख दें और उसे निष्पादित करने का प्रयास करें। केवल दिलचस्प बात यह है कि शामिल टूलकिन शामिल होगा।
ऑरेंजडॉग

3
* पुराने कार्यक्रमों को पोस्ट करने वाले लोग जो कि काम नहीं करते थे *
रुडोल्फजेलिन

जवाबों:


112

पीडीपी -11 असेंबलर (UNIX छठा संस्करण), 1 बाइट

9

निर्देश 9 पीडीपी -11 पर एक वैध निर्देश नहीं है (अष्ट में, यह होगा 000011, जो निर्देशों की सूची में प्रकट नहीं होता है (पीडीएफ))। PDP-11 कोडांतरक जो UNIX छठे संस्करण के साथ जहाज करता है, वह स्पष्ट रूप से वह सब कुछ गूँजता है जो सीधे फाइल में नहीं आता है; इस मामले में, 9 एक संख्या है, इसलिए यह एक शाब्दिक निर्देश उत्पन्न करता है। 9. इसके पास विषम संपत्ति (आजकल असेंबली भाषाओं में असामान्य) है जो फाइलें शुरू से चल रही हैं, इसलिए हमें कार्यक्रम बनाने के लिए किसी भी घोषणा की आवश्यकता नहीं है काम।

आप इस एमुलेटर का उपयोग करके प्रोग्राम का परीक्षण कर सकते हैं , हालांकि आपको प्रोग्राम को इनपुट करने के लिए इसके साथ कुछ लड़ना होगा।

यहां बताया गया है कि जब आप फाइलसिस्टम, एडिटर, टर्मिनल, और इसी तरह की चीजों का उपयोग करने का तरीका जान लेते हैं, तो आपको लगता है कि आप पहले से ही जानते हैं कि कैसे उपयोग करना है:

% a.out
Illegal instruction -- Core dumped

मैंने प्रलेखन के साथ पुष्टि की है कि यह एक वास्तविक SIGILLसंकेत है (और यह भी एक ही संकेत संख्या, 4, सभी तरह से वापस था!)


1
इसका एक ही सिग्नल नंबर था क्योंकि POSIX और UNIX और SUS निकट से संबंधित हैं :)
cat

4
V6 में लगभग सभी सिग्नल संख्याओं के आज भी समान अर्थ हैं; mnemonics वास्तव में संख्याओं की तुलना में कम स्थिर रहा है। की तुलना करें minnie.tuhs.org/cgi-bin/utree.pl?file=V6/usr/sys/param.h साथ github.com/freebsd/freebsd/blob/master/sys/sys/signal.h - के लिए समान अर्थ विज्ञान 13 के माध्यम से 1, लेकिन केवल 1, 2, और 13 के बिल्कुल समान नाम हैं। (SIGALRM / 14 और SIGTERM / 15 केवल V7 में जोड़े गए थे।) (सिस्टम V वंश में कुछ बदलाव हैं, विशेष रूप से SIGBUS को 10 से 7 तक ले जाना (बेकार SIGEMT की जगह) और SIGSYS 15 से ऊपर, SIGUSR1 के लिए जगह बनाने के लिए। SIGUSR2।)
zwol

4
@ पॉट पॉसिक्स और एसयूएस वास्तव में संकेतों के मूल्यों को निर्दिष्ट नहीं करते हैं - वे कुछ संख्याओं के अर्थ को निर्दिष्ट करते हैं जब मार कमांड के तर्क के रूप में पारित किया जाता है, लेकिन SIGILL शामिल नहीं है।
रैंडम 832

7
a.outइसमें कई बाइट्स हैं, वास्तव में ( 9निर्देश दो बाइट्स को संकलित करता है, और कोडांतरक प्रोग्राम को निष्पादन योग्य बनाने के लिए एक हेडर और पाद लेख भी जोड़ता है)। इसलिए मैंने मशीन कोड में नहीं, बल्कि विधानसभा भाषा में कार्यक्रम लिखा। असेंबली लैंग्वेज प्रोग्राम में केवल एक बाइट होता है, और अधिक बाइट्स वाले प्रोग्राम को संकलित करता है; यह एक कोड-गोल्फ समस्या है (स्रोत का आकार कम से कम), न कि एक सिज़कोडिंग समस्या (निष्पादन योग्य का आकार कम से कम), इसलिए यह स्रोत का 1-बाइट आकार है जो मायने रखता है।

2
एक पुरानी लेकिन भयानक प्रणाली का बहुत चालाक दुरुपयोग।
मस्त

81

सी (x86_64, tcc ), 7 बाइट्स

main=6;

इस उत्तर से प्रेरित ।

इसे ऑनलाइन आज़माएं!

यह काम किस प्रकार करता है

उत्पन्न विधानसभा इस तरह दिखती है।

    .globl  main
main:
    .long 6

ध्यान दें कि टीसीसी परिभाषित "फ़ंक्शन" को डेटा सेगमेंट में नहीं रखता है ।

संकलन के बाद, _start हमेशा की तरह मुख्य को इंगित करेगा । जब परिणामी कार्यक्रम निष्पादित किया जाता है, तो यह मुख्य रूप से कोड की अपेक्षा करता है और छोटे-एंडियन (!) 32-बिट पूर्णांक 6 को पाता है , जिसे 0x06 0x00 0x00 0x00 के रूप में एन्कोड किया गया है । पहला बाइट - 0x06 - एक अमान्य ओपकोड है , इसलिए प्रोग्राम SIGILL के साथ समाप्त हो जाता है


सी (x86_64, जीसीसी ), 13 बाइट्स

const main=6;

इसे ऑनलाइन आज़माएं!

यह काम किस प्रकार करता है

कॉन्स्ट संशोधक के बिना , उत्पन्न विधानसभा इस तरह दिखती है।

    .globl  main
    .data
main:
    .long   6
    .section    .note.GNU-stack,"",@progbits

जीसीसी का लिंकर अंतिम पंक्ति को एक संकेत के रूप में मानता है कि उत्पन्न वस्तु को निष्पादन योग्य स्टैक की आवश्यकता नहीं है। चूंकि मुख्य रूप से डेटा अनुभाग में स्पष्ट रूप से रखा गया है , इसमें जो ओपकोड है वह निष्पादन योग्य नहीं है, इसलिए प्रोग्राम समाप्त हो जाएगा SIGSEGV (विभाजन दोष)।

दूसरी या आखिरी पंक्ति को हटाने से उत्पन्न निष्पादन योग्य कार्य करना होगा। अंतिम पंक्ति को कंपाइलर फ्लैग -zexecstack( ऑनलाइन प्रयास करें! ) के साथ अनदेखा किया जा सकता है , लेकिन इसकी लागत 12 बाइट्स होती है

एक छोटा विकल्प यह है कि कॉन्स्टेंट संशोधक के साथ मुख्य घोषित किया जाए , जिसके परिणामस्वरूप निम्नलिखित विधानसभा है।

        .globl  main
        .section    .rodata
main:
        .long   6
        .section    .note.GNU-stack,"",@progbits

यह बिना किसी कंपाइलर झंडे के काम करता है। ध्यान दें कि डेटाmain=6; में परिभाषित "फ़ंक्शन" लिखना होगा , लेकिन कॉन्स्ट संशोधक जीसीसी को इसके बजाय कृंतक में लिखता है , जो (कम से कम मेरे प्लेटफ़ॉर्म पर) कोड को रखने की अनुमति है।


किसी फ़ंक्शन का उपयोग करते हुए भी पूर्ण परिहार से प्यार करें :) यह C शब्दों में कैसे काम करता है, हालांकि? क्या संकलक देखता है कि mainएक 6 है और इसे कॉल करने की कोशिश करें (जो मुझे लगता है कि यह हार मान लेगा और निर्देश की कोशिश करेगा)?
मिया यूं

11
@JackDobson यह अपरिभाषित व्यवहार है, इसलिए यह C के संदर्भ में काम नहीं करता है; आप संकलक की दया पर हैं। क्लैंग को किसी कारण से इसके लिए चेतावनी भी है: "बाहरी लिंकेज के साथ 'मुख्य' नाम के चर में अपरिभाषित व्यवहार होता है"।
बॉबी सैकमैनो

2
जीसीसी के बारे में शिकायत करेंगे mainएक समारोह लेकिन नहीं किया जा रहा केवल यदि आप चेतावनी पर बारी (या तो -Wallया -pedanticयह काम हो जाएगा)।
zwol

मुझे लगता है कि यह यूनिक्स जैसे सिस्टम के लिए टेक्स्ट / डेटा / बीएसएस सेगमेंट के लिए निष्पादन योग्य मानक है । लिंकर निष्पादन योग्य के पाठ खंड के अंदर .rodata अनुभाग रखता है , और मुझे उम्मीद है कि यह किसी भी मंच पर बहुत अधिक होगा। (कर्नेल का प्रोग्राम-लोडर केवल खंडों की परवाह करता है, खंडों का नहीं)।
पीटर कॉर्ड्स

3
यह भी ध्यान दें कि 06x86-64 में केवल एक अवैध निर्देश है। 32-बिट मोड में, यह है PUSH ES, इसलिए यह उत्तर केवल उन कंपाइलरों के साथ काम करता है जो डिफ़ॉल्ट हैं -m64। देखें ref.x86asm.net/coder.html#x06 । केवल बाइट क्रम कि भविष्य की सभी 86 CPUs पर एक अवैध अनुदेश के रूप में डिकोड करने के लिए गारंटी है 2 बाइट है UD2 : 0F 0B। कुछ और भविष्य के कुछ उपसर्ग या निर्देश-एन्कोडिंग हो सकते हैं। फिर भी, mainकुछ बाइट्स पर एक लेबल छड़ी करने के लिए सी कंपाइलर प्राप्त करने के लिए एक शांत तरीके के लिए upvoted !
पीटर कॉर्डेस

39

स्विफ्ट, 5 बाइट्स

[][0]

खाली सरणी का एक्सेस इंडेक्स 0। यह कॉल fatalError(), जो एक त्रुटि संदेश प्रिंट करता है और एक SIGILL के साथ क्रैश होता है। आप इसे यहाँ आज़मा सकते हैं


यह चालबाजियों में से एक है;)
मेगा मैन

26
... पृथ्वी पर यह SIGILL से क्यों टकराता है? किसने सोचा कि यह एक उपयुक्त संकेत था? खूनी हिपस्टर्स: डी
मुजेर

4
@Asu नहीं; fatalError()जान-बूझकर चलने से दुर्घटनाग्रस्त ud2। उन्होंने ऐसा करने का विकल्प क्यों चुना जो मुझे नहीं पता, लेकिन शायद उन्होंने सोचा कि त्रुटि संदेश "अवैध निर्देश" से समझ में आया क्योंकि कार्यक्रम ने कुछ अवैध किया।
नाडा

2
प्रतिभाशाली। मैं शर्त लगा सकता हूं कि यह दुर्घटना का कारण बनने वाला सबसे छोटा स्विफ्ट कोड भी है।
JAL

3
@ जाल हाँ; मैं कुछ भी छोटा नहीं सोच सकता। मैंने कोशिश की nil!, लेकिन कंपाइलर परिणाम प्रकार का अनुमान नहीं लगा सका। (इसके अलावा, हाय जाल!)
कोई नहीं

23

जीएनयू सी, 25 बाइट्स

main(){__builtin_trap();}

GNU C (एक्सटेंशन के साथ C की एक विशिष्ट बोली) में प्रोग्राम को जानबूझकर क्रैश करने का निर्देश है। सटीक कार्यान्वयन संस्करण से संस्करण में भिन्न होता है, लेकिन अक्सर डेवलपर्स दुर्घटना को सस्ते में संभव के रूप में लागू करने का प्रयास करते हैं, जिसमें सामान्य रूप से एक अवैध निर्देश का उपयोग शामिल होता है।

परीक्षण करने के लिए मैंने जिस विशिष्ट संस्करण का उपयोग किया है gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0; हालाँकि, यह प्रोग्राम प्लैटफॉम्स की काफी विस्तृत श्रृंखला पर एक SIGILL का कारण बनता है, और इस प्रकार यह काफी पोर्टेबल है। इसके अतिरिक्त, यह वास्तव में एक अवैध निर्देश को निष्पादित करने के माध्यम से करता है। यहाँ विधानसभा कोड है कि ऊपर डिफ़ॉल्ट अनुकूलन सेटिंग्स के साथ संकलन:

main:
    pushq %rbp
    movq %rsp, %rbp
    ud2

ud2 एक निर्देश है कि इंटेल की गारंटी हमेशा अपरिभाषित रहेगी।


11
−6:main(){asm("ud2");}
wchargin

इसके अलावा, मैं नहीं जानता कि हम कैसे कच्चे विधानसभा के लिए बाइट्स गिनते हैं, लेकिन 00 00 0f 0bमशीन भाषा के लिए है ud2...
wchargin

5
@wchargin: यह एक x86 + GNU C उत्तर है। यह सभी जीएनयू प्रणालियों के लिए पोर्टेबल है। यह भी ध्यान दें कि UD2 केवल 2 बाइट्स है । IDK जहाँ आपको वो 00बाइट्स मिले; वे UD2 के लिए मशीन कोड का हिस्सा नहीं हैं। BTW, जैसा कि मैंने डेनिस के जवाब पर टिप्पणी की , अभी के लिए x86-64 में एक-एक बाइट अवैध निर्देश हैं, लेकिन वे इस तरह से रहने की गारंटी नहीं हैं।
पीटर कॉर्ड्स

@wchargin: हम मशीन-कोड फ़ंक्शंस / प्रोग्राम के लिए बाइट्स गिनते हैं, जैसे आप अपेक्षा करते हैं। मेरे कुछ जवाब देखें, जैसे कि x86-64 मशीन कोड के 32 बाइट्स में Adler32 या x86-32 मशीन कोड के 8 बाइट्स में GCD
पीटर कॉर्ड्स

1
@ रोलन: वे नहीं हैं; 00 00x86-64 (as add [rax], al) में समान डिकोड करता है । 00 00 0f 0bआमतौर पर SIGSEGV SIGILL से पहले होगा, जब तक कि आप में रिटिटेबल पॉइंटर न हो rax
पीटर कॉर्ड्स

22

सी (x86_64), 11, 30, 34, या 34 + 15 = 49 बाइट्स

main[]="/";
c=6;main(){((void(*)())&c)();}
main(){int c=6;((void(*)())&c)();}

मैंने कई तरह के समाधान प्रस्तुत किए हैं जो पुस्तकालय के कार्यों को SIGILLविभिन्न माध्यमों से फेंकने के लिए उपयोग करते हैं , लेकिन यकीनन यह धोखा है, जिसमें पुस्तकालय समारोह समस्या का हल करता है। यहां उन समाधानों की एक श्रृंखला है जो कोई लाइब्रेरी फ़ंक्शंस का उपयोग नहीं करते हैं, और इस बारे में अलग-अलग धारणा बनाते हैं कि ऑपरेटिंग सिस्टम आपको गैर-निष्पादन योग्य कोड निष्पादित करने के लिए तैयार है। (यहां स्थिरांक को x86_64 के लिए चुना गया है, लेकिन आप उन्हें उन अन्य प्रोसेसर के लिए काम करने वाले समाधान प्राप्त करने के लिए बदल सकते हैं जिनके पास अवैध निर्देश हैं)।

06मशीन कोड का सबसे कम संख्या वाला बाइट है जो x86_64 प्रोसेसर पर परिभाषित निर्देश के अनुरूप नहीं है। तो हम सभी को इसे निष्पादित करना होगा। (वैकल्पिक रूप से, 2Fअपरिभाषित भी है, और एक मुद्रण योग्य ASCII वर्ण से मेल खाती है।) इनमें से किसी की भी हमेशा अपरिभाषित होने की गारंटी नहीं है, लेकिन वे आज तक परिभाषित नहीं हैं।

यहां पहला कार्यक्रम 2Fकेवल-पढ़ने वाले डेटा खंड से निष्पादित होता है। अधिकांश linkers से एक काम कूद उत्पादन करने में सक्षम नहीं हैं .textकरने के लिए .rodata(या उनके ओएस समकक्ष) यह कुछ है कि कभी भी एक सही ढंग से खंडित कार्यक्रम में उपयोगी होगा नहीं है के रूप में; मुझे एक ऑपरेटिंग सिस्टम नहीं मिला है जिस पर यह अभी तक काम करता है। आपको इस तथ्य के लिए भी अनुमति देनी होगी कि कई संकलक प्रश्न में स्ट्रिंग को एक विस्तृत स्ट्रिंग चाहते हैं, जिसके लिए एक अतिरिक्त की आवश्यकता होगीL; मैं यह मान रहा हूं कि जिस भी ऑपरेटिंग सिस्टम पर यह काम करता है, उसके पास चीजों के बारे में काफी पुराना दृष्टिकोण है, और इस प्रकार डिफ़ॉल्ट रूप से पूर्व-C94 मानक के लिए निर्माण हो रहा है। यह संभव है कि कहीं भी यह कार्यक्रम काम नहीं करता है, लेकिन यह भी संभव है कि कहीं न कहीं यह कार्यक्रम काम करता है, और इस तरह मैं इसे अधिक-संदिग्ध-से-कम-संदिग्ध संभावनाओं के इस संग्रह में सूचीबद्ध कर रहा हूं। (जब मैंने इस उत्तर को पोस्ट किया, तो डेनिस ने main[]={6}चैट में संभावना का भी उल्लेख किया , जो समान लंबाई है, और जो चरित्र की चौड़ाई के साथ समस्याओं में नहीं चलता है, और यहां तक ​​कि संभावित के लिए संकेत दिया है main=6; मैं इन उत्तरों के रूप में यथोचित दावा नहीं कर सकता हूं; मेरा, जैसा कि मैंने खुद उनके बारे में नहीं सोचा था।)

यहां दूसरा प्रोग्राम 06रीड-राइट डेटा सेगमेंट से निष्पादित होता है। अधिकांश ऑपरेटिंग सिस्टम पर यह एक विभाजन दोष का कारण बनेगा, क्योंकि लिखने योग्य डेटा सेगमेंट को एक खराब डिजाइन दोष माना जाता है जो शोषण की संभावना बनाता है। यह हमेशा मामला नहीं रहा है, हालांकि, यह शायद लिनक्स के एक पर्याप्त पुराने संस्करण पर काम करता है, लेकिन मैं आसानी से इसका परीक्षण नहीं कर सकता।

तीसरा कार्यक्रम 06स्टैक से निष्पादित होता है। फिर, यह आजकल एक विभाजन दोष का कारण बनता है, क्योंकि स्टैक को आमतौर पर सुरक्षा कारणों से गैर-लिखित के रूप में वर्गीकृत किया जाता है। लिंकर डॉक्यूमेंटेशन मैंने बहुत हद तक देखा है कि यह स्टैक से निष्पादित करने के लिए कानूनी हुआ करता था (पूर्ववर्ती दो मामलों के विपरीत, ऐसा करना कभी-कभार उपयोगी होता है), इसलिए हालांकि मैं इसका परीक्षण नहीं कर सकता, मुझे पूरा यकीन है कि कुछ है लिनक्स का संस्करण (और शायद अन्य ऑपरेटिंग सिस्टम) जिस पर यह काम करता है।

अंत में, यदि आप -Wl,-z,execstack(15 बाइट पेनल्टी) gcc(यदि बैक ldके हिस्से के रूप में जीएनयू का उपयोग करते हैं) देते हैं, तो यह स्पष्ट रूप से निष्पादन योग्य स्टैक संरक्षण को बंद कर देगा, तीसरे कार्यक्रम को काम करने की अनुमति देता है और उम्मीद के मुताबिक एक अवैध संचालन संकेत देता है। मैं है परीक्षण किया है और यह 49-बाइट काम करने के लिए संस्करण को सत्यापित। (डेनिस चैट में उल्लेख करता है कि यह विकल्प स्पष्ट रूप से काम करता है main=6, जो 6 + 15 का स्कोर देगा। मुझे बहुत आश्चर्य है कि यह काम करता है, यह देखते हुए कि 6 स्थिर रूप से स्टैक पर नहीं है; लिंक विकल्प स्पष्ट रूप से अधिक है; इसके नाम से पता चलता है।)


X86-64 / linux पर gcc6 के साथ इसके डिफॉल्ट (लीनिएंट) मोड में const main=6;काम करता है, जैसा कि कई बदलाव करते हैं। यह लिंकर (जो मुझे संदेह है कि आपका लिंकर भी है) से एक छलांग उत्पन्न करने में सक्षम .textहै .rodata; आपके पास जो समस्या है, वह यह है कि, constआप बिना किसी योग्य डेटा खंड ( .data) में कूद रहे हैं , जो आधुनिक हार्डवेयर पर निष्पादन योग्य नहीं है। यह पुराने x86 पर काम करता होगा, जहां मेमोरी प्रोटेक्शन हार्डवेयर पृष्ठों को पठनीय-लेकिन-निष्पादन योग्य के रूप में चिह्नित नहीं कर सकता है।
zwol

ध्यान दें कि C89 में भी, mainएक फ़ंक्शन (.15.1.2.2.1.1) होना आवश्यक है - मुझे नहीं पता कि gcc mainकेवल एक चेतावनी के लायक डेटा ऑब्जेक्ट के रूप में घोषित करने पर विचार क्यों करता है, और केवल -pedanticकमांड लाइन पर ही । 1990 के दशक की शुरुआत में किसी ने सोचा था कि कोई भी दुर्घटना से ऐसा नहीं करेगा, लेकिन यह इस तरह के खेल को छोड़कर उद्देश्य पर करना उपयोगी नहीं है।
zwol

1
... फिर से भरोसा करते हुए, ऐसा लगता है कि आपको main[]="/"केवल-पढ़ने के लिए डेटा खंड में कूदने की उम्मीद है, क्योंकि स्ट्रिंग शाब्दिक कृन्ता में जाते हैं। के बीच अंतर से आप पकड़े गए हैं char *foo = "..."और char foo[] = "..."char *foo = "..."के लिए सिंटैक्टिक शुगर है const char __inaccessible1[] = "..."; char *foo = (char *)&__inaccessible1[0];, इसलिए स्ट्रैट शाब्दिक कृन्तक में जाता है, और fooएक अलग , लिखने योग्य वैश्विक चर है जो इसे इंगित करता है। साथ char foo[] = "...", हालांकि, पूरे सरणी लिखने योग्य डेटा सेगमेंट में चला जाता है।
17

19

GNU के रूप में (x86_64), 3 बाइट्स

ud2

$ xxd sigill.S

00000000: 7564 32                                  ud2

$ के रूप में --64 sigill.S -o sigill.o; ld -S sigill.o -o sigill

sigill.S: Assembler messages:
sigill.S: Warning: end of file not at end of a line; newline inserted
ld: warning: cannot find entry symbol _start; defaulting to 0000000000400078

$ ./sigill

Illegal instruction

$ objdump -d सिगिल

sigill:     file format elf64-x86-64

Disassembly of section .text:

0000000000400078 <__bss_start-0x200002>:>
  400078:       0f 0b                   ud2

यह व्यक्त करने का एक तरीका होना चाहिए कि दो-बाइट "स्रोत" में ...
ऑरेंजडॉग

ओह, चतुर। मैं सोच रहा था कि क्या यह बनाने का कोई तरीका है जो फ़ाइल के शुरू में प्रवेश बिंदु डाल देगा (कोई घोषणाओं के साथ) और जो एक असामान्य बिल्ड सिस्टम कॉन्फ़िगरेशन के लिए दंड को लागू नहीं करेगा। मुझे एक नहीं मिला, लेकिन ऐसा लगता है कि आपने किया।

@ ais523: हाँ, मेरी सामान्य NASM / YASM बिल्ड-स्क्रिप्ट (asm-link सिंगल-फाइल टॉय प्रोग्राम के लिए ) इस स्रोत से उसी तरह एक निष्पादन योग्य का निर्माण करेगी, क्योंकि ldटेक्स्ट सेगमेंट की शुरुआत के लिए प्रवेश बिंदु को चूक या उसके बाद कुछ। मैं सिर्फ इस पर एक स्रोत के आकार के लिए जाने के बारे में नहीं सोचा था: पी
पीटर कॉर्ड्स

18

QEMU, 4 (1?) बाइट्स पर रास्पियन पर बैश

मेरे काम का नहीं। मैं केवल दूसरे के काम की रिपोर्ट करता हूं। मैं दावे का परीक्षण करने की स्थिति में भी नहीं हूं। चूंकि इस चुनौती का एक महत्वपूर्ण हिस्सा एक ऐसा वातावरण ढूंढ रहा है, जहां यह संकेत उठाया जाएगा और पकड़ा जाएगा, मैं QEMU, रास्पियन या बैश के आकार सहित नहीं हूं।

27 फरवरी 2013 को रात 8:49 बजे, उपयोगकर्ता इम्फालैक ने रास्पबेरी पाई फोरा पर " अवैध निर्देश 'प्राप्त करने की कोशिश की

ping

उत्पादन

qemu: uncaught target signal 4 (Illegal instruction) - core dumped
Illegal instruction (core dumped)

मैं कल्पना करता हूं कि बहुत कम कमांड इस आउटपुट का उत्पादन करेंगे, उदाहरण के लिए tr,।

संपादित करें: @ शराबी की टिप्पणी के आधार पर , इनपुट लंबाई पर बंधे अनुमान को घटाकर "1" कर दिया।


5
मुझे लगता है कि [कमान जीतेगी। :)
शराबी

17

x86 MS-DOS COM फ़ाइल, 2 बाइट्स

संपादित करें: जैसा कि टिप्पणियों में बताया गया है, डॉस स्वयं सीपीयू अपवाद को नहीं फँसाएगा और बस लटकाएगा (न केवल ऐप, संपूर्ण ओएस)। 32-बिट NT- आधारित OS जैसे Windows XP पर चल रहा है, वास्तव में, एक अवैध अनुदेश संकेत को ट्रिगर करेगा।

0F 0B

से प्रलेखन :

एक अमान्य opcode बनाता है। यह निर्देश सॉफ़्टवेयर परीक्षण के लिए स्पष्ट रूप से अमान्य opcode उत्पन्न करने के लिए प्रदान किया गया है।

जो बहुत आत्म-व्याख्यात्मक है। एक .com फ़ाइल के रूप में सहेजें, और किसी भी डॉस एमुलेटर में चलाएं डॉस एमुलेटर बस दुर्घटनाग्रस्त हो जाएगा। Windows XP, Vista, या 7 32-बिट पर चलाएँ।

Windows XP पर SIGILL


1
यह तकनीकी रूप से प्रोसेसर को अवैध अनुदेश अपवाद उत्पन्न करने का कारण बनता है। हालाँकि, DOS में बहुत सीमित मेमोरी सुरक्षा और अपवाद हैंडलिंग क्षमताएं हैं, और मुझे आश्चर्य नहीं होगा अगर यह सिर्फ अपरिभाषित व्यवहार / OS क्रैश का कारण बन जाए। ओपी ने नहीं कहा कि कर्नेल को त्रुटि पकड़नी थी और कंसोल में "अवैध निर्देश" प्रिंट करना था।
मेसर्वेंट

4
मैंने इस समाधान के बारे में सोचा, लेकिन मुझे नहीं लगता कि यह मान्य है। प्रश्न के लिए एक अवैध इंस्ट्रक्शन सिग्नल की आवश्यकता होती है , न कि केवल एक अवैध इंस्ट्रक्शन प्रोसेसर ट्रैप की , इसलिए इसका उद्देश्य एक ऑपरेटिंग सिस्टम खोजना था जो वास्तव में #UDट्रैप के जवाब में एक सिग्नल उत्पन्न करेगा । (इसके अलावा, मैंने वास्तव में इसका परीक्षण करने का फैसला किया, और यह मेरे डॉस एम्यूलेटर को एक अनंत लूप में फेंकने के लिए प्रकट हुआ।)

2
मैं एक AMD K6-II पर वास्तविक एमएस-डॉस पर यह परीक्षण किया। इसे चलाने से सिर्फ EMM386 के साथ और बिना चले, सिस्टम हैंग हो जाता है। (EMM386 कुछ त्रुटियों को फंसाता है और एक संदेश के साथ सिस्टम को रोक देता है, इसलिए यह देखने के लिए परीक्षण के लायक था कि क्या इससे कोई फर्क पड़ा है।)
मार्क

2
हां, डॉस-आधारित विंडो वास्तव में जाल को पकड़ने और कम से कम ऐप को क्रैश करने में सक्षम होना चाहिए।
Asu

2
@ क्या मैं पुष्टि कर सकता हूं कि यह XP 32-बिट पर काम करता है, और संभवतः अन्य सभी 32-बिट विंडोज सिस्टम पर काम करेगा। मैं मानता हूं कि यह डॉस पर ही समाधान नहीं है, क्योंकि यह दुर्घटनाग्रस्त हो गया है।
22

13

सी (32-बिट विंडोज), 34 बाइट्स

f(i){(&i)[-1]-=9;}main(){f(2831);}

यह केवल तभी काम करता है जब अनुकूलन के बिना संकलन किया जाता है (अन्यथा, fफ़ंक्शन में अवैध कोड "अनुकूलित किया गया है")।

mainफ़ंक्शन का डिस्सैसम इस तरह दिखता है:

68 0f 0b 00 00    push 0b0f
e8 a1 d3 ff ff    call _f
...

हम देख सकते हैं कि यह pushशाब्दिक मूल्य के साथ एक निर्देश का उपयोग करता है 0b0f(थोड़ा-सा एंडियन, इसलिए इसकी बाइट्स स्वैप की जाती हैं)। callअनुदेश (की वापसी पते धक्का ..., समारोह के पैरामीटर के पास ढेर पर स्थित है जो शिक्षा)। एक [-1]विस्थापन का उपयोग करके , फ़ंक्शन रिटर्न एड्रेस को ओवरराइड करता है इसलिए यह 9 बाइट्स को पहले से इंगित करता है, जहां बाइट्स 0f 0bहैं।

ये बाइट्स एक "अपरिभाषित अनुदेश" अपवाद का कारण बनते हैं, जैसा कि डिज़ाइन किया गया है।


12

जावा, 50 43 24 बाइट्स

a->a.exec("kill -4 $$");

यह एक java.util.function.Consumer<Runtime>1 है जिसका आदेश शराबी के जवाब से चुराया गया है । यह काम करता है क्योंकि आपको इसे कॉल करना होगाwhateverNameYouGiveIt.accept(Runtime.getRuntime()) !

ध्यान दें कि यह एक नई प्रक्रिया बनाएगा और इसे SIGILL खुद फेंकने के बजाय SIGILL फेंक देगा।

1 - तकनीकी तौर पर, यह भी हो सकता है एक java.util.function.Function<Runtime, Process>है क्योंकि Runtime#exec(String)एक रिटर्न java.lang.Processजो प्रक्रिया आप सिर्फ एक शेल कमांड को क्रियान्वित करने के द्वारा बनाई गई नियंत्रित करने के लिए इस्तेमाल किया जा सकता।


इस तरह की क्रिया भाषा में कुछ अधिक प्रभावशाली करने के लिए, यहां एक 72 60 48-बाइट बोनस है:

a->for(int b=0;;b++)a.exec("sudo kill -s 4 "+b);

यह एक और है Consumer<Runtime>जो सभी प्रक्रियाओं (स्वयं सहित) से गुजरता है, जिससे उनमें से प्रत्येक एक SIGILL फेंक देता है। एक हिंसक दुर्घटना के लिए बेहतर ब्रेस।


और एक और बोनस (ए Consumer<ANYTHING_GOES>), जो कम से कम 20 बाइट्स में एक साइगिल फेंकने का दिखावा करता है:

a->System.exit(132);

8

पर्ल, 9 बाइट्स

kill+4,$$

बस एक प्रक्रिया को संकेत देने के लिए उपयुक्त लाइब्रेरी फ़ंक्शन को कॉल करता है, और प्रोग्राम को स्वयं के साथ सिग्नल करने के लिए प्राप्त करता है SIGILL। कोई वास्तविक अवैध निर्देश यहां शामिल नहीं हैं, लेकिन यह उचित परिणाम पैदा करता है। (मुझे लगता है कि यह चुनौती काफी सस्ती है, लेकिन अगर किसी चीज की अनुमति है, तो यह वह खामी है जिसका आप उपयोग करेंगे ...)


के बजाय एक स्थान के साथ, एक ही पोस्ट करने के लिए यहाँ आया था +। :)
simbabque

2
जब लोग गैर-गोल्फ प्रोग्रामिंग के लिए पर्ल सीखते हैं, तो वे इसे एक के साथ सीखते हैं +। कुछ समय तक गोल्फ खेलने के बाद, वे +कभी-कभार शो ऑफ करते हैं। आखिरकार, वे पर्याप्त कार्यक्रम लिख चुके हैं, जहां उन्हें किसी कारण से व्हाट्सएप से बचने की आवश्यकता होती है, जो +आदत बन जाती है। (यह कम अस्पष्ट रूप से भी पार्स करता है, क्योंकि यह कोष्ठक में विशेष मामले को ट्रिगर करने के आसपास काम करता है।)

8

एआरएम यूनिफाइड असेंबलर लैंग्वेज (UAL), 3 बाइट्स

nop

उदाहरण के लिए:

$ as ill.s -o ill.o
$ ld ill.o -o ill
ld: warning: cannot find entry symbol _start; defaulting to 00010054
$ ./ill 
Illegal instruction

निष्पादित करने के बाद nop, प्रोसेसर .ARM.attributesअनुभाग को कोड के रूप में व्याख्या करता है और वहां एक अवैध निर्देश का सामना करता है:

$ objdump -D ill

ill:     file format elf32-littlearm


Disassembly of section .text:

00010054 <__bss_end__-0x10004>:
   10054:       e1a00000        nop                     ; (mov r0, r0)

Disassembly of section .ARM.attributes:

00000000 <.ARM.attributes>:
   0:   00001341        andeq   r1, r0, r1, asr #6
   4:   61656100        cmnvs   r5, r0, lsl #2
   8:   01006962        tsteq   r0, r2, ror #18
   c:   00000009        andeq   r0, r0, r9
  10:   01080106        tsteq   r8, r6, lsl #2

एक रास्पबेरी पाई 3 पर परीक्षण किया गया।


किसी तरह यह एक पी 2 पर काम नहीं करता है
मेगा मैन

7

Microsoft C (Visual Studio 2005 आगे की ओर), 16 बाइट्स

main(){__ud2();}

मैं आसानी से इसका परीक्षण नहीं कर सकता, लेकिन प्रलेखन के अनुसार इसे उपयोगकर्ता-मोड प्रोग्राम से जानबूझकर कर्नेल-केवल निर्देश को निष्पादित करने का प्रयास करके एक अवैध निर्देश का उत्पादन करना चाहिए। (ध्यान दें कि क्योंकि गैरकानूनी निर्देश प्रोग्राम को क्रैश कर देता है, इसलिए हमें वापस लौटने की कोशिश करने की आवश्यकता नहीं है main, जिसका अर्थ है कि यह K & R- शैली mainफ़ंक्शन मान्य है। दृश्य स्टूडियो कभी भी C89 से स्थानांतरित नहीं होता है, यह सामान्य रूप से एक बुरी बात है, लेकिन इसमें आया है। यहाँ उपयोगी है।)


क्या आप VS2015 के साथ लिनक्स के लिए संकलन कर सकते हैं? क्योंकि मुझे नहीं लगता कि विंडोज में SIGILL परिभाषित है, है?
एंड्रयू सविनाख

7

रूबी, 13 बाइट्स

`kill -4 #$$`

मुझे लगता है कि यह मान लेना सुरक्षित है कि हम इसे * nix शेल से चला रहे हैं। Backtick शाब्दिक दिए गए शेल कमांड चलाता है। $$रूबी प्रक्रिया चल रही है, और #स्ट्रिंग प्रक्षेप के लिए है।


शेल को सीधे कॉल किए बिना:

रूबी, 17 बाइट्स

Process.kill 4,$$

6

कोई भी शेल (sh, bash, csh, आदि), कोई POSIX (10 बाइट्स)

तुच्छ उत्तर लेकिन मैंने किसी को भी इसे पोस्ट करते नहीं देखा था।

kill -4 $$

अभी SIGILL को वर्तमान प्रक्रिया में भेजता है। OSX पर उदाहरण आउटपुट:

bash-3.2$ kill -4 $$
Illegal instruction: 4

आप यह कर सकते हैं कि kill -4 1यदि प्रश्न विशिष्ट नहीं है कि किस कार्यक्रम में SIGILL
मार्क K कोवन

@MarkKowan हेह, अच्छी बात है, हालांकि यह जड़ को मानता है ...
शराबी

2
You will have root in your programs- अपने उत्तर से एक बाइट खटखटाएं और उसी समय प्रश्न को थोड़ा सा ट्रोल करें: डी। बोनस: आपको मारने के लिए मिलता हैinit
मार्क के कोवान

2
@ मर्ककॉवन: ऑन (के आधुनिक संस्करण?) लिनक्स initवास्तव में संकेतों के लिए प्रतिरक्षा है , जो विशेष रूप से रूट के लिए भी प्राप्त करने का अनुरोध नहीं किया है। आप शायद इसके चारों ओर एक अलग POSIX OS का उपयोग करके काम कर सकते हैं, हालांकि।

2
kill -4 2तत्पश्चात:
मार्क के कोवान

6

ELF + x86 मशीन कोड, 45 बाइट्स

यह यूनिक्स मशीन पर सबसे छोटा निष्पादन योग्य प्रोग्राम होना चाहिए जो SIGILL फेंकता है (लिनक्स के कारण निष्पादन योग्य को पहचानने में सक्षम नहीं है यदि कोई छोटा बना हो)।

संकलित करें nasm -f bin -o a.out tiny_sigill.asm, एक x64 वर्चुअल मशीन पर परीक्षण किया गया।

वास्तविक 45 बाइट्स बाइनरी:

0000000 457f 464c 0001 0000 0000 0000 0000 0001

0000020 0002 0003 0020 0001 0020 0001 0004 0000

0000040 0b0f c031 cd40 0080 0034 0020 0001

विधानसभा सूची (नीचे स्रोत देखें):

;tiny_sigill.asm      
BITS 32


            org     0x00010000

            db      0x7F, "ELF"             ; e_ident
            dd      1                                       ; p_type
            dd      0                                       ; p_offset
            dd      $$                                      ; p_vaddr 
            dw      2                       ; e_type        ; p_paddr
            dw      3                       ; e_machine
            dd      _start                  ; e_version     ; p_filesz
            dd      _start                  ; e_entry       ; p_memsz
            dd      4                       ; e_phoff       ; p_flags


_start:
                ud2                             ; e_shoff       ; p_align
                xor     eax, eax
                inc     eax                     ; e_flags
                int     0x80
                db      0
                dw      0x34                    ; e_ehsize
                dw      0x20                    ; e_phentsize
                db      1                       ; e_phnum
                                                ; e_shentsize
                                                ; e_shnum
                                                ; e_shstrndx

  filesize      equ     $ - $$

डिस्क्लेमर: किसी नंबर को वापस करने के लिए सबसे छोटे असेंबली प्रोग्राम लिखने पर निम्नलिखित ट्यूटोरियल से कोड, लेकिन mov के बजाय opcode ud2 का उपयोग करते हुए: http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html


2
मैं उस सटीक ट्यूटोरियल के एक संशोधित निष्पादन योग्य पोस्ट करने वाला था, लेकिन आपने मुझे इसे हरा दिया। यह जीत का हकदार है; यह सिस्टम रिसोर्स सेंस में एक सच्चा न्यूनतावादी है (इसमें इन-फाइल और इन-मेमोरी दोनों में 45 बाइट्स की आवश्यकता नहीं है, और दोनों में बिल्कुल समान है), और अन्य कोडांतरक समाधानों की तरह कोई फूला हुआ दुभाषिया नहीं है। बस यह है कि यह क्या है।
इविलनोटिक्सिस्ट इडोनाटेक्सिस्ट

5

ऑटो इट , 93 बाइट्स

फ्लैटस्सेम्बलर इनलाइन असेंबली का उपयोग करना:

#include<AssembleIt.au3>
Func W()
_("use32")
_("ud2")
_("ret")
EndFunc
_AssembleIt("int","W")

SciTE इंटरेक्टिव मोड में चलाने पर, यह तुरंत क्रैश हो जाएगा। विंडोज डीबगर को एक सेकंड के एक अंश के लिए पॉपअप करना चाहिए। कंसोल आउटपुट कुछ इस तरह होगा:

--> Press Ctrl+Alt+Break to Restart or Ctrl+Break to Stop
0x0F0BC3
!>14:27:09 AutoIt3.exe ended.rc:-1073741795

-1073741795WinAPI द्वारा फेंका गया अपरिभाषित त्रुटि कोड कहां है। यह कोई भी नकारात्मक संख्या हो सकती है।

अपने स्वयं के कोडांतरक LASM का उपयोग करने के समान :

#include<LASM.au3>
$_=LASM_ASMToMemory("ud2"&@CRLF&"ret 16")
LASM_CallMemory($_,0,0,0,0)

5

एनएएसएम, 25 बाइट्स

मुझे नहीं पता कि यह कैसे काम करता है, बस यह मेरे कंप्यूटर पर विशेष रूप से करता है (लिनक्स x86_64)।

global start
start:
jmp 0

संकलन और चलाएं:

$ nasm -f elf64 ill.asm && ld ill.o && ./a.out
ld: warning: cannot find entry symbol _start; defaulting to 0000000000400080
Illegal instruction

आप शायद इसे चार बाइट्स के लिए छोटा कर सकते हैं, जैसेja 0
मार्क के कोवान

1
या तीन के रूप मेंud2
मार्क के कोवान

1
शायद इसलिए कि यह कुछ डेटा पर कूदने की कोशिश कर रहा है?
आसू

5

TI-83 हेक्स असेंबली, 2 बाइट्स

PROGRAM:I
:AsmPrgmED77

के रूप में चलाएँ Asm(prgmI)। अवैध 0xed77 opcode निष्पादित करता है। मैं हेक्स अंकों की प्रत्येक जोड़ी को एक बाइट के रूप में गिनता हूं।



3

x86 .COM, 1 बाइट

c

ARPL#UD16-बिट मोड में कारण


1

लिनक्स शेल, 9 बाइट्स

kill -4 0

SIGILLPID 0 के साथ प्रक्रिया को भेजता है। मुझे नहीं पता कि PID 0 में क्या प्रक्रिया है, लेकिन यह हमेशा मौजूद है।

इसे ऑनलाइन आज़माएं!


प्रेषक man kill:0 All processes in the current process group are signaled.
डेनिस

1

जीएनयू सी, 24 19 18 बाइट्स

-4 डेनिस
के लिए धन्यवाद -1 सीलिंगकैट के लिए धन्यवाद

main(){goto*&"'";}

इसे ऑनलाइन आज़माएं! यह ASCII और x86_64 को मानता है। यह मशीन कोड को चलाने का प्रयास करता है 27, जो ... अवैध है।


शॉर्टसी , 10 5 4 बाइट्स

AV"'

उपरोक्त GNU C कोड के बराबर है। इसे ऑनलाइन आज़माएं!


L"\6"यह भी अवैध है, x86_64 मान रहा है।
डेनिस

@ डेनिस 0x06 क्या निर्देश है? इसके अलावा, Lयह आवश्यक नहीं है।
एमडी XF

यह अप्रमाणित है।
डेनिस

यह अप्रकाशित है; वही इसे अवैध बनाता है। इसके अलावा, 'है 39 = 0x27 , नहीं 0x39
डेनिस

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.