1. ホーム
  2. javascript

[解決済み] JavaScriptの組み込み文字列は何ですか?

2022-05-10 08:55:18

質問

この質問は、質問のタイトルで要約するのは難しいです。

アップデイト この質問から抽出された文字をもとに、入力から難読化された文字列を構築するJSFiddleを作成しました。あなたはそれにアクセスすることができます ここから または 要 旨 の方が簡単でしょうか?

私は最近、難読化されたJavaScriptの楽しいビットに出会いました。 このプロファイル で、こんな感じの難読JavaScriptを見つけました。

javascript:[[]+1/!1][1^1][1>>1]+({}+[])[1<<1^11>>1]+([]+!!-
[])[1<<1]+[/~/+{}][+!1][-~1<<1]+([]+/-/[(!!1+[])[1>>1]+(!!1
+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^11<<1]+([,][
~1]+[])[1-~1]+[[]+{}][!1.1%1][11111.1%11.1*111e11|!1]+(/1/+
1/[1<1][1%1])[1^11]+[[],[]+{}][1][+1]+(/<</[1]+[])[1/1.1&1]

驚きを台無しにして申し訳ないのですが、これが評価されるとこのようなものが返ってきます。

"I love you" in Chrome
"I lone you" In Firefox
"I lo[e you" in IE10

これを分解すると、一連のメッセージを生成して、その中から文字を抜き出すというような仕組みになります("I"を例にしています)。

[]+1/!1
returns
"Infinity"
then
[[]+1/!1]
creates this array:
["Infinity"]
then
[[]+1/!1][1^1]
Takes the first (1^1 == 0) element of that array
"Infinity"
finally
[[]+1/!1][1^1][1>>1]
Takes the first (1>>1 == 0) char of that string
"I"

その他に生成される文字列は以下の通りです。

({}+[])       -> "[object Object]" (where the space comes from)
([]+!!-[])    -> "false" (used for it's "l")
[/~/+{}][+!1] -> "/~/[object Object]" (this is used for an "o")
(/<</[1]+[])  -> "undefined"

私は "n" と "[" に代わるものを見つけることに興味があり、これを思いつきました。

String.fromCharCode(('1'.charCodeAt(0)<<1)+(10<<1))

これは、1と0を使うという精神に則っていると感じますが、文字列とは全く関係ないように見えるという、元のコードのよりエレガントな側面の1つを侵しています。 どなたか、難読化されたオリジナルのコードと調和する "v" を生成する方法についてアイデアをお持ちの方はいらっしゃいますか?

多くの有能な JavaScript プログラマーがこれを深く調べた後に見つかった、いくつかの追加情報です。

Firefox が "I lone you" を返すのは、この行のせいです。

([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^11<<1]+

[1^11<<1] は、この中から特定の文字を切り出します。

([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])

と評価されます。

"function test() {
    [native code]
}"

ということは、quot;V" を手に入れることができそうです!!!

Chromeは"I love you"を返しますが、同じコードがこれを返すからです。

"function test() { [native code] }"


質問が "実際のプログラミングの問題" との関連が疑わしいとして閉じられる前に、私は以下を基にした要約された解決策を追加しようと思いました。 Supr の , コーリー α123 の は、見よ。

alert([[]+1/!1][1^1][1>>1]+({}+[])[1<<1^11>>1]+(
[]+!!-[])[1<<1]+[/~/+{}][+!1][-~1<<1]+[([]+/-/[(
!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(
!!1+[])[1^1]])[1+(1^(11+1+1)<<1)],([]+/-/[(!!1+[
])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[
])[1^1]])[1^11<<1],([]+/-/[(!!1+[])[1>>1]+(!!1+[
])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^(11
+1+1)<<1]][((([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<
1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[(1<<1<<1<<1
)+1<<1]==({}+[])[1^1])*1)+((([]+/-/[(!!1+[])[1>>
1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1
]])[(1^11<<1)-1]==({}+[])[1^1])<<1)]+([,][~1]+[]
)[1-~1]+[[]+{}][!1.1%1][11111.1%11.1*111e11|!1]+
(/1/+1/[1<1][1%1])[1^11]+[[],[]+{}][1][+1]+(/<</
[1]+[])[1/1.1&1])

コードの複雑さと生成されるメッセージを考えると、まるでJavaScriptエンジンが、あなたがどれだけ特別な存在であるかを教えてくれているようです :)

どのように解決するのですか?

まず最初に、あの面白いスニペットで遊んでくれたジェイソンとすべての貢献者に感謝したいと思います。私はコードのその部分を書きました を書きました。 2月14日に妻に送るために書いたものです :) ラップトップにはChromeしかインストールされていないので、FirefoxやIEでどのように動作するかを確認する方法がありませんでした。さらに、私は本当に期待していなかったのですが toString() の表現が他のブラウザで違って見えるかもしれないとは思っていませんでした。

では 本当の問題に移ります。 では、正確にコードを見てみましょう。そうです。 "v" が本当の問題だったのです。この文字を取得する方法は [native code] という文字列をパースする以外に方法は見つかりませんでしたが、これはどの組み込みメソッドからも取得できます。私は、文字列も数字もないことに限定したので 1 を除く文字列と数字を使用しないことに限定していたので、名前に使用可能な文字だけを持つ何らかのメソッドを利用する必要がありました。

利用可能な文字は、既存のキーワードや文字列表現から取得することができます。つまり、最初から NaN , null , undefined , Infinity , true , false そして "[object Object]" . これらのうちいくつかは,例えば以下のように簡単に文字列に変換することができます. 1/!1+[] が与える "Infinity" .

私は、配列に対するさまざまなビルドインメソッドを分析しました。 [] オブジェクト {} 正規表現 /(?:)/ 数字 1.1 文字列 "1" の美しいメソッドを発見しました。 RegExp というオブジェクトの test() . その名前は、利用可能なすべての文字から組み立てることができます。 "t""e" から true であり、かつ "s" から false . 私は、文字列 "test" で、正規表現リテラルに角括弧表記を用いたこの方法に対応しました。 /-/ という正規表現があり、この行で正しく認識されます。

/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]]

すでに説明したように、このコード片はChromeで次のように評価されます。

function test() { [native code] }

としてFirefoxで表示します。

function test() {
    [native code]
}

というように、IEでは

 function test() {     [native code] }  

(後者のペイでは 特別 の前にあるスペースに注意してください。 function キーワード)

つまり、明らかにわかるように、私のコードは提示された文字列から24番目の文字を取得しており、それはChromeでは "v" (予定通り) でしたが、残念ながら Firefox と IE では -- "n" をそれぞれ

すべてのブラウザで同じ出力になるように、私は 異なるアプローチ を使用しました。現在、修正されたバージョンは次のようになります。

"["

しかし、読者の興味をそそるように、私はそのための解決策を提供することはありません。正直なところ、みなさんはそれがどのように機能するかを簡単に理解できると思いますし、中にはクロスブラウザの方法で愛する人を驚かせることさえできる人もいます ;)

追伸 もうひとつの難読化ツール

普遍的な難読化ツールを作るという Jason のアイデアに触発され、もう一つ書いてみました。以下のサイトで見ることができます。 JSBinにあります。 http://jsbin.com/amecoq/2 . 数字を含むあらゆるテキストを難読化することができます。 javascript:[[]+1/!1][1^1][1>>1]+({}+[])[1<<1^11>>1]+([]+!!- [])[1<<1]+[/~/+{}][+!1][-~1<<1]+/\[[^1]+\]/[([]+![])[1<<1<< 1]+(/|/[(1+{})[1+11>>>1]+[[]+{}][+!1][1]+([]+1/[])[1<<1>>1] +([1<1]+[])[1+11>>>1+1]+[[!!1]+1][+[]][1-1]+([]+!!/!/)[1|1] +(/1/[1]+[])[!1%1]+(-{}+{})[-1+1e1-1]+(1+[!!1])[1]+([]+1+{} )[1<<1]+[!!/!!/+[]][+[]][1&1]]+/=/)[1e1+(1<<1|1)+(([]+/-/[( !!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1 ]])[1^1]==+!1)]+(!![]+{})[1|1<<1]+[1+{}+1][!1+!1][(11>>1)+1 ]](([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+ (!!1+[])[1^1]]))[1&.1][11>>>1]+([,][~1]+[])[1-~1]+[[]+{}][! 1.1%1][11111.1%11.1*111e11|!1]+(/1/+1/[1<1][1%1])[1^11]+[[] ,[]+{}][1<<1>>>1][1||1]+(/[<+>]/[1&1|1]+[1.1])[1/11.1&1.11] 小さなラテン文字 [0-9] およびスペースです。文字列の長さはほとんどあなたのRAMで制限されます(少なくとも私の答えのボディはうまく難読化されました)。出力は、Chrome、Firefox、およびIEでサポートされています。

ヒント このツールは上で紹介したものとは異なる難読化手法を使用しています。