SIGILL'i fırlatmak için en kısa kod


76

Arka fon

Biz zaten bir sorunları olduğunu SIGSEGV atma , neden SIGILL atma konusunda bir meydan okuma?

SIGILL Nedir?

SIGILL, işlemcide çok nadir görülen yasadışı bir talimatın işaretidir. SIGILL'i aldıktan sonra yapılan varsayılan eylem programı sonlandırmak ve bir çekirdek dökümü yazmaktır. SIGILL'in sinyal kimliği 4'tür. SIGILL ile çok nadir karşılaşırsınız ve kodları dışında kodunuzu nasıl oluşturacağımı kesinlikle bilmiyorum sudo kill -s 4 <pid>.

kurallar

Programlarınızda root olacaktır ancak herhangi bir nedenden dolayı istemiyorsanız normal bir kullanıcı da kullanabilirsiniz. Alman yerel ayarlı bir Linux bilgisayardayım ve SIGILL'i yakaladıktan sonra görüntülenen İngilizce metni bilmiyorum ama bence 'Yasadışı talimat' gibi bir şey. SIGILL'i fırlatan en kısa program kazanır.


6
Komutun çekirdek tarafından oluşturulup oluşturulmayacağını açıklığa kavuşturmak isteyebilirsiniz. Özellikle, programın doğrudan libc çağrısını kullanarak doğrudan onu oluşturmasına izin vermek ister misiniz raise(SIGILL)?

1
Gerçekten öyle diyor Illegal instruction (core dumped).
Outgolfer Erik,

@ ais523 Her şeye izin verilir.
Mega Man

5
SIGILL'i yükseltebilecek herhangi bir donanım için cevap, talimat uzunluğuyla aynı olacaktır. Sadece bir yere yasadışı bir talimat ver ve çalıştırmayı dene. Tek ilginç şey, katlanmış kıvrımlı takım zinciri olacaktır.
OrangeDog

3
* Eski programlarını yayınlayan insanlar işe yaramadı *
RudolfJelin

Yanıtlar:


112

PDP-11 Assembler (UNIX Altıncı Baskı), 1 bayt

9

Talimat 9, PDP-11'de geçerli bir talimat değildir (sekizlik olarak 000011, talimatlar listesinde görünmeyecektir (PDF)). UNIX Altıncı Sürüm'le birlikte gelen PDP-11 birleştiricisi, açıkça anlamadığı her şeyi doğrudan dosyaya yansıtıyor; Bu durumda, 9 bir sayıdır, bu nedenle değişmez bir yönerge 9 oluşturur. Aynı zamanda, dosyaların başlangıçtan itibaren yayınlanmaya başlaması gibi tuhaf bir özelliğe de sahiptir (günümüzde alışılmadık dillerde). iş.

Bu emülatörü kullanarak programı test edebilirsiniz , ancak programa girmek için biraz mücadele etmeniz gerekecek.

Dosya sistemini, editörü, terminali ve nasıl kullanacağınızı bildiğinizi düşündüğünüz benzer şeyleri kullanmayı düşündüğünüzde, işler nasıl bitiyor:

% a.out
Illegal instruction -- Core dumped

Bunun gerçek bir SIGILLsinyal olduğunu belgeledim (ve o zamana kadar aynı sinyal numarasına 4, hatta sahipti!)


1
Aynı sinyal numarasına sahipti çünkü POSIX ve UNIX ve SUS yakından ilişkiliydi :)
cat

4
V6'daki sinyal numaralarının hemen hepsi bugün hala aynı anlama geliyor; anımsatıcılar gerçekte sayılardan daha az kararlılardı. Minnie.tuhs.org/cgi-bin/utree.pl?file=V6/usr/sys/param.h ile github.com/freebsd/freebsd/blob/master/sys/sys/signal.h - benzer semantiklerle karşılaştırın 1 ile 13 arasında, ancak yalnızca 1, 2 ve 13 tam olarak aynı ada sahip. (SIGALRM / 14 ve SIGTERM / 15 sadece V7'ye eklenmiştir.) (Sistem V neslinde, SIGBR ve SIGSYS'e yer açmak için SIGBR'yi 10'dan 7'ye (işe yaramaz SIGEMT'in yerini alarak) ve SIGSYS'i 15'in üzerine taşıyan birkaç değişiklik vardır. SIGUSR2.)
zwol

4
@cat POSIX ve SUS aslında sinyallerin değerlerini belirtmezler - kill komutuna argüman olarak iletildiğinde bazı sayıların anlamlarını belirtirler, ancak SIGILL dahil değildir.
Random832

7
a.outaslında içinde çok sayıda bayt vardır ( 9komut iki bayta kadar derlenir ve assembler ayrıca programı çalıştırılabilir kılmak için bir başlık ve alt bilgi ekler). Bu yüzden programı makine dilinde değil, assembly dilinde yazdım. Assembly dili programı sadece bir bayt içeriyor ve içinde daha fazla bayt olan bir programda derleniyor; bu bir kodlama problemidir (kaynağın boyutunu küçültün), bir boyut kodlama sorunu değildir (çalıştırılabilir boyutun küçültülmesi), bu nedenle önemli olan kaynağın 1 bayt boyutudur.

2
Eski ama müthiş bir sistemin çok zekice istismarı.
Mast

81

C (x86_64, tcc ), 7 bayt

main=6;

Bu cevaptan ilham aldım .

Çevrimiçi deneyin!

Nasıl çalışır

Oluşturulan montaj buna benziyor.

    .globl  main
main:
    .long 6

TCC'nin tanımlanmış "işlevi" bir veri segmentine yerleştirmediğini unutmayın.

Derlemeden sonra, _start her zamanki gibi ana noktaya işaret edecektir . Sonuçta ortaya çıkan program çalıştırıldığında, ana kodunu bekler ve 0x06 0x00 0x00 0x00 olarak kodlanan küçük endian (!) 32-bit tamsayı 6'yı bulur . İlk bayt - 0x06 - geçersiz bir koddur , bu yüzden program SIGILL ile sonlanır .


C (x86_64, gcc ), 13 bayt

const main=6;

Çevrimiçi deneyin!

Nasıl çalışır

Const değiştiricisi olmadan, üretilen montaj buna benzer.

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

GCC'nin bağlayıcısı, son satırı, oluşturulan nesnenin yürütülebilir bir yığın gerektirmediğine dair bir ipucu olarak görür. Yana ana açıkça yerleştirilir veri bölümü, içerdiği işlem kodu yürütülebilir değildir, bu nedenle programı sonlandırıldığında olacaktır SIGSEGV (bölümleme hatası).

İkinci veya son satırın kaldırılması, oluşturulan yürütülebilir çalıştırmanın amaçlandığı şekilde çalışmasını sağlar. Son satır derleyici bayrağını görmezden gelebilir -zexecstack( Çevrimiçi deneyin! ) Ancak bu 12 bayt tutar .

Daha kısa bir alternatif const modifier ile ana ilan etmek ve aşağıdaki montaj ile sonuçlanır.

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

Bu derleyici bayrağı olmadan çalışır. Not main=6;tanımlanan "işlevini" yazıyormuş verileri , ancak const değiştirici GCC bunu yazmak yapar RODATA (en azından benim platformda) kodu içeren izin verilen, bunun yerine.


Bir işlevi kullanmaktan bile kaçınmanın tam bir sevgisi var :) Bu nasıl olsa C terimiyle çalışıyor? Derleyici mainbunun 6 olduğunu görüyor mu ve onu aramayı deniyor mu (sanırım vazgeçip talimatı deneyecekti)?
Mia yun Ruse

11
@ JackDobson bu tanımsız davranış, bu nedenle C açısından çalışmaz; derleyicinin merhametindesiniz. Clang'ın bazı nedenlerden dolayı bile bir uyarısı var: "harici bağlantıya sahip 'main' isimli değişken tanımsız davranışa sahip".
Bobby Sacamano,

2
GCC mainbir işlev olmadığından şikayet eder, ancak yalnızca uyarıları açarsanız (ya -Wallda -pedanticyaparsanız).
zwol

Unix benzeri sistemler için çalıştırılabilir dosyalar için metin / veri / bss bölümlerinin bulunmasının oldukça standart olduğunu düşünüyorum . Bağlayıcı, .rodata bölümü çalıştırılabilir metin bölümünün içine yerleştirir ve bunun hemen hemen tüm platformlarda böyle olacağını umuyorum. (Çekirdeğin program yükleyicisi, bölümlere değil yalnızca bölümlere önem verir).
Peter Cordes,

3
Ayrıca 06, yalnızca x86-64'te geçersiz bir talimat olduğunu unutmayın . 32 bit modunda, bu PUSH ESyüzden bu cevap sadece varsayılan olan derleyicilerle çalışır -m64. Bakınız ref.x86asm.net/coder.html#x06 . Gelecekteki tüm x86 İşlemciler yasadışı talimat olarak çözmek için garanti olan tek bayt sırası 2 bayt olduğunu UD2 : 0F 0B. Başka bir şey gelecekteki bir önek veya talimat kodlaması olabilir. Yine de, mainbazı baytlarda bir etiket yapıştırmak için bir C derleyicisini elde etmek için harika bir yol için yükseltildi !
Peter Cordes,

39

Swift, 5 bayt

[][0]

Boş bir dizinin erişim dizini 0. Bu fatalError(), bir hata mesajı basan ve bir SIGILL ile kilitlenen çağrılar. Burada deneyebilirsiniz .


Bu hileli olanlardan biridir;)
Mega Man

26
... neden dünyada bir SIGILL ile çarpışıyor? Bunun uygun bir sinyal olduğunu kim düşündü? Kanlı hipsters: D
Muzer

4
@Asu No; fatalError()kasten çalıştırarak çöküyor ud2. Neden bilmediğimi yapmayı seçtiler, ama belki de "Yasadışı talimat" hata mesajının mantıklı olduğunu düşündüğü için mantıklı olmadığını düşündüler.
KimseNada

2
Parlak. Bahse girerim, bu aynı zamanda çökmeye sebep olacak en kısa Swift kodudur.
JAL

3
@ JAL Evet; Daha kısa bir şey düşünemiyorum. Denedim nil!, ancak derleyici sonuç türünü çıkaramadı. (Ayrıca, merhaba JAL!)
KimseNada

23

GNU C, 25 bayt

main(){__builtin_trap();}

GNU C (uzantılara sahip belirli bir C lehçesi) programı kasıtlı olarak çökertmek için bir talimat içerir. Tam uygulama sürümden sürüme değişir, ancak genellikle geliştiriciler kazayı olabildiğince ucuz bir şekilde uygulamaya koyma girişiminde bulunur; bu da normalde yasadışı bir talimatın kullanılmasını içerir.

Test etmek için kullandığım belirli sürüm gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0; bununla birlikte, bu program oldukça geniş bir platfom yelpazesinde bir SIGILL'e neden olur ve bu nedenle oldukça taşınabilirdir. Ek olarak, yasadışı bir talimatı gerçekten yerine getirerek yapar. Yukarıdakilerin varsayılan optimizasyon ayarlarıyla derlediği montaj kodu:

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

ud2 Intel garantilerinin her zaman tanımsız kalacağı bir talimattır.


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

Ayrıca, ham derleme için baytları nasıl sayarız bilmiyorum ama 00 00 0f 0bmakine dili ud2
wchargin

5
@ wchargin: Bu bir x86 + GNU C cevabı. Bu, tüm GNU sistemlerine taşınabilir. Ayrıca, UD2'nin yalnızca 2 bayt olduğunu unutmayın . Bu 00baytları aldığınız IDK ; UD2 için makine kodunun bir parçası değillerdir. BTW, Dennis'in cevabını yorumladığım gibi , şimdilik x86-64'te bir baytlık yasa dışı talimatlar var, ancak bu şekilde kalmaları garanti edilmiyor.
Peter Cordes,

@wchargin: Beklediğiniz gibi makine kodu işlevleri / programları için bayt sayıyoruz. 32 byte x86-64 makine kodundaki Adler32 veya 8 byte x86-32 makine kodundaki GCD gibi cevaplarımın bazılarına bakın .
Peter Cordes,

1
@Ruslan: Onlar değil; 00 00x86-64 (as add [rax], al) ' da aynı kodu çözer . 00 00 0f 0beğer yazılabilir bir işaretçi bulunmadıkça, genellikle SIGILL'ten önce SIGSEGV olur rax.
Peter Cordes

22

C (x86_64), 11, 30, 34 veya 34 + 15 = 49 bayt

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

SIGILLÇeşitli yollarla atmak için kütüphane işlevlerini kullanan birkaç çözüm önerdim, ancak tartışmanın hile yaptığı, kütüphane işlevinin sorunu çözdüğüdür. Kütüphane işlevlerini kullanmayan ve işletim sisteminin çalıştırılabilir olmayan kodları çalıştırmanıza izin verme konusunda istekli olduğu konusunda çeşitli varsayımlarda bulunan çözümler. (Buradaki sabitler x86_64 için seçilmiştir, ancak yasa dışı talimatlara sahip çoğu diğer işlemciler için çalışma çözümleri almak üzere bunları değiştirebilirsiniz.)

06x86_64 işlemci üzerindeki tanımlanmış bir talimatla uyuşmayan makine kodunun en düşük numaralı baytıdır. Tek yapmamız gereken onu yürütmek. (Alternatif olarak, 2Faynı zamanda tanımsızdır ve tek bir yazdırılabilir ASCII karakterine karşılık gelir.) Bunların hiçbirinin her zaman tanımsız olması garanti edilmez, ancak bugün itibariyle tanımlanmamıştır.

Buradaki ilk program 2Fsalt okunur veri bölümünden yürütülür . Bağlayıcıların çoğu , doğru bölümlere ayrılmış bir programda hiçbir zaman faydalı olamayacağından , .textkendisinden .rodata(veya işletim sistemlerinin eşdeğerinden) bir çalışma atlaması üretemez; Bunun üzerinde çalıştığı bir işletim sistemi bulamadım. Ayrıca birçok derleyicinin söz konusu dizginin geniş bir dize olmasını istemesine izin vermeniz gerekir;L; Bunun üzerinde çalıştığı herhangi bir işletim sisteminin şeyleri oldukça eski bir görünüme sahip olduğunu ve bu nedenle varsayılan olarak C94 öncesi bir standart için oluşturulduğunu farz ediyorum. Bu programın çalıştığı hiçbir yerde olması mümkün değildir, ancak bu programın çalıştığı bir yerde olması da mümkün ve bu nedenle daha şüpheli-şüpheli-şüpheli-potansiyel şüpheli cevaplar koleksiyonunda listeliyorum. (Bu cevabı gönderdikten sonra Dennis main[]={6}, aynı uzunluktaki ve karakter genişliği ile ilgili sorunlara rastlamayan ve hatta potansiyelini ima eden sohbet olasılığından da bahsetti main=6; benim, kendileri hakkında düşünmediğim gibi.)

Buradaki ikinci program 06okuma-yazma veri bölümünden yürütülür . Çoğu işletim sisteminde bu, segmentasyon hatasına neden olur, çünkü yazılabilir veri segmentleri, istismarları muhtemel kılan kötü bir tasarım hatası olarak kabul edilir. Yine de, her zaman böyle olmadı, bu yüzden muhtemelen yeterince eski bir Linux sürümünde çalışıyor, ancak kolayca test edemiyorum.

Üçüncü program 06yığından yürütülür . Yine, bu, bugünlerde bir segmentasyon hatasına neden olmaktadır, çünkü yığın, güvenlik nedenleriyle normal olarak yazılamaz olarak sınıflandırılmaktadır. Gördüğüm bağlayıcı belgeler, yığıntan yürütmek için yasal olduğu anlamına gelir (önceki iki durumun aksine, bunu yapmak bazen yararlı olur), bu yüzden test edemesem de, biraz eminim. üzerinde çalıştığı Linux sürümü (ve muhtemelen diğer işletim sistemleri).

Son olarak, -Wl,-z,execstack(15 bayt ceza) verirseniz ( arka ucun bir parçası olarak gccGNU kullanıyorsanız ld), üçüncü programın çalışmasına ve beklendiği gibi yasadışı bir çalışma sinyali vermesine izin vererek çalıştırılabilir yığın korumasını açıkça kapatır. Ben var test edilmiş ve çalışmak için bu 49 bayt sürümünü doğrulandı. (Dennis, bu seçeneğin main=66 + 15 puan verecek görünüşte çalıştığı sohbette bahsetti . 6'nın açıkça yığında olmadığı göz önüne alındığında, bu seçeneğin çalıştığından oldukça şaşırdım; onun adı önerir.)


X86-64 / linux'da gcc6 ile varsayılan (yumuşak) modda, const main=6;çeşitli varyasyonlarda olduğu gibi çalışır. (Ben bağlayıcı da şüpheli) Bu bağlayıcı olan bir sıçrama üretebilen .textiçin .rodata; Eğer yapıyorduk sorundur, bu olmadan const, içine sıçrıyoruz yazılabilir veri segmenti ( .dataModern donanım üzerinde çalıştırılabilir değildir). Bellek koruma donanımının sayfaları okunabilir ancak çalıştırılamaz olarak işaretleyemediği eski x86'da çalışacaktı.
zwol

Hatta C89 içinde, unutmayın maingcc ilan görmesinin nedeni bilmiyorum - bir işlev (§5.1.2.2.1) olması gerekir mainancak ve ancak birlikte, bir uyarı hak edecek bir veri nesnesi olarak -pedantickomut satırında. 1990'ların başlarında birileri belki kimsenin bunu kazara yapmayacağını düşündü, ama bu tür bir oyun haricinde bilerek yapılması yararlı bir şey değil.
zwol

1
... Tekrar main[]="/"okuduğunuzda, salt okunur veri segmentine atlamayı umuyorsunuz, çünkü string değişmezleri rodata içinde gidiyor. char *foo = "..."Ve arasındaki farklardan yakalandınız char foo[] = "...". char *foo = "..."sözdizimi const char __inaccessible1[] = "..."; char *foo = (char *)&__inaccessible1[0];şekeridir, bu nedenle string değişmezi rodata olur ve kendine işaret fooeden ayrı , yazılabilir bir global değişkendir. Bununla char foo[] = "..."birlikte, dizinin tamamı yazılabilir veri bölümüne girer.
zwol

19

GNU (x86_64), 3 bayt

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 imza

sigill:     file format elf64-x86-64

Disassembly of section .text:

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

Bunu iki byte'lık bir "kaynak" olarak ifade etmenin bir yolu olmalı ...
OrangeDog

Oh, zekice. Bunu yapmanın bir yolu olup olmadığını, giriş noktasını dosyanın başlangıcına yerleştirecek (bildirim olmadan) ve alışılmadık bir derleme sistemi yapılandırması için ceza vermeyecek bir şey olup olmadığını merak ediyordum. Bir tane bulamadım, ama senin yaptığın gibi görünüyor.

@ ais523: evet, benim her zamanki NASM / YASM build-script ( asm-link) , tek dosyalık oyuncak programları için çalıştırılabilir bir yapı oluşturacaktı, çünkü ldvarsayılan olarak giriş noktası metin bölümünün başlangıcına ya da onun gibi bir şeye öncülük ediyordu. Bu konuda asm kaynak büyüklüğü elde etmeyi düşünmedim: P
Peter Cordes

18

QEMU'daki Raspbian'daki Bash, 4 (1?) Bayt

Benim işim değil. Sadece bir başkasının çalışmalarını rapor ediyorum. Talebi test edecek durumda bile değilim. Bu zorluğun önemli bir parçası, bu sinyalin üretileceği ve yakalanacağı bir ortam bulmak gibi gözüktüğü için, QEMU, Raspbian veya bash boyutunu dahil etmiyorum.

27 Şubat 2013, 20: 49'da , kullanıcı emlhalac , Raspberry Pi fora'da " chroot yapmaya çalışırken" yasadışı talimatlar almayı "söyledi.

ping

üreten

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

Örneğin, bu çıktıyı daha kısa komutların üreteceğini düşünüyorum tr.

EDIT: @ fluffy'nin yorumuna dayanarak, girilen uzunluktaki varsayımlı alt sınırı "1?" E düşürdü.


5
[Komutun kazanacağını düşünüyorum . :)
kabarık

17

x86 MS-DOS COM dosyası, 2 bayt

DÜZENLEME: Yorumlarda belirtildiği gibi, DOS'un kendisi CPU istisnasını yakalamayacak ve sadece kilitlenmeyecek (sadece uygulama değil, tüm işletim sistemi). Windows XP gibi 32 bitlik bir NT tabanlı bir işletim sistemi üzerinde çalıştırmak gerçekten de geçersiz bir talimat sinyali tetikler.

0F 0B

Gönderen belgeler :

Geçersiz bir opcode oluşturur. Bu talimat, yazılım testlerinde açıkça geçersiz bir opcode oluşturmak için verilmiştir.

Bu oldukça kendini açıklayıcı. Bir .com dosyası olarak kaydedin ve herhangi bir DOS emülatöründe çalıştırın DOS emülatörleri çökecektir. Windows XP, Vista veya 7 32 bit ile çalıştırın.

Windows XP'de SIGILL


1
Teknik olarak, işlemcinin geçersiz bir talimat istisnası oluşturmasına neden olur. Bununla birlikte, DOS'un bellek koruması ve istisna işleme yetenekleri çok sınırlıdır ve tanımsız davranış / işletim sistemi çökmesine neden olsaydı şaşırmam. OP, çekirdeğin hatayı yakalaması ve "Yasadışı Talimatı" konsola yazdırması gerektiğini söylemedi.
Kasım’da

4
Bu çözümü düşündüm, ama geçerli olduğuna inanmıyorum. Soru , yalnızca yasadışı bir işlem işlemcisi tuzağı değil, yasadışı bir yönerge sinyali gerektiriyor ; bu nedenle amaç, tuzağa yanıt olarak bir sinyal üreten bir işletim sistemi bulmaktı . (Ayrıca, ben aslında bunu denemeye karar verdik ve o sonsuz döngüye benim DOS emülatörü atmak ortaya çıktı.)#UD

2
Bunu bir AMD K6-II'deki gerçek MS-DOS üzerinde test ettim. Çalıştırılması, hem EMM386 çalışıyorken hem de olmadan, sistemi kapatıyor. (EMM386 bazı hataları yakalar ve bir mesajla sistemi durdurur, bu yüzden bir fark
Mark

2
Evet, DOS tabanlı pencereler gerçekten tuzağı yakalayabilmeli ve en azından uygulamayı kilitleyebilmelidir.
Asu

2
@Asu Bunun XP 32 bit üzerinde çalıştığını ve muhtemelen tüm 32 bit Windows sistemlerinde çalışacağını onaylayabilirim. Bunun çöktüğü için DOS’un kendisinde bir çözüm olmadığını kabul ediyorum.
Kasım’da

13

C (32 bit Windows), 34 bayt

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

Bu, yalnızca optimizasyon olmadan derleme yaparsa çalışır (başka bir deyişle, fişlevdeki geçersiz kod "optimize edilmiştir").

mainFonksiyonun sökülmesi şöyle görünür:

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

Bunun pushbir hazır değeri olan bir komut kullandığını görebiliriz 0b0f(küçük-endian, bu nedenle baytları değiştirilir). callTalimatı (bir dönüş adresi iter ...işlevi parametresi yakın yığında yer alan, talimat). Bir [-1]yer değiştirmeyi kullanarak , işlev dönüş adresini geçersiz kılar, böylece baytların olduğu yerde 9 bayt gösterir 0f 0b.

Bu baytlar, tasarlandığı gibi bir "tanımsız komut" istisnasına neden oluyor.


12

Java, 50 43 24 bayt

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

Bu, emir kabuğunun yanıtından çalınan bir java.util.function.Consumer<Runtime>1'dir . Eğer çünkü çalışır gerekir olarak diyoruz !whateverNameYouGiveIt.accept(Runtime.getRuntime())

Bunun yeni bir süreç yaratacağını ve SIGILL'in kendisini atmak yerine SIGILL'i atmasını sağlayacaktır.

1 - Teknik olarak, aynı zamanda bir olabilir java.util.function.Function<Runtime, Process>çünkü Runtime#exec(String)bir döner java.lang.Processsadece bir kabuk komutu yürüterek oluşturulan işlemi kontrol etmek için kullanılabilir olan.


Bu kadar ayrıntılı bir dilde daha etkileyici bir şeyler yapmak uğruna, işte 72 60 48 baytlık bir bonus:

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

Bu, Consumer<Runtime>TÜM süreçlerden (kendisi de dahil olmak üzere) geçen ve her birinin bir SIGILL atmasına neden olan başka bir şey. Şiddetli bir kaza için daha iyi bir destek.


Ve başka bir bonus (a Consumer<ANYTHING_GOES>en azından), süsü 20 bayt bir SIGILL atmak:

a->System.exit(132);

8

Perl, 9 bayt

kill+4,$$

Sadece bir süreci işaret etmek için uygun kütüphane işlevini çağırır ve programın kendisini işaret etmesi için program başlatır SIGILL. Burada hiçbir yasadışı talimat yoktur, ancak uygun sonucu verir. (Bence bu meydan okumayı oldukça ucuz kılıyor, ama eğer bir şeye izin verilirse, bu kullanacağın boşluktur ...)


Aynı göndermek için buraya geldi, yerine +. :)
simbabque

2
İnsanlar golf dışı programlama için Perl'i öğrendiğinde, bunu bir ile öğrenirler +. Bir süre golf oynadıktan sonra, +zaman zaman gösteriş yaparlar . Sonunda, nedense beyazlıktan kaçınmak için ihtiyaç duydukları yerlerde veya +alışkanlık haline gelebilecek kadar program yazdılar. (Aynı zamanda daha az belirsiz bir şekilde ayrıştırır, çünkü parantez için ayrıştırıcıdaki özel durumu tetikleme etrafında çalışır.)

8

ARM Birleşik Assembler Dili (UAL), 3 bayt

nop

Örneğin:

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

Çalıştırdıktan sonra nop, işlemci .ARM.attributesbölümü kod olarak yorumlar ve orada bir yerde yasa dışı bir talimatla karşılaşır:

$ 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

Ahududu Pi 3'te test edilmiştir.


Her nasılsa, bu bir Pi 2'de çalışmıyor.
Mega Man

7

Microsoft C (Visual Studio 2005 ve sonrası), 16 bayt

main(){__ud2();}

Bunu kolayca test edemiyorum, ancak belgelere göre , bir kullanıcı modu programından kasıtlı olarak yalnızca bir çekirdek komutu çalıştırmaya çalışarak yasadışı bir talimat üretmesi gerekiyor. (Yasadışı talimatın programa mainzarar vermesi nedeniyle , geri dönmeye çalışmamız gerekmediğine dikkat edin , bu K & R tarzı mainfonksiyonun geçerli olduğu anlamına gelir . Visual Studio, C89’dan hiç geçmemiş, normalde kötü bir şeydir, ancak burada yararlı.)


VS2015 ile Linux için derleme yapabilir misiniz? Çünkü SIGILL’in Windows’ta tanımlanmış olduğunu sanmıyorum, değil mi?
Andrew Savinykh

7

Ruby, 13 bayt

`kill -4 #$$`

Bunu bir * nix kabuğundan çalıştırdığımızı varsaymak güvenlidir sanırım. Backtick değişmezleri verilen kabuk komutunu çalıştırır. $$çalışan Ruby işlemidir ve #string enterpolasyonu içindir.


Doğrudan kabuğu çağırmadan:

Ruby, 17 bayt

Process.kill 4,$$

6

Herhangi bir kabuk (sh, bash, csh, vs.), herhangi bir POSIX (10 bayt)

Önemsiz bir cevap, ancak kimsenin postaladığını görmemiştim.

kill -4 $$

Sadece SIGILL'i mevcut işleme gönderir. OSX'te örnek çıktı:

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

Sen yapabileceği kill -4 1soru özgü değildir hakkında ise hangi programın SIGILL atar
Mark K Cowan

@MarkKCowan Heh, iyi bir nokta, her ne kadar kökü varsayarsa ...
kabarık

2
You will have root in your programs- Cevabınızı bir bayt vurmak ve aynı anda hafifçe soruyu troll: D. BONUS: Öldürmeye başladınızinit
Mark K Cowan

2
@MarkKCowan: Açık (? 'In modern sürümleri) Linux, initaslında, kök ile bile özel olarak almak istemediği sinyallerine karşı bağışıklık kazanmıştır . Yine de, farklı bir POSIX OS kullanarak bu sorunu çözebilirsiniz.

2
kill -4 2Öyleyse: D
Mark K Cowan,

6

ELF + x86 makine kodu, 45 bayt

Bu, SIGILL'i fırlatan bir Unix makinesindeki en küçük çalıştırılabilir program olmalıdır (Linux, daha küçük hale getirildiğinde çalıştırılabilir dosyayı tanımıyor olması nedeniyle).

Derleyin nasm -f bin -o a.out tiny_sigill.asm, x64 sanal makinesinde test edildi.

Gerçek 45 bayt ikili:

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

Montaj listesi (aşağıdaki kaynağa bakınız):

;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     $ - $$

Sorumluluk reddi: Bir numarayı döndürmek için en küçük derleme programını yazarken aşağıdaki kodu, ancak mov yerine ud2 kodunu kullanarak kodu: http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html


2
Bu öğretici yazının değiştirilmiş bir dosyasını yayınlayacaktım ama sen beni yendin. Bu kazanmayı hak ediyor; Sistem kaynakları anlamında gerçek bir minimalisttir (Hem dosya içi hem de hafıza içi en fazla 45 bayt gerektirir ve her ikisi de aynıdır) ve diğer assembler çözümleri gibi şişirilmiş bir tercüman yoktur. Sadece budur.
Iwotnotexist Idonotexist

5

AutoIt , 93 bayt

Flatassembler satır içi derlemesini kullanarak:

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

SciTE interaktif modunda çalıştırıldığında, hemen çökecek. Windows hata ayıklayıcısının bir saniyenin bir kısmıyla açılır. Konsol çıkışı şu şekilde olacak:

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

-1073741795WinAPI tarafından atılan tanımsız hata kodu nerede . Bu herhangi bir olumsuz sayı olabilir.

Kendi montajcı LASM kullanarak benzer :

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

5

NASM, 25 bayt

Bunun nasıl çalıştığını bilmiyorum, sadece bilgisayarımda tam olarak çalışıyor (Linux x86_64).

global start
start:
jmp 0

Derleme ve çalıştırma:

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

Muhtemelen dört byte olarak kısaltabilirsiniz,ja 0
Mark K Cowan

1
ya da üç olarakud2
Mark K Cowan

1
Muhtemelen bazı verilere atlamaya çalıştığından mı?
Asu

5

TI-83 Hex Meclisi, 2 bayt

PROGRAM:I
:AsmPrgmED77

Olarak çalıştır Asm(prgmI). Geçersiz 0xed77 işlem kodunu çalıştırır. Her onaltılık hane çiftini bir bayt olarak sayıyorum.



3

x86 .COM, 1 bayt

c

ARPL#UD16 bit modunda neden olur


1

Linux kabuğu, 9 bayt

kill -4 0

Gönderir SIGILLBen PID 0 neler süreç bilmiyorum PID 0. ile sürecine, ancak her zaman vardır.

Çevrimiçi deneyin!


Kimden man kill:0 All processes in the current process group are signaled.
Dennis,

1

GNU C, 24 19 18 bayt

-4 Dennis
-1 sayesinde ceilingcat sayesinde

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

Çevrimiçi deneyin! Bu, ASCII ve x86_64 olduğunu varsayar. 27Yasadışı olan makine kodunu çalıştırmaya çalışıyor .


shortC , 10 5 4 bayt

AV"'

Yukarıdaki GNU C koduna eşittir. Çevrimiçi deneyin!


L"\6"ayrıca x86_64 varsayımıyla da yasaktır.
Dennis,

@Dennis Hangi komut 0x06 nedir? Ayrıca, Lgerekli değildir.
MD XF

Atanmamış.
Dennis,

Atanmamış; yasadışı kılan şey budur. Ayrıca, 'bir 39 = 0x27 değil 0x39 .
Dennis,

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.