Files
rea/README_ar.md
T
e4d3e1399d feat(flutter): identify Dart snapshot builds and inspect AOT payloads by pure APK parsing (#1582)
* feat(flutter): identify Dart snapshot builds by pure APK parsing

Add a flutter-provider family with one operation, identify_flutter_build,
that reads an APK's lib/<abi>/libapp.so and libflutter.so through the
hardened ZIP reader and reports build facts as observations:

- The Dart VM snapshot hash, read 20 bytes after every snapshot magic
  (f5f5dcdc). The vm and isolate sections are cross-checked: agreeing
  sections collapse to one snapshot_hash, disagreeing sections keep every
  candidate with snapshot_hash null and partial coverage.
- Per-ABI library digests and byte sizes, plus the engine library's GNU
  build-id note and any labeled 'Dart VM version' or Android clang/LLVM
  toolchain strings, verbatim; release builds without a version string
  report null rather than a guess.
- The APK is digested before parsing so Evidence binds the observation to
  the exact input, and a target with no libapp.so reports not-detected
  with complete coverage.

The scanner is streaming with explicit pending-magic and rescan
bookkeeping, so chunk boundaries cannot double-count or drop sections, and
magic-free streams never accumulate. No engine, no external lookups: the
hash-to-SDK mapping stays with external datasets by design.

Verified against Flutter Gallery 2.9.2 (112 MB, three ABIs): every ABI
reports the same agreeing hash 65817c30a78bb44c3dc3771876b6010a from two
sections, per-ABI build-ids, and the clang toolchain line; a plain
aapt2-built APK reports not-detected with complete coverage. Scanner
goldens come from the same libraries. READMEs carry the new 'Flutter apps'
row in every supported language.

* feat(flutter): inspect Dart AOT snapshots through the ELF symbol table

Add inspect_dart_aot to the flutter family: for one ABI's libapp.so it
locates the four _kDart*Snapshot* symbols through the ELF dynamic symbol
table (ELF32 and ELF64 little-endian, bounds-checked reads; a payload
without exported symbols is refused), reports each section's offset and
size, validates data-section headers (magic, kind, length; instructions
sections honestly report nulls for the fields their layout does not
carry), and projects a bounded string pool from the isolate data section:
distinct package: source URIs (the app's dependency inventory), dart: SDK
URIs, and identifier-shaped tokens, each with counts, bounds, and partial
coverage when truncated.

The string pool is labeled as a byte-pattern projection, not deserialized
cluster semantics: typed class and function recovery remains an
SDK-specific parser, which the snapshot hash now unlocks. The ABI is
caller-selected with a deterministic default (arm64-v8a, x86_64, then
first available).

Verified against Flutter Gallery 2.9.2: all four symbols on both ELF64
(arm64-v8a) and ELF32 (armeabi-v7a) images, header validation, hash
agreement with identify_flutter_build, and a 756 package: / 201 dart:
URI pool from the isolate data section; goldens in DartElf.test.ts come
from the same libraries.

* fix(flutter): own snapshots, bound image reads, and preserve cancellation

Mirror the ownership bar the maintainers applied across the merged JEB,
ADB, and Apktool PRs:

- Copy the admitted APK into a provider-owned, read-only snapshot (EXCL
  create, chmod 0400) before digesting and parsing; every later read uses
  the snapshot, so a concurrently modified original cannot mix into one
  observation. The result reports the snapshot's byte size and digest.
- Retain failed snapshot-root cleanup in a provider set and retry it on
  close(), throwing an aggregate error when a root is still owned; root
  removal is injectable so the retention is testable.
- Allocate the AOT image buffer at exactly the declared library size
  before reading (bounded before allocation, not concat-after-stream),
  keep the 256 MiB ceiling, and check cancellation between digest and
  stream chunks through a captured abort reason.
- Accept APK paths containing spaces (covered by a fixture test) and
  escape the ABI pattern's dash for v-mode regex compatibility.

Also add tests for cleanup retention with close retry and for
cancellation before any snapshot root is created.

* docs(flutter): cover the Italian README with the Flutter row

The Italian translation landed between the merged feature PRs; its table
now carries every merged row plus this one, keeping its documentation-link
set identical to README.md.

* fix(flutter): make the ABI pattern portable for v-mode validators

Use a hex-escaped hyphen in the ABI character class, matching the form
the ADB portability fix uses, so clients compiling advertised schemas in
unicodeSets mode accept the inspect_dart_aot input schema.

* refactor(flutter): reuse shared harnesses and deduplicate the vertical

The duplicate-detection gate (jscpd, 2.5% threshold) tipped to 2.51% with
the flutter files added. Reuse the existing machinery instead of repeating
it:

- FlutterBuildAnalysisService delegates to executeProviderOperation, the
  shared admission/Evidence composition, instead of restating its body.
- The CLI registers both commands from one table-driven spec.
- Boundary tests use the shared serveCli and assertAdvertisedMcpContracts
  harnesses rather than hand-rolled equivalents.
- The provider test consolidates the four payload-shape cases into one
  table-driven case; the service test uses one admission table and
  distinct phrasings.

Duplicate lines fall from 2.51% to 2.48%, back under the gate.

* fix(flutter): address review findings from real-app verification

CassieFox23 verified the PR against three real F-Droid Flutter apps and
a control app, and found five gaps. All are fixed and re-verified against
cone (info.tangential.cone), one of the tested apps:

- Build-id: the scanner now reads the descriptor length from the note
  header instead of assuming 20 bytes, so 8-byte ids from older
  toolchains parse; the schema accepts 8-128 hex characters. Verified
  against cone's readelf-reported ids on all three ABIs.
- Compiler line: the toolchain capture bound rises from 200 to 500
  characters, keeping cone's 262-character clang line verbatim.
- Zero-byte libapp.so: the extraction target is created before streaming,
  so an empty entry yields a clean unsupported_target refusal for
  inspect_dart_aot and elf_header_valid: false with partial coverage for
  identify_flutter_build, instead of a raw ENOENT with code UNKNOWN.
- Truncated library: identify_flutter_build marks fewer than two snapshot
  sections as partial coverage with a limitation naming the count, and a
  missing ELF magic gets its own limitation.
- Docs: the default ABI preference now matches the code exactly
  (arm64-v8a, x86_64, x86, armeabi-v7a, then the rest alphabetically).

Also: every test that read the author's /tmp/opencode goldens now builds
a self-contained synthetic ELF64 image with dynsym, four snapshot
symbols, two snapshot sections, and a string pool, so the suite runs
anywhere; the verify lane now requires a present hex build-id per ABI
instead of accepting null.

* fix(flutter): address the Codex review findings

Eight findings, all applied:

- P1: SnapshotHashScanner keeps candidates in a Set (no quadratic
  Array.includes) with a 64-distinct-hash cap, so a hostile payload of
  magic+hash records cannot stall the scan or bloat the response.
- P1: projectStringPool stops admitting new distinct entries once each
  category reaches twice its projection bound and reports
  collectionCapped; allocation and sorting now track the response, not
  the payload.
- P2: ZIP reader rejections during entry iteration or entry streaming
  map into the typed error algebra (cancellation vs input refusal)
  instead of escaping as unhandled exceptions in both operations.
- P2: magic_valid now marks coverage only for the *Data symbols; a
  complete four-symbol image with valid data magics reports complete
  coverage (the instruction symbols intentionally lack the magic).
- P2: the MCP server closes the Flutter provider during shutdown, so a
  retained snapshot root is retried and reported, not leaked.
- P2: LabeledStringScanner commits matches only when a printable run is
  delimiter-terminated; the carry grows to 600 bytes so a 500-character
  toolchain line survives any chunk boundary untruncated.
- P2: both Flutter tool effects declare writesFilesystem: true; the
  owned APK snapshot and extracted libapp.so are temporary writes.
- P2: the verify lane asserts every ABI agrees on exactly one snapshot
  hash instead of discarding the computed set.

* fix(flutter): address the second Codex review round

Nine findings on the first-round fixes:

- P1: identify_flutter_build enforces a cumulative extraction budget
  (768 MiB) across every library entry, not just per library, so an APK
  with many ABIs cannot stream an unbounded total.
- P1: a single NUL-free printable run stops materializing at 1024 bytes
  and marks the pool capped, so an adversarial one-run section cannot
  allocate unbounded strings.
- P1: ELF cString bounds the NUL-terminator scan to the name maximum
  plus one, so malformed symbol tables cannot scan the whole image per
  entry.
- P2: mapReaderFailure distinguishes ArtifactReaderFailure texts —
  budget/limit rejections map to resource constraints, integrity
  failures (CRC/overlap/signature) to their own input refusal — instead
  of collapsing all reader failures into one message.
- P2: the labeled-string carry is cleared when a delimiter commits a
  run, so consecutive toolchain lines are never concatenated.
- P2: string-pool counts are renamed *_count_at_least and documented as
  lower bounds, because capped collection discards values beyond twice
  the projection bound.
- P2: inspect_dart_aot marks hash disagreements, non-pair source counts,
  and candidate-cap saturation as partial coverage.
- P2: only valid lowercase-hex hash records count as snapshot sources;
  complete magic records with non-hex fields do not inflate agreement.
- P2: the per-entry size refusal in inspect_dart_aot moves after ABI
  selection, so an oversized unselected ABI no longer refuses a small
  request.

* fix(flutter): address the third Codex review round

Five findings:

- P2: the owned snapshot revalidates the source after the copy (size,
  mtime, inode), so an in-place replacement or swap mid-copy refuses
  the observation instead of publishing mixed bytes.
- P2: a failed ZipArtifactReader close retains the snapshot root for
  close() retry instead of silently swallowing the descriptor leak,
  in both operations.
- P2: snapshot headers are parsed within their symbol bounds and a
  symbol smaller than the 16-byte header reports magic_valid false,
  so trailing-image bytes can no longer fake a valid data section.
- P2: the verify lane counts provider.close() cleanup failures as
  lane failures instead of certifying a run with retained roots.
- P2: LabeledStringScanner reports toolchain_capped when further
  distinct matching lines are observed past the 4-line projection;
  identify marks such results partial with a naming limitation.

* fix(flutter): address rounds three and four of the Codex review

Round three (one missed finding) plus round four (five findings):

- P2: the GNU build-id note descriptor size is decoded from all four
  bytes of the little-endian field, rejecting nonzero high bytes
  instead of masking them to 16 bits.
- P1: the Flutter MCP handlers route through createContractToolHandler
  and the session's analysisAdmission, so close_binary and snapshot
  operations drain in-flight Flutter calls instead of racing them.
- P2: the owned-snapshot copy is a streamed, abort-checked write (no
  copyFile), so cancellation stops the write promptly while the
  source-identity revalidation (size, mtime, inode) still guards
  against mid-copy replacement.
- P2: identify marks any snapshot_hash_sources value other than exactly
  two as partial, matching the inspection path's pair requirement.
- P2: the verify lane refuses to run without --apk (exit 2) instead of
  printing a false-green pass, and the engine check requires every
  libapp-carrying ABI to have a present libflutter with a valid hex
  build-id rather than filtering missing engines away vacuously.

* fix(flutter): address the fifth Codex review round

Six findings plus the upstream duplication baseline:

- P2: the flutter-provider kind reports available in the capability
  inventory, so binary_session no longer lists always-registered
  Flutter tools as provider_missing.
- P2: printable runs that exceed the 1024-byte cap are discarded at
  their delimiter instead of emitting their truncated prefix as a
  fabricated observation.
- P2: ELF symbols must fit inside the file-backed portion of their
  PT_LOAD segment (p_filesz), so addresses in gaps or BSS are refused
  instead of accepting unrelated bytes.
- P2: the build-id carry spans the complete 80-byte maximum note
  (16-byte header + 64-byte descriptor) so chunk-boundary splits
  cannot drop the first byte.
- P2: the labeled-string carry is sized for the toolchain pattern's
  true 605-byte maximum, not the previous 600.
- P2: the AOT completeness predicate requires exactly two sources and
  one candidate unconditionally, so zero-source images with valid data
  magics report partial instead of complete.

Also: the shared ELF fixture builder and snapshot-section helper moved
to a dedicated FlutterTestFixtures module, eliminating cross-file test
duplication; jscpd now passes at 2.50% while main sits at 2.52%.

* fix(flutter): address the sixth Codex review round

Five findings:

- P2: snapshot-hash scanning is bounded to the exported data symbols'
  byte ranges, so decoy or stale magic/hash sequences elsewhere in the
  image cannot inflate source counts or contribute candidates.
- P2: labeled-string runs longer than the carry bound are rejected
  instead of truncated, preventing a regex prefix from being published
  as a verbatim source string.
- P2: the AOT image reread checks cancellation between file reads and
  before the synchronous parsing stage, so a cancelled caller cannot
  receive a success from a completed 256 MiB read.
- P2: the verify lane requires exactly two snapshot sources per ABI,
  matching the provider's pair requirement, instead of accepting any
  count >= 2.
- P2: ELF section and program header entry sizes are validated against
  the class-defined minimum widths before walking either table, so
  undersized entries cannot cause field reads to cross into
  neighboring bytes.

* fix(flutter): address the seventh Codex review round

Six findings:

- P2: data-symbol ranges are deduplicated by offset and size, so aliased
  symbols mapping to the same bytes are scanned once and the result
  marks partial coverage with a limitation naming the shared range.
- P2: openEntrySafely forwards return/throw to the underlying Readable's
  iterator, so an early for-await exit closes the ZIP entry stream and
  releases its producer instead of leaking a backpressured pipe.
- P2: inspect_dart_aot now reports snapshot_hash_candidates and
  snapshot_hash_sources alongside snapshot_hash, so a null hash from
  conflicting evidence is distinguishable from missing hash data.
- P2: overlong printable runs only set toolchain_capped when they begin
  with a recognized label prefix (Dart VM version: or Android (); other
  long strings such as license text are skipped without marking partial.
- P2: readElfSymbol falls back to PT_DYNAMIC/DT_SYMTAB when section
  headers are absent (e_shnum 0, ET_DYN), so stripped Flutter libraries
  with exported snapshot symbols are no longer refused; the dynamic
  table is bounded by DT_STRSZ, DT_SYMENT, and the image end.
- P2: the verify lane exercises inspect_dart_aot for every ABI carrying
  libapp.so, not just the preferred default.

* fix(flutter): address the eighth Codex review round

Five findings:

- P2: each data-symbol range gets a fresh SnapshotHashScanner so the
  carry from one noncontiguous slice cannot fabricate a record spanning
  into the next; results are aggregated after scanning.
- P2: dynsym name lookups are bounded to the linked string table —
  st_name offsets outside the table and terminators beyond it are
  rejected instead of reading unrelated payload bytes as symbol names,
  in both the section-header and PT_DYNAMIC paths.
- P2: identify_flutter_build routes its reader.entries and reader.open
  calls through the same collectEntriesSafely and openEntrySafely
  wrappers as inspect_dart_aot, so malformed ZIPs surface as input
  refusals instead of AnalysisProtocolError.
- P2: mapReaderFailure recognizes ArtifactReaderFailure texts carrying
  a cancelled reason, mapping them to AnalysisCancelledError instead
  of AnalysisInputError.
- P2: the cumulative extraction cap is enforced inside the chunk loop,
  not after each library completes, so refusal happens before the
  remaining bytes are streamed and hashed.

* fix(flutter): harden streaming, sizes, and cancellation after self-review

Four issues found in a systematic self-audit across all bug classes
from eight Codex rounds:

- createReadStream in both the digest function and the owned-snapshot
  copy now receives the AbortSignal directly, so cancellation aborts
  the filesystem read at the source instead of waiting for the next
  chunk to arrive on a slow filesystem.
- The owned snapshot enforces a 2 GiB APK-level size cap before any
  copy I/O, so a path pointing at an enormous file is refused before
  disk usage grows.
- identify_flutter_build preflights the sum of declared entry sizes
  against the 768 MiB cumulative budget, refusing before any ZIP
  extraction when the declared total already exceeds it.
- The LabeledStringScanner triple result() call is collapsed to a
  single invocation (the previous code called result() three times in
  the emission, relying on end() being idempotent).

No behavior change for valid inputs; all 36 tests, check:fast, and
the cone verify lane pass unchanged.

* fix(flutter): require structurally parseable ELF headers for complete coverage

CassieFox23's third corrupt-header case: an ELF with valid magic but
zeroed section/program header offsets passes the 4-byte magic check
and the byte scanner still finds hash patterns in the data sections,
so identify_flutter_build reports complete coverage for a structurally
broken file.

The elf_header_valid check now also verifies beyond the magic:
e_type must be a known value (ET_REL/ET_EXEC/ET_DYN), at least one
of e_shoff/e_phoff must be non-zero, and at least one of
e_shnum/e_phnum must be non-zero. A file with valid magic but zeroed
structure reports partial coverage with the existing ELF-magic
limitation.

* fix(flutter): validate ELF and snapshot coverage

Share bounded ELF header parsing between identification and inspection. Accumulate headers across ZIP chunks and validate table entry widths and extents before claiming complete identification coverage.

Bind AOT hashes to the exported VM and isolate headers, validate stored snapshot lengths including the magic bytes, and preserve partial evidence for missing, malformed, aliased, or overlapping data headers.

Preserve native stream cancellations and APK resource constraints across both operations. Bound snapshot copies while streaming and retain useful input-failure diagnostics and lower-bound count wording.

Validation: 72 focused tests; check:fast; check including formatting; docs:check; test discovery; jscpd; real cone APK and non-Flutter control on Linux. Verified CLI/MCP parity for valid and corrupted ELF headers and AOT inspection across three ABIs. Native Windows and macOS were not run.

* fix(flutter): unify artifact ownership and bound ELF evidence

* fix(flutter): preserve ELF provenance and partial coverage

Read GNU build IDs only from bounded ELF note ranges and retain conflicting candidates. Preserve source versus owned storage failures and honor cancellation through parsing and final cleanup.

Separate snapshot structure from string-pool coverage. Verify every Gallery ABI with digest-bound engine labels and URI counts, and document the supported snapshot-kind layout.

---------

Co-authored-by: REA Contributor <contributor@rea.tools>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-12 22:35:55 +08:00

25 KiB

English · 简体中文 · 繁體中文 · 日本語 · 한국어 · Türkçe · Русский · Tiếng Việt · ไทย · Deutsch · Español · Français · Українська · Polski · Português (Brasil) · العربية · فارسی · Bahasa Indonesia · Italiano

REA: هندسة عكسية لأي شيء

خادم MCP واحد للهندسة العكسية للملفات الثنائية والتطبيقات والسلوك أثناء التشغيل.

وجدت ميزة تعجبك؟ افهم طريقة عملها حتى مستوى الشيفرة الثنائية.

npm version MCP tool catalog Node.js requirements skills.sh MIT license Discord

morluto%2Frea | Trendshift

الموقع · الأدلة · دراسات الحالة

البدء السريع · كيف يعمل REA · ما الذي يمكنك تحليله · دراسات الحالة · الأسئلة الشائعة · التوثيق

npx rea-agents setup


REA يشغّل جسر التحليل داخل Hopper لفحص ملف ثنائي للشيفرة الأصلية



Discord
انضم إلى مجتمع الهندسة العكسية

Discord · أسئلة وأجوبة · مشاركة النتائج


هل وجدت في تطبيق ميزة تريد إضافتها إلى منتجك؟ اطلب من وكيلك استقصاءها باستخدام REA. يستطيع فحص التطبيق من دون شيفرته المصدرية، وشرح طريقة عمل الميزة وعرض الأدلة، ثم بناء نسخة تناسب مشروعك.

يربط REA وكيلك بأدوات لفحص الملفات الثنائية للشيفرة الأصلية، وتطبيقات JavaScript وElectron، وتجميعات .NET، والمواقع. يمكنك أيضًا استخدام الأدوات نفسها من الطرفية. يجري التحليل محليًا، وتتضمن النتائج الأدلة والقيود التي تستند إليها كل خلاصة.

يسجّل الإعداد REA لدى وكيلك ويثبّت تعليمات سير العمل المطابقة. يمكن لتحليل الشيفرة الأصلية استخدام تثبيت موجود من Hopper أو Ghidra؛ ويمكن للإعداد أيضًا تثبيت Hopper اختياريًا بعد موافقتك. لا يحتاج التحليل الثابت لـ JavaScript إلى أي من المحركين.

زر موقع REA للاطلاع على تعليمات الإعداد والأدلة المصوّرة ودراسات الحالة الفعلية.

البدء السريع

إعداد وكيلك

بعد تثبيت Node.js وnpm، نفّذ:

npx rea-agents setup

اختر الوكلاء، وراجع التغييرات المقترحة، ثم وافق عليها. يضيف الإعداد خادم MCP الخاص بـ REA وتعليمات سير العمل المطابقة، مع الاحتفاظ بنسخ احتياطية من الإعدادات الموجودة. أعد تشغيل وكيلك بعد ذلك.

يدعم الإعداد Claude Code وCodex وCursor وGemini CLI وGrok Build ووكلاء آخرين. راجع التثبيت والإعداد لتهيئة موفّري التحليل وتسجيل MCP يدويًا.

اطلب من وكيلك

استقصِ طريقة عمل البحث في تطبيق Notes، واعرض الأدلة، ثم ابنِ ميزة مشابهة لمشروعي.

استبدل Notes بالتطبيق المستهدف وحدّد الميزة التي تريد فهمها.

استخدام الطرفية

افحص مجلد تطبيق JavaScript/Electron بعد فك حزمه، أو ملف ASAR:

npx -y rea-agents@latest analyze-javascript-application /absolute/path/to/app --json

تتضمن النتيجة الوحدات وعمليات الاستيراد وحدود Electron والأدلة المتعلقة بها. استبدل المسار بمسار هدفك، مثل "D:/apps/example" على Windows.

لتثبيت أمر rea للاستخدام المعتاد:

npm install --global rea-agents
rea --help

لتحليل الشيفرة الأصلية، هيّئ موفّرًا أولًا. راجع دليل CLI وEvidence لأوامر تحليل الشيفرة الأصلية، واختيار الموفّر، واللقطات، والاستخدام في السكربتات.

تحديث REA

يتطور REA بسرعة، وتتضمن الإصدارات الجديدة إصلاحات متكررة للأخطاء. حافظ على تحديث نسختك.

لواجهة CLI المثبّتة عبر npm:

rea update

لتحديث تسجيلات الوكلاء والمهارة، نفّذ أمر الإعداد الذي يعرضه التحديث.

إذا كنت تستخدم npx، فحدّث إعداد وكيلك بالأمر التالي:

npx rea-agents@latest setup

راجع تغييرات الإعداد وأعد تشغيل وكيلك. لأوامر CLI التي تنفّذها مرة واحدة، استخدم npx rea-agents@latest متبوعًا بالأمر المطلوب.

كيف يعمل REA

يستدعي وكيلك REA عبر MCP لفحص الهدف وتتبع الشيفرة ذات الصلة. يعيد REA النتائج مع أدلتها. يستخدمها الوكيل لطرح أسئلة متابعة، أو شرح السلوك، أو كتابة تنفيذ واختباره. تستخدم أوامر CLI سير العمل نفسه.

مسار الاستقصاء في REA: يسأل وكيلك عن هدف محلي، ويفحصه REA ويتتبعه بأدوات التحليل، ثم يستخدم الوكيل الشيفرة والمراجع والجوانب غير المحسومة التي أعادتها الأدوات لشرح السلوك وتنفيذه واختباره.

افتح الشكل بحجمه الكامل.

ما الذي يمكنك تحليله

يتطلب REA إصدار Node.js 22.x (>=22.19) أو 24.x (>=24.11) أو 26+، إضافة إلى npm. تعتمد الأدوات الإضافية والأنظمة المضيفة المدعومة على الهدف:

الهدف ما يعيده REA المتطلبات والدليل
الملفات الثنائية للشيفرة الأصلية شيفرة شبه برمجية، وتعليمات تجميع، وسلاسل نصية، ورموز، واستدعاءات، ومراجع Hopper أو Ghidra أو IDA؛ تحليل الشيفرة الأصلية
بنية ELF دون تشغيل الأقسام والمقاطع والرموز ومعلومات إعادة التموضع الأصلية، وآليات الحماية المحتملة المستدلّ عليها بالفحص الثابت pwntools يوفّره المستدعي على Linux x64؛ تشخيص الملفات الثنائية
شيفرة EVM البايتية محددات التوجيه، وإزاحات البايتات، والمعاملات المستنتجة، وقابلية تغيير الحالة مدخل محلي يحمل بايتات خامًا أو تمثيلًا سداسيًا عشريًا على Linux x64؛ دليل EVM دون تشغيل
أعطال Linux المسجّلة سجلات note الخام، ومسجّلات المعالج/الإشارات لكل خيط مسجّل، وترشيحات اختيارية لخرائط الذاكرة pwntools يوفّره المستدعي على Linux x64؛ GDB/pwndbg اختياريان؛ الأعطال المسجّلة
JavaScript / Electron الوحدات، وعمليات الاستيراد، وخرائط المصدر، والمسارات، وIPC، وعلاقات إضافات الشيفرة الأصلية Node.js وnpm؛ تحليل التطبيقات
المواقع بنية الصفحة، والسكربتات، وملاحظات الشبكة، ولقطات الشاشة المطلوبة متصفح من عائلة Chrome؛ تحليل المتصفح
تسجيلات الشبكة المحفوظة الطلبات، والاستجابات، ومحتويات الحمولة المتاحة، ومواضعها في المصدر HAR؛ وmitmdump على Linux لتسجيلات mitmproxy بصيغتها الأصلية؛ دليل تسجيلات الشبكة
تجميعات .NET البيانات الوصفية، وتعليمات CIL، واعتماديات الشيفرة الأصلية المعلنة، ومقارنات البناء فحص ثابت؛ دليل الشيفرة المُدارة
حزم Android APK تصريحات ملف manifest، والأصناف، والدوال الناتجة عن فك الترجمة، والمراجع JADX دون واجهة رسومية وJDK كامل على Linux/macOS/Windows x64؛ دليل Android
أجهزة Android الأجهزة والحزم والعمليات والسجلات والدامبات ولقطات الشاشة ونقل APK/الملفات adb يوفّره المُستدعي (محاكي أو جهاز)؛ دليل ADB
مشاريع JEB وحدات المشروع من المحرك وبصمات المصنّفات والكود الزائف للأنواع/الدوال عميل JEB يبدأه المُستدعي ويقدّم MCP، ويُختار عبر REA_JEB_MCP_URL؛ دليل JEB
موارد Android البيان المفكوك الترميز وجداول السلاسل واللغات وحقائق الإصدار مُشغّل Apktool يوفّره المُستدعي؛ دليل الموارد
تطبيقات Flutter بصمة لقطة Dart وهشوش المكتبات لكل ABI وأصل بناء المحرك لا شيء (تحليل APK ساكن)؛ دليل Flutter
البرامج الثابتة المناطق، ونتائج الاستخراج، وما يُمرّر إلى تحليل الشيفرة الأصلية Binwalk / Unblob على Linux؛ دليل البرامج الثابتة
الحزم والموارد قوائم الملفات، والبصمات، وملفات plist، وبنية حزم Apple، والموارد المستخرجة دليل تحليل الملفات وJavaScript، تطبيقات Apple
سلوك العمليات مخرجات الطرفية، والتفاعلات، وملاحظات الخروج ونظام الملفات، ومقارنات التشغيل Linux/macOS مع PTY أصلي؛ تسجيل سلوك العمليات

يقرأ الفحص الثابت لـ JavaScript و.NET الملفات المقدّمة دون تشغيل التطبيق. يشغّل التسجيل أثناء التنفيذ الهدف المحدد أو يتفاعل معه بصلاحيات مستخدمك؛ ويشرح كل دليل للتسجيل أثناء التنفيذ آثاره.

تختلف صيغ ملفات الشيفرة الأصلية والأنظمة المضيفة المدعومة باختلاف الموفّر. راجع إعداد Hopper وGhidra، ودليل IDA، ودعم Ghidra التجريبي على Windows. يدعم Ghidra أيضًا تحليل DOS ذي 16 بت. لاختيار الموفّر، راجع دليل CLI. تحقّق من توفر الميزات في الإصدارات للميزات المضافة بعد أحدث إصدار على npm.

دراسات الحالة

رسوم توضيحية لأمثلة توزيع الصوت في DX-Ball وجسر الحافظة في Notion وحلقة الطلقات في TH04

DX-Ball: إعادة بناء حساب توزيع الصوت بين القناتين

تتبّع استدعاء صوت إلى الدالة المساعدة التي تحوّل الموضع إلى توزيع بين القناتين، وافحص التعليمات، وحوّل الشيفرة شبه البرمجية غير المكتملة إلى C. تجتاز إعادة البناء 3,205 حالات اختبار على x86 الأصلي، وتعيد إنتاج جميع بايتات الدالة المترجمة البالغ عددها 63 بايتًا.

اقرأ دراسة الحالة · مستودع إعادة البناء

Notion: تتبّع جسر الحافظة في Electron

اعثر على API الحافظة في عملية العرض، وتتبّعه عبر preload وIPC إلى العملية الرئيسية، وافحص صيغة الحافظة ذات التنسيق الغني.

اقرأ دراسة الحالة

TH04: استعادة حساب حلقة المقذوفات في DOS

افحص تعليمات اللعبة الأصلية على PC-98 ذات 16 بت، واستعد حساب الزوايا الثابتة والموجّهة نحو الهدف، وقارن شيفرة C++ المعاد بناؤها بمخرجات المترجم المستخدم آنذاك.

اقرأ دراسة الحالة · مستودع إعادة البناء

إذا استخدمت REA لفحص هدف مثير للاهتمام، فنود الاطلاع عليه. شارك حالتك في issue أو pull request، مع ذكر الهدف، وسؤالك، وكيف ساعدك REA، وما توصلت إليه.

الأسئلة الشائعة

أي وكلاء يمكنهم استخدام REA؟

أي وكيل يدعم خوادم MCP المحلية. يهيّئ الإعداد الوكلاء المدعومين؛ ويمكن للعملاء الآخرين استخدام تسجيل MCP يدويًا.

هل أحتاج إلى Hopper أو Ghidra أو IDA؟

يستخدم تحليل الشيفرة الأصلية المتعمق أحدها. يعمل الفحص الثابت لـ JavaScript و.NET دون محرك لتحليل الشيفرة الأصلية. يستطيع الإعداد تثبيت Hopper بعد الموافقة؛ أما Ghidra وIDA فيستخدمان تثبيتاتك الموجودة. راجع إعداد الموفّرين.

هل أحتاج إلى تشغيل Hopper أولًا؟

يشغّل REA برنامج Hopper عندما تحتاج العملية إليه. على macOS، قد تظهر عند التشغيل الأول نافذة تطلب اختيار وضع العرض التجريبي أو تفعيل الترخيص. راجع تشغيل Hopper واستكشاف الأخطاء.

ماذا يفعل تثبيت المهارة من skills.sh؟

توفّر المهارة تعليمات الاستقصاء لوكيلك. استخدم npx rea-agents setup لتسجيل خادم MCP الخاص بـ REA وتثبيت التعليمات المطابقة، ثم أعد تشغيل وكيلك. راجع تثبيت المهارة وحدها.

ما الشيفرة التي يعيدها REA؟

يعيد تحليل الشيفرة الأصلية شيفرة شبه برمجية وتعليمات تجميع. يستعيد تحليل JavaScript/Electron الوحدات والعلاقات بينها. يستخدم وكيلك هذه النتائج لكتابة تنفيذ واختباره؛ وتقدّم دراسات الحالة أمثلة عملية.

هل يرفع REA تطبيقي؟

يحلّل REA الأهداف محليًا. يتلقى وكيلك نتائج الأدوات، ولموفّر النموذج الذي يستخدمه سياسة بيانات خاصة به.

ماذا أفعل إذا واجهت خطأ؟

حدّث أولًا؛ فقد يكون إصدار حديث قد أصلح المشكلة بالفعل.

لواجهة CLI المثبّتة عبر npm:

rea update

لإعداد الوكيل عبر npx:

npx rea-agents@latest setup

إذا كنت تستخدم وكيلًا، فأكمل تحديث الإعداد وأعد تشغيله. أعد محاولة المهمة نفسها. إذا استمرت المشكلة، افتح issue يتضمن إصدار REA، ونوع الهدف، وخطوات إعادة الإنتاج، ومخرجات الخطأ.

التوثيق

ابدأ بـ الأدلة العملية على الموقع. للخيارات الدقيقة والمتطلبات وعقود النتائج:

أبلغ عن الثغرات وفق SECURITY.md.

سجل النجوم

🎉 110,000 نجمة على GitHub — شكرًا لكم!

شكرًا لكل من يستخدم REA، ويبلّغ عن الأخطاء، ويقترح ميزات، ويختبر إصدارات البناء، ويساهم بالإصلاحات.

سجل نجوم REA على GitHub

إخلاء المسؤولية

راجع DISCLAIMER.md للحصول على إرشادات الاستخدام المسؤول.

REA مخصص للبحث والتعليم والتشغيل البيني وحفظ البرمجيات بشكل قانوني، ولتحليل البرمجيات التي تملكها أو لديك تفويض لفحصها.

The project's position on illegal or unauthorized use covers all REA versions, distribution channels, and platforms; each copy retains its applicable licenses.

المساهمة

نرحّب بمساعدتك في تطوير REA! افتح issue للإبلاغ عن خطأ أو اقتراح ميزة، أو أرسل pull request لتحسين الشيفرة أو التوثيق.

راجع CONTRIBUTING.md لإعداد بيئة التطوير والفحوص، ودليل الاختبار لمسارات التحقق، وخريطة البنية لهيكل المشروع.

الترخيص

MIT

REA-authored code is licensed under MIT. Third-party material retains its own licenses and copyright notices; see Third-party notices for the dependency inventory, preserved license texts, and external-tool terms.

You must legally obtain and be authorized to use commercial tools, including IDA Pro / Hex-Rays decompilers, Hopper, and JEB, under their applicable licenses. REA grants no tool license, key, or activation entitlement. Trials and demos remain subject to vendor terms, including user, feature, automation, and output sharing restrictions. Cracked copies, stolen keys, unauthorized key sharing, and bypassing license restrictions are not authorized. This guidance does not amend MIT or third-party licenses.