
View8 は、シリアライズされたV8バイトコードオブジェクト(JSCファイル)を高水準の読み取り可能なコードに逆コンパイルするために設計された静的解析ツールです。これらのシリアライズされたオブジェクトを解析および逆アセンブルするために、View8はパッチ適用済みのコンパイル済みV8バイナリを利用します。その結果、View8はJavaScriptに類似したテキスト出力を生成します。
9.4.146.24 (Node V16.x で使用)10.2.154.26 (Node V18.x で使用)11.3.244.8 (Node V20.x で使用)コンパイル済みバージョンについては、リリースページを参照してください。
--inp, -i: 入力ファイル名。--out, -o: 出力先パス。選択したオプションに応じて、出力は単一ファイルまたはディレクトリツリーになります。--input_format, -f: 入力形式を指定します。オプションは以下のとおりです:
raw: 入力は生のJSCファイルです。disassembled: 入力ファイルは既に逆アセンブル済みです。serialized: 入力は既に逆コンパイルされ、シリアライズ形式で保存されています。現在のシリアライズ形式はPython pickleです。信頼できる入力のみを使用してください。--export_format, -e: エクスポート形式を指定します。オプションは v8_opcode、translated、decompiled、serialized です。複数のオプションを組み合わせることができます。デフォルト: decompiled。--path, -p: 逆アセンブラバイナリへのパス。入力がraw形式であり、View8が一致する逆アセンブラを自動的に見つけられない場合に必要です。--scope: スコープ引数を伝播します。デフォルト: 1。--normalize: アドレス由来の関数識別子を、解析順序に基づく決定論的な名前に置き換えます。--normalize-map [CSV]: --normalize 使用中に、すべての元の関数名を正規化された名前にマッピングするCSVを書き出します。パスが省略された場合、View8は --out から <output>.name_map.csv を導出します。出力パスが設定されていない場合は --inp から導出します。--tree, -t: すべての関数を1つのファイルに格納する代わりに、出力をツリー構造に分割します。ツリーのルートとして使用する関数を指定します。デフォルトのメイン関数から開始するには、start を使用します。--split_mode: ツリー分割モード。オプションは declarers、calls、references です。デフォルト: declarers。--inline_depth, -d: calls および references モードで、選択したツリールートから深さNまで到達可能な関数をメインツリーファイルに含めます。深さ 0 は選択したルートのみを意味し、深さ 1 は直接の呼び出し先/参照を含み、深さ 2 はその子を含みます。declarers では使用されません。--inline_branch_limit, -l: ツリーモードで、--inline_depth によって子ブランチが含まれる場合、最大N個の関数を持つ完全な子ブランチをメインツリーファイルにインライン化します。より大きなブランチは別途保存されます。--split_depth: calls および references モードで、エクスポートされた使用ブランチをどの深さまで走査するかを制限します。デフォルト: 4。--include, -n: 出力に含める関数を含むファイル。--exclude, -x: 出力から除外する関数を含むファイル。--func: 選択した関数を表示します。--show_all: 関数表示モードで、非表示としてマークされた行も表示します。--verbosity, -v: 詳細レベル。許容範囲: 0 から 3。V8バイトコードファイルを逆コンパイルし、逆コンパイルされたコードをエクスポートするには:
python view8.py -i input_file -o output_fileデフォルトでは、View8 は VersionDetector.exe を使用して入力ファイルのV8バイトコードバージョンを検出し、Bin フォルダ内で互換性のある逆アセンブラバイナリを自動的に検索します。これは、--path または -p オプションで別の逆アセンブラバイナリを指定することで変更できます:
python view8.py -i input_file -o output_file --path /path/to/disassembler逆アセンブル処理をスキップして、既に逆アセンブルされたファイルを入力として提供するには、--input_format disassembled または -f disassembled オプションを使用します:
python view8.py -i input_file -o output_file -f disassembled--normalize を使用して、アドレス由来の関数名を決定論的な識別子に置き換えます。元の名前と正規化された名前の関係を保持するには、--normalize-map を追加します:
python view8.py \
--input_format disassembled \
--inp sample.jsc.disasm.txt \
--normalize \
--normalize-map \
--out decompiled/sample.dec.txt \
--export_format decompiled serializedこれにより、以下の列を持つ decompiled/sample.dec.name_map.csv が書き出されます:
original_name,normalized_name
func_start_0x268514e9dcd9,func_start_0x100000000
func_rne_0x268514eb0779,func_rne_0x100000001明示的なCSVパスを指定することもできます:
python view8.py \
--input_format disassembled \
--inp sample.jsc.disasm.txt \
--normalize \
--normalize-map mappings/sample.names.csv \
--out decompiled/sample.dec.txt解析されたオブジェクトと構造を保持するシリアライズ形式にファイルを逆コンパイルすると便利な場合があります。このタイプの出力は、例えばさらなる難読化解除中など、テキスト形式よりも後処理が容易な場合があります。シリアライズ出力を作成するには、serialized エクスポート形式を使用します:
python view8.py -i input_file -o output_file -e serializedセキュリティ警告: 現在のシリアライズ形式はPython pickle ファイル (.pkl) です。信頼できないソースからのデータをアンピックルすると、任意のコードが実行される可能性があります。自分で生成したシリアライズファイルのみをロードしてください。
シリアライズ出力をロードして別の形式でエクスポートするには、--input_format serialized または -f serialized を使用します:
python view8.py -i input_file -o output_file -f serialized--export_format または -e オプションを使用してエクスポート形式を指定します。複数の形式を組み合わせることができます:
v8_opcodetranslateddecompiledserialized例えば、V8オペコードと逆コンパイルされたコードの両方を並べてエクスポートするには:
python view8.py -i input_file -o output_file -e v8_opcode decompiledデフォルトでは、使用される形式は decompiled です。
大規模なバンドルペイロードの場合、すべての逆コンパイルされた関数を単一のファイルに書き込むと分析が困難になることがあります。ツリー出力は、選択したルートと関連する関数をディレクトリ構造に分割します。
--tree を使用してツリールートを選択します:
python view8.py \
--inp input.pkl \
--input_format serialized \
--out ./tree_out/ \
--tree start特別な値 start は、View8によって復元されたデフォルトのメイン関数を意味します。
ツリーは次の3つのモードのいずれかで分割できます:
declarers: 字句的な宣言関係を追跡します。つまり、どの関数が別の関数の内部または下で宣言されているかを追跡します。これはバンドルまたはモジュールのような構造を理解するのに役立ちますが、実行フローを表すものではありません。calls: func_x(...) などの直接の関数呼び出しを追跡します。これは選択したルートから実行スケルトンを復元するのに役立ちます。references: 直接の呼び出しだけでなく、すべての可視の関数参照を追跡します。これには、コールバック、エクスポートされたハンドラ、ルートハンドラ、オブジェクトプロパティ、およびその他の割り当てられた関数が含まれます。このモードは機能面を発見するのに役立ちますが、calls よりもはるかに大きなツリーを生成する可能性があります。例:
python view8.py \
--inp input.pkl \
--input_format serialized \
--out ./tree_calls/ \
--tree start \
--split_mode callsメインツリーファイルには常に選択したルート関数が含まれます。
calls および references モードでは、--inline_depth がメインファイルに含まれるグラフレベル数を制御します:
--inline_depth 0 -> ルートのみ
--inline_depth 1 -> ルート + 直接の呼び出し先/参照
--inline_depth 2 -> ルート + 直接の呼び出し先/参照 + その子例えば、次のコマンドは、ルートとその直接の呼び出し先を含むコンパクトな実行概要を作成します:
python view8.py \
--inp input.pkl \
--input_format serialized \
--out ./tree_calls/ \
--tree start \
--split_mode calls \
--inline_depth 1呼び出しレイヤーをさらに1つ含めるには:
python view8.py \
--inp input.pkl \
--input_format serialized \
--out ./tree_calls/ \
--tree start \
--split_mode calls \
--inline_depth 2--inline_depth は calls および references モードでのみサポートされています。declarers では使用されません。
大きな子ブランチは別々のファイルに保存されます。calls および references モードでは、--split_depth がエクスポートされた使用ブランチをどの深さまで走査するかを制御します:
python view8.py \
--inp input.pkl \
--input_format serialized \
--out ./tree_calls/ \
--tree start \
--split_mode calls \
--inline_depth 1 \
--split_depth 5--inline_branch_limit オプションは、小さな完全な子ブランチもメインファイルに含めるかどうかを制御します:
--inline_branch_limit 3これは、最大3つの関数を含む完全な子ブランチがメインファイルにインライン化される可能性があることを意味します。より大きなブランチは別途保存されます。
calls および references モードでは、選択した --inline_depth が既に子関数を含む場合にのみ、子ブランチがインライン化されます。例えば、--inline_depth 0 はルートのみを意味するため、子ブランチが小さくてもインライン化されません。
コンパクトな実行概要の場合:
python view8.py \
--inp input.pkl \
--input_format serialized \
--out ./tree_calls/ \
--tree start \
--split_mode calls \
--inline_depth 1 \
--split_depth 5より広範なアーキテクチャ概要の場合:
python view8.py \
--inp input.pkl \
--input_format serialized \
--out ./tree_calls/ \
--tree start \
--split_mode calls \
--inline_depth 2 \
--split_depth 5エクスポートされたコールバック、ハンドラ、ルート、および機能面の場合:
python view8.py \
--inp input.pkl \
--input_format serialized \
--out ./tree_refs/ \
--tree start \
--split_mode references \
--inline_depth 1 \
--split_depth 3字句的またはモジュールのような構造の場合:
python view8.py \
--inp input.pkl \
--input_format serialized \
--out ./tree_declarers/ \
--tree start \
--split_mode declarers \
--split_depth 3選択した関数を表示するには、--func を使用します:
python view8.py \
--inp input.pkl \
--input_format serialized \
--func func_name非表示としてマークされた行も表示するには:
python view8.py \
--inp input.pkl \
--input_format serialized \
--func func_name \
--show_allV8バイトコードバージョンは、ファイルの先頭にハッシュとして保存されています。以下は VersionDetector.exe で利用可能なオプションです:
-h: バージョンを取得し、そのハッシュを返します。-d: リトルエンディアン形式のハッシュを取得し、ブルートフォースを使用して対応するバージョンを返します。-f: ファイルを取得し、そのバージョンを返します。