JavaScriptの難読化を解除するためのビジュアルワークベンチ。変換チェーンを構築し、ステップ実行し、独自のプラグインを作成できます。


このアプリケーションはJavaScriptプログラムの抽象構文木(AST)を表示します。このアイデアは、obfuscatio.io関連のマルウェアサンプルを分析しているときに生まれ、結果としてBabelJSを使った難読化解除についてさらに学ぶことになりました。 もし難読化されたJS(例:webpackバンドル、obfuscator.ioの出力、パックされたマルウェアサンプル)をリバースエンジニアリングしようとしたことがあるなら、その苦痛をご存知でしょう。このツールを使えば次のことができます:
npm install
npm start
# ブラウザで http://localhost:3000 を開く
これだけです。
左サイドバー - 利用可能なすべての変換(組み込み + レシピとしてのプラグイン)とレシピチェーン。(Cyberchef をイメージ)
中央 - 入力/出力エディター。左側に難読化されたコードを貼り付け、右側で変換後のコードを表示します。
右パネル - ASTビューアー、スコープアナライザー、わかりやすいサマリー。

BabelJSを使用してスコープとバインディングを表示できます。これは特に未使用の変数などがあるかどうかを確認するのに便利です。また、このビューでは変数が参照されている場所を探すこともできます。

+ ボタンをクリックするか Ctrl+N を押してスクリプトエディターを開きます。変換は単なるJSコードで、以下のものにアクセスできます:
// 利用可能なグローバル変数:
ast // 解析されたBabel AST
traverse // ツリーを走査: traverse({ Identifier(path) { ... } })
t // Babelタイプ: t.isStringLiteral(node), t.identifier('x')
config // レシピカードからのユーザー設定
stats // 変更を追跡: stats.replaced = 5
parser // コードを解析: parser.parse('var x = 1')
generate // コードを生成: generate(node).code
run // evalヘルパー: run('1+1') => 2 (危険。自分のマシンのサンドボックス内で実行することを想定)
例 - すべての "debug" 文字列を削除(StringLiteral):
// 次の2つはレシピチェーン内でパラメータとして表示されます(次のスクリーンショット参照)
const targetValue = config.targetValue || 'debug';
const removeMatches = config.removeMatches !== false;
traverse({
StringLiteral(path) {
if (path.node.value === targetValue) {
if (removeMatches) {
path.remove();
stats.removed = (stats.removed || 0) + 1;
}
}
}
});
次のいずれかを選択できます:
以下のスクリーンショットは次のものを示しています:

これらは難読化手法によっては失敗する可能性があり、カスタムスクリプトが必要になる場合があることに注意してください。また、変更して新しいカスタムスクリプトとして保存することもできます。
| 名前 | 動作 |
|---|---|
| Beautify | コードをきれいにフォーマット |
| Constant Folding | 1 + 2 → 3、"a" + "b" → "ab" |
| Decode Strings | \x48\x65\x6c\x6c\x6f → "Hello" をデコード |
| Inline Array Values | 単純な配列要素アクセスをインライン化 |
| Inline String Array | 難読化ツールが使用する文字列配列をインライン化 |
| Opaque Predicate Removal | 常に真/偽の条件を削除 |
| Remove Comments | コードからすべてのコメントを削除 |
| Remove IIFE | (function(){...})() ラッパーを展開 |
| Remove Unused Code | デッド変数と関数を削除 |
| Simplify Literals | !0 → true、void 0 → undefined |
plugins/<カテゴリ>/ サブフォルダーに独自の .js ファイルを配置します。サイドバーにフォルダーごとにグループ化されて表示されます。

例:
Bracket-to-dot-notation.js → "Decode Strings")plugins/Utilities/ → カテゴリ "nyx")/**
* Bracket to Dot Notation
* Changes things like console["log"] to console.log
*
* Category: utilities
*/
// Script Editor - Ctrl+Enter to run, Ctrl+E to close
// Use traverse(visitor) to modify the AST
// Access 't' for Babel types
traverse({
MemberExpression(path) {
if(path.node.computed === true){
// this is the bracket notation
prop = path.node.property
if(t.isStringLiteral(prop) &&
/^[a-zA-Z_][a-zA-Z_0-9]*$/.test(prop.value)
){
path.node.computed = false; // step 1
// step 2 change literal to identifier
path.node.property = t.identifier(prop.value)
}
}
}
});
パラメーターを追加する方法は2つあります:
targetValue と removeMatches)を作成しようとします。const targetValue = config.targetValue || 'debug';
const removeMatches = config.removeMatches !== false;

含まれるもの:

| キー | アクション |
|---|---|
Ctrl+E | スクリプトエディターの表示/非表示 |
Ctrl+Shift+E | evalパネルの表示/非表示(危険) |
Ctrl+S | プロジェクトを保存 |
ネストされたノードが多い場合、スタンドアロンでは問題が発生する可能性があります。回避策が常にうまくいくとは限りません。
npmを使用してビルドするには、次のコマンドを使用します。
npm run build # Windowsのみ
出力は dist/ に生成されます。カスタム変換を使用する場合は、plugins/ フォルダーをexeと同じ場所にコピーしてください。
深くネストされたコード(JSFuckなど)はスタックを溢れさせる可能性があります。ビルドスクリプトはWindows上で自動的にスタックサイズを増やそうと試みます。スタックオーバーフローが発生する場合は、ソースから npm start(--stack-size=65536 を使用)で実行してみてください。
スタンドアロン実行ファイルにビルドする際にスタックサイズを増やす方法はまだわかっていません。もし方法をご存知でしたら教えてください!
以下のライブラリを使用して構築されています:

質問は?問題がありますか?GitHubのIssueを開いてください。