難読化された Perl を理解するためのステップ 1: 実行します-MO=Deparse
。次に、次の出力が得られます: (小さな構文エラーが削除されています)
use warnings;
use strict;
my($japh, $q, $qq, %b) = "Just another Perl hacker\n";
$_ = join('', (1045737470, 21650696, 478656270, 205562730, 602861636, 965627100));
s/9/f/;
s/9/b/;
$q = $_;
*9 = sub {
$japh = '';
print $japh;
}
;
map {m{^((?i)(?#q#;
print \$japh;#()[^
for (my $(b) = 1; $(b) < $(q); \$b++;) {
/g])+[\](^.^)\[
}
]*$}x ? do {
$qq = ord($_) - 96 . (~~%b - $?);
$/ = $+;
$q =~ s[$qq][$/]g
} : 9->({});} 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z';
$qq = [$q, %b];
$\ = pack('h*', '' . $$qq[0]);
9->();
まだきれいではありませんが、より良いです。特に、次の正規表現は興味深いものです。
m{^((?i)(?#q#;
print \$japh;#()[^
for (my $(b) = 1; $(b) < $(q); \$b++;) {
/g])+[\](^.^)\[
}
]*$}x
は(?# ... )
埋め込みコメントで、削除できます。次は文字クラス
[^
for (my $(b) = 1; $(b) < $(q); \$b++;) {
/g]
と
[\](^.^)\[
}
]
[^bfgmoqry]
ここでは、それらはおよび と同等です[\[\]()^.}\s]
が、正規表現は単一の文字に対してのみ一致するため、[...]*
はゼロ文字と一致します。
したがって、正規表現は次と同等です
m/^([^bfgmoqry])$/
この特別な場合( に対して照合され"a" .. "z"
ます)。
*9 = sub {...}
コードリファレンスをグロブに割り当てます。9
は有効なサブルーチン名ではありませんが、->
演算子で使用できるため、その coderef を呼び出し9->()
ます。これは と同じでsub foo {...}
、foo()
と"foo"->()
は同じものです。
charはASCII のようにa
10 進数としてエンコードされるため、 の場合は 26 になります。97
ord("a")-96
1
z
は$?
最後の子エラーであり、ゼロである必要があります。$+
は最後のキャプチャ グループの値です (ergo, $_
)。空の~~%b
ハッシュを二重否定します。空のハッシュのスカラー化は0
であるため、ビットごとの二重否定は再びゼロを生成します。
これ$/ = $+; $q =~ s[$qq][$/]g
はちょっとした難読化です。そのまま、直接書くこと$+
が$_
できます$q =~ s/$qq/$_/g
。
は$qq = [$q, %b]; ... $$qq[0]
不自由ですが、$\ = pack('h*', $q)
十分です。
サブでは、空の文字列が出力され、最後から 2 番目の行まで空の文字列に設定される が9
続きます。$\
このレベルの間接化、現在使用されていない変数、および単純な置換を削除すると、次のようになります。
use warnings;
use strict;
my $q = '1045737470216506f6478656270205562730602861636b65627100';
for ("a" .. "z") {
m/^([^bfgmoqry])$/ or next;
my $qq = ord($_) - 96;
$q =~ s/${qq}0/$_/g;
}
print pack('h*', $q);
置換はゼロでのみ一致するs/${qq}0/$_/g
可能性があり、出力がpack
. マッチングの可能な位置は次のとおりです。
1045737470216506f6478656270205562730602861636b65627100
*^ *^ *^ *^*^ *^*^ *^^
a g e g b c f a
正規表現によりb, f, g
禁止されています。結果の文字列は
a45737470216e6f64786562702055627c602861636b65627a0
これはJAPHにデコードされます。