
このツールは、javascript-obfuscator で保護された、コンパイル済み V8 JavaScript バイトコードを静的に難読化解除することに特化しています。
元の JavaScript ソースではなく、View8 が生成する疑似コードに対して動作します。このプロジェクトは JSCeal ペイロードを対象に開発・テストされました。
フィルタはパターン駆動型であり、主に研究ツールキットおよびリファレンス実装として意図されています。このツールは汎用の JavaScript 難読化解除ツールではなく、元のソースコードを再構築せず、実行可能な JavaScript を生成しません。その出力は、静的解析、検索、比較、関数ツリーのエクスポートを目的とした View8 疑似コードのままです。
📖 Wiki を読む
pickle を使用します。悪意のある、または信頼できない .pkl ファイルを読み込むと、コードが実行される可能性があります。View8 でローカルに生成したシリアライズファイルのみを読み込んでください。requirements.txt からの Python 依存関係brotli コマンドラインユーティリティ分離された Python 環境を作成します:
python3 -m venv .venv
source .venv/bin/activate
python3 -m pip install --upgrade pip
python3 -m pip install -r requirements.txt
deobf_ai.py の OpenAI バックエンドには、追加で OpenAI Python パッケージが必要です:
python3 -m pip install openai
Anthropic バックエンドは requests を通じて HTTP API を使用します。Ollama バックエンドは、到達可能な Ollama サーバーを期待します。
元の JSCeal app.jsc ペイロードは Brotli 圧縮されています。Linux では、brotli ユーティリティで解凍できます:
brotli -d app.jsc -o app.decompressed.jsc
scripts/ 配下のバッチワークフローは、この手順を scripts/unpack_all.sh で実行します。
Windows で、または brotli コマンドラインユーティリティが利用できない場合、同梱の Node.js ヘルパーをフォールバックとして使用できます。これは入力の解凍のみを行い、実行はしません:
node Utils/decompress-jsc.js app.jsc
次のファイルを書き出します:
app.jsc.decompressed.jsc
V8 コードキャッシュはバージョン固有です。ペイロードと同じ V8 バージョン用にビルドされた逆アセンブラを使用してください。
開発中に使用された JSCeal サンプルは、V8 10.2.154.26 に基づいていました。無関係な V8 ビルドのデフォルト逆アセンブラは正しく動作しません。
ソースツリーには、逆アセンブラのソースと必要な V8 パッチが以下に含まれています:
Utils/disasm/v8dasm.cpp
Utils/disasm/patches/
プリビルドの Linux バイナリはプロジェクトリリースに同梱されており、ソースツリーには再ビルドに必要なソースとパッチが含まれています。詳細な説明はプロジェクトの Wiki にあります。一致する v8dasm を入手またはビルドした後、以下を実行します:
/path/to/v8dasm app.decompressed.jsc > app.jsc.disasm.txt
逆アセンブルされたファイルを view8.py に渡し、さらなる処理用のシリアライズ出力と人間が読める疑似コードの両方を生成します:
mkdir -p decompiled
python3 View8/view8.py \
--input_format disassembled \
--inp app.jsc.disasm.txt \
--normalize \
--out decompiled/app.dec.txt \
--export_format decompiled serialized
これにより、以下が生成されます:
decompiled/app.dec.txt
decompiled/app.dec.pkl
--normalize オプションにより、生成された関数識別子が、逆アセンブルと逆コンパイルを繰り返し実行しても再現可能になります。
個々の難読化レイヤー用に個別のフィルタがあります。これらは deobf_all.py でシリアライズされた View8 出力にまとめて適用できます:
mkdir -p deobfuscated
python3 deobf_all.py \
--inp decompiled/app.dec.pkl \
--out deobfuscated/app.deobf.txt \
--export_format decompiled serialized
デフォルトの文字列フィルタは、分析された JSCeal ペイロードの大部分で使用されているバリアント 2 です。より単純な文字列スキームを明示的に選択するには、次を追加します:
--str_deobf 1
典型的な出力は次のとおりです:
deobfuscated/app.deobf.txt
deobfuscated/app.deobf.pkl
deobfuscated/app.deobf.txt.strings.txt
decompiled/app.dec.resolved_funcs.csv
解決済み関数 CSV はサンプル固有のキャッシュです。これが存在しない場合、文字列パスは必要なデコーダ設定を回復し、CSV を書き込み、同じ実行で文字列の難読化解除を続行します。以降の実行はキャッシュを再利用するため、通常は高速です。
解決済み関数 CSV を、異なる逆コンパイル済みペイロードで再利用しないでください。
すべての構造的難読化解除フィルタが適用された後、deobf_ai.py は関数の動作を説明する名前を提案できます。Anthropic、OpenAI、Ollama バックエンドをサポートしています。
実行を再現可能にするために、モデルを明示的に渡してください。
export ANTHROPIC_API_KEY='...'
python3 deobf_ai.py \
--inp deobfuscated/app.deobf.pkl \
--out deobfuscated/app.renamed.txt \
--llm_backend anthropic \
--model '<model-id>' \
--export_format decompiled serialized
export OPENAI_API_KEY='...'
python3 deobf_ai.py \
--inp deobfuscated/app.deobf.pkl \
--out deobfuscated/app.renamed.txt \
--llm_backend openai \
--model '<model-id>' \
--export_format decompiled serialized
python3 deobf_ai.py \
--inp deobfuscated/app.deobf.pkl \
--out deobfuscated/app.renamed.txt \
--llm_backend ollama \
--model '<local-model>' \
--ollama_url http://localhost:11434 \
--export_format decompiled serialized
デフォルトモードでは、リネーマーはエントリ関数から始まる直接呼び出しツリーを構築し、呼び出しを通じて到達した関数のみをリネームします。コールバックや割り当てられたハンドラを含む、すべての可視の関数参照を含めるには --greedy を追加します。
生成された 2 列の CSV はキャッシュとして機能し、中断された実行を続行できます。既存のキャッシュを --csv で明示的に選択します:
python3 deobf_ai.py \
--inp deobfuscated/app.deobf.pkl \
--out deobfuscated/app.renamed.txt \
--csv deobfuscated/app.deobf.renamed_funcs.greedy.example-model.csv \
--llm_backend anthropic \
--model '<model-id>' \
--greedy \
--export_format decompiled serialized
通常モードでは、CSV は潜在的に部分的なキャッシュとして扱われます。キャッシュされた名前が最初に適用され、キャッシュでカバーされている関数は選択された呼び出しまたは参照ツリーから削除され、LLM は未解決の関数に対してのみ呼び出されます。CSV がそのツリーを完全にカバーしている場合、API キーや LLM 接続は不要です。ツリーの一部のみをカバーしている場合、選択されたバックエンドが初期化され、新しく生成されたマッピングが同じ CSV に追加されます。
CSV が作成されたときと同じツリーモードを使用してください。--greedy 実行から生成された CSV は、直接呼び出しサブセットを再利用するだけでなく、その実行を続行することが目的の場合は、通常、再度 --greedy が必要です。
CSV に、レビュー済み、編集済み、インポート済み、またはリベース済みのマッピングなど、適用したいラベルがすでに含まれている場合は、--apply-csv-only を使用します:
python3 deobf_ai.py \
--inp deobfuscated/app.deobf.pkl \
--out deobfuscated/app.renamed.txt \
--csv renamed_functions.normalized.csv \
--apply-csv-only \
--export_format decompiled serialized
このモードでは:
--csv が必要です;--func と組み合わせることはできません。元の関数識別子が入力に存在しない行は無視されます。CSV に、読み込まれたファイルに適用可能なマッピングが含まれていない場合、コマンドは失敗します。
--func を正確な完全な関数識別子とともに使用して、難読化解除された 1 つの関数の焦点を絞ったセマンティック分析を要求します:
python3 deobf_ai.py \
--inp deobfuscated/app.deobf.pkl \
--func func_example_0x100001234 \
--llm_backend anthropic \
--model '<model-id>'
分析には、提案された名前、動作の要約、入力と戻り値、副作用、ステップバイステップのロジック、クリーンアップされた疑似コード、裏付けとなる証拠、未解決の不確実性が含まれます。--csv を指定すると、読み込まれたコーパスを変更せずに、選択した関数内の参照のコンテキストとしてキャッシュされたセマンティック名が追加されます。--analysis-out analysis/function.md を使用して、レポートを Markdown として保存します。あいまい一致は提案としてのみ出力されます。要求された関数識別子は正確に一致する必要があります。
温度、バッチ処理、Anthropic 思考モード、トークン制限、カスタム CSV パスを制御するオプションについては、--help を使用してください。
LLM が生成した名前はナビゲーションの補助であり、証拠ではありません。常に難読化解除された本体と照合して検証してください。
難読化解除された JSCeal 出力は通常、非常に大きくなります。シリアライズされた出力を View8 に再読み込みし、より小さな関数ツリーに分割します。
この段階で、--scope 0 を追加します。スコープ伝播は難読化解除器によってすでに実行されており、繰り返すと値が誤って伝播される可能性があります。
宣言者関係に基づくツリー:
python3 View8/view8.py \
--input_format serialized \
--inp deobfuscated/app.deobf.pkl \
--out trees/declarers \
--export_format decompiled \
--tree start \
--scope 0
コンパクトな直接呼び出しの概要:
python3 View8/view8.py \
--input_format serialized \
--inp deobfuscated/app.deobf.pkl \
--out trees/calls \
--export_format decompiled \
--tree start \
--scope 0 \
--split_mode calls \
--inline_depth 1 \
--split_depth 5
コールバックや割り当てられたハンドラを含む、より広範な参照ツリー:
python3 View8/view8.py \
--input_format serialized \
--inp deobfuscated/app.deobf.pkl \
--out trees/references \
--export_format decompiled \
--tree start \
--scope 0 \
--split_mode references \
--inline_depth 1 \
--split_depth 3
JSC ファイルによっては、異なる文字列難読化モードを使用する場合があります。
最も単純な観測モードはインデックスシフトを使用し、deobf_str1.py で処理されます。最も一般的な JSCeal モードは、Base64、RC4、チャンク化された文字列、および変換されたインデックスを使用します。これは deobf_str2.py で処理されます。
完全なパイプラインはデフォルトでバリアント 2 を選択します。フィルタはテスト用に個別に実行することもできます。
deobf_str2.py--help を使用して、利用可能なすべてのモードとオプションを表示します:
python3 deobf_str2.py --help
直接的な文字列難読化解除の実行は、次のように開始できます: