JavaScript難読化解除ツール:読みやすいコードに戻す
JavaScript難読化解除ツールは、コードを読みにくくしている仕掛けを元に戻します。このツールは、単純な文字列配列の展開、定数式の計算、16進数とUnicodeのエスケープの復号、_0x形式の名前の付け替えを行い、結果を2スペースのインデントで出力します。これらはすべてコードを読み取って行うもので、実行はしません。JavaScriptが実行されることも、アップロードされることもありません。また、後述する一部の難読化はそのまま残します。
JavaScript難読化解除の手順
- コードを「難読化されたJavaScript」の欄に貼り付けます。貼り付けるまでは「難読化されたJavaScriptをここに貼り付け…」と表示されています。上限は5,000,000文字です。
- 「難読化解除のオプション」を選ぶと、4つのチェックボックスが開きます。初期設定ではすべてオンです。「文字列配列を展開」「定数を計算」「16進数とUnicodeのエスケープを復号」「16進数の変数名を変更」のうち、使わない処理のチェックを外してください。
- 「難読化を解除」を押します。「難読化を解除したコード」の画面に、結果が色分けされた読み取り専用のコードで表示されます。
- コードの上に表示されるチップを確認してください。「配列参照を3件置き換えました」「5件の式を簡略化しました」「リテラルを2件復号しました」「変数名を4件変更しました」のように、何が変わったかが分かります。何も該当しなかった場合は「展開や簡略化が必要な箇所はなかったため、コードの整形だけを行いました。」と表示されます。
- 「コピー」(押すと「コピー完了」に変わります)または「.jsをダウンロード」を押すと、コードを難読化解除済み.jsとして保存できます。
- 「コードを編集」を選ぶと入力画面に戻り、別のオプションでもう一度実行できます。
入力が有効なJavaScriptでない場合は、「有効なJavaScriptではありません。N行目、M列目で構文エラーがあります。」のように実際の行と列が表示され、内容は何も変更されません。
各オプションの働き
- 文字列配列を展開:
var a = ['x', 'y']; log(a[1]);(または'x|y'.split('|'))はlog("y");になります。配列は、どこからも読まれなくなった時点で削除されます。 - 定数を計算:
1 + 2 * 3、'a' + 'b'、!![]、!0、obj['key']は、それぞれ7、"ab"、true、true、obj.keyになります。 - 16進数とUnicodeのエスケープを復号:
'\x68\u0069'は"hi"に、0x1fは31になります。 - 16進数の変数名を変更:
_0x1a2bや_0x3c4dは、名前の宣言のされ方に応じてvar1、func1、arg1などになります。
処理はこの順番で実行されるため、配列参照を先に展開し、そのあと定数の計算で前後の文字列と結合することもできます。プロパティ名、ラベル、import と export の名前は変更されません。スクリプト先頭のシバン行は残ります。
作業例で見る変換結果
次の入力には、文字列配列、16進数風の名前、引用符付きのプロパティ、足し算が含まれています。
var _0x1a2b = ['hello', 'world', '\x68\x69']; function _0x3c(_0x4d) { console['log'](_0x1a2b[0] + ' ' + _0x1a2b[1], _0x4d, _0x1a2b[2]); } _0x3c(1 + 2 * 3);
結果は次のとおりです。
function func1(arg1) { console.log("hello world", arg1, "hi"); } func1(7);
チップには「配列参照を3件置き換えました」「5件の式を簡略化しました」「リテラルを1件復号しました」「変数名を2件変更しました」と表示されます。実際の出力は、2スペースのインデントで複数行に整形されます。
元に戻せるものと戻せないもの
このツールはコードを実行しないため、元に戻せるのはテキスト上で見えているものだけです。プログラムを先に動かさないと分からないものは、推測せずそのまま残します。
- 対応:固定のインデックスでしか読まれない単純な文字列配列(
var a = ['x', 'y']と'x|y'.split('|'))。 - そのまま残す:起動時に回転させる配列、obfuscator.ioの
push(shift())という手法。 - 対応:定数の計算、連結された文字列、
!![]と!0、16進数とUnicodeのエスケープ、16進数の数値、obfuscator.ioの出力に見られる_0x形式の名前。 - そのまま残す:検索用の関数を通して復号される文字列、本当のコードを隠している
evalやFunctionの文字列、制御フローの平坦化、仮想マシン方式の難読化。 - 見た目:コードは2スペースのインデントで出力し直されます。コメントは削除され、元の変数名はファイルに残っていないため復元できません。
これは読むための補助であり、セキュリティスキャナーではありません。コードが有害かどうかは判定せず、出どころの分からないコードを安全にすることもできません。信頼できない入手元のスクリプトは、出力がきれいに見えても実行しないでください。
回転した文字列配列が残る理由
多くの難読化ツールは、最初に読み取る前に短いループで文字列配列の要素を回転させます。そのため、ソース上で最初に見える要素が list[0] とは限りません。見えている要素をそのまま当てはめると、コードに間違った文字列が入ってしまいます。
そこで、配列のすべての使い方が範囲内の数値での list[3] か list.length のときだけ展開します。配列が関数に渡されている、push で追加されている、再代入されている、計算できないインデックスで読まれている場合は、その配列を書かれたままの形で残します。
JavaScript整形オンラインと大きなファイル
難読化されていない圧縮コードは、2スペースのインデントで整形し直されて戻ります。チップには、レイアウトだけが変わったことが表示されます。a や b のような短い名前は、16進数風ではなく元の名前も失われているため、変更されません。すでに読みやすいコードの整形や、JSON、HTML、CSSの整形には、コードフォーマッターを使ってください。スタイルシートを再び圧縮するにはCSSミニファイア、スクリプトの中で見つけたBase64文字列を復号するにはBase64変換が便利です。
処理はすべてWeb Workerで行われるため、大きなファイルでもページは応答し続けます。非常に長い式や深くネストした式はページの手に負えないことがあり、その場合は「このコードは大きすぎるか、入れ子が深すぎるため、ここでは処理できません。」と表示されます。
よくある質問
JavaScript難読化解除のやり方は?
コードを「難読化されたJavaScript」に貼り付けて「難読化を解除」を押します。コードは構文木に変換され、文字列配列の展開、定数の計算、エスケープの復号、_0x形式の名前の付け替えが行われ、インデント付きのコードとして出力されます。コピーするか、「.jsをダウンロード」を押すと難読化解除済み.jsとして保存できます。
オンラインで使えるJavaScript難読化解除ツールはありますか?
はい、このページがそのツールです。ブラウザーのタブ内で動作し、コードはWeb Workerで解析され、アップロードも実行もされません。単純な文字列配列、定数式、16進数とUnicodeのエスケープ、_0x形式の名前に対応しています。すべての種類の難読化を元に戻せるわけではなく、そのまま残るもののリストはこのページに載せています。
obfuscator.ioで難読化したコードにも使えますか?
コードを実行しなくても済む部分だけ対応します。16進数とUnicodeのエスケープは復号し、定数は計算し、_0x形式の名前は var1、func1、arg1 に付け替えます。obfuscator.ioが起動時に push(shift()) で回転させる文字列配列や、復号用の関数を通して取り出される文字列は、元に戻すにはコードの実行が必要になるため、そのまま残ります。
JavaScriptの16進数文字列の変換はできますか?
できます。「難読化解除のオプション」で「16進数とUnicodeのエスケープを復号」をオンのままにしてください。\x68\u0069 のような文字列は hi に、0x1f のような16進数の数値は 31 になります。復号されるのはコードに書かれているエスケープだけで、プログラムが実行時に組み立てる16進数の文字列は対象外です。
圧縮されたJavaScriptの整形にも使えますか?
はい。出力は常に2スペースのインデントで出力し直されるため、展開するものがなくても、圧縮コードは読みやすくなります。その場合は「展開や簡略化が必要な箇所はなかったため、コードの整形だけを行いました。」と表示されます。入力のコメントは削除されます。a や b のように短くされた変数名は復元できません。
このツールは私のJavaScriptを実行しますか?
いいえ。コードはテキストとして読み取って書き直すだけです。eval も Function の呼び出しもなく、ページ内でもWeb Workerでも実行はしません。そのため、回転した配列や復号用の関数はそのまま残ります。また、これは安全性の検査ではありません。出力は読みやすくなりますが、スキャンやマルウェアの判定は別の作業です。
文字列配列が出力に残ったのはなぜですか?
配列は、すべての使い方が list[3] や list.length のような固定のインデックスのときだけ展開されます。コードがその配列を回転させている、関数に渡している、push で追加している、計算したインデックスで読んでいるといった場合は、読み取りの置き換えで間違った文字列が入る恐れがあるため、配列全体をそのまま残します。
「16進数の変数名を変更」では何が行われますか?
_0x1a2b のような名前に読みやすい名前を付けます。変数は var1、関数は func1、引数は arg1 です。同じ名前の使用箇所はまとめて変更され、プログラム内にすでにある名前は再利用されず、プロパティ名とラベルには手を付けません。元の名前はファイルに残っていないため、復元することはできません。
コードはどのくらいの大きさまで扱えますか?エラーがある場合は?
5,000,000文字までです。有効なJavaScriptでない場合は、「有効なJavaScriptではありません。N行目、M列目で構文エラーがあります。」のように実際の行と列が表示され、内容は何も変更されません。入力した内容は欄に残るので、その箇所を直してください。
コードはどこかにアップロードされますか?
いいえ。解析、書き換え、出力はすべてお使いのブラウザー内のWeb Workerで行われ、サーバーには何も送信されません。コードが実行されることもありません。
おすすめ
-
リーダブルコード(書籍)読み解いたコードを、自分の手で読みやすく書き直すための一冊です。
-
暗号技術入門 第3版難読化の裏にある暗号とハッシュの仕組みを、基礎から押さえられます。
-
Acer 15.6インチ モバイルモニター整えたコードと元の難読化コードを並べて、見比べながら読めます。
無料でツールを続ける支えになります。✨
画像はイメージです。 Amazonのアソシエイトとして、Capsule Toolsは適格販売により収入を得ています。