ابزار REA در نسخه‌ی 6.7.0 روی یک اپلیکیشن Node واقعی، ۵۹۸٬۹۸۳ توکن خروجی تولید کرد؛ اما با یک دستور inspect-analysis-view همان تحلیل به ۲٬۳۵۴ توکن رسید، یعنی ۲۵۴ برابر کمتر. در همین اجرا ۵۰ ماژول و ۶۷ یال import را بدون اجرای یک خط جاوااسکریپت بازسازی کرد و ۱٬۰۲۴ رابطه‌ی معنایی نگه داشت، در کنار ۵۰۴ موردی که صریحا «نامعلوم» اعلام شد.

REA چیست و چرا اصلا به درد ایجنت می‌خورد

REA مهندسی معکوس را به یک قرارداد ثابت تبدیل کرده است: به‌جای اینکه شما ابزار انتخاب کنید، API یاد بگیرید و شاهد را بین چند برنامه جابه‌جا کنید، همان کار را از طریق خط فرمان یا MCP به ایجنت بسپارید. لحظه‌ی خواندن: ۲۷ مهر ۱۴۰۵، برابر با ۱۹ اکتبر ۲۰۲۶.

در همان لحظه ریپوی morluto/rea با ۳۲۷٬۱۷۷ ستاره، ۸۲٬۸۳۴ فورک و ۱٬۲۲۴ issue باز ایستاده بود و زبان اصلی آن TypeScript است. نسخه‌ی 6.7.0 روی npm در ۲۶ مهر منتشر شده بود، یعنی یک روز پیش. کل بسته از ۲۱ تیر در npm بوده و تا لحظه‌ی خواندن ۳۳ نسخه دارد.

نکته‌ای که آن را از یک ابزار معمولی جدا می‌کند، فلسفه‌ی «شاهد» است. هر نتیجه با یک evidence_id برمی‌گردد و کنار آن confidence، authority و فهرست limitations می‌آید. یعنی ابزار دامنه‌ی ادعایش را هم برمی‌گرداند. در بخش قرارداد MCP همین تفکیک صریح است: مشاهده‌ی ایستا از مشاهده‌ی زمان اجرا جدا نگه داشته می‌شود.

تفاوت با ابزارهای هم‌رده

برای اینکه بدانید سراغ چه زمانی بروید، جدول زیر مسیرهای موجود را کنار هم می‌گذارد. ستون آخر دقیقا همان چیزی است که خود مستندات راهنمای خط فرمان ادعا می‌کنند.

هدففرمانپیش‌نیاز
اپلیکیشن جاوااسکریپتanalyze-javascript-applicationفقط Node.js
پایگاه‌داده SQLiteinspect-sqlite-databaseفقط Node.js
باینری Goinspect-go-binaryبدون نصب Go
باینری Rustinspect-rust-binaryبدون نصب Rust
چیدمان باینریinspect-binary-layoutpwntools 4.15.0
باینری بومیdecompileHopper یا Ghidra

سطر آخر را جدا کنید. doctor --json روی این ماشین چهار مهارت missing_analysis_engine برگرداند: Hopper، Ghidra، ثبت IDA و jadx. یعنی برای تحلیل بومی ابزار جداگانه لازم دارید، اما برای پنج سطر بالا هیچ نصبی لازم نیست.

نصب و اولین اجرا روی یک اپ واقعی

پیش‌نیاز سخت‌افزاری REA سخت‌گیرانه‌تر از چیزی است که در README کوتاه دیده می‌شود. نسخه‌ی خط فرمان روی Node.js باید 22.19 به بالا، یا 24.11 به بالا، یا 26 به بالا باشد. روی این ماشین Node نسخه‌ی 26.7.0 و میزبان اوبونتو 24.04 بود و هر دو بررسی node و host با وضعیت healthy برگشتند.

$ node --version
v26.7.0

# doctor بدون تغییر در سیستم: این اجرا فقط می‌خواند
$ npx -y rea-agents@latest doctor --json | head -c 400
{"healthy":false,"environment_healthy":false,"scope":{"mode":"audit-wide", ... }}

خروجی healthy:false در اینجا نقص نیست. environment_healthy فقط وقتی صفر می‌شود که همه‌ی مهارت‌های اختیاری هم آماده باشند. نکته‌ی درست این است که دو بررسی پایه‌ی node و host سبز بودند و بقیه با کد missing_analysis_engine و یک راهکار مشخص علامت خوردند.

برای دیدن فهرست فرمان‌ها بدون نصب سراسری، همان مسیر npx کافی است. در اجرای ما ۱۵۳ فرمان خط فرمان و ۲۰۷ ابزار MCP ثبت شده بودند.

$ npx -y rea-agents@latest --help | head -3
rea@6.7.0 — Reverse engineer anything from your terminal or agent.

Usage: rea <command>

اگر فرمان rea را در هر نشست می‌خواهید، نصب سراسری لازم است. نصب محلی بدون --global فرمان را به PATH اضافه نمی‌کند و در پوشه‌ی پروژه می‌ماند.

$ npm install --global rea-agents
$ rea --version
6.7.0

تحلیل واقعی: از اپلیکیشن تا گراف

هدف، بسته‌ی واقعی agent-browser نسخه‌ی 0.26.0 بود که روی همین ماشین نصب بود. مسیر یک پوشه‌ی استخراج‌شده است و نه فایل asar، پس REA خودش فرمت را تشخیص می‌دهد.

$ npx -y rea-agents@latest analyze-javascript-application \
    /root/.hermes/tools/agent-browser-0.26.0-linux-x64 > app-evidence.json
$ wc -c < app-evidence.json
2514357

اندازه‌ی فایل ۲٬۵۱۴٬۳۵۷ بایت است. این همان نقطه‌ای است که اکثر ایجنت‌ها شکست می‌خورند: اگر این خروجی مستقیم وارد کانتکست شود، هزینه‌ی یک فراخوانی دو رقم می‌شود. راه درست، ذخیره روی دیسک و برداشتن یک نمای کوچک از همان فایل است.

$ npx -y rea-agents@latest inspect-analysis-view app-view.json --token-count
2354

عدد ۲٬۳۵۴ توکن را خود ابزار با --token-count اندازه گرفته است. برای مقایسه، اندازه‌گیری کل تحلیل هم با همان پرچم ۵۹۸٬۹۸۳ توکن داد. یعنی تحلیل کامل ۲۵۴ برابر بزرگ‌تر از نمای خلاصه است.

$ npx -y rea-agents@latest analyze-javascript-application "$APP" --token-count
598983
$ npx -y rea-agents@latest analyze-javascript-application "$APP" \
    --filter-output "normalized_result.graph.nodes" --token-count
32962
خروجیتوکننسبت به کل
کل تحلیل۵۹۸٬۹۸۳۱۰۰٪
فقط گره‌های گراف۳۲٬۹۶۲۵٫۵٪
نمای خلاصه۲٬۳۵۴۰٫۳۹٪

نسبت‌ها از تقسیم ساده به دست آمده‌اند: ۵۹۸٬۹۸۳ تقسیم بر ۲٬۳۵۴ می‌شود ۲۵۴٫۵ که یعنی ۲۵۴ برابر. و ۵۹۸٬۹۸۳ تقسیم بر ۳۲٬۹۶۲ می‌شود ۱۸٫۲ برابر. برای ساختن app-view.json هم کل Evidence را در یک شیء JSON می‌پیچیدیم و view را روی summary گذاشتیم.

$ printf '%s' '{"source":{"kind":"inline","evidence":'"$(cat app-evidence.json)"'},"view":{"kind":"summary"}}' > app-view.json
$ npx -y rea-agents@latest inspect-analysis-view app-view.json --format json | head -c 300
{"evidence_id":"ev_873a05d9...","subject":{"name":"agent-browser-0.26.0-linux-x64", ... }}

نکته‌ی مهم در طراحی همین مسیر است: نما، دوباره کار نمی‌کند. inspect-analysis-view فقط از Evidence ذخیره‌شده می‌خواند و در parent_evidence_id به تحلیل مادر اشاره می‌کند. پس هزینه‌ی تحلیل را یک بار می‌دهید و بعدا هر تعداد نما از همان داده می‌سازید. مستندات گردش‌کارهای جاوااسکریپت هم می‌گویند نما «روابط را دنبال نمی‌کند».

تحلیل چه چیزی بیرون کشید

بخش statistics از همان نمای خلاصه، شمارش خام تحلیل است و مستقیم از اجرا خوانده شده است.

"statistics": {"relevant_files": 6, "nested_asar_containers": 0,
 "text_bytes_read": 20674, "invalid_utf8_files": 0,
 "parsed_javascript_files": 5, "skipped_javascript_files": 0,
 "visited_ast_nodes": 2124, "findings": 67, "modules": 0,
 "parse_failures": 0}

از شش فایل مرتبط، پنج فایل جاوااسکریپت واقعا پارس شدند و ۲٬۱۲۴ گره‌ی درخت نحوی دیده شد. تعداد یافته‌ها ۶۷ است که در جدول گراف دقیقا ۶۷ یال با رابطه‌ی imports به آن می‌خورد.

سنجهمقدار
گره‌های گراف۵۸
ماژول۵۰
دارایی۵
یال import۶۷
یال contains۱۲
کل یال‌ها۷۹

یک ماژول مشخص را می‌شود از همین ساختار بیرون کشید. برای نمونه scripts/copy-native.js با قالب esm و هشت رابطه‌ی import ثبت شده است.

"label": "scripts/copy-native.js",
"semantic_role": "source-module", "module_format": "esm",
"import_relationships": 8, "type_relationships": 0,
"export_relationships": 0, "export_names": []

مهم‌تر از این شمارش‌ها، آن چیزی است که ابزار درباره‌ی مرز اطمینانش می‌گوید. بخش coverage نشان می‌دهد از ۵۸ گره، ۵۵ گره در نمای خلاصه بررسی شده‌اند و وضعیت پوشش complete-within-view است.

"coverage": {"status": "complete-within-view", "examined": 55,
 "total": 58, "exhausted": true}
"semantic_unknowns": 504

عدد ۵۰۴ همان چیزی است که باید جدی بگیرید. این تعداد «نامعلوم» صریح است، یعنی ابزار نقاطی را که نفهمیده اعلام کرده به‌جای اینکه ساکت بماند. جمع رابطه‌های نگه‌داشته‌شده ۱٬۰۲۴ است و ۱۲ خانواده بین آن‌ها پخش شده‌اند.

خانواده‌ی رابطهنگه‌داشتهنامعلوم
data-flow۸۰۹۱۴۲
closure۹۰۰
call-flow۴۵۲۱۱
object-flow۴۵۱۳۴
configuration۱۰۶
promise-ownership۱۰۷
boundary۵۰
event۴۱
child-process۳۲
resource-lifecycle۲۰
request۱۱
timer۰۰

جالب‌ترین سطر این جدول، call-flow است: از ۲۵۶ مورد، تنها ۴۵ مورد نگه داشته شد. یعنی کمتر از یک‌پنجم مسیرهای فراخوانی از تحلیل ایستا بیرون آمده‌اند. همان data-flow با ۸۰۹ رابطه، پرمایه‌ترین بخش است. اگر از ایجنت خواستید جریان داده را دنبال کند، دقیقا بدانید کجا لنگ می‌زند.

وقتی ابزار جواب نمی‌دهد

یک ابزار تحلیل فقط وقتی قابل اعتماد است که در حالت شکست هم راست بگوید. در این اجرا دو شکست واقعی را دیدیم.

اول، تحلیل یک باینری ELF بدون ابزار جانبی. فرمان inspect-binary-layout روی /usr/bin/apt-get به‌جای نتیجه، خطای provider_unavailable داد.

$ npx -y rea-agents@latest inspect-binary-layout /usr/bin/apt-get
{"code": "provider_unavailable",
 "message": "Set REA_PWNTOOLS_PYTHON to an absolute caller-supplied Python
 executable with pwntools 4.15.0, pyelftools 0.33 and Unicorn 2.1.2;
 REA never installs Python or packages."}

خطا دقیق می‌گوید چه نسخه‌ای از چه بسته‌ای لازم است و صریحا یادآوری می‌کند که خودش چیزی نصب نمی‌کند. همین رفتار با مستندات تشخیص باینری هم‌خوان است.

دوم، فراخوانی روی باینری‌هایی که متادیتای لازم را ندارند. inspect-go-binary روی /usr/bin/Xvfb اجرا شد و یک پاکتومنده‌ی کامل برگرداند، ولی build_info برابر null بود.

$ npx -y rea-agents@latest inspect-go-binary /usr/bin/Xvfb
"build_info": null,
"limitations": ["No recognized Go build-info record was found in the
 inspected image; absent metadata does not establish that the binary
 is not Go."]

جمله‌ی آخر مهم است: «فقدان متادیتا ثابت نمی‌کند که باینری Go نیست». ابزار نتیجه‌ی منفی را به یک ادعای منفیِ ساختگی تبدیل نکرده است. inspect-rust-binary روی /usr/bin/VGAuthService هم دقیقا همین الگو را نشان داد و auditable_metadata را null گذاشت.

آزمون منفی سوم هم یک پوشه‌ی خالی بود. analyze-javascript-application روی پوشه‌ای بدون فایل با پیام «Processing 0 selected application files» تمام شد و باز هم یک پاکتومنده‌ی معتبر ساخت. یعنی ابزار روی ورودی خالی خطا نمی‌دهد، بلکه گرافی با صفر گره تحویل می‌دهد؛ ایجنت شما باید این را از اپ واقعی تشخیص دهد.

کِی سراغش برویم و کِی نه

REA وقتی ارزش دارد که سه شرط با هم برقرار باشند: هدف اپلیکیشنی باشد که سورسش را ندارید، بخشی از رفتارش را می‌خواهید بفهمید، و مدرکی بخواهید که این فهم از حدس بیرون آمده است.

$ npx -y rea-agents@latest analyze-javascript-application /path/to/app --json > ev.json
$ npx -y rea-agents@latest inspect-analysis-view ev-view.json --token-count
$ npx -y rea-agents@latest inspect-sqlite-database app.db --schema-scope inventory

برای دیتابیس هم مسیر مشابه است. در این اجرا روی یک پایگاه‌داده‌ی محلی، اسکیمای دو جدول و یک ایندکس برگشت.

$ npx -y rea-agents@latest inspect-sqlite-database demo_reas.sqlite
"engine": {"name": "SQLite", "version": "3.53.4"},
"schema": {"tables": [{"name": "subscriptions", "column_count": 5},
                       {"name": "api_keys", "column_count": 4}],
            "indexes": ["idx_plan,subscriptions,3"], "views": [], "triggers": []}

سه محدودیت را جدی بگیرید. REA سورس اصلی را بازیابی نمی‌کند؛ خودش در نقشه‌ی راه بازسازی رفتار را هدف می‌گیرد. تحلیل ایستا یعنی کد مبهم‌ساز و مسیرهای پویا از دست می‌روند. و برای باینری بومی هنوز Hopper یا Ghidra می‌خواهد.

پس الگوی واقعی این است: تحلیل را یک بار روی دیسک انجام دهید، هزینه‌ی آن را نپردازید، و فقط نمایی را که لازم دارید وارد کانتکست کنید. اگر پیش از آن بودجه‌ی کانتکست را خوانده‌اید، حالا می‌بینید این ابزار همان جایی است که آن پست توصیف می‌کرد: ورودی بزرگ، اگر مدیریت نشود، کل پنجره را می‌بلعد.

برای دیدن نسخه‌ی سبک‌تر همین روش روی یک ابزار محلی، پست خط لوله‌ی تست پرامپت بدون کلید API را بخوانید؛ آنجا هم همه‌چیز روی همان ماشین می‌ماند.

منابع

  1. ریپوی morluto/rea روی گیت‌هاب — شمارش ستاره، فورک و تاریخ‌ها در لحظه‌ی ۱۹ اکتبر ۲۰۲۶
  2. متن کامل README پروژه — ادعای «یک MCP برای مهندسی معکوس» و جدول هدف‌ها
  3. راهنمای خط فرمان و Evidence — الگوی ذخیره روی دیسک و ساخت نما
  4. راهنمای نصب و راه‌اندازی — پیش‌نیازهای نسخه‌ی Node و میزبان
  5. گردش‌کارهای بین‌لایه‌ی جاوااسکریپت — تفاوت گراف ساختاری و معنایی
  6. قراردادهای MCP — کاتالوگ ابزارها و تفکیک مشاهده‌ی ایستا از زمان اجرا
  7. راهنمای تشخیص باینری — الزام pwntools برای چیدمان ELF
  8. تحلیل بومی — نقش Hopper، Ghidra و IDA
  9. نقشه‌ی راه — مرز میان بازیابی سورس و بازسازی رفتار
  10. پروانه‌ی MIT پروژه
  11. سیاست امنیتی — گزارش آسیب‌پذیری
  12. بسته‌ی rea-agents روی npm — نسخه‌ی ۶٫۷٫۰ منتشرشده در ۲۶ مهر
  13. وب‌سایت رسمی REA — راهنماها و مطالعات موردی