プログラムが変異しているかどうかを検出する


16

エラーなしで終了するプログラムを作成します。

単一のバイトが他のバイトで置き換えられた場合、プログラムは出力する必要があります

CORRUPTED
  • ファイルからソースコードを読み取らないでください
  • プログラムは他の出力を生成しないはずです

これはので、バイト単位の最短回答が勝ちです。

編集:「破損していない」要件を削除


放射線硬化には多くの同様の質問がありますが、私はこのような質問をまったく見つけていません。
FryAmTheEggman

7
ダウンボッターへ:適切な言語を選択すれば、これは可能です(非常に難しい場合)。不可能である以外に何か問題があると思わない限り、質問を閉じたり削除したりしないでください。

7
変更とはどういう意味ですか?別のバイトで置き換えられますか?
デニス

4
@ ais523 FWIW難易度が高すぎると思うからではなく、急いで書かれているように見えるので、私はこの挑戦を断念しました。
デニス

5
何も不明なことではありませんが、より明確にすることができます。完全なプログラムが必要かどうかを明確にし、サンプルプログラムを追加し、可能なすべての変更を示し、シングルバイト置換がUTF-8エンコードファイルにどのように影響するかを述べ、提出物のテストに使用できるスクリプトを追加し、プログラムに言及しますなど、入力を取るべきではない
デニス・

回答:


30

梨の木、76バイト

$@='NOT ';print"$@CORRUPTED"__DATA__ =®®”print"$@CORRUPTED"__DATA__ =®®”Ê®›~

このプログラムには、有効なUTF-8ではないいくつかの浮遊オクテットが含まれています。そのため、Windows-1252のように表示されます。(デフォルトでは、Pear Treeが文字列リテラルなどでASCII以外のオクテットを検出した場合、不透明なオブジェクトとして扱い、その文字コードが何であるかを認識している以上に理解しようとはしません;この動作はエンコード宣言を介して変更されましたが、プログラムにはありません。したがって、プログラムは論理的に「指定されていないASCII互換文字セット」です。非ASCIIオクテットはすべてコメントにあるため、実際には問題ではありません。)

説明

Pear Treeはプログラムをチェックサムし、CRC-32がの最も長い部分文字列を探し00000000ます。(同点の場合は、最初にオクテットを選択します。)その後、プログラムが回転して開始位置に配置されます。最後に、プログラムはほとんどPerlのスーパーセットである言語として解釈され、Perlで未定義のいくつかのことをPythonと同じように動作するように定義します(いくつかの小さな変更を加えて、たとえばprintA Pear Treeしかし、Perlではそうではありません)。このメカニズム(および言語全体)は、および問題用に設計されました。これは前者ではありませんが、間違いなく後者です。

このプログラムでは、CRC-32に2つの注目すべき部分文字列があり00000000ます。プログラム全体がそうであり、プログラムprint"$@CORRUPTED"__DATA__ =®®自体もそうです(2回表示されます)。そのため、プログラムが破損していない場合は、に設定$@NOT てから印刷し、その後にを続けCORRUPTEDます。プログラムが破損している場合、プログラム全体のCRC-32は一致しませんが、短いセクションの1つは破損しません。どちらがプログラムの先頭まで回転しても、null文字列とCORRUPTED同様に印刷され$@ます。

文字列が印刷さ__DATA__れると、プログラムの残りが実行されないようにするために使用されます。(__END__代わりに使用できるこれを書くと、2バイトを節約することができます。しかし、私はそれを検証するのに多くの時間を費やし、変更されたバージョンはCRCの変更により再検証されました。「ペイロード」のゴルフにはまだ大きな労力を費やしていませんので、同時に組み込むことができるコメントに他の改善点があるかどうかを確認したいと思います。#文字が改行に破損している状況では機能しないことに注意してください。)

そもそもどうやってコードのCRC-32を制御したのか不思議に思うかもしれません。これは、CRC-32の定義方法に基づいた非常に単純な数学的トリックです。コードのCRC-32を取得し、リトルエンディアン順(CRC-32計算で通常使用されるバイト順の逆)で記述します。プログラム)、およびとのXOR 9D 0A D9 6D。次に、それをプログラムに追加すると、CRC-32が0のプログラムが作成されます(可能な限り簡単な例として、NULL文字列のCRC-32は0なので、9D 0A D9 6DCRC-32も0です。 )

検証

Pear Treeは、ほとんどの種類の突然変異を処理できますが、「変更された」とは「任意のオクテットに置き換えられた」ことを意味すると想定しています。理論的には(この短いプログラムでは考えられないことですが)ハッシュ衝突がどこかで間違ったプログラムの実行につながる可能性があるため、オクテット置換が可能なすべてのプログラムが正常に動作することをブルートフォースで確認する必要がありました。これが、私が使用した検証スクリプト(Perlで記述された)です。

use 5.010;
use IPC::Run qw/run/;
use warnings;
use strict;
undef $/;
$| = 1;
my $program = <>;
for my $x (0 .. (length $program - 1)) {
    for my $a (0 .. 255) {
        print "$x $a    \r";
        my $p = $program;
        substr $p, $x, 1, chr $a;
        $p eq $program and next;
        alarm 4;
        run [$^X, '-M5.010', 'apeartree.pl'], '<', \$p, '>', \my $out, '2>', \my $err;
        if ($out ne "CORRUPTED\n") {
            print "Failed mutating $x to $a\n";
            print "Output: {{{\n$out}}}\n";
            print "Errors: {{{\n$err}}}\n";
            exit;
        }
    }
}

say "All OK!    ";

N CRCは任意の単一誤りを検出するビットはnよりビット長くない破裂しました。与えられたケースではハッシュ衝突は不可能であり、総当たり検証の必要はありません。
Rainer P.

@RainerP .:私は、変異が元々0のCRCマッチングを持っている部分のCRCを防ぐことを知っています。ただし、CRCが0であるコードの新しいサブストリングを導入する可能性があります。総当たり攻撃の目的は、それが起こらなかったことを保証することです。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.