2026-10-27

話題のREAを触ってみた

最近、GitHub Trendingで REA(Reverse Engineer Anything) というリポジトリをよく見かけるようになりました。スター数は約40万と、とんでもない数字です。「AIエージェントにリバースエンジニアリングをさせるツール」とのことで、どれくらいのことができるのか気になったので、実際に触ってみました。

リバースエンジニアリング自体が初めてだったので、今回はClaude Codeと一緒にREAを使ってどんなことができるのかを試してみました。 題材には、お絵描きツール Excalidraw の共同編集機能を選びました。「なぜサーバーに絵の中身が見えないのか」をREAで調べてみた結果と、使ってみて感じたことをまとめます。

REAとは

REAは、一言でいうと「AIエージェントにリバースエンジニアリング用の道具箱を渡すMCPサーバー」です。

REAをMCPサーバーとして登録すると、AIが「このアプリの検索ってどう動いてる?」といった質問に対して、REAのツールを使って対象を調べ、根拠付きで答えてくれるようになります。

REA自身が解析エンジンを持っているわけではなく、Ghidraなどの既存ツールを、AIが扱いやすい形にまとめる「つなぎ役」になっています。

ここで出てくるGhidra・Hopper・IDAは、どれも実行ファイルの中身を人間が読める形に戻すための、リバースエンジニアリング用のツールです。実行ファイルはCPU向けの命令(機械語)の並びになっていて、そのままでは読めません。これらのツールは、機械語をアセンブリ(命令を文字で表したもの)に変換したり、さらにC言語に近い擬似コードに戻したりしてくれます。

ツール特徴
Ghidra アメリカの国家安全保障局(NSA)が公開している無料のOSS
Hopper macOS / Linux向けの有料ツール。比較的手頃な価格
IDA 業界標準と言われる有料ツール。機能を絞った無料版もある

なお、これらのツールはREAに含まれていないので、使う場合は自分でインストールする必要があります(HopperとIDAは有料)。今回の検証ではブラウザ観察の機能だけを使ったので、どれもインストールしていません。

解析できる対象はかなり幅広いです。主なものを抜き出すとこんな感じです。

分類例必要なもの
ネイティブバイナリC / Rust / Go の実行ファイル → 擬似コード、アセンブリ、関数の呼び出し関係Ghidra / Hopper / IDA
JS / Electron / .NETElectronアプリのモジュール構成や、画面側と裏側の通信(IPC)追加ツール不要
Webページの構造、読み込まれたスクリプト、通信Chrome系ブラウザ

他にもAndroidのAPK、Unity / Godotのゲームデータ、pcap(通信の記録ファイル)など、READMEの対応表はかなり長いです。

特徴的なのは、結論に必ず「根拠」と「限界」が付いて返ってくることです。「たぶんこう」ではなく、「このファイルのこの部分が根拠で、ここから先は分からない」という形で結果が返ってきます。

セットアップ

MCPサーバーの登録

公式の手順では npx rea-agents setup を実行すると、対話形式で登録先のエージェントを選べます。

Excalidrawの共同編集を調べてみる

調べたいこと

Excalidrawは、手書き風の図を描けて、URLを共有するだけで共同編集もできるホワイトボードツールです。共同編集の機能は「Live collaboration」と呼ばれていて、始めるとURLが次のような形に変わります。

Excalidrawは「共同編集のデータはE2E暗号化(送る人と受け取る人だけが読める暗号化)されている」と説明しています。そこで、「なぜサーバーに絵の中身が見えないのか」 を、REAを使って自分で確かめてみることにしました。

なお、Excalidraw は MITライセンスのOSS で、ソースコードが公開されています。最後にソースと答え合わせができるのも、題材に選んだ理由です。

鍵は何のためにあるのか

検証に入る前に、そもそも鍵が何のためにあるのかを整理しておきます。

共同編集では、描いた図形を相手の画面に出すために、データが必ずExcalidrawのサーバーを経由します。暗号化しなければ、運営者やDBを提供しているGoogle、サーバーに侵入した攻撃者など、途中にいる誰にでも中身が読めてしまいます。

そこで、

  • データはブラウザの中で鍵を使って暗号化してから送る
  • 鍵はURLのフラグメントに入れて、URLを共有することで相手に渡す(サーバーには届かない)

という形にすれば、サーバーを経由してもデータを読まれずに済みます。鍵付きの箱で郵便を送り、合鍵は郵便局を通さずに相手へ直接渡すイメージです。サーバーは「どの部屋に届けるか」は分かっても、「何が描かれているか」は分かりません。

URLの #room= 以降の2つの値は、それぞれ次の役割を持っています。

部分役割サーバーに渡る?
部屋IDどの部屋のメンバーにデータを中継するかの宛先渡る
暗号鍵データを暗号化・復号する渡らない

裏を返すと、URLそのものが合鍵です。URLを知っている人は誰でも部屋に入って中身を読めますし、URLをなくすと運営者でも復元できません。共同編集のURLを気軽にチャットに貼らないほうがいいのは、このためです。

ここからは、本当にこの仕組みになっているのかを、REAで確かめていきます。

通信を観察する

観察は次の流れで行いました。

1. デバッグポートを開けたChromeを起動する

REAのブラウザ観察は、REAがブラウザを起動してくれるわけではありません。Chromeの開発者向けの接続口(CDP: Chrome DevTools Protocol)を開けた状態で自分で起動し、そこにREAが接続する方式です。

※ WSLのターミナルからChromeを起動しています

  • --remote-debugging-port=9222: 127.0.0.1:9222 でCDPの接続を受け付ける
  • --user-data-dir: 普段使いとは別の、使い捨てのプロファイルを使う(理由は後述)
  • --password-store=basic: Linuxでキーリング(パスワードの保管庫)の確認に引っかかって、Chromeの起動が止まるのを防ぐ

普段使っているChromeにつなげばいいのでは、と思うかもしれませんが、REAで調査するときは、このようにREA用のChromeを別で起動するのがおすすめです。理由は2つあります。

1つ目は、そもそも普段のプロファイルでは使えないことです。デバッグ用のポートが開いていると、接続したプログラムはCookieやログイン状態も含めてブラウザを丸ごと操作できてしまいます。これを悪用してCookieを盗むマルウェアがあったため、Chrome 136以降は、普段使いのプロファイルでは --remote-debugging-port が無視されるようになりました。

2つ目は、余計な情報をAIに渡さないためです。普段のプロファイルには、Googleアカウントや各サービスのログイン状態、開いている他のタブなどが含まれています。REAの観察結果はAIに渡されるので、普段のプロファイルにつなぐと、調べたいページと関係ない情報までAIに見えてしまう可能性があります。使い捨てのプロファイルなら空の状態から始まりますし、使い終わったらフォルダごと消すだけで済みます。

ログインが必要なページを調べたいときも、普段のChromeにつなぐのではなく、REA用のChromeで調べたいサービスにだけログインするのが安全だと思います。

2. Claude CodeからREAを呼び出す

REAのMCPサーバーは、自分で起動する必要はありません。claude mcp add で登録しておけば、Claude Codeの起動時に、登録したコマンド(npx -y rea-agents@6.8.0 mcp)が裏で自動的に実行されます。Claude Codeの中で /mcp を開くと、REAが接続済みになっているのを確認できます。

あとはClaude Codeに日本語で「Excalidrawの通信を観察して」と頼むと、REAのツールを順番に呼び出してくれます。実際に呼ばれたのは次の2つでした。

  1. list_browser_targets: Chromeで開いているタブの一覧を取得して、ExcalidrawのタブのIDを調べる
  2. inspect_web_page: そのタブに接続して、指定した時間だけ通信やDOMを記録する

3. 観察中に自分で操作する

inspect_web_page は、呼び出した時点から観察を始めます。接続する前の通信は記録されないので、観察が始まってから、自分の手でExcalidrawの共同編集を開始して、図形をいくつか描きました。

一度、観察の時間内に操作が間に合わず、何も記録されなかったことがありました。観察時間は、余裕を持って長めに取ったほうがいいです。

4. 結果を読む

観察の結果は、JSONで返ってきます。

観察の結果、通信は大きく2種類ありました。

  • Firestore(GoogleのDB) への保存・読み込み
  • oss-collab.excalidraw.com とのWebSocket通信

観察で分かったこと

鍵はサーバーに送られていない

まず、URLに入っている暗号鍵の文字列を、観察結果の全体から検索しました。見つかったのはページ自身のURLの2か所だけで、通信先のURLには1回も出てきませんでした。

ただし、REAは安全のため、通信の本文(ボディ)を保存しない設計になっています。記録されるのは「どんな構造のデータか」という形だけです。なので、厳密には「本文の中に鍵が入っていない」ことまでは、この観察だけでは言い切れません。ここは後でコードを読んで補います。

サーバーに保存されているのは暗号文だけ

Firestoreから返ってきたデータの構造は次のとおりでした。

絵の中身を読める形で持っているフィールドはありません。サーバー側のDBには、鍵がないと読めないデータしか置かれていないことが分かります。

WebSocketの通信は「宛名+暗号文+乱数」の3点セット

WebSocketは、ブラウザとサーバーをつなぎっぱなしにして、どちらからでも好きなときにデータを送れる通信方式です。普通のHTTPは「ブラウザが頼んで、サーバーが答える」の一往復で終わりますが、WebSocketは電話をつなぎっぱなしにしているイメージです。共同編集のように、相手の動きをすぐに反映したい場面で使われます。

WebSocketで送る1回分のデータをフレームと呼びます。フレームには、文字列を送るテキストフレームと、生のデータを送るバイナリフレームがあります。

Excalidrawから送られていたフレームを集計すると、次のようになりました。

フレーム回数正体
テキスト 116B214回宛名(イベント名 server-volatile-broadcast と部屋ID)
テキスト 107B70回宛名(イベント名 server-broadcast と部屋ID)
バイナリ 12B284回IV(暗号化のたびに作る使い捨ての乱数)
バイナリ 135〜938B多数暗号化された絵のデータ

宛名の数(214 + 70 = 284)と12Bのフレームの数(284)がぴったり一致しています。つまり、送信のたびに「宛名 → 暗号文 → IV」の3点セットを送っていることになります。

宛名が2種類あるのは、送る内容の重要度の違いです。volatile(揮発性)が付いているほうは「届かなくてもいい」通信で、マウスの位置のように頻繁に送るものに使われていそうです。116Bと107Bの差の9バイトは、イベント名の文字数の差(25文字 − 16文字)とちょうど一致します。ただ、どちらがどの操作に対応するかは、中身が暗号化されているので推測です。

ここで出てきたAES-GCMとIVについても整理しておきます。

AES-GCM は、今いちばん標準的に使われている暗号化の方式です。AESは、同じ鍵で暗号化と復号をする「共通鍵暗号」のアルゴリズムで、GCMはその使い方(モード)の1つです。GCMを使うと、中身を隠すだけでなく、暗号文が途中で書き換えられていないかも見抜けます。Excalidrawでは、URLで共有した鍵を使って、この方式で絵のデータを暗号化しています。

IV(Initialization Vector) は、暗号化するたびに鍵と一緒に混ぜる、使い捨ての乱数です。IVがないと、同じ鍵で同じデータを暗号化したときに毎回同じ暗号文になり、中身は読めなくても「さっきと同じ操作をした」というパターンが外から分かってしまいます。IVを毎回変えることで、同じデータでも暗号文が変わるようになります。

IVは受け取る側も復号に使うので、秘密にする必要はなく、暗号文と一緒にそのまま送ります。12バイトのフレームが毎回送られていたのは、このためです。AES-GCMでは、IVの長さは12バイトが推奨されています。

サーバーから見えるのは「どの部屋宛てか」だけで、「何が描かれたか」は分からない、という形になっています。

JSのコードで裏付ける

次に、REAの export_web_scripts で、ページに読み込まれていたJavaScriptをファイルとして書き出しました。圧縮されたメインのバンドル(約2.2MB)を検索すると、暗号化に関する処理が見つかりました。読みやすいように抜き出して整形すると、次のような処理です。

鍵の生成と暗号化には、ブラウザに標準で入っている Web Crypto API を使っています。鍵を作るのも、暗号化するのも、すべてブラウザの中で完結していることが分かります。

ソースと答え合わせ

最後に、GitHubのソースコード とClaude Codeに見比べてらい、結果は、REAで観察・検索した内容と一致していました。

  • 暗号化の処理(encryption.ts )では、AES-GCMで暗号化し、IVの長さは12バイトになっていた
  • WebSocketで送る処理(Portal.tsx )では、部屋の鍵で暗号化してから、イベント名・部屋ID・暗号文・IVを送っていた。これが観察で見えた「宛名+暗号文+IV」の3点セットの正体だった
  • 鍵をサーバーへ送る処理はなかった。通信の観察だけでは言い切れなかった「本文の中にも鍵は入っていない」という点も、これで裏付けられた

40万スターの理由

触ってみても、正直なところ「40万スターも付くほどなのか」という理由は、まだ分かりませんでした。

ただ、REAが紹介している事例は、古いゲームの計算処理をC言語で復元したものなど、ネイティブバイナリの解析がほとんどです。ネイティブバイナリは、CPUが直接実行する機械語だけで書かれた実行ファイルで、変数名やコメントがほとんど残っていません。読める形に戻すところから大仕事なので、ここをAIに任せられるのは、専門家にとって大きいのだと思います。

一方で、Webエンジニアの自分の普段の仕事には、ネイティブバイナリを解析する場面がほとんどありません。今回はREAの得意分野を試していないので、REAの良さが分からなかったのだと思います。

まとめ

話題のREAを使って、Excalidrawの共同編集の仕組みを調べてみました。URLに入っている鍵がサーバーに送られていないことや、絵のデータがブラウザの中で暗号化されていることを、自分の目で確かめられたのは面白かったです。

ただ、実際にWebサービスの機能を解説してもらう体験は初めてで楽しかったですが、Webサービスではフロントエンドの処理しかリバースエンジニアリングできません。オープンソースでないサービスを調べると、中途半端な結果に終わることが多そうでした。組み込みなどでより力を発揮しそうなMCPだなと思いました。

参考資料

Thanks for the visit Nozo Blog