SIGILLをスローする最短コード


76

バックグラウンド

すでにSIGSEGVを投げることに挑戦していますので、なぜSIGILLを投げることに挑戦しませんか?

SIGILLとは

SIGILLは、非常にまれにしか発生しない、プロセッサでの不正な命令のシグナルです。SIGILLを受け取った後のデフォルトのアクションは、プログラムを終了し、コアダンプを書き込むことです。SIGILLのシグナルIDは4です。SIGILLに遭遇することは非常にまれであり、経由でコードを生成する方法はまったくわかりませんsudo kill -s 4 <pid>

ルール

プログラムにはroot権限がありますが、何らかの理由で必要ない場合は、通常のユーザーを使用することもできます。私はドイツ語ロケールのLinuxコンピューターで、SIGILLをキャッチした後に表示される英語のテキストを知りませんが、「違法な命令」のようなものだと思います。SIGILLをスローする最短のプログラムが勝ちます。


6
命令をカーネルによって生成する必要があるかどうかを明確にしたい場合があります。特に、プログラムがlibc呼び出しを使用して直接生成することを許可しますraise(SIGILL)か?

1
それは本当に言うIllegal instruction (core dumped)
エリックアウトゴルファー

@ ais523すべてが許可されています。
メガマン

5
SIGILLを発生させるハードウェアの場合、答えは命令の長さと同じになります。ただどこかに違法な命令を置き、それを実行しようとします。興味深いのは、複雑なツールチェーンのみです。
-OrangeDog

3
*人々が持っていた古いプログラムを投稿しましたが、機能しませんでした*
RudolfJelin

回答:


112

PDP-11アセンブラー(UNIX第6版)、1バイト

9

命令9は、PDP-11で有効な命令では000011ありません(8進数では、命令のリスト(PDF)には表示されません)。UNIX Sixth Editionに同梱されているPDP-11アセンブラーは、理解できないものをすべてファイルに直接エコーするようです。この場合、9は数値であるため、リテラル命令9を生成します。また、ファイルが最初から実行を開始するという奇妙なプロパティ(今日のアセンブリ言語では珍しい)があるため、プログラムを作成するための宣言は必要ありません作業。

このエミュレータを使用してプログラムをテストすることができますが、プログラムを入力するためにいくらか戦う必要があります。

ファイルシステム、エディター、ターミナルなど、使用方法を既に知っていると思われるものを使用する方法を理解した後、次のようになります。

% a.out
Illegal instruction -- Core dumped

私は、これが本物のSIGILL信号であることをドキュメントで確認しました(そして、それは同じ信号番号、4さえもずっと持っていました!)


1
POSIXとUNIXおよびSUSは密接に関連しているため、信号番号は同じでした:)
cat

4
V6のほとんどすべての信号番号は、現在でも同じ意味を持っています。ニーモニックは、実際には数字よりも安定していません。比較minnie.tuhs.org/cgi-bin/utree.pl?file=V6/usr/sys/param.hをしてgithub.com/freebsd/freebsd/blob/master/sys/sys/signal.h -のために、同一の意味を1から13ですが、1、2、および13のみがまったく同じ名前を持っています。(SIGALRM / 14およびSIGTERM / 15はV7でのみ追加されました。)(System V系統にはいくつかの変更があり、特にSIGBUSを10から7(役に立たないSIGEMTを置き換える)に移動し、SIGUSR1およびSIGUSR2。)
zwol

4
@cat POSIXとSUSは、実際にはシグナルの値を指定しません。killコマンドに引数として渡されるときにいくつかの数値の意味を指定しますが、SIGILLは含まれません。
Random832

7
a.out実際、複数のバイトが含まれています(9命令は2バイトにコンパイルされ、アセンブラはヘッダーとフッターも追加してプログラムを実行可能にします)。そのため、プログラムをマシンコードではなくアセンブリ言語で記述しました。アセンブリ言語プログラムには1バイトのみが含まれ、より多くのバイトを含むプログラムにコンパイルされます。これはコードゴルフの問題(ソースのサイズを最小化)であり、サイズコーディングの問題(実行可能ファイルのサイズを最小化)ではないため、重要なのはソースの1バイトサイズです。

2
古いが素晴らしいシステムの非常に巧妙な乱用。
マスト

81

C(x86_64、tcc)、7バイト

main=6;

この答えに触発されました

オンラインでお試しください!

使い方

生成されたアセンブリは次のようになります。

    .globl  main
main:
    .long 6

TCCは、定義された「関数」をデータセグメントに配置しないことに注意してください。

コンパイル後、_startは通常どおりmainを指します。結果のプログラムが実行されると、main内のコードが予期され、0x06 0x00 0x00 0x00としてエンコードされたリトルエンディアン(!)32ビット整数6が検出されます。最初のバイト– 0x06 –は無効なオペコードであるため、プログラムはSIGILLで終了します


C(x86_64、gcc)、13バイト

const main=6;

オンラインでお試しください!

使い方

const修飾子を使用しない場合、生成されるアセンブリは次のようになります。

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

GCCのリンカーは、最後の行を、生成されたオブジェクトが実行可能スタックを必要としないというヒントとして扱います。以来、主に明示的に配置され、データセクション、それに含まれる命令コードは、実行可能ではないので、プログラムは終了しますがSIGSEGV(セグメンテーションフォールト)。

2行目または最後の行を削除すると、生成された実行可能ファイルが意図したとおりに機能します。コンパイラフラグ-zexecstackオンラインで試してみてください!)を使用すると、最後の行を無視できますが、これには12バイトかかります

より短い代替方法は、const修飾子を使用してmainを宣言し、次のアセンブリを作成することです。

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

これは、コンパイラフラグなしで機能します。main=6;定義された「関数」をdataに書き込むことに注意してくださいが、const修飾子はGCCに代わりにrodataに書き込みます。これは(少なくとも私のプラットフォームでは)コードを含めることができます。


関数を使用することさえ完全に回避するのが大好きです:) コンパイラーはそれmainが6であると認識し、それを呼び出そうとしますか?
ミアユンルセ

11
@JackDobsonは未定義の動作なので、Cの観点では機能しません。あなたはコンパイラの慈悲にかかっています。Clangには、何らかの理由で「外部リンケージを持つ 'main'という名前の変数の動作は未定義です」という警告があります。
ボビーSacamano

2
GCCはmain、機能ではないという警告を出しますが、警告をオンにした場合のみです(どちらか-Wallまたはそれ-pedanticを行います)。
zwol

Unixライクなシステムの実行可能ファイルがtext / data / bss セグメントを持つのはかなり標準だと思います。リンカーは、実行可能ファイルのテキストセグメント内に.rodata セクションを配置します。これは、ほとんどすべてのプラットフォームで当てはまると思います。(カーネルのプログラムローダーは、セクションではなくセグメントのみを考慮します)。
ピーターコーデス

3
また06、x86-64では無効な命令にすぎないことに注意してください。32ビットモードではであるPUSH ESため、この回答は、デフォルトがのコンパイラでのみ機能します-m64ref.x86asm.net/coder.html#x06を参照してください。将来のすべてのx86 CPUで不正な命令としてデコードされることが保証されている唯一のバイトシーケンスは、2バイトUD2です0F 0B。それ以外のものは、将来の接頭辞または命令エンコーディングになる可能性があります。それでも、Cコンパイラmainにいくつかのバイトにラベルを付けるクールな方法を支持しました!
ピーターコーデス

39

Swift、5バイト

[][0]

空の配列のインデックス0にアクセスします。これはを呼び出しfatalError()、エラーメッセージを出力し、SIGILLでクラッシュします。 ここで試してみることができます


これはトリッキーなものの1つです;)
メガマン

26
...なぜ地球上でSIGILLでクラッシュするのですか?誰がそれが適切なシグナルだと思いましたか?流血のヒップスター:D
ミューザー

4
@Asuいいえ; fatalError()を実行して意図的にクラッシュしますud2。私が知らないことを彼らが選んだ理由は、プログラムが違法なことをしたため、「違法な命令」というエラーメッセージが意味をなすと考えたのかもしれません。
NobodyNada

2
ブリリアント。これはクラッシュを引き起こす最短のSwiftコードでもあるに違いありません。
JAL

3
@JALうん。これより短いものは考えられません。試しましたnil!が、コンパイラは結果の型を推測できませんでした。(また、こんにちはJAL!)
NobodyNada

23

GNU C、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 Intelが常に未定義のままにすることを保証する命令です。


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

また、私たちは生の組み立てのためのバイトを数える方法を知りませんが、00 00 0f 0bための機械語はあるud2...
wchargin

5
@wchargin:それはx86 + GNU Cの答えです。これはすべてのGNUシステムに移植可能です。また、UD2は2バイトしかないことに注意してください。これらの00バイトを取得したIDK 。UD2のマシンコードの一部ではありません。ところで、デニスの答えについてコメントしたように、x86-64には今のところ1バイトの違法な命令がありますが、そのようにとどまる保証はありません。
ピーターコーデス

@wchargin:マシンコード関数/プログラムのバイト数を期待どおりにカウントします。32バイトのx86-64マシンコードのAdler32、8バイトのx86-32マシンコードのGCDなど、私の回答をご覧ください。
ピーターコーデス

1
@Ruslan:そうではありません。00 00x86-64で同じものを(としてadd [rax], al)デコードします。 00 00 0f 0bに書き込み可能なポインターがあった場合を除き、通常はSIGILLの前にSIGSEGVになりますrax
ピーターコーデス

22

C(x86_64)、11、30、34、または34 + 15 = 49バイト

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

ライブラリ関数を使用しSIGILLてさまざまな手段でスローするいくつかのソリューションを提出しましたが、ライブラリ関数が問題を解決するという点で、おそらく不正行為です。ライブラリ関数を使用せず、オペレーティングシステムが非実行コードの実行を許可する場所についてさまざまな仮定を立てるさまざまなソリューションを以下に示します。(ここでの定数はx86_64用に選択されていますが、違法な命令を持っている他のほとんどのプロセッサー用の有効なソリューションを取得するために変更できます。)

06x86_64プロセッサで定義された命令に対応しないマシンコードの最小番号のバイトです。実行するだけです。(または、2F未定義であり、単一の印刷可能なASCII文字に対応します。)これらのどちらも常に未定義であることが保証されていませんが、今日では定義されていません。

最初のプログラムは2F、読み取り専用のデータセグメントから実行されます。ほとんどのリンカは、正しくセグメント化されたプログラムで有用なものではない.textため、.rodata(またはそれらのOSに相当する)からの機能的なジャンプを生成できません。これが動作するオペレーティングシステムはまだ見つかりません。また、多くのコンパイラが問題の文字列をワイド文字列にしたいという事実を考慮しなければなりません。L; 私は、これが動作するオペレーティングシステムは物事についてかなり時代遅れの見方をしており、したがってデフォルトでC94以前の標準のために構築されていると想定しています。このプログラムが機能する場所は存在しない可能性がありますが、このプログラムが機能している場所も存在する可能性があります。そのため、このプログラムをより疑わしいものから疑わしいものへの潜在的な回答のコレクションにリストしています。(この回答を投稿した後、デニスmain[]={6}はチャットの可能性についても言及しました。これは同じ長さであり、文字幅の問題に遭遇せず、潜在的な可能性を示唆さえしましたmain=6;これらの答えを合理的に主張することはできません私自身は考えていなかったので)

ここの2番目のプログラムは06、読み取り/書き込みデータセグメントから実行されます。ほとんどのオペレーティングシステムでは、書き込み可能なデータセグメントは悪用される可能性のある設計上の欠陥であると見なされるため、セグメンテーションエラーが発生します。ただし、これは常にそうとは限らないため、おそらく十分に古いバージョンのLinuxで動作しますが、簡単にテストすることはできません。

3番目のプログラムは06スタックから実行されます。繰り返しになりますが、スタックは通常、セキュリティ上の理由で書き込み不可として分類されているため、これにより、最近ではセグメンテーション違反が発生します。私が見たリンカのドキュメントは、スタックから実行することが以前は合法だったことを暗示しています(前の2つのケースとは異なり、そうすることは時々有用です)ので、私はそれをテストすることはできませんが、いくつかがあると確信していますこれが機能するLinux(およびおそらく他のオペレーティングシステム)のバージョン。

最後に、-Wl,-z,execstack(バックエンドの一部としてgccGNU ldを使用する場合)に(15バイトのペナルティ)を与えると、実行可能スタック保護が明示的にオフになり、3番目のプログラムが動作し、予想どおりに違法な操作信号が与えられます。この49バイトバージョンが動作することテストおよび検証しました。(Dennisはチャットでこのオプションmain=6が6 + 15のスコアを与えると思われると述べています。6が露骨にスタック上にないことを考えると、これが機能することはかなり驚いています。リンクオプションは明らかにその名前が示唆している。)


xcc-64 / linuxでgcc6をデフォルト(寛大)モードで使用const main=6;すると、いくつかのバリエーションが機能します。このリンカ(あなたのリンカでもあると思われます)、から.textへのジャンプを生成でき.rodataます。あなたが抱えていた問題は、なしconstでは、書き込み可能なデータセグメント(.data)にジャンプしているということです。メモリ保護ハードウェアがページを読み取り可能だが実行不可能としてマークできなかった古いx86で機能していました。
zwol

C89でもmain、関数である必要があることに注意してください(§5.1.2.2.1)-gcc mainがデータオブジェクトとして宣言することを警告するに値するだけで-pedanticコマンドラインでのみ考慮する理由を私は知りません。1990年代前半に戻った人は、おそらく偶然に誰もそれをしないだろうと考えていたかもしれませんが、この種のゲームを除いて、意図的に行うのが有用なことではありません。
zwol

1
...もう一度main[]="/"読み直すと、文字列リテラルがrodataに格納されるため、読み取り専用のデータセグメントにジャンプすることが予想されます。char *foo = "..."との違いに気づきましたchar foo[] = "..."char *foo = "..."以下のための糖衣構文があるconst char __inaccessible1[] = "..."; char *foo = (char *)&__inaccessible1[0];ので、文字列リテラルはrodataに行く、とんfoo別のことを指して、書き込み可能なグローバル変数。ではchar foo[] = "..."、しかし、全体の配列は、書き込み可能なデータセグメントになります。
zwol

19

GNU as(x86_64)、3バイト

ud2

$ xxd sigill.S

00000000: 7564 32                                  ud2

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

sigill:     file format elf64-x86-64

Disassembly of section .text:

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

...「ソース」2バイトでそれを表現する方法があるに違いありません
OrangeDog

ああ、賢い。ファイルの先頭にエントリポイントを置き(宣言なし)、通常とは異なるビルドシステム構成でペナルティを受けない、これをビルドする方法があるかどうか疑問に思っていました。見つけられませんでしたが、あなたが見つけたようです。

@ ais523:ええ、単一ファイルのおもちゃプログラム用の私の通常のNASM / YASM build-script(asm-linkは、このソースから同じ方法で実行可能ファイルを構築しますld。私はこの1つだけのASMソースの大きさのために行くことを考えていませんでした:P
ピーター・コルド

18

QEMU上のRaspbianのBash、4(1?)バイト

私の仕事ではありません。私は単に他の人の仕事を報告するだけです。私は主張をテストする立場にさえありません。この課題の重要な部分は、このシグナルが発生してキャッチされる環境を見つけることであると思われるため、QEMU、Raspbian、またはbashのサイズは含めません。

2013年2月27日午後8時49分、ユーザーemlhalacは、Raspberry Piフォーラムで「chrootしようとすると「違法な指示」を取得する」と報告しました。

ping

生産

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

たとえば、はるかに短いコマンドでこの出力が生成されると思いますtr

編集:@fluffyのコメントに基づいて、入力長の推測される下限を「1?」に減らしました。


5
[コマンドが勝つと思います。:)
ふわふわ

17

x86 MS-DOS COMファイル、2バイト

編集:コメントで指摘したように、DOS自体はCPU例外をトラップせず、単にハングします(アプリだけでなく、OS全体)。実際、Windows XPなどの32ビットNTベースのOSで実行すると、不正な命令信号がトリガーされます。

0F 0B

ドキュメントから:

無効なオペコードを生成します。この命令は、無効なオペコードを明示的に生成するソフトウェアテスト用に提供されています。

これはかなり自明です。.comファイルとして保存し、DOSエミュレーターで実行する DOSエミュレーターはクラッシュします。Windows XP、Vista、または7 32ビットで実行します。

Windows XPのSIGILL


1
技術的には、プロセッサが不正な命令例外を生成します。ただし、DOSのメモリ保護と例外処理機能は非常に限られているため、未定義の動作やOSクラッシュにつながるだけで驚かないでしょう。OPは、カーネルがエラーをキャッチし、「不正な命令」をコンソールに出力する必要があるとは言いませんでした。
下僕

4
私はこの解決策を考えましたが、それが有効だとは思いません。問題は、不正な命令プロセッサトラップだけでなく、不正な命令信号を必要とするため、その目的は、トラップに応答して実際に信号を生成するオペレーティングシステムを見つけることでした。(また、実際にテストすることにし、DOSエミュレーターを無限ループに陥れたようです。)#UD

2
AMD K6-II上の実際のMS-DOSでこれをテストしました。これを実行すると、EMM386を実行している場合と実行していない場合の両方でシステムがハングします。(EMM386はいくつかのエラーをトラップし、メッセージでシステムを停止します。そのため、違いが生じるかどうかをテストする価値がありました。)
Mark

2
はい、DOSベースのウィンドウは本当にトラップをキャッチし、少なくともアプリをクラッシュさせることができるはずです。
明日

2
@AsuこれはXP 32ビットで動作し、おそらく他のすべての32ビットWindowsシステムで動作することを確認できます。クラッシュするだけなので、これはDOS自体の解決策ではないことに同意します。
下僕

13

C(32ビットWindows)、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]ディスプレイスメントを使用することにより、関数は戻りアドレスをオーバーライドして、バイト0f 0bが存在する9バイト前を指すようにします。

これらのバイトにより、設計どおりに「未定義命令」例外が発生します。


12

Java、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)、aで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バイトのSIGILLをスローするふりをする別のボーナス(a ):

a->System.exit(132);

8

Perl、9バイト

kill+4,$$

プロセスを通知するために適切なライブラリ関数を呼び出すだけで、プログラムがを使用して自身に通知するようにしSIGILLます。ここには実際の違法な指示は含まれていませんが、適切な結果が得られます。(これにより、チャレンジはかなり安くなると思いますが、許可されている場合は、これが使用する抜け穴です…)


ここに来て、の代わりにスペースを入れて同じものを投稿しました+。:)
シンバク

2
ゴルフ以外のプログラミングでPerlを学ぶときは、で学習し+ます。しばらくゴルフをした後、彼らは+時々自慢する。最終的に、何らかの理由で+習慣になる空白を避けるために必要なプログラムを十分に作成しました。(また、括弧のパーサーで特殊なケースをトリガーすることで動作するため、曖昧さを軽減します。)

8

ARM Unified Assembler Language(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

Raspberry Pi 3でテスト済み。


どういうわけか、これはパイ2上では動作しません
ロックマン

7

Microsoft C(Visual Studio 2005以降)、16バイト

main(){__ud2();}

これを簡単にテストすることはできませんが、ドキュメントによるとユーザーモードプログラムからカーネルのみの命令を意図的に実行しようとすることにより、違法な命令を生成するはずです。(違法な命令がプログラムをクラッシュさせるため、mainこのK&Rスタイルのmain関数が有効であることを意味するから戻るように試みる必要がないことに注意してください。ここで便利です。)


VS2015でLinux用にコンパイルできますか?SIGILLはWindowsで定義されているとは思わないのですか?
アンドリューサビニク

7

ルビー、13バイト

`kill -4 #$$`

これを* nixシェルから実行していると仮定するのは安全だと思います。バックティックリテラルは、指定されたシェルコマンドを実行します。$$は実行中のRubyプロセスであり、#文字列補間用です。


シェルを直接呼び出さずに:

ルビー、17バイト

Process.kill 4,$$

6

シェル(sh、bash、cshなど)、POSIX(10バイト)

些細な答えですが、誰も投稿していません。

kill -4 $$

SIGILLを現在のプロセスに送信するだけです。OSXでの出力例:

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

どのプログラムがSIGILLをスローするかkill -4 1についての質問が具体的でない場合に行うことができます
マークKコーワン

@MarkKCowan Heh、良い点、それはルートを前提としていますが...-
ふわふわ

2
You will have root in your programs-回答から1バイトをノックして、質問を少しずつトロールします:D。ボーナス:殺すinit
マークKコーワン

2
@MarkKCowan:Linux(の最新バージョン?)では、init実際には、たとえルートであっても、受信するように特に要求されていない信号には影響されません。ただし、別のPOSIX OSを使用してこの問題を回避することもできます。

2
kill -4 2その後:D
マークKコーワン

6

ELF + x86マシンコード、45バイト

これは、SIGILLをスローするUnixマシン上で最小の実行可能プログラムである必要があります(これより小さくすると、Linuxが実行可能ファイルを認識しないため)。

でコンパイルし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バイト以下で、両方でまったく同じです)、他のアセンブラソリューションのような肥大化したインタプリタはありません。それは単にそれが何であるかです。
Iwillnotexist Idonotexist

5

AutoIt、93バイト

flatassemblerインラインアセンブリの使用:

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

SciTEインタラクティブモードで実行すると、すぐにクラッシュします。Windowsデバッガーは数秒間ポップアップします。コンソール出力は次のようになります。

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

NASM、25バイト

これがどのように機能するかはわかりませんが、私のコンピューター(Linux 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

あなたは、おそらくとして、4バイトに、それを短縮することができますja 0
マーク・K・コーワン

1
または3つud2
マークKコーワン

1
おそらく、何らかのデータにジャンプしようとしているからでしょうか?
明日

5

TI-83六角アセンブリ、2バイト

PROGRAM:I
:AsmPrgmED77

として実行しAsm(prgmI)ます。不正な0xed77オペコードを実行します。16進数の各ペアを1バイトとしてカウントします。



3

x86 .COM、1バイト

c

ARPL#UD16ビットモードでの原因



1

GNU C、24 19 18バイト

-4デニスの
おかげで-1シーリングキャットのおかげで-1

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

オンラインでお試しください!これは、ASCIIおよびx86_64を想定しています。マシンコードを実行しようとしますが27、これは違法です。


shortC10 5 4バイト

AV"'

上記のGNU Cコードと同等です。オンラインでお試しください!


L"\6"x86_64を想定した場合も違法です。
デニス

@Dennis 0x06とはどのような命令ですか?また、Lは必要ありません。
MD XF

割り当てられていません。
デニス

割り当てられていません。それが違法です。また、'ある=は0x27 39、ないます。0x39
デニス

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.