黒魔術の説明書
/**
* Copyright bkzen ( http://wonderfl.net/user/bkzen )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/kBvW
*/
// forked from bkzen's もっと禍々しくしてみた
// forked from Kaede's 禍々しい配列参照
package {
import flash.display.Sprite;
dynamic public class FlashTest extends Sprite {
public function FlashTest() {
// write as3 code here..
//({}[this.g = graphics,"beginFill"])(0)[this.g,"drawCircle"](100,100,100);
var $:*=this;
/*
【よくわかる解説】
まずは、これを人間がわかる言語に直すとこんな感じになる。
this["f"] = "constructor";
this["fa"] = this.graphics;
this["t"] = String.fromCharCode;
this["fa"].beginFill(0);
this["fa"].drawCircle(100, 100, 100);
最初の三行は後の二行を作るための準備です。
もう少し黒魔術に近づけるとこうなります。
0[this, "f"] = "constructor";
0[this, "fa"] = this["graphics"];
0[this, "t"] = ""["constructor"]["fromCharCode"];
0[this["fa"], "beginFill"](0)[this["fa"], "drawCircle"](100, 100, 100);
これらをどうやって作っているのかですが、「正規表現」を使い、文字列を生成します。
例えば、 /./("moja") と書いた場合、 返される値は "m" です。
ということは !{} は false なので /./(!{}) -> /./("false") となり "f" が取り出せるわけです。
false の a だけ取り出したい時はどうするのかといえば、
/.$/("fa") と 書いてやればいいので、 /.$/(/../(!{})) となります。
これで、文字単体はわかりました。
では、その連結はどうやっているのかですが、+ は使えないので E4X を使って各文字を連結します。
trace(<>{"m"}{"o"}{"j"}{"a"}</>); // moja
こんな感じです。
つまり constructor を作るには
[Object object] の c
[Object object] の o
null の n
false の s
true の tru
[Object object] の ct
[Object object] の o
true の r
をそれぞれ連結して作成します。
この constructor がかなり重要です。
これで 指定されたオブジェクトインスタンスのクラスオブジェクトまたはコンストラクタ関数への参照 を取得します。
そうすることで、Object や true false NaN null undefined 以外の文字列も取得できるわけです。(例えば RegExp など)
そのため、この文字列はよく使うことになります。(って事で this["f"] という使いやすい位置に登録しておきます。)
そして、今回はもうひとつ重要なことの為にこの constructor を使用します。
それは後ほど。
次は数字について。
実は0さえ作れてしまえば数字なんてなんとでもなるんです。
まずは、その無から有を作り出すための 0 を作りましょう。
勘のいい方は気付いていたと思いますが各行の一番最初の文字列
(~~([][{}])) が 0 です。
JavaScript では ~~[] と書けてしまいますが ActionScript3 ではコンパイルエラーになります。
その為一度、コンパイル時にはわからないものにしてあげて、それを数字に変換してあげれば、出来上がりです。
そのコンパイル時にはわからないものが [][{}] です。
これだけを trace すると undefined が出力されます。
配列の arr に対して arr["[Object object]"] とやってやると undefined が返ってきます。それと同じ原理です。
そして、"~" は ビット演算で出てくる bitwise NOT というものです。 これを使うことでビットを反転させます。
0 を反転すれば -1 になり、-1 を反転すれば 0 に戻ります。
undefined の前に ~ をつけ、 一旦数字にしてやります。ここで -1 になります。
そしてもう一度 ~ で 0 にして、 0 の完成です。
しかもこれで 0 と -1 の二つを作れる事になります。
+-* は使えないので ビット演算などを使い、これらを自由な数字にしていきますが、
まず簡単な数字のバリエーションの増やし方として -1<<-1 があります。
これで -2147483648 が出力されるので、残るは 5, 6, 9 だけです。
さて、一通りの作り方がわかったところで実際読んで見ると・・・
気付くことがあると思います。
"h" という文字列がズルい取得しかたをしていることに。
こういう取り方をしているが為 FlashTest のように /.*h..../ のようなクラス名じゃないとできません。
というのもこの "h" という文字列、よく使うくせに見当たらないんです・・・。(見つけたよ!って人が居たら教えてください。)
"h" さえ作れてしまえば、String.fromCharCode で文字列なんて数字から作れるようになります。
この String.fromCharCode を仕様するためには文字列のクラスオブジェクトにアクセスしなければなりません。
そこで先ほどの constructor が生きてくるわけです。
""(文字列)に対して["constructor"] でクラスにアクセスすれば String クラスが取得できます。
そして、これもよく使うので使いやすい this["t"] に登録しておきます。
実際今回も drawCircle の w 等はこれを使って作っています。
(w の Unicode は 119 なので <>{1}{1}{8|1}</> で作っています。)
さあ。重要なことは全て話し終えました。
今日からあなたも黒魔術師です!
あとは、あなたの思うがままに!
*/
(~~([][{}]))[$,/./(!{})]=<>{/./(/.. /({}))}{/.$/(/../({}))}{/./(/./([]))}{/./(/..$/(!{}))}{/.../(!!{})}{/../(/.. /({}))}{/.$/(/../({}))}{/.$/(/../(!!{}))}</>;
(~~([][{}]))[$,/../(!{})]=$[<>{/.$/(/ .../(/./[$[/./(!{})]]))}{/.$/(/../(!!{}))}{/.$/(/../(!{}))}{/./(/..$/(/./[$[/./(!{})]]))}{/./(/......$/($[$[/./(!{})]]))}{/./(/....$/([][{}]))}{/./(/.. /({}))}{/./(/..$/(!{}))}</>];
(~~([][{}]))[$,/./(!!{})]=(""[$[/./(!{})]][<>{/./(!{})}{/.$/(/../(!!{}))}{/.$/(/../({}))}{/.$/(/ .../((~([][{}]))[$[/./(!{})]]))}{/.$/(/ ./([][$[/./(!{})]][$[/./(!{})]]))}{/./(/......$/($[$[/./(!{})]]))}{/.$/(/../(!{}))}{/.$/(/../(!!{}))}{/.$/(/ ./([][$[/./(!{})]][$[/./(!{})]]))}{/.$/(/../({}))}{/.$/([][{}])}{/.$/(!{})}</>]);
(~~([][{}]))[$[/../(!{})],<>{/.$/(/.../({}))}{/.$/(!{})}{/.$/(/ .../(/./[$[/./(!{})]]))}{/./(/....$/([][{}]))}{/./(/./([]))}{/.$/(/ ./($[$[/./(!{})]]))}{/./(/....$/([][{}]))}{/..$/(/./([]))}</>](~~([][{}]))[$[/../(!{})],<>{/.$/([][{}])}{/.$/(/../(!!{}))}{/.$/(/../(!{}))}{$[/./(!!{})](<>{/.$/(~([][{}]))}{/.$/(~([][{}]))}{/.$/(~([][{}])<<~([][{}]))|/.$/(~([][{}]))}</>)}{/.$/(/ ./([][$[/./(!{})]][$[/./(!{})]]))}{/./(/....$/([][{}]))}{/.$/(/../(!!{}))}{/./(/.. /({}))}{/.$/(/./([]))}{/.$/(!{})}</>](<>{/.$/(~([][{}]))}{~~([][{}])}{~~([][{}])}</>,<>{/.$/(~([][{}]))}{~~([][{}])}{~~([][{}])}</>,<>{/.$/(~([][{}]))}{~~([][{}])}{~~([][{}])}</>)
}
}
}