「このファイルはどこを読み込んでるんやろう?」を、元コードの位置と対応させて調べたい。REAを使って、自分で作った小さなJavaScriptアプリの参照関係を確認するで。
morluto/reaは、CLIやAIエージェント向けのMCPからソフトウェアを調べるための道具や。JavaScriptの静的解析と、Ghidraなどの解析エンジンを使うネイティブバイナリの調査は、別の入口になってるで。
今回のゴールと環境
ゴールは、index.jsの1行目がsearch.jsを参照していることを、REAのJSONと元ファイルの両方で確認することや。題材は自分で作る3ファイルだけ。アプリを実行した結果と、ソースを読んで得た解析結果は分けて見るで。
実行して確認した範囲:2026年10月24日、Windows 11 x64、PowerShell 7.6.5、Node.js 22.20.0、npm 11.12.1、公開npmパッケージREA 6.7.0で、この題材の実行・静的解析・下記のJSON抽出を確認したで。npmキャッシュの保存先だけを検証用フォルダーへ変えて実行した。OSからの新規インストール、別のアプリやASAR、Ghidraによるネイティブ解析は今回実行してへんで。
1.ツールの準備
Windows 11 x64を使うで。まずスタートメニューから端末を開き、PowerShell 7がなければ次で入れてな。インストールが終わったら、スタートメニューで「PowerShell 7」を探して開き直すんや。以下の作業はその画面で行うで。
winget install --id Microsoft.PowerShell --source wingetPowerShell公式のWindows向け導入案内も確認してな。次にNode.js公式サイトで、Windows x64用の24系LTSインストーラーを選んで入れるで。PowerShell 7を開き直して、次を実行してな。
$PSVersionTable.PSVersion
node --version
npm.cmd --versionPowerShellは7系、Node.jsはこの記事で固定するREA 6.7.0の対応範囲を使うで。公開パッケージの条件はNode.js ^22.19.0 || ^24.11.0 || >=26.0.0や。22系なら22.19.0以上、24系なら24.11.0以上が目安になるで。今回はnpx.cmdから呼び出すから、REAのグローバルインストールはせえへん。
今回のJavaScript静的解析では、AIサービスの契約・APIキー・MCPへの登録・Ghidraは使わへん。これは今回のコマンドに限った話や。GhidraがREA全般で不要という意味やなく、ネイティブ解析でGhidra Providerを選ぶ場合は別途必要になるで。
2.題材の作成
ここは準備だけや。まだREAで解析せえへんで。自分のユーザーフォルダーの下に練習場所を作り、そこへ移動するんや。同名の練習ファイルがあると次の操作で上書きするから、残したいものがある場合は別の練習フォルダー名にしてな。
New-Item -ItemType Directory -Force "$env:USERPROFILE\github-practice\rea" | Out-Null
Set-Location "$env:USERPROFILE\github-practice\rea"sample-appフォルダーと3つのファイルを作るで。@'と'@を含め、ブロック全体をPowerShell 7へ貼り付けてな。
New-Item -ItemType Directory -Force sample-app | Out-Null
@'
{
"name": "rea-practice",
"version": "1.0.0",
"type": "module",
"main": "index.js"
}
'@ | Set-Content sample-app/package.json -Encoding UTF8
@'
export function findItem(items, word) {
return items.filter(item => item.includes(word));
}
'@ | Set-Content sample-app/search.js -Encoding UTF8
@'
import { findItem } from "./search.js";
const result = findItem(["apple", "pear"], "app");
console.log(result);
'@ | Set-Content sample-app/index.js -Encoding UTF8
Get-ChildItem sample-app -Name準備が終わると、次の3ファイルが表示されるで。表示順は環境によって変わっても構わへん。
index.js
package.json
search.js| ファイル | 役割 |
|---|---|
package.json | 名前・版・入口を記録する。type: moduleでES Modulesとして扱うで。 |
index.js | search.jsからfindItemを読み込み、結果を表示する入口や。 |
search.js | 配列から指定した文字を含む要素を選ぶ、自作の関数や。 |
3.題材の動作確認
これは自作アプリをNode.jsで動かす確認や。REAの解析とは別やで。
node .\sample-app\index.js今回の実行結果はこうやったで。
[ 'apple' ]appleはappを含み、pearは含まへんから、この結果になるんや。この表示は自作プログラムの出力で、REAが推測した実行結果やないで。ここまでで題材の準備は完了や。
4.解析の実行
ここからREAを実行するで。作業フォルダーは引き続きgithub-practice\reaや。sample-appの中には移動せえへん。次のコマンドはソースを静的に読むもので、題材のindex.jsをアプリとして起動する操作やないで。
$target = (Resolve-Path .\sample-app).Path
npx.cmd -y rea-agents@6.7.0 analyze-javascript-application "$target" --format json 1> rea-result.json 2> rea-progress.log
$reaExit = $LASTEXITCODE
if ($reaExit -ne 0) {
Get-Content rea-result.json
Get-Content rea-progress.log -Tail 20
throw "REAの解析が失敗したで。上に出た内容を確認してな。"
}初回はnpmからREAと依存パッケージを取得するので通信が発生するで。-yは、その取得確認に自動で同意するnpxの指定や。解析のJSONをファイルに保存するから、正常終了しても画面に大きな結果は出えへんで。
| 指定 | 今回の意味 |
|---|---|
rea-agents@6.7.0 | 記事の出力と合わせるため、使う公開版を固定してるで。 |
analyze-javascript-application | JavaScript/Electronのアプリ用の静的解析コマンドや。 |
"$target" | 解析するフォルダーの絶対パスや。空白を含むパスも1つの引数として渡すため引用符を付けるで。 |
--format json | 結果をJSONで出す指定や。 |
1> rea-result.json | PowerShellが標準出力をこのファイルへ保存する指定や。REA固有のオプションやないで。 |
2> rea-progress.log | 進捗や診断を別ファイルへ保存し、JSONに混ざらへんようにするで。 |
5.出力の読み方
出力全体は長いから、まずPowerShellでJSONを読み、対象ファイル数と構文解析の失敗を取り出すで。以下は同じ作業フォルダーで実行してな。
$report = Get-Content .\rea-result.json -Raw | ConvertFrom-Json
if ($report.error) { throw $report.error }
$report.normalized_result.statistics |
Select-Object relevant_files, parsed_javascript_files, parse_failures |
ConvertTo-Json実測出力:今回作った3ファイルを解析して得たJSONから、上の3項目だけを取り出した結果やで。
{
"relevant_files": 3,
"parsed_javascript_files": 2,
"parse_failures": 0
}| 項目 | どう読むか |
|---|---|
relevant_files: 3 | 今回の解析で関連ファイルとして扱った数や。題材の3ファイルと照らし合わせるで。 |
parsed_javascript_files: 2 | 構文を解析したJavaScriptファイル数や。index.jsとsearch.jsに対応するで。 |
parse_failures: 0 | 今回の構文解析の失敗は0件や。プログラム全体が正しい、安全、という判定やないで。 |
次に、importsのうち静的import文から得た関係を取り出すで。関数の束縛などを表す別の辺まで全部並べると、同じimportから得た複数の関係が混ざるため、この例ではkind: static-importに絞ってるんや。
$report.normalized_result.graph.edges |
Where-Object { $_.relation -eq 'imports' -and $_.properties.kind -eq 'static-import' } |
ForEach-Object {
[pscustomobject]@{
source = $_.evidence.location.value.source
line = $_.evidence.location.value.start.line
relation = $_.relation
specifier = $_.properties.specifier
resolved_path = $_.properties.resolved_path
resolution_status = $_.properties.resolution_status
}
} | ConvertTo-Json実測出力:これはREAの生JSON全体やなくて、直前のPowerShellで必要な値に名前を付けて取り出した表示やで。
{
"source": "index.js",
"line": 1,
"relation": "imports",
"specifier": "./search.js",
"resolved_path": "search.js",
"resolution_status": "resolved"
}| 項目 | 元コードとの対応 |
|---|---|
source: index.js/line: 1 | 根拠になる場所はindex.jsの1行目や。 |
relation: imports | 他のモジュールを読み込む関係を表してるで。 |
specifier: ./search.js | import文に書いた読み込み先の文字列や。 |
resolved_path: search.js | REAが題材の中で対応付けたファイルや。 |
resolution_status: resolved | この参照先を解決できたという意味や。関数の動作や全経路まで保証するものやないで。 |
最後に元ファイルを表示して、解析結果の根拠を自分で確かめるんや。
Get-Content .\sample-app\index.js
Get-Content .\sample-app\search.jsindex.jsの1行目はimport { findItem } from "./search.js";、search.jsの1行目はexport function findItem(items, word) {になってるで。この2つを照らし合わせれば、「どこから何を読み込んだか」を追えるんや。
成功の目安:解析が終了コード0で終わり、この題材で3ファイル・JavaScript 2ファイル・構文解析の失敗0件を確認し、index.jsの1行目からsearch.jsへの参照を元コードと対応付けられたら今回のゴールや。JSONが返ったことだけで、調査が完了したとはせえへんで。
REAのこの出力は、ソースに書かれた関係を静的に調べたものや。先ほどの[ 'apple' ]という実行値を保証する結果やないし、動的に作るパスや難読化された関係が全部解決するとも限らへん。出力のlimitationsも確認してな。
導入と解析の流れ
6.別の対象を解析する場合
同じJavaScriptアプリの別フォルダーなら、まず$targetのパスを実在する場所へ変えるで。対象の種類が変わる場合は、パスを変えるだけでは足りへんことがある。ここで渡してるのはREA自身の引数で、解析対象アプリの起動引数やないで。
| 対象・目的 | 選ぶ入口と変えるもの |
|---|---|
| 展開済みJavaScriptアプリのフォルダー | 今回と同じanalyze-javascript-applicationで、対象フォルダーのパスを変えるで。 |
| ElectronのASAR | 同じコマンドへASARファイルのパスを渡せるで。--artifact-formatの既定値はautoで、必要ならasar/directoryを明示する。ASARでの実行は今回未確認や。 |
| JavaScriptの一部ファイルに絞る | --source-path index.jsのように、アプリのルートからの正確な相対パスを指定するで。依存先は自動で追加されへんから、search.jsも見たいなら繰り返し指定する。今回の最小例では絞らへんで。 |
| ネイティブ実行ファイルの概要 | analyzeへ実行ファイルのパスを渡し、Ghidraなら--provider ghidraを指定するで。先に解析エンジンの準備が必要や。 |
| ネイティブの関数を逆コンパイル | decompileでは、対象パスに加えて、実際の解析結果で確かめた関数名またはアドレスが必要や。どのプログラムにも同じmainやアドレスがあるとは限らへんで。 |
| ヘッダーのないrawバイナリ | --target-format raw-binaryに加え、CPUの--architectureと読み込み・入口の--entry-pointが必要になる。値を推測で入れず、公式のraw解析ガイドを確認してな。 |
版によって引数が変わる場合があるから、対象を変える前に、実際に使う版のヘルプを開くで。
npx.cmd -y rea-agents@6.7.0 analyze-javascript-application --help
npx.cmd -y rea-agents@6.7.0 analyze --help
npx.cmd -y rea-agents@6.7.0 decompile --help7.Ghidraを使う場合
GhidraはREAのネイティブ解析を受け持つProviderの1つや。「今回のJavaScript静的解析では使わない」と「REAではGhidraが不要」は別やで。Hopper・IDAなど別のProviderを使う場合も、それぞれの導入と対応対象を確認する必要があるんや。
以下はGhidraを選ぶ場合の設定とコマンドの例で、この記事では実行してへんで。公式のGhidra設定は対応版・フルJDK・ネイティブdecompilerの条件を指定してる。確認時点ではGhidra 12.1.xが対象で、Windows x64の経路は実験的なP0扱いや。GhidraやJavaはREAのsetupから自動で入るわけやないで。
Ghidraと対応するJDKを公式手順で用意したうえで、次の3つのパスを自分の実在する場所に置き換えてな。Ghidraには解凍先、JavaにはフルJDKのフォルダー、$nativeTargetには解析権限のある実行ファイルを指定するで。
$env:GHIDRA_INSTALL_DIR = "C:\tools\ghidra_12.1.4_PUBLIC"
$env:JAVA_HOME = "C:\Program Files\Java\jdk-21"
$nativeTarget = "C:\my-own-app\program.exe"
npx.cmd -y rea-agents@6.7.0 doctor --provider ghidra --target "$nativeTarget" --format jsondoctorが返した診断を読み、Ghidra・JDK・対象ファイルの準備ができているか確認するんや。問題があれば、先に表示された項目を直すで。Providerの準備が通った場合に、次でネイティブ解析へ進める。このコマンドの成功例を今回実測したという意味ではないで。
npx.cmd -y rea-agents@6.7.0 analyze "$nativeTarget" --provider ghidra --format json出力はJavaScript用のgraph.edgesと同じとは限らへんから、今回のJSON抽出コマンドをそのまま当てはめんようにしてな。Windows固有の制限は公式Windows Ghidraガイドで確認するで。
トラブルシューティング
| 困ったこと | 確認すること |
|---|---|
nodeやnpx.cmdが見つからない | Node.jsを入れた後でPowerShell 7を開き直し、node --versionとnpm.cmd --versionを確認してな。 |
EBADENGINEなどNode.jsの版に関する警告 | REA 6.7.0の対応範囲とNode.jsの版を照らし合わせるで。mainブランチや別の公開版の条件と混ぜへんようにするんや。 |
Resolve-Pathで止まる | 今いる場所をGet-Locationで確認し、Get-ChildItem .\sample-appで3ファイルが見えるか調べてな。 |
| 解析後に画面が静かなまま | 結果はrea-result.jsonへ保存してるで。Get-Item .\rea-result.jsonとGet-Content .\rea-progress.log -Tail 20でファイルと進捗を確かめるんや。 |
JSONが読めない・結果にerrorがある | 終了コードとrea-progress.logを確認してな。取得の失敗や解析の失敗を成功として扱わんようにするで。 |
参照が出ない・unresolvedになる | index.jsのimport先と実際のファイル名を照合するで。対象フォルダーを間違えてへんか、--source-pathで依存先を除外してへんかも確認してな。動的な参照は静的に解決できへん場合があるで。 |
| GhidraやJavaの診断で止まる | 今回のJavaScript用コマンドなのか、--provider ghidraを使うネイティブ用なのかをまず分けるで。後者ならGhidra・JDK・対象の対応条件を確認するんや。 |
終了と再開
今回のCLI解析は1回ごとの処理や。終了した後に常駐サーバーを止める作業は要らへんで。再開するときはPowerShell 7で練習フォルダーへ戻り、「4.解析の実行」からやり直してな。結果とログは同名ファイルを上書きするから、比較に残すなら先に別名で保存するんや。
練習データを片付けるときは、エクスプローラーでgithub-practice\reaを開き、必要な結果を残してから練習用フォルダーをゴミ箱へ移してな。
公式資料と利用条件
REA本体はMITライセンスや。Ghidraなどの解析ツール、依存コンポーネント、調べるプログラムの権利や利用条件はそれぞれ別やで。自作または解析の許可がある対象で試してな。
改訂・実行確認日:2026年10月24日。実測値はこの記事の小さな題材と上記の環境で得たものや。別のアプリで同じ件数や解析結果になるとは限らへんで。本文・図解・題材コードは独自制作。出力例は実行結果から必要な項目を抽出したもので、パスや識別用ハッシュを含む生JSON全体は掲載してへんで。