REA入門:アプリの内部動作を、根拠をたどりながら調べる

「このファイルはどこを読み込んでるんやろう?」を、元コードの位置と対応させて調べたい。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 winget

PowerShell公式のWindows向け導入案内も確認してな。次にNode.js公式サイトで、Windows x64用の24系LTSインストーラーを選んで入れるで。PowerShell 7を開き直して、次を実行してな。

$PSVersionTable.PSVersion
node --version
npm.cmd --version

PowerShellは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.jssearch.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-applicationJavaScript/Electronのアプリ用の静的解析コマンドや。
"$target"解析するフォルダーの絶対パスや。空白を含むパスも1つの引数として渡すため引用符を付けるで。
--format json結果をJSONで出す指定や。
1> rea-result.jsonPowerShellが標準出力をこのファイルへ保存する指定や。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.jsimport文に書いた読み込み先の文字列や。
resolved_path: search.jsREAが題材の中で対応付けたファイルや。
resolution_status: resolvedこの参照先を解決できたという意味や。関数の動作や全経路まで保証するものやないで。

最後に元ファイルを表示して、解析結果の根拠を自分で確かめるんや。

Get-Content .\sample-app\index.js
Get-Content .\sample-app\search.js

index.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も確認してな。

導入と解析の流れ

自分のPC:今回の静的解析npmの配布元(PCの外)REA CLIを取得する場所導入時:CLIを取得自作のJSファイル解析する対象REA CLIPowerShellで実行rea-result.json結果を保存して読む読む表示実線:今回の解析 / 点線:CLIを入れるときの取得npmは配布元。解析するたびに結果を返す相手としては描かない。
CLIの取得と、自分のコードを読む処理を分けたで。この記事の静的解析コマンドを示した図で、REAの全機能が外部通信なしで動くと保証するものやないで。 独自制作の説明図で、製品画面や実行結果やないで。スマートフォンでは横へスクロールしてな。

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 --help

7.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 json

doctorが返した診断を読み、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全体は掲載してへんで。