* 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>
21 KiB
English · 简体中文 · 繁體中文 · 日本語 · 한국어 · Türkçe · Русский · Tiếng Việt · ไทย · Deutsch · Español · Français · Українська · Polski · Português (Brasil) · العربية · فارسی · Bahasa Indonesia · Italiano
REA: 무엇이든 리버스 엔지니어링
하나의 MCP로 바이너리, 애플리케이션, 런타임 동작을 리버스 엔지니어링합니다.
마음에 드는 기능을 발견했다면, 바이너리 수준까지 작동 원리를 이해하세요.
빠른 시작 · REA의 작동 방식 · 분석할 수 있는 대상 · 사례 · 자주 묻는 질문 · 문서
npx rea-agents setup
|
리버스 엔지니어링 커뮤니티에 참여하세요 Discord · 질문과 답변 · 결과 공유 |
앱에서 내 제품에도 넣고 싶은 기능을 발견했나요? 에이전트에게 REA로 조사해 달라고 요청하세요. 소스 코드가 없어도 앱을 검사하고, 기능의 작동 원리를 설명하고, 근거를 보여 주고, 프로젝트에 맞는 기능을 구현할 수 있습니다.
REA는 에이전트를 분석 도구에 연결해 네이티브 바이너리, JavaScript와 Electron 앱, .NET 어셈블리, 웹사이트를 검사할 수 있게 합니다. 터미널에서도 같은 도구를 사용할 수 있습니다. 분석은 로컬에서 실행되며, 결과에는 각 결론의 근거와 한계가 포함됩니다.
설정 과정은 에이전트에 REA를 등록하고 해당 버전에 맞는 워크플로 지침을 설치합니다. 네이티브 분석에는 기존 Hopper 또는 Ghidra 설치를 사용할 수 있습니다. 승인하면 설정 과정에서 Hopper를 설치할 수도 있습니다. 정적 JavaScript 분석에는 두 엔진 모두 필요하지 않습니다.
**REA 웹사이트**에서 설정 방법, 그림으로 설명한 가이드, 실제 사례를 확인하세요.
빠른 시작
에이전트 설정
Node.js와 npm이 설치된 환경에서 다음 명령을 실행하세요.
npx rea-agents setup
에이전트를 선택하고, 예정된 변경 사항을 검토한 뒤 승인하세요. 설정 과정은 기존 설정을 백업하고 REA의 MCP 서버와 버전에 맞는 워크플로 지침을 추가합니다. 완료 후 에이전트를 다시 시작하세요.
설정은 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 경계와 관련 근거가 포함됩니다. 경로를 분석할 대상으로 바꾸세요. Windows에서는 "D:/apps/example" 같은 경로를 사용할 수 있습니다.
자주 사용할 경우 rea 명령을 설치하세요.
npm install --global rea-agents
rea --help
네이티브 분석에는 먼저 제공자를 설정해야 합니다. 네이티브 명령, 제공자 선택, 스냅샷, 스크립트 사용은 CLI 및 Evidence 가이드를 참고하세요.
REA 업데이트
REA는 빠르게 바뀌며 새 릴리스에는 버그 수정이 자주 포함됩니다. 설치된 버전을 최신으로 유지하세요.
npm으로 설치한 CLI에서는 다음 명령을 사용합니다.
rea update
에이전트 등록과 스킬을 갱신하려면 업데이트 과정에서 출력된 설정 명령을 실행하세요.
npx를 사용한다면 다음 명령으로 에이전트 설정을 갱신하세요.
npx rea-agents@latest setup
설정 변경 사항을 검토하고 에이전트를 다시 시작하세요. 일회성 CLI 작업에는 npx rea-agents@latest 뒤에 필요한 명령을 붙여 실행하세요.
REA의 작동 방식
에이전트는 MCP를 통해 REA를 호출하여 대상을 검사하고 관련 코드를 추적합니다. REA는 조사 결과와 근거를 반환합니다. 에이전트는 이를 바탕으로 추가 질문을 하고, 동작을 설명하거나, 구현을 작성하고 테스트합니다. CLI 명령도 같은 워크플로를 사용합니다.
분석할 수 있는 대상
REA에는 Node.js 22.x(>=22.19), 24.x(>=24.11) 또는 26+와 npm이 필요합니다. 추가 도구와 호스트 지원은 대상에 따라 다릅니다.
| 대상 | REA가 반환하는 내용 | 요구 사항 및 가이드 |
|---|---|---|
| 네이티브 바이너리 | 의사 코드, 어셈블리, 문자열, 심볼, 호출, 참조 | Hopper, Ghidra 또는 IDA; 네이티브 분석 |
| 오프라인 ELF 레이아웃 | 섹션, 세그먼트, 원본 심볼/재배치 정보, 정적 분석으로 얻은 보안 완화 기법 후보 | Linux x64에서 호출자가 제공하는 pwntools; 바이너리 진단 |
| EVM 바이트코드 | 디스패치 선택자, 바이트 오프셋, 추론한 인자와 상태 변경 가능 여부 | Linux x64의 로컬 원시 바이트/16진수 입력 파일; 오프라인 EVM 가이드 |
| 기록된 Linux 크래시 | 원시 note 레코드, 기록된 모든 스레드의 레지스터/시그널, 선택적 매핑 후보 | Linux x64에서 호출자가 제공하는 pwntools; GDB/pwndbg는 선택 사항; 기록된 크래시 |
| JavaScript / Electron | 모듈, 임포트, 소스 맵, 라우트, IPC, 네이티브 애드온 관계 | Node.js와 npm; 애플리케이션 분석 |
| 웹사이트 | 페이지 구조, 스크립트, 네트워크 관찰 결과, 요청한 스크린샷 | Chrome 계열 브라우저; 브라우저 분석 |
| 저장된 네트워크 캡처 | 요청, 응답, 접근 가능한 페이로드, 소스 위치 | HAR; mitmproxy 네이티브 캡처에는 Linux의 mitmdump; 캡처 가이드 |
| .NET 어셈블리 | 메타데이터, CIL 명령, 선언된 네이티브 의존성, 빌드 비교 | 정적 검사; 관리 코드 가이드 |
| Android APK | 매니페스트 선언, 클래스, 디컴파일된 메서드, 참조 | Linux/macOS/Windows x64의 헤드리스 JADX와 전체 JDK; Android 가이드 |
| Android 기기 | 기기, 패키지, 프로세스, 로그, 덤프, 화면 캡처, APK/파일 전송 | 호출자 제공 adb(에뮬레이터 또는 실제 기기); ADB 가이드 |
| JEB 프로젝트 | 엔진 기반 프로젝트 유닛, 아티팩트 해시, 타입/메서드 의사코드 | 호출자가 시작하고 MCP를 제공하는 JEB 클라이언트(REA_JEB_MCP_URL로 선택); JEB 가이드 |
| Android 리소스 | 디코딩된 매니페스트, 문자열 테이블, 로캘, 버전 정보 | 호출자 제공 Apktool 런처; 리소스 가이드 |
| Flutter 앱 | Dart 스냅샷 해시, ABI별 라이브러리 해시, 엔진 빌드 출처 | 없음 (정적 APK 파싱); Flutter 가이드 |
| 펌웨어 | 영역, 추출 결과, 네이티브 분석으로 전달할 정보 | Linux의 Binwalk / Unblob; 펌웨어 가이드 |
| 패키지 및 리소스 | 파일 목록, 다이제스트, plist, Apple 번들 구조, 추출한 리소스 | 아티팩트 및 JavaScript 가이드, Apple 애플리케이션 |
| 프로세스 동작 | 터미널 출력, 상호작용, 종료 및 파일 시스템 관찰 결과, 실행 비교 | 네이티브 PTY를 지원하는 Linux/macOS; 프로세스 캡처 |
정적 JavaScript 및 .NET 검사는 제공된 파일을 읽으며 애플리케이션을 실행하지 않습니다. 런타임 캡처는 사용자의 권한으로 선택한 대상을 실행하거나 대상과 상호작용합니다. 각 런타임 가이드에서 그 영향을 설명합니다.
지원하는 네이티브 형식과 호스트는 제공자마다 다릅니다. Hopper 및 Ghidra 설정, IDA 가이드, 실험적 Windows Ghidra 지원을 참고하세요. Ghidra는 16비트 DOS 분석도 지원합니다. 제공자 선택은 CLI 가이드를 참고하세요. 최신 npm 릴리스 이후 추가된 기능은 릴리스에서의 사용 가능 여부를 확인하세요.
사례
DX-Ball: 사운드 패닝 계산 재구현
사운드 호출에서 위치를 패닝 값으로 변환하는 보조 함수까지 추적하고, 명령을 검사하여 불완전한 의사 코드를 C로 옮깁니다. 재구현한 코드는 원본 x86에 대한 3,205개 테스트 케이스를 통과했으며, 컴파일된 함수의 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으로 REA의 MCP 서버를 등록하고 버전에 맞는 지침을 설치한 뒤 에이전트를 다시 시작하세요. 스킬만 설치하기를 참고하세요.
REA는 어떤 코드를 반환하나요?
네이티브 분석은 의사 코드와 어셈블리를 반환합니다. JavaScript/Electron 분석은 모듈과 그 관계를 복원합니다. 에이전트는 이 결과를 사용해 구현을 작성하고 테스트합니다. 사례에서 구체적인 예를 볼 수 있습니다.
REA가 내 앱을 업로드하나요?
REA는 대상을 로컬에서 분석합니다. 에이전트는 도구 결과를 받으며, 에이전트의 모델 제공자에는 별도의 데이터 정책이 있습니다.
버그가 발생하면 어떻게 해야 하나요?
먼저 업데이트하세요. 최근 릴리스에서 이미 수정되었을 수 있습니다.
npm으로 설치한 CLI에서는 다음 명령을 사용합니다.
rea update
npx로 에이전트를 설정했다면 다음 명령을 사용합니다.
npx rea-agents@latest setup
에이전트를 사용 중이라면 설정 갱신을 완료하고 다시 시작하세요. 같은 작업을 다시 시도하세요. 문제가 계속되면 REA 버전, 대상 유형, 재현 단계, 오류 출력을 포함해 issue를 등록하세요.
문서
웹사이트의 실습 가이드부터 읽어 보세요. 정확한 옵션, 사전 요구 사항, 결과 계약은 다음 문서를 참고하세요.
- 설치 및 설정: 에이전트 등록, 제공자 설정, 업데이트, 제거.
- 준비 상태 확인 및 문제 해결: 특정 에이전트 또는 분석 엔진 진단.
- CLI 및 Evidence: 명령, 제공자 선택, 스냅샷, 가져오기/내보내기, 종료 상태.
- MCP 계약 및 에이전트 프롬프트: 도구 결과, 세션, 안내에 따른 조사.
- 도구 카탈로그: 빌드 시 생성되는 도구, 제공자, CLI 명령 목록.
- 로드맵: 계획된 작업과 기능 진행 상황.
취약점은 SECURITY.md에 따라 보고하세요.
스타 기록
🎉 GitHub 스타 110,000개, 감사합니다!
REA를 사용하고, 버그를 보고하고, 기능을 요청하고, 빌드를 테스트하고, 수정에 기여해 주신 모든 분께 감사드립니다.
면책 조항
책임 있는 사용에 관한 안내는 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, 검증 절차는 테스트 가이드, 프로젝트 구조는 아키텍처 지도를 참고하세요.
라이선스
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.
