Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c865e20a0b | ||
|
|
0fd4021842 | ||
|
|
4db6ff461f | ||
|
|
ce58aebc0e | ||
|
|
80f6365523 | ||
|
|
dabcd783d5 | ||
|
|
3d34185171 |
@@ -2,7 +2,7 @@
|
|||||||
name: reverse-engineer-anything
|
name: reverse-engineer-anything
|
||||||
description: Reverse engineer native, managed, Electron/JavaScript, packaged, firmware, and browser targets with REA. Use shipped-artifact or requested runtime evidence to explain features, compare versions, decompile code, or guide a reconstruction. Skip REA for ordinary source-repository architecture analysis.
|
description: Reverse engineer native, managed, Electron/JavaScript, packaged, firmware, and browser targets with REA. Use shipped-artifact or requested runtime evidence to explain features, compare versions, decompile code, or guide a reconstruction. Skip REA for ordinary source-repository architecture analysis.
|
||||||
metadata:
|
metadata:
|
||||||
version: "39"
|
version: "37"
|
||||||
---
|
---
|
||||||
|
|
||||||
# REA
|
# REA
|
||||||
@@ -67,11 +67,6 @@ explicit path or endpoint and do not need it.
|
|||||||
[historical captures](https://github.com/morluto/rea/blob/main/docs/web-network-captures.md) for the exact upstream
|
[historical captures](https://github.com/morluto/rea/blob/main/docs/web-network-captures.md) for the exact upstream
|
||||||
profile and credential exclusions.
|
profile and credential exclusions.
|
||||||
- User-owned Electron runtime already open: `list_electron_targets`.
|
- User-owned Electron runtime already open: `list_electron_targets`.
|
||||||
- Explicit local WebAssembly artifact: `inspect_wasm_artifact`. Supply WABT 1.0.42
|
|
||||||
through `REA_WABT_BIN_DIRECTORY`; retain exact byte/tool identity and decoded WAT.
|
|
||||||
Select JavaScript glue and candidate paths explicitly and preserve URL/path
|
|
||||||
ambiguity. No implicit fetch or target execution; WAT is not original source.
|
|
||||||
See the [WASM guide](https://github.com/morluto/rea/blob/main/docs/wasm-artifacts.md).
|
|
||||||
- Explicit local EVM bytecode carrier: `inspect_evm_interface` with caller-selected
|
- Explicit local EVM bytecode carrier: `inspect_evm_interface` with caller-selected
|
||||||
`raw` or `hex` encoding. Preserve carrier/decoded digests and treat selectors,
|
`raw` or `hex` encoding. Preserve carrier/decoded digests and treat selectors,
|
||||||
argument strings and mutability as inferred candidates; this performs no chain
|
argument strings and mutability as inferred candidates; this performs no chain
|
||||||
|
|||||||
@@ -1,30 +1,7 @@
|
|||||||
# JavaScript and Electron application artifacts
|
# JavaScript and Electron application artifacts
|
||||||
|
|
||||||
For captured or bundled JavaScript that needs readable source recovery, use
|
|
||||||
`recover_javascript_sources` with an absolute `path` and absent
|
|
||||||
`output_directory`. Supply related runtime/shared/lazy files in
|
|
||||||
`additional_paths` when advertised, then analyze the returned `analysis_input`
|
|
||||||
directory together. Each input retains its own snapshot, digest and byte-range
|
|
||||||
provenance; inputs and recovered code are never executed. Recovery requires a
|
|
||||||
caller-supplied Wakaru on Linux x64; see [the recovery guide](https://github.com/morluto/rea/blob/main/docs/javascript-recovery.md).
|
|
||||||
|
|
||||||
Use `analyze_javascript_application` directly on the operator-supplied ASAR or
|
Use `analyze_javascript_application` directly on the operator-supplied ASAR or
|
||||||
extracted tree. When the question concerns known source paths and the connected
|
extracted tree. When size is unknown or large and the connected schema advertises
|
||||||
schema advertises `source_paths`, select exact inventoried paths such as
|
|
||||||
`["package.json", "main.js", "preload.js"]`. Include supporting manifests or
|
|
||||||
source maps explicitly; dependencies are not implicitly analyzed. REA retains
|
|
||||||
the complete artifact inventory and identity but reads source text and analyzes
|
|
||||||
only selected files. The result and summary record `source_selection`; files
|
|
||||||
outside scope and their relationships remain unknown, so partial application
|
|
||||||
coverage does not mean the selected source failed. Use repeated `--source-path`
|
|
||||||
on either static application CLI route. Omit the selection when the question
|
|
||||||
requires complete application analysis. `detail: "summary"` reduces delivery
|
|
||||||
and does not by itself reduce analysis work.
|
|
||||||
|
|
||||||
Exact `#alias` specifiers resolve through the importer's
|
|
||||||
enclosing package `imports` map to package-local files; nested `node_modules`
|
|
||||||
packages use their own map. Wildcard, recursive, and external-package import
|
|
||||||
targets stay unresolved with that limitation. When size is unknown or large and the connected schema advertises
|
|
||||||
`detail`, request `detail: "summary"`. This returns an `inspect_analysis_view`
|
`detail`, request `detail: "summary"`. This returns an `inspect_analysis_view`
|
||||||
Evidence record with a distinct ID and a `normalized_result.parent_evidence_id`
|
Evidence record with a distinct ID and a `normalized_result.parent_evidence_id`
|
||||||
for the complete retained application analysis. Source-map contents are part of
|
for the complete retained application analysis. Source-map contents are part of
|
||||||
@@ -35,10 +12,7 @@ the complete application Evidence inline when it fits.
|
|||||||
When the connected schema advertises `max_heap_mb` and `analysis_timeout_ms`,
|
When the connected schema advertises `max_heap_mb` and `analysis_timeout_ms`,
|
||||||
these select the isolated source analyzer's old-space heap and per-source
|
these select the isolated source analyzer's old-space heap and per-source
|
||||||
deadline. Defaults are 1024 MiB and 300000 ms. They do not change the MCP
|
deadline. Defaults are 1024 MiB and 300000 ms. They do not change the MCP
|
||||||
process heap. A Bun-hosted REA does not enforce the heap choice; on Windows it
|
process heap. Resource-limited analyses preserve completed static facts and
|
||||||
instead limits the analyzer's committed memory to that choice plus a 512 MiB
|
|
||||||
runtime reserve.
|
|
||||||
Resource-limited analyses preserve completed static facts and
|
|
||||||
report partial semantic coverage with specific unknown scopes; this does not
|
report partial semantic coverage with specific unknown scopes; this does not
|
||||||
mean the source is malformed. Inspect those limits before retrying a source.
|
mean the source is malformed. Inspect those limits before retrying a source.
|
||||||
When expanded relationships exceed the parent's available memory, inspect the
|
When expanded relationships exceed the parent's available memory, inspect the
|
||||||
|
|||||||
@@ -150,13 +150,6 @@ For headerless DOS COM, explicitly open with `format: "dos-com"` (CLI
|
|||||||
analysis: the entry is `0x10100`, file offset zero, with imposed real-mode segment
|
analysis: the entry is `0x10100`, file offset zero, with imposed real-mode segment
|
||||||
context. PSP/stack/device state remains unmodeled. See [DOS guide](https://github.com/morluto/rea/blob/main/docs/ghidra-dos.md).
|
context. PSP/stack/device state remains unmodeled. See [DOS guide](https://github.com/morluto/rea/blob/main/docs/ghidra-dos.md).
|
||||||
|
|
||||||
For other headerless images (embedded firmware without ELF/Mach-O/PE/MZ
|
|
||||||
headers), open with `format: "raw-binary"`, `architecture` (`x86`, `x86_64`,
|
|
||||||
`arm`, or `arm64`), and `entry_point` (`0x` hex). File offset 0 is mapped at
|
|
||||||
that address. Hopper and IDA refuse this interpretation; Ghidra uses
|
|
||||||
`BinaryLoader` with a little-endian generic language. Big-endian, Thumb-only,
|
|
||||||
and Cortex-M variants are unsupported. See [raw binary guide](https://github.com/morluto/rea/blob/main/docs/raw-binary.md).
|
|
||||||
|
|
||||||
### Function annotations in Ghidra
|
### Function annotations in Ghidra
|
||||||
|
|
||||||
Use `annotate_native_function` for one function name and/or entry comments, with at least one explicit change. Review its annotation readback and refreshed dossier inline. Changes are atomic and session-scoped; empty comments clear them, omitted fields preserve them. Later MCP calls observe edits until close. CLI `annotate-native-function` returns the updated analysis before discarding the session. Original executable bytes are unchanged; edits invalidate immutable snapshots. Windows P0 does not admit database mutations. For naming only, `set_address_name` / `set_addresses_names` also work with Ghidra: they name function entries or data addresses (primary labels) and return compact per-address success booleans instead of a dossier.
|
Use `annotate_native_function` for one function name and/or entry comments, with at least one explicit change. Review its annotation readback and refreshed dossier inline. Changes are atomic and session-scoped; empty comments clear them, omitted fields preserve them. Later MCP calls observe edits until close. CLI `annotate-native-function` returns the updated analysis before discarding the session. Original executable bytes are unchanged; edits invalidate immutable snapshots. Windows P0 does not admit database mutations. For naming only, `set_address_name` / `set_addresses_names` also work with Ghidra: they name function entries or data addresses (primary labels) and return compact per-address success booleans instead of a dossier.
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
# Keep text checkouts consistent with the repository formatter on every platform.
|
|
||||||
* text=auto eol=lf
|
|
||||||
|
|
||||||
# Windows command fixtures retain their native line endings.
|
|
||||||
*.cmd text eol=crlf
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
name: Portable build cache
|
|
||||||
description: Reuse Turbo build outputs without serializing verification jobs.
|
|
||||||
inputs:
|
|
||||||
save:
|
|
||||||
description: Save newly built outputs after the job succeeds.
|
|
||||||
default: "false"
|
|
||||||
runs:
|
|
||||||
using: composite
|
|
||||||
steps:
|
|
||||||
- name: Resolve portable build task hashes
|
|
||||||
id: plan
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
BUILD_CACHE_PREFIX: rea-portable-build-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('.npmrc') }}
|
|
||||||
run: |
|
|
||||||
npm run --silent test:prepare -- --dry=json |
|
|
||||||
node --input-type=module -e '
|
|
||||||
import { createHash } from "node:crypto";
|
|
||||||
import { readFileSync } from "node:fs";
|
|
||||||
const { tasks } = JSON.parse(readFileSync(0, "utf8"));
|
|
||||||
const hashes = tasks.map(({ taskId, hash }) => {
|
|
||||||
if (typeof hash !== "string")
|
|
||||||
throw new Error(`Build task ${taskId} must have an eager Turbo hash`);
|
|
||||||
return `${taskId}:${hash}`;
|
|
||||||
}).sort();
|
|
||||||
const hash = createHash("sha256").update(hashes.join("\n")).digest("hex");
|
|
||||||
console.log(`key=${process.env.BUILD_CACHE_PREFIX}-${hash}`);
|
|
||||||
' >> "$GITHUB_OUTPUT"
|
|
||||||
- name: Restore portable build outputs
|
|
||||||
if: inputs.save != 'true'
|
|
||||||
uses: actions/cache/restore@v4
|
|
||||||
with:
|
|
||||||
path: .turbo/cache/
|
|
||||||
key: ${{ steps.plan.outputs.key }}
|
|
||||||
- name: Restore and save portable build outputs
|
|
||||||
if: inputs.save == 'true'
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: .turbo/cache/
|
|
||||||
key: ${{ steps.plan.outputs.key }}
|
|
||||||
@@ -118,8 +118,6 @@ jobs:
|
|||||||
name: rea-test-runtime
|
name: rea-test-runtime
|
||||||
path: .
|
path: .
|
||||||
- run: npm run test:ci:shard:run -- --shard=${{ matrix.shard }}
|
- run: npm run test:ci:shard:run -- --shard=${{ matrix.shard }}
|
||||||
env:
|
|
||||||
REA_CI_TEST_HISTORY: .cache/ci-test-history/test-results.json
|
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v4
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
with:
|
with:
|
||||||
@@ -135,9 +133,6 @@ jobs:
|
|||||||
needs: changes
|
needs: changes
|
||||||
if: needs.changes.outputs.code == 'true'
|
if: needs.changes.outputs.code == 'true'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
actions: read
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
@@ -145,33 +140,7 @@ jobs:
|
|||||||
node-version-file: .nvmrc
|
node-version-file: .nvmrc
|
||||||
cache: npm
|
cache: npm
|
||||||
- run: npm ci
|
- run: npm ci
|
||||||
- name: Reuse portable build outputs across runs
|
|
||||||
uses: ./.github/actions/portable-build-cache
|
|
||||||
with:
|
|
||||||
save: "true"
|
|
||||||
- run: npm run test:prepare
|
- run: npm run test:prepare
|
||||||
- name: Find successful default-branch timing history
|
|
||||||
id: history
|
|
||||||
continue-on-error: true
|
|
||||||
env:
|
|
||||||
GH_TOKEN: ${{ github.token }}
|
|
||||||
CI_REPOSITORY: ${{ github.repository }}
|
|
||||||
CI_DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
|
|
||||||
run: |
|
|
||||||
run_id="$(gh api --method GET \
|
|
||||||
"repos/${CI_REPOSITORY}/actions/workflows/ci.yml/runs" \
|
|
||||||
-f branch="${CI_DEFAULT_BRANCH}" -f event=push -f status=success -f per_page=1 \
|
|
||||||
--jq '.workflow_runs[0].id // empty')"
|
|
||||||
echo "run-id=${run_id}" >> "${GITHUB_OUTPUT}"
|
|
||||||
- name: Download previous timing report
|
|
||||||
if: steps.history.outputs.run-id != ''
|
|
||||||
continue-on-error: true
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: test-results
|
|
||||||
run-id: ${{ steps.history.outputs.run-id }}
|
|
||||||
github-token: ${{ github.token }}
|
|
||||||
path: .cache/ci-test-history
|
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: rea-test-runtime
|
name: rea-test-runtime
|
||||||
@@ -179,24 +148,12 @@ jobs:
|
|||||||
dist/
|
dist/
|
||||||
skills/
|
skills/
|
||||||
.cache/mcp-tool-catalog.json
|
.cache/mcp-tool-catalog.json
|
||||||
.cache/ci-test-history/test-results.json
|
|
||||||
docs/public/product-catalog.json
|
docs/public/product-catalog.json
|
||||||
docs/verification/managed-conformance-*.json
|
docs/verification/managed-conformance-*.json
|
||||||
include-hidden-files: true
|
include-hidden-files: true
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
retention-days: 7
|
retention-days: 7
|
||||||
|
|
||||||
# test:prepare caches only portable JS, skill, and catalog outputs.
|
|
||||||
# Native package jobs still run their build and prepack checks; Turbo
|
|
||||||
# restores matching outputs or rebuilds when their inputs differ.
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: rea-build-cache
|
|
||||||
path: .turbo/cache/
|
|
||||||
include-hidden-files: true
|
|
||||||
if-no-files-found: error
|
|
||||||
retention-days: 7
|
|
||||||
|
|
||||||
test:
|
test:
|
||||||
name: Test (coverage + timing)
|
name: Test (coverage + timing)
|
||||||
needs: [changes, test-shard]
|
needs: [changes, test-shard]
|
||||||
@@ -305,12 +262,6 @@ jobs:
|
|||||||
sudo apt-get install --no-install-recommends -y g++-mingw-w64-x86-64
|
sudo apt-get install --no-install-recommends -y g++-mingw-w64-x86-64
|
||||||
- run: npm run build:windows-native
|
- run: npm run build:windows-native
|
||||||
- run: npm run verify:windows-native:artifact
|
- run: npm run verify:windows-native:artifact
|
||||||
- run: node scripts/build-windows-native.mjs --inspection-fixture
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: windows-native-inspection-fixture
|
|
||||||
path: .cache/windows-native-inspection-fixture/
|
|
||||||
if-no-files-found: error
|
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: windows-native-controls
|
name: windows-native-controls
|
||||||
@@ -319,7 +270,7 @@ jobs:
|
|||||||
|
|
||||||
package-e2e:
|
package-e2e:
|
||||||
name: Native package baseline (${{ matrix.platform }} ${{ matrix.architecture }})
|
name: Native package baseline (${{ matrix.platform }} ${{ matrix.architecture }})
|
||||||
needs: [changes, build, windows-native-build]
|
needs: [changes, windows-native-build]
|
||||||
if: needs.changes.outputs.runtime == 'true'
|
if: needs.changes.outputs.runtime == 'true'
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
@@ -349,23 +300,12 @@ jobs:
|
|||||||
assert.equal(process.arch, process.env.EXPECTED_CI_ARCHITECTURE);
|
assert.equal(process.arch, process.env.EXPECTED_CI_ARCHITECTURE);
|
||||||
console.log(JSON.stringify({ platform: process.platform, architecture: process.arch, node: process.version }));"
|
console.log(JSON.stringify({ platform: process.platform, architecture: process.arch, node: process.version }));"
|
||||||
- run: npm ci
|
- run: npm ci
|
||||||
- uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: rea-build-cache
|
|
||||||
path: .turbo/cache/
|
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: windows-native-controls
|
name: windows-native-controls
|
||||||
path: native/windows/build/
|
path: native/windows/build/
|
||||||
- run: npm run verify:windows-native:artifact
|
- run: npm run verify:windows-native:artifact
|
||||||
- name: Resolve npm cache before verifier HOME isolation
|
|
||||||
id: npm-cache
|
|
||||||
run: |
|
|
||||||
cache_path="$(npm config get cache)"
|
|
||||||
echo "path=${cache_path}" >> "${GITHUB_OUTPUT}"
|
|
||||||
- run: npm run verify:package
|
- run: npm run verify:package
|
||||||
env:
|
|
||||||
npm_config_cache: ${{ steps.npm-cache.outputs.path }}
|
|
||||||
- name: Verify real Node Inspector discovery and observation
|
- name: Verify real Node Inspector discovery and observation
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
run: npm run verify:inspector
|
run: npm run verify:inspector
|
||||||
@@ -384,8 +324,6 @@ jobs:
|
|||||||
cache: npm
|
cache: npm
|
||||||
- run: npm ci
|
- run: npm ci
|
||||||
- name: Verify Apple artifact formats and metadata
|
- name: Verify Apple artifact formats and metadata
|
||||||
env:
|
|
||||||
REA_ARTIFACT_NODE_COMPILE_CACHE: ${{ runner.temp }}/rea-artifact-node-cache
|
|
||||||
run: |
|
run: |
|
||||||
npm run verify:keyed-archive
|
npm run verify:keyed-archive
|
||||||
npm run verify:asset-catalog
|
npm run verify:asset-catalog
|
||||||
@@ -493,7 +431,7 @@ jobs:
|
|||||||
tests/acceptance/webSourceLocationCli.test.ts
|
tests/acceptance/webSourceLocationCli.test.ts
|
||||||
tests/boundary/cli/referenceSourceImportStatus.test.ts
|
tests/boundary/cli/referenceSourceImportStatus.test.ts
|
||||||
tests/boundary/filesystem/asarInventoryFreshness.test.ts
|
tests/boundary/filesystem/asarInventoryFreshness.test.ts
|
||||||
tests/boundary/filesystem/javascript-applications/javascriptArtifactReconstruction.test.ts
|
tests/composition/javascript-applications/javascriptArtifactReconstruction.test.ts
|
||||||
tests/conformance/providers/ghidra/windowsCapabilities.test.ts
|
tests/conformance/providers/ghidra/windowsCapabilities.test.ts
|
||||||
src/ghidra/GhidraInstallation.test.ts
|
src/ghidra/GhidraInstallation.test.ts
|
||||||
tests/boundary/providers/ghidra/ghidraTransport.test.ts
|
tests/boundary/providers/ghidra/ghidraTransport.test.ts
|
||||||
@@ -511,12 +449,6 @@ jobs:
|
|||||||
tests/process-global/updateMaintenance.test.ts
|
tests/process-global/updateMaintenance.test.ts
|
||||||
tests/conformance/providers/ghidra/realGhidraWindowsWorkflow.test.ts
|
tests/conformance/providers/ghidra/realGhidraWindowsWorkflow.test.ts
|
||||||
- run: npm run verify:windows-native
|
- run: npm run verify:windows-native
|
||||||
- uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: windows-native-inspection-fixture
|
|
||||||
path: .cache/windows-native-inspection-fixture/
|
|
||||||
- name: Verify native inspection failure ownership and recovery
|
|
||||||
run: node scripts/verify-windows-native-inspection.mjs
|
|
||||||
- name: Verify real Node Inspector discovery and observation
|
- name: Verify real Node Inspector discovery and observation
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
env:
|
env:
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ jobs:
|
|||||||
node-version-file: .nvmrc
|
node-version-file: .nvmrc
|
||||||
cache: npm
|
cache: npm
|
||||||
- run: npm ci
|
- run: npm ci
|
||||||
- uses: ./.github/actions/portable-build-cache
|
|
||||||
- name: Acquire exact upstream libraries in an isolated runner environment
|
- name: Acquire exact upstream libraries in an isolated runner environment
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -22,10 +22,9 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: .nvmrc
|
node-version: 24
|
||||||
cache: npm
|
cache: npm
|
||||||
- run: npm ci
|
- run: npm ci
|
||||||
- uses: ./.github/actions/portable-build-cache
|
|
||||||
- run: npm run verify:browser
|
- run: npm run verify:browser
|
||||||
env:
|
env:
|
||||||
REA_BROWSER_EXECUTABLE: /usr/bin/google-chrome
|
REA_BROWSER_EXECUTABLE: /usr/bin/google-chrome
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ jobs:
|
|||||||
node-version-file: .nvmrc
|
node-version-file: .nvmrc
|
||||||
cache: npm
|
cache: npm
|
||||||
- run: npm ci
|
- run: npm ci
|
||||||
- uses: ./.github/actions/portable-build-cache
|
|
||||||
- name: Acquire unchanged fixture compiler in isolated runner storage
|
- name: Acquire unchanged fixture compiler in isolated runner storage
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -24,10 +24,9 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: .nvmrc
|
node-version: 24
|
||||||
cache: npm
|
cache: npm
|
||||||
- run: npm ci
|
- run: npm ci
|
||||||
- uses: ./.github/actions/portable-build-cache
|
|
||||||
- name: Fetch pinned Wakaru release into the job workspace
|
- name: Fetch pinned Wakaru release into the job workspace
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ jobs:
|
|||||||
node-version-file: .nvmrc
|
node-version-file: .nvmrc
|
||||||
cache: npm
|
cache: npm
|
||||||
- run: npm ci
|
- run: npm ci
|
||||||
- uses: ./.github/actions/portable-build-cache
|
|
||||||
- name: Install GDB on the disposable CI runner
|
- name: Install GDB on the disposable CI runner
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ jobs:
|
|||||||
- name: Use pinned package manager
|
- name: Use pinned package manager
|
||||||
run: npm install --global npm@11.16.0
|
run: npm install --global npm@11.16.0
|
||||||
- run: npm ci
|
- run: npm ci
|
||||||
- uses: ./.github/actions/portable-build-cache
|
|
||||||
- name: Acquire fixed upstream native profile in runner temporary storage
|
- name: Acquire fixed upstream native profile in runner temporary storage
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -17,10 +17,9 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: .nvmrc
|
node-version: 24
|
||||||
cache: npm
|
cache: npm
|
||||||
- run: npm ci
|
- run: npm ci
|
||||||
- uses: ./.github/actions/portable-build-cache
|
|
||||||
- run: npm run verify:browser:runtime
|
- run: npm run verify:browser:runtime
|
||||||
env:
|
env:
|
||||||
REA_BROWSER_EXECUTABLE: /usr/bin/google-chrome
|
REA_BROWSER_EXECUTABLE: /usr/bin/google-chrome
|
||||||
|
|||||||
@@ -17,10 +17,9 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: .nvmrc
|
node-version: 24
|
||||||
cache: npm
|
cache: npm
|
||||||
- run: npm ci
|
- run: npm ci
|
||||||
- uses: ./.github/actions/portable-build-cache
|
|
||||||
- name: Install the pinned compiler into an isolated fixture directory
|
- name: Install the pinned compiler into an isolated fixture directory
|
||||||
run: npm install --prefix "$RUNNER_TEMP/rea-web-source-map-compiler" --no-audit --no-fund --package-lock=false esbuild@0.25.10
|
run: npm install --prefix "$RUNNER_TEMP/rea-web-source-map-compiler" --no-audit --no-fund --package-lock=false esbuild@0.25.10
|
||||||
- run: npm run verify:browser:source-maps
|
- run: npm run verify:browser:source-maps
|
||||||
|
|||||||
@@ -30,5 +30,9 @@ jobs:
|
|||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install --no-install-recommends -y libcairo2 fonts-dejavu-core
|
sudo apt-get install --no-install-recommends -y libcairo2 fonts-dejavu-core
|
||||||
python3 -m pip install -r website/requirements.txt
|
python3 -m pip install -r website/requirements.txt
|
||||||
|
- name: Set up Node.js for website script tests
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version-file: .nvmrc
|
||||||
- name: Check shared HTML, links, assets and contributor workflows
|
- name: Check shared HTML, links, assets and contributor workflows
|
||||||
run: python3 scripts/website.py check
|
run: python3 scripts/website.py check
|
||||||
|
|||||||
@@ -59,8 +59,15 @@ jobs:
|
|||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install --no-install-recommends -y libcairo2 fonts-dejavu-core
|
sudo apt-get install --no-install-recommends -y libcairo2 fonts-dejavu-core
|
||||||
python3 -m pip install -r website/requirements.txt
|
python3 -m pip install -r website/requirements.txt
|
||||||
|
- name: Set up Node.js for website script tests
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version-file: .nvmrc
|
||||||
- name: Check shared HTML, links, assets and contributor workflows
|
- name: Check shared HTML, links, assets and contributor workflows
|
||||||
run: python3 scripts/website.py check
|
run: python3 scripts/website.py check
|
||||||
|
# An out-of-date translation only warns in checks; publish it with its notice.
|
||||||
|
- name: Refresh translation notices
|
||||||
|
run: python3 scripts/website.py sync
|
||||||
- name: Record the published commit
|
- name: Record the published commit
|
||||||
run: |
|
run: |
|
||||||
python3 - <<'PY'
|
python3 - <<'PY'
|
||||||
@@ -68,7 +75,7 @@ jobs:
|
|||||||
import os
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
Path("website/_site/deployment.json").write_text(
|
Path("website/public/deployment.json").write_text(
|
||||||
json.dumps({"commit": os.environ["GITHUB_SHA"]}) + "\n",
|
json.dumps({"commit": os.environ["GITHUB_SHA"]}) + "\n",
|
||||||
encoding="utf-8",
|
encoding="utf-8",
|
||||||
)
|
)
|
||||||
@@ -78,7 +85,7 @@ jobs:
|
|||||||
- name: Upload the website
|
- name: Upload the website
|
||||||
uses: actions/upload-pages-artifact@v4
|
uses: actions/upload-pages-artifact@v4
|
||||||
with:
|
with:
|
||||||
path: website/_site
|
path: website/public
|
||||||
|
|
||||||
deploy:
|
deploy:
|
||||||
needs: prepare
|
needs: prepare
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ codedb.snapshot
|
|||||||
htmlcov/
|
htmlcov/
|
||||||
.coverage
|
.coverage
|
||||||
coverage/
|
coverage/
|
||||||
.vitest/
|
|
||||||
.vitest-reports/
|
.vitest-reports/
|
||||||
test-results.xml
|
test-results.xml
|
||||||
.turbo/
|
.turbo/
|
||||||
@@ -68,6 +67,3 @@ Thumbs.db
|
|||||||
/docs/public/product-catalog.json
|
/docs/public/product-catalog.json
|
||||||
/docs/verification/managed-conformance-manifest.json
|
/docs/verification/managed-conformance-manifest.json
|
||||||
/docs/verification/managed-conformance-ledger.json
|
/docs/verification/managed-conformance-ledger.json
|
||||||
|
|
||||||
# Complete static website output, including generated language editions.
|
|
||||||
website/_site/
|
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"_comment": "Test files remain included so the gate measures duplication across both src/ and tests/. The 3.0% limit leaves headroom for ordinary changes while keeping duplication visible.",
|
"_comment": "Test files are intentionally NOT excluded: the gate used to report zero clones because it skipped **/*.test.ts, hiding all test-tree duplication. Current actual is ~2.47% lines across src+ and tests/, down from 3.4% when tests were included. The 2.6% limit leaves modest headroom for ordinary changes; lower it as duplication is removed.",
|
||||||
"threshold": 3.0,
|
"threshold": 2.6,
|
||||||
"reporters": ["consoleFull"],
|
"reporters": ["consoleFull"],
|
||||||
"ignore": [
|
"ignore": [
|
||||||
"node_modules/**",
|
"node_modules/**",
|
||||||
|
|||||||
@@ -18,8 +18,6 @@ Give each interpretation and resource a clear owner. Preserve identity, omission
|
|||||||
|
|
||||||
Assess brittleness in touched code during implementation, debugging, review, and maintenance. Fix the producing representation or ownership rule before adding downstream repairs. Normalize once at the owning boundary using format-aware parsers. Remove superseded representations, aliases, wrappers, and redundant tests after verifying affected consumers. Introduce abstractions only when they remove observed complexity.
|
Assess brittleness in touched code during implementation, debugging, review, and maintenance. Fix the producing representation or ownership rule before adding downstream repairs. Normalize once at the owning boundary using format-aware parsers. Remove superseded representations, aliases, wrappers, and redundant tests after verifying affected consumers. Introduce abstractions only when they remove observed complexity.
|
||||||
|
|
||||||
When fixing a bug, inspect the producing boundary and affected consumers for duplicated interpretation or unclear ownership. Complete any directly related refactor in the same change and remove superseded code. Passing regression tests alone does not establish that the brittleness is resolved. If related cleanup remains, explain what remains and why.
|
|
||||||
|
|
||||||
Parse unknown boundary values and model expected failures with the tagged error algebra and `Result`. Preserve partial facts and meaningful failure reasons. Keep identity and lookup values separate from display formatting; preserve source values and explicit unknowns when normalization loses information. Absolute paths, file URLs, and HTTP paths have different semantics.
|
Parse unknown boundary values and model expected failures with the tagged error algebra and `Result`. Preserve partial facts and meaningful failure reasons. Keep identity and lookup values separate from display formatting; preserve source values and explicit unknowns when normalization loses information. Absolute paths, file URLs, and HTTP paths have different semantics.
|
||||||
|
|
||||||
Validate advertised JSON Schemas after SDK conversion against their declared dialect and actual clients. Bind handlers to named contracts with exact types; catalog ordering must never select an operation or schema.
|
Validate advertised JSON Schemas after SDK conversion against their declared dialect and actual clients. Bind handlers to named contracts with exact types; catalog ordering must never select an operation or schema.
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
**See a feature you like. Understand how it works, down to the binary level.**
|
**See a feature you like. Understand how it works, down to the binary level.**
|
||||||
|
|
||||||
[](https://www.npmjs.com/package/rea-agents)
|
[](https://www.npmjs.com/package/rea-agents)
|
||||||
|
[](https://github.com/morluto/rea/actions/workflows/ci.yml)
|
||||||
[](docs/mcp-contracts.md#generated-catalog)
|
[](docs/mcp-contracts.md#generated-catalog)
|
||||||
[](#what-you-can-analyze)
|
[](#what-you-can-analyze)
|
||||||
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
||||||
@@ -110,15 +111,12 @@ snapshots and scripting.
|
|||||||
REA changes quickly, and new releases include frequent bug fixes. Keep your
|
REA changes quickly, and new releases include frequent bug fixes. Keep your
|
||||||
installation up to date.
|
installation up to date.
|
||||||
|
|
||||||
For a CLI installed with `npm install --global` or `bun add --global`:
|
For an npm-installed CLI:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
rea update
|
rea update
|
||||||
```
|
```
|
||||||
|
|
||||||
Bun global updates require Bun 1.2.17 or later. With an older Bun release,
|
|
||||||
upgrade Bun manually before running `rea update`.
|
|
||||||
|
|
||||||
To refresh your agent registrations and skill, run the setup command printed
|
To refresh your agent registrations and skill, run the setup command printed
|
||||||
by the update.
|
by the update.
|
||||||
|
|
||||||
@@ -129,8 +127,7 @@ npx rea-agents@latest setup
|
|||||||
```
|
```
|
||||||
|
|
||||||
Review the setup changes and restart your agent. For one-off CLI commands,
|
Review the setup changes and restart your agent. For one-off CLI commands,
|
||||||
use `npx rea-agents@latest` followed by the command. With Bun, use
|
use `npx rea-agents@latest` followed by the command.
|
||||||
`bunx rea-agents@latest` in place of `npx rea-agents@latest`.
|
|
||||||
|
|
||||||
## How REA works
|
## How REA works
|
||||||
|
|
||||||
@@ -154,7 +151,6 @@ Additional tools and host support depend on the target:
|
|||||||
| ---------------------- | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- |
|
| ---------------------- | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| Native binaries | Pseudocode, assembly, strings, symbols, calls and references | Hopper, Ghidra or IDA; [native analysis](https://rea.tools/guides/native/) |
|
| Native binaries | Pseudocode, assembly, strings, symbols, calls and references | Hopper, Ghidra or IDA; [native analysis](https://rea.tools/guides/native/) |
|
||||||
| Offline ELF layout | Sections, segments, original symbols/relocations and static mitigation candidates | Caller-supplied pwntools on Linux x64; [binary diagnostics](docs/binary-diagnostics.md) |
|
| Offline ELF layout | Sections, segments, original symbols/relocations and static mitigation candidates | Caller-supplied pwntools on Linux x64; [binary diagnostics](docs/binary-diagnostics.md) |
|
||||||
| WASM artifact | Validation, sections, exact import/export WAT forms and decoded WAT | Caller-supplied WABT 1.0.42; `inspect_wasm_artifact` |
|
|
||||||
| EVM bytecode | Dispatch selectors, byte offsets, inferred arguments and mutability | Local raw/hex carrier on Linux x64; [offline EVM guide](docs/evm-bytecode.md) |
|
| EVM bytecode | Dispatch selectors, byte offsets, inferred arguments and mutability | Local raw/hex carrier on Linux x64; [offline EVM guide](docs/evm-bytecode.md) |
|
||||||
| Recorded Linux crashes | Raw notes, every recorded thread's registers/signals and optional mapping candidates | Caller-supplied pwntools on Linux x64; optional GDB/pwndbg; [recorded crashes](docs/recorded-crashes.md) |
|
| Recorded Linux crashes | Raw notes, every recorded thread's registers/signals and optional mapping candidates | Caller-supplied pwntools on Linux x64; optional GDB/pwndbg; [recorded crashes](docs/recorded-crashes.md) |
|
||||||
| JavaScript / Electron | Modules, imports, source maps, routes, IPC and native add-on relationships | Node.js and npm; [application analysis](https://rea.tools/guides/javascript/) |
|
| JavaScript / Electron | Modules, imports, source maps, routes, IPC and native add-on relationships | Node.js and npm; [application analysis](https://rea.tools/guides/javascript/) |
|
||||||
@@ -180,8 +176,8 @@ Native formats and host support vary by provider. See
|
|||||||
[IDA guide](docs/ida-provider.md), and
|
[IDA guide](docs/ida-provider.md), and
|
||||||
[experimental Windows Ghidra support](docs/windows-ghidra-p0.md).
|
[experimental Windows Ghidra support](docs/windows-ghidra-p0.md).
|
||||||
Ghidra also supports [16-bit DOS analysis](docs/ghidra-dos.md).
|
Ghidra also supports [16-bit DOS analysis](docs/ghidra-dos.md).
|
||||||
For large binaries, raise the provider's startup deadline with
|
For large binaries, raise its startup deadline with
|
||||||
`REA_GHIDRA_STARTUP_TIMEOUT_MS` or `REA_HOPPER_STARTUP_TIMEOUT_MS`.
|
`REA_GHIDRA_STARTUP_TIMEOUT_MS`.
|
||||||
For provider selection, see the [CLI guide](docs/cli.md#choose-a-provider).
|
For provider selection, see the [CLI guide](docs/cli.md#choose-a-provider).
|
||||||
Check [release availability](docs/installation.md#released-package-and-main)
|
Check [release availability](docs/installation.md#released-package-and-main)
|
||||||
for features added since the latest npm release.
|
for features added since the latest npm release.
|
||||||
@@ -244,9 +240,7 @@ Ghidra and IDA use your existing installations. See [provider setup](docs/instal
|
|||||||
<summary><strong>Do I need to start Hopper first?</strong></summary>
|
<summary><strong>Do I need to start Hopper first?</strong></summary>
|
||||||
|
|
||||||
REA starts Hopper when an operation needs it. On macOS, a first-run dialog may
|
REA starts Hopper when an operation needs it. On macOS, a first-run dialog may
|
||||||
ask you to choose demo mode or activate your license. Complete that prompt in the
|
ask you to choose demo mode or activate your license. See
|
||||||
same user session before your first CLI/MCP operation or unattended job. Open
|
|
||||||
Hopper manually if needed. See
|
|
||||||
[Hopper startup and troubleshooting](docs/installation.md#launcher-paths-and-troubleshooting).
|
[Hopper startup and troubleshooting](docs/installation.md#launcher-paths-and-troubleshooting).
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
@@ -282,7 +276,7 @@ model provider has its own data policy.
|
|||||||
|
|
||||||
Update first; a recent release may already fix it.
|
Update first; a recent release may already fix it.
|
||||||
|
|
||||||
For a CLI installed with `npm install --global` or `bun add --global`:
|
For an npm-installed CLI:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
rea update
|
rea update
|
||||||
@@ -316,7 +310,7 @@ Report vulnerabilities through [SECURITY.md](SECURITY.md).
|
|||||||
|
|
||||||
## Star history
|
## Star history
|
||||||
|
|
||||||
🎉 **90,000 GitHub stars — thank you!**
|
🎉 **60,000 GitHub stars — thank you!**
|
||||||
|
|
||||||
Thanks to everyone using REA, reporting bugs, requesting features, testing builds, and contributing fixes.
|
Thanks to everyone using REA, reporting bugs, requesting features, testing builds, and contributing fixes.
|
||||||
|
|
||||||
|
|||||||
+12
-11
@@ -9,6 +9,7 @@
|
|||||||
**وجدت ميزة تعجبك؟ افهم طريقة عملها حتى مستوى الشيفرة الثنائية.**
|
**وجدت ميزة تعجبك؟ افهم طريقة عملها حتى مستوى الشيفرة الثنائية.**
|
||||||
|
|
||||||
[](https://www.npmjs.com/package/rea-agents)
|
[](https://www.npmjs.com/package/rea-agents)
|
||||||
|
[](https://github.com/morluto/rea/actions/workflows/ci.yml)
|
||||||
[](docs/mcp-contracts.md#generated-catalog)
|
[](docs/mcp-contracts.md#generated-catalog)
|
||||||
[](#current-status)
|
[](#current-status)
|
||||||
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
||||||
@@ -17,7 +18,7 @@
|
|||||||
|
|
||||||
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
||||||
|
|
||||||
**[الموقع](https://rea.tools/ar/) · [الأدلة](https://rea.tools/ar/guides/) · [دراسات الحالة](https://rea.tools/ar/showcase/)**
|
**[الموقع](https://rea.tools/) · [الأدلة](https://rea.tools/guides/) · [دراسات الحالة](https://rea.tools/showcase/)**
|
||||||
|
|
||||||
[البدء السريع](#البدء-السريع) · [كيف يعمل REA](#كيف-يعمل-rea) · [ما الذي يمكنك تحليله](#ما-الذي-يمكنك-تحليله) · [دراسات الحالة](#دراسات-الحالة) · [الأسئلة الشائعة](#الأسئلة-الشائعة) · [التوثيق](#التوثيق)
|
[البدء السريع](#البدء-السريع) · [كيف يعمل REA](#كيف-يعمل-rea) · [ما الذي يمكنك تحليله](#ما-الذي-يمكنك-تحليله) · [دراسات الحالة](#دراسات-الحالة) · [الأسئلة الشائعة](#الأسئلة-الشائعة) · [التوثيق](#التوثيق)
|
||||||
|
|
||||||
@@ -53,7 +54,7 @@
|
|||||||
|
|
||||||
يسجّل الإعداد REA لدى وكيلك ويثبّت تعليمات سير العمل المطابقة. يمكن لتحليل الشيفرة الأصلية استخدام تثبيت موجود من Hopper أو Ghidra؛ ويمكن للإعداد أيضًا تثبيت Hopper اختياريًا بعد موافقتك. لا يحتاج التحليل الثابت لـ JavaScript إلى أي من المحركين.
|
يسجّل الإعداد REA لدى وكيلك ويثبّت تعليمات سير العمل المطابقة. يمكن لتحليل الشيفرة الأصلية استخدام تثبيت موجود من Hopper أو Ghidra؛ ويمكن للإعداد أيضًا تثبيت Hopper اختياريًا بعد موافقتك. لا يحتاج التحليل الثابت لـ JavaScript إلى أي من المحركين.
|
||||||
|
|
||||||
> **[زر موقع REA](https://rea.tools/ar/)** للاطلاع على تعليمات الإعداد والأدلة المصوّرة ودراسات الحالة الفعلية.
|
> **[زر موقع REA](https://rea.tools/)** للاطلاع على تعليمات الإعداد والأدلة المصوّرة ودراسات الحالة الفعلية.
|
||||||
|
|
||||||
## البدء السريع
|
## البدء السريع
|
||||||
|
|
||||||
@@ -132,12 +133,12 @@ npx rea-agents@latest setup
|
|||||||
|
|
||||||
| الهدف | ما يعيده REA | المتطلبات والدليل |
|
| الهدف | ما يعيده REA | المتطلبات والدليل |
|
||||||
| ------------------------------- | ---------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
|
| ------------------------------- | ---------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| الملفات الثنائية للشيفرة الأصلية | شيفرة شبه برمجية، وتعليمات تجميع، وسلاسل نصية، ورموز، واستدعاءات، ومراجع | Hopper أو Ghidra أو IDA؛ [تحليل الشيفرة الأصلية](https://rea.tools/ar/guides/native/) |
|
| الملفات الثنائية للشيفرة الأصلية | شيفرة شبه برمجية، وتعليمات تجميع، وسلاسل نصية، ورموز، واستدعاءات، ومراجع | Hopper أو Ghidra أو IDA؛ [تحليل الشيفرة الأصلية](https://rea.tools/guides/native/) |
|
||||||
| بنية ELF دون تشغيل | الأقسام والمقاطع والرموز ومعلومات إعادة التموضع الأصلية، وآليات الحماية المحتملة المستدلّ عليها بالفحص الثابت | pwntools يوفّره المستدعي على Linux x64؛ [تشخيص الملفات الثنائية](docs/binary-diagnostics.md) |
|
| بنية ELF دون تشغيل | الأقسام والمقاطع والرموز ومعلومات إعادة التموضع الأصلية، وآليات الحماية المحتملة المستدلّ عليها بالفحص الثابت | pwntools يوفّره المستدعي على Linux x64؛ [تشخيص الملفات الثنائية](docs/binary-diagnostics.md) |
|
||||||
| شيفرة EVM البايتية | محددات التوجيه، وإزاحات البايتات، والمعاملات المستنتجة، وقابلية تغيير الحالة | مدخل محلي يحمل بايتات خامًا أو تمثيلًا سداسيًا عشريًا على Linux x64؛ [دليل EVM دون تشغيل](docs/evm-bytecode.md) |
|
| شيفرة EVM البايتية | محددات التوجيه، وإزاحات البايتات، والمعاملات المستنتجة، وقابلية تغيير الحالة | مدخل محلي يحمل بايتات خامًا أو تمثيلًا سداسيًا عشريًا على Linux x64؛ [دليل EVM دون تشغيل](docs/evm-bytecode.md) |
|
||||||
| أعطال Linux المسجّلة | سجلات note الخام، ومسجّلات المعالج/الإشارات لكل خيط مسجّل، وترشيحات اختيارية لخرائط الذاكرة | pwntools يوفّره المستدعي على Linux x64؛ GDB/pwndbg اختياريان؛ [الأعطال المسجّلة](docs/recorded-crashes.md) |
|
| أعطال Linux المسجّلة | سجلات note الخام، ومسجّلات المعالج/الإشارات لكل خيط مسجّل، وترشيحات اختيارية لخرائط الذاكرة | pwntools يوفّره المستدعي على Linux x64؛ GDB/pwndbg اختياريان؛ [الأعطال المسجّلة](docs/recorded-crashes.md) |
|
||||||
| JavaScript / Electron | الوحدات، وعمليات الاستيراد، وخرائط المصدر، والمسارات، وIPC، وعلاقات إضافات الشيفرة الأصلية | Node.js وnpm؛ [تحليل التطبيقات](https://rea.tools/ar/guides/javascript/) |
|
| JavaScript / Electron | الوحدات، وعمليات الاستيراد، وخرائط المصدر، والمسارات، وIPC، وعلاقات إضافات الشيفرة الأصلية | Node.js وnpm؛ [تحليل التطبيقات](https://rea.tools/guides/javascript/) |
|
||||||
| المواقع | بنية الصفحة، والسكربتات، وملاحظات الشبكة، ولقطات الشاشة المطلوبة | متصفح من عائلة Chrome؛ [تحليل المتصفح](https://rea.tools/ar/guides/browser/) |
|
| المواقع | بنية الصفحة، والسكربتات، وملاحظات الشبكة، ولقطات الشاشة المطلوبة | متصفح من عائلة Chrome؛ [تحليل المتصفح](https://rea.tools/guides/browser/) |
|
||||||
| تسجيلات الشبكة المحفوظة | الطلبات، والاستجابات، ومحتويات الحمولة المتاحة، ومواضعها في المصدر | HAR؛ وmitmdump على Linux لتسجيلات mitmproxy بصيغتها الأصلية؛ [دليل تسجيلات الشبكة](docs/web-network-captures.md) |
|
| تسجيلات الشبكة المحفوظة | الطلبات، والاستجابات، ومحتويات الحمولة المتاحة، ومواضعها في المصدر | HAR؛ وmitmdump على Linux لتسجيلات mitmproxy بصيغتها الأصلية؛ [دليل تسجيلات الشبكة](docs/web-network-captures.md) |
|
||||||
| تجميعات .NET | البيانات الوصفية، وتعليمات CIL، واعتماديات الشيفرة الأصلية المعلنة، ومقارنات البناء | فحص ثابت؛ [دليل الشيفرة المُدارة](docs/managed-code-analysis.md) |
|
| تجميعات .NET | البيانات الوصفية، وتعليمات CIL، واعتماديات الشيفرة الأصلية المعلنة، ومقارنات البناء | فحص ثابت؛ [دليل الشيفرة المُدارة](docs/managed-code-analysis.md) |
|
||||||
| حزم Android APK | تصريحات ملف manifest، والأصناف، والدوال الناتجة عن فك الترجمة، والمراجع | JADX دون واجهة رسومية وJDK كامل على Linux/macOS/Windows x64؛ [دليل Android](docs/android-analysis.md) |
|
| حزم Android APK | تصريحات ملف manifest، والأصناف، والدوال الناتجة عن فك الترجمة، والمراجع | JADX دون واجهة رسومية وJDK كامل على Linux/macOS/Windows x64؛ [دليل Android](docs/android-analysis.md) |
|
||||||
@@ -156,26 +157,26 @@ npx rea-agents@latest setup
|
|||||||
|
|
||||||
## دراسات الحالة
|
## دراسات الحالة
|
||||||
|
|
||||||
[](https://rea.tools/ar/showcase/)
|
[](https://rea.tools/showcase/)
|
||||||
|
|
||||||
### DX-Ball: إعادة بناء حساب توزيع الصوت بين القناتين
|
### DX-Ball: إعادة بناء حساب توزيع الصوت بين القناتين
|
||||||
|
|
||||||
تتبّع استدعاء صوت إلى الدالة المساعدة التي تحوّل الموضع إلى توزيع بين القناتين، وافحص التعليمات، وحوّل الشيفرة شبه البرمجية غير المكتملة إلى C. تجتاز إعادة البناء 3,205 حالات اختبار على x86 الأصلي، وتعيد إنتاج جميع بايتات الدالة المترجمة البالغ عددها 63 بايتًا.
|
تتبّع استدعاء صوت إلى الدالة المساعدة التي تحوّل الموضع إلى توزيع بين القناتين، وافحص التعليمات، وحوّل الشيفرة شبه البرمجية غير المكتملة إلى C. تجتاز إعادة البناء 3,205 حالات اختبار على x86 الأصلي، وتعيد إنتاج جميع بايتات الدالة المترجمة البالغ عددها 63 بايتًا.
|
||||||
|
|
||||||
[اقرأ دراسة الحالة](https://rea.tools/ar/showcase/dx-ball/) ·
|
[اقرأ دراسة الحالة](https://rea.tools/showcase/dx-ball/) ·
|
||||||
[مستودع إعادة البناء](https://github.com/N0zoM1z0/dx-ball)
|
[مستودع إعادة البناء](https://github.com/N0zoM1z0/dx-ball)
|
||||||
|
|
||||||
### Notion: تتبّع جسر الحافظة في Electron
|
### Notion: تتبّع جسر الحافظة في Electron
|
||||||
|
|
||||||
اعثر على API الحافظة في عملية العرض، وتتبّعه عبر preload وIPC إلى العملية الرئيسية، وافحص صيغة الحافظة ذات التنسيق الغني.
|
اعثر على API الحافظة في عملية العرض، وتتبّعه عبر preload وIPC إلى العملية الرئيسية، وافحص صيغة الحافظة ذات التنسيق الغني.
|
||||||
|
|
||||||
[اقرأ دراسة الحالة](https://rea.tools/ar/showcase/notion/)
|
[اقرأ دراسة الحالة](https://rea.tools/showcase/notion/)
|
||||||
|
|
||||||
### TH04: استعادة حساب حلقة المقذوفات في DOS
|
### TH04: استعادة حساب حلقة المقذوفات في DOS
|
||||||
|
|
||||||
افحص تعليمات اللعبة الأصلية على PC-98 ذات 16 بت، واستعد حساب الزوايا الثابتة والموجّهة نحو الهدف، وقارن شيفرة C++ المعاد بناؤها بمخرجات المترجم المستخدم آنذاك.
|
افحص تعليمات اللعبة الأصلية على PC-98 ذات 16 بت، واستعد حساب الزوايا الثابتة والموجّهة نحو الهدف، وقارن شيفرة C++ المعاد بناؤها بمخرجات المترجم المستخدم آنذاك.
|
||||||
|
|
||||||
[اقرأ دراسة الحالة](https://rea.tools/ar/showcase/th04/) ·
|
[اقرأ دراسة الحالة](https://rea.tools/showcase/th04/) ·
|
||||||
[مستودع إعادة البناء](https://github.com/N0zoM1z0/th04)
|
[مستودع إعادة البناء](https://github.com/N0zoM1z0/th04)
|
||||||
|
|
||||||
إذا استخدمت REA لفحص هدف مثير للاهتمام، فنود الاطلاع عليه. شارك حالتك في [issue](https://github.com/morluto/rea/issues) أو [pull request](https://github.com/morluto/rea/pulls)، مع ذكر الهدف، وسؤالك، وكيف ساعدك REA، وما توصلت إليه.
|
إذا استخدمت REA لفحص هدف مثير للاهتمام، فنود الاطلاع عليه. شارك حالتك في [issue](https://github.com/morluto/rea/issues) أو [pull request](https://github.com/morluto/rea/pulls)، مع ذكر الهدف، وسؤالك، وكيف ساعدك REA، وما توصلت إليه.
|
||||||
@@ -247,7 +248,7 @@ npx rea-agents@latest setup
|
|||||||
|
|
||||||
## التوثيق
|
## التوثيق
|
||||||
|
|
||||||
ابدأ بـ [الأدلة العملية](https://rea.tools/ar/guides/) على الموقع. للخيارات الدقيقة والمتطلبات وعقود النتائج:
|
ابدأ بـ [الأدلة العملية](https://rea.tools/guides/) على الموقع. للخيارات الدقيقة والمتطلبات وعقود النتائج:
|
||||||
|
|
||||||
- [التثبيت والإعداد](docs/installation.md): تسجيل الوكلاء، وتهيئة الموفّرين، والتحديثات، وإلغاء التثبيت.
|
- [التثبيت والإعداد](docs/installation.md): تسجيل الوكلاء، وتهيئة الموفّرين، والتحديثات، وإلغاء التثبيت.
|
||||||
- [الجاهزية واستكشاف الأخطاء](docs/installation.md#check-readiness-for-your-task): تشخيص وكيل أو محرك تحليل محدد.
|
- [الجاهزية واستكشاف الأخطاء](docs/installation.md#check-readiness-for-your-task): تشخيص وكيل أو محرك تحليل محدد.
|
||||||
@@ -260,7 +261,7 @@ npx rea-agents@latest setup
|
|||||||
|
|
||||||
## سجل النجوم
|
## سجل النجوم
|
||||||
|
|
||||||
🎉 **90,000 نجمة على GitHub — شكرًا لكم!**
|
🎉 **50,000 نجمة على GitHub — شكرًا لكم!**
|
||||||
|
|
||||||
شكرًا لكل من يستخدم REA، ويبلّغ عن الأخطاء، ويقترح ميزات، ويختبر إصدارات البناء، ويساهم بالإصلاحات.
|
شكرًا لكل من يستخدم REA، ويبلّغ عن الأخطاء، ويقترح ميزات، ويختبر إصدارات البناء، ويساهم بالإصلاحات.
|
||||||
|
|
||||||
|
|||||||
+12
-11
@@ -9,6 +9,7 @@
|
|||||||
**Eine Funktion gefällt dir? Verstehe, wie sie funktioniert – bis hinunter auf die Binärebene.**
|
**Eine Funktion gefällt dir? Verstehe, wie sie funktioniert – bis hinunter auf die Binärebene.**
|
||||||
|
|
||||||
[](https://www.npmjs.com/package/rea-agents)
|
[](https://www.npmjs.com/package/rea-agents)
|
||||||
|
[](https://github.com/morluto/rea/actions/workflows/ci.yml)
|
||||||
[](docs/mcp-contracts.md#generated-catalog)
|
[](docs/mcp-contracts.md#generated-catalog)
|
||||||
[](#current-status)
|
[](#current-status)
|
||||||
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
||||||
@@ -17,7 +18,7 @@
|
|||||||
|
|
||||||
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
||||||
|
|
||||||
**[Website](https://rea.tools/de/) · [Anleitungen](https://rea.tools/de/guides/) · [Fallstudien](https://rea.tools/de/showcase/)**
|
**[Website](https://rea.tools/) · [Anleitungen](https://rea.tools/guides/) · [Fallstudien](https://rea.tools/showcase/)**
|
||||||
|
|
||||||
[Schnellstart](#schnellstart) · [So funktioniert REA](#so-funktioniert-rea) · [Was du analysieren kannst](#was-du-analysieren-kannst) · [Fallstudien](#fallstudien) · [Häufige Fragen](#häufige-fragen) · [Dokumentation](#dokumentation)
|
[Schnellstart](#schnellstart) · [So funktioniert REA](#so-funktioniert-rea) · [Was du analysieren kannst](#was-du-analysieren-kannst) · [Fallstudien](#fallstudien) · [Häufige Fragen](#häufige-fragen) · [Dokumentation](#dokumentation)
|
||||||
|
|
||||||
@@ -53,7 +54,7 @@ REA verbindet deinen Agenten mit Werkzeugen zum Untersuchen nativer Binärdateie
|
|||||||
|
|
||||||
Die Einrichtung registriert REA bei deinem Agenten und installiert passende Workflow-Anweisungen. Für native Analysen kannst du eine vorhandene Hopper- oder Ghidra-Installation verwenden. Mit deiner Zustimmung kann die Einrichtung auch Hopper installieren. Statische JavaScript-Analysen benötigen keines der beiden Programme.
|
Die Einrichtung registriert REA bei deinem Agenten und installiert passende Workflow-Anweisungen. Für native Analysen kannst du eine vorhandene Hopper- oder Ghidra-Installation verwenden. Mit deiner Zustimmung kann die Einrichtung auch Hopper installieren. Statische JavaScript-Analysen benötigen keines der beiden Programme.
|
||||||
|
|
||||||
> **[Besuche die REA-Website](https://rea.tools/de/)** für Einrichtungshinweise, bebilderte Anleitungen und echte Fallstudien.
|
> **[Besuche die REA-Website](https://rea.tools/)** für Einrichtungshinweise, bebilderte Anleitungen und echte Fallstudien.
|
||||||
|
|
||||||
## Schnellstart
|
## Schnellstart
|
||||||
|
|
||||||
@@ -132,12 +133,12 @@ REA benötigt Node.js 22.x (>=22.19), 24.x (>=24.11) oder 26+ sowie npm. Zusätz
|
|||||||
|
|
||||||
| Ziel | Was REA zurückgibt | Voraussetzungen und Anleitung |
|
| Ziel | Was REA zurückgibt | Voraussetzungen und Anleitung |
|
||||||
| ----------------------------------- | --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
|
| ----------------------------------- | --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| Native Binärdateien | Pseudocode, Assemblercode, Zeichenketten, Symbole, Aufrufe und Verweise | Hopper, Ghidra oder IDA; [native Analyse](https://rea.tools/de/guides/native/) |
|
| Native Binärdateien | Pseudocode, Assemblercode, Zeichenketten, Symbole, Aufrufe und Verweise | Hopper, Ghidra oder IDA; [native Analyse](https://rea.tools/guides/native/) |
|
||||||
| Offline-ELF-Struktur | Sektionen, Segmente, ursprüngliche Symbole/Relokationen und mögliche Schutzmaßnahmen aus statischer Analyse | Vom Aufrufer bereitgestelltes pwntools unter Linux x64; [Binärdiagnostik](docs/binary-diagnostics.md) |
|
| Offline-ELF-Struktur | Sektionen, Segmente, ursprüngliche Symbole/Relokationen und mögliche Schutzmaßnahmen aus statischer Analyse | Vom Aufrufer bereitgestelltes pwntools unter Linux x64; [Binärdiagnostik](docs/binary-diagnostics.md) |
|
||||||
| EVM-Bytecode | Dispatch-Selektoren, Byte-Offsets, abgeleitete Argumente und Veränderbarkeit des Zustands | Lokale Eingabe mit Rohbytes oder Hexdarstellung unter Linux x64; [Offline-EVM-Leitfaden](docs/evm-bytecode.md) |
|
| EVM-Bytecode | Dispatch-Selektoren, Byte-Offsets, abgeleitete Argumente und Veränderbarkeit des Zustands | Lokale Eingabe mit Rohbytes oder Hexdarstellung unter Linux x64; [Offline-EVM-Leitfaden](docs/evm-bytecode.md) |
|
||||||
| Aufgezeichnete Linux-Abstürze | Unverarbeitete Note-Einträge, Register/Signale aller aufgezeichneten Threads und optionale Zuordnungskandidaten | Vom Aufrufer bereitgestelltes pwntools unter Linux x64; optional GDB/pwndbg; [aufgezeichnete Abstürze](docs/recorded-crashes.md) |
|
| Aufgezeichnete Linux-Abstürze | Unverarbeitete Note-Einträge, Register/Signale aller aufgezeichneten Threads und optionale Zuordnungskandidaten | Vom Aufrufer bereitgestelltes pwntools unter Linux x64; optional GDB/pwndbg; [aufgezeichnete Abstürze](docs/recorded-crashes.md) |
|
||||||
| JavaScript / Electron | Module, Imports, Source Maps, Routen, IPC und Beziehungen zu nativen Add-ons | Node.js und npm; [Anwendungsanalyse](https://rea.tools/de/guides/javascript/) |
|
| JavaScript / Electron | Module, Imports, Source Maps, Routen, IPC und Beziehungen zu nativen Add-ons | Node.js und npm; [Anwendungsanalyse](https://rea.tools/guides/javascript/) |
|
||||||
| Websites | Seitenstruktur, Skripte, Netzwerkbeobachtungen und angeforderte Screenshots | Ein Browser aus der Chrome-Familie; [Browseranalyse](https://rea.tools/de/guides/browser/) |
|
| Websites | Seitenstruktur, Skripte, Netzwerkbeobachtungen und angeforderte Screenshots | Ein Browser aus der Chrome-Familie; [Browseranalyse](https://rea.tools/guides/browser/) |
|
||||||
| Gespeicherte Netzwerkaufzeichnungen | Anfragen, Antworten, zugängliche Nutzdaten und Quellpositionen | HAR; mitmdump unter Linux für Aufzeichnungen im nativen mitmproxy-Format; [Leitfaden zu Netzwerkaufzeichnungen](docs/web-network-captures.md) |
|
| Gespeicherte Netzwerkaufzeichnungen | Anfragen, Antworten, zugängliche Nutzdaten und Quellpositionen | HAR; mitmdump unter Linux für Aufzeichnungen im nativen mitmproxy-Format; [Leitfaden zu Netzwerkaufzeichnungen](docs/web-network-captures.md) |
|
||||||
| .NET-Assemblies | Metadaten, CIL-Anweisungen, deklarierte native Abhängigkeiten und Build-Vergleiche | Statische Untersuchung; [Leitfaden für verwalteten Code](docs/managed-code-analysis.md) |
|
| .NET-Assemblies | Metadaten, CIL-Anweisungen, deklarierte native Abhängigkeiten und Build-Vergleiche | Statische Untersuchung; [Leitfaden für verwalteten Code](docs/managed-code-analysis.md) |
|
||||||
| Android-APKs | Manifest-Deklarationen, Klassen, dekompilierte Methoden und Verweise | JADX ohne grafische Oberfläche und ein vollständiges JDK unter Linux/macOS/Windows x64; [Android-Leitfaden](docs/android-analysis.md) |
|
| Android-APKs | Manifest-Deklarationen, Klassen, dekompilierte Methoden und Verweise | JADX ohne grafische Oberfläche und ein vollständiges JDK unter Linux/macOS/Windows x64; [Android-Leitfaden](docs/android-analysis.md) |
|
||||||
@@ -156,25 +157,25 @@ Native Formate und unterstützte Hostsysteme unterscheiden sich je nach Provider
|
|||||||
|
|
||||||
## Fallstudien
|
## Fallstudien
|
||||||
|
|
||||||
[](https://rea.tools/de/showcase/)
|
[](https://rea.tools/showcase/)
|
||||||
|
|
||||||
### DX-Ball: Eine Stereo-Panning-Berechnung rekonstruieren
|
### DX-Ball: Eine Stereo-Panning-Berechnung rekonstruieren
|
||||||
|
|
||||||
Verfolge einen Sound-Aufruf zur Hilfsfunktion, die Positionen in Panning-Werte umrechnet, untersuche die Anweisungen und überführe unvollständigen Pseudocode in C. Die Rekonstruktion besteht 3.205 Tests mit dem ursprünglichen x86-Code und reproduziert alle 63 Bytes der kompilierten Funktion.
|
Verfolge einen Sound-Aufruf zur Hilfsfunktion, die Positionen in Panning-Werte umrechnet, untersuche die Anweisungen und überführe unvollständigen Pseudocode in C. Die Rekonstruktion besteht 3.205 Tests mit dem ursprünglichen x86-Code und reproduziert alle 63 Bytes der kompilierten Funktion.
|
||||||
|
|
||||||
[Fallstudie lesen](https://rea.tools/de/showcase/dx-ball/) · [Rekonstruktionsrepository](https://github.com/N0zoM1z0/dx-ball)
|
[Fallstudie lesen](https://rea.tools/showcase/dx-ball/) · [Rekonstruktionsrepository](https://github.com/N0zoM1z0/dx-ball)
|
||||||
|
|
||||||
### Notion: Die Electron-Zwischenablagebrücke verfolgen
|
### Notion: Die Electron-Zwischenablagebrücke verfolgen
|
||||||
|
|
||||||
Finde die Zwischenablage-API des Renderers, verfolge sie über preload und IPC bis zum Hauptprozess und untersuche das Zwischenablageformat samt Formatierungsdaten.
|
Finde die Zwischenablage-API des Renderers, verfolge sie über preload und IPC bis zum Hauptprozess und untersuche das Zwischenablageformat samt Formatierungsdaten.
|
||||||
|
|
||||||
[Fallstudie lesen](https://rea.tools/de/showcase/notion/)
|
[Fallstudie lesen](https://rea.tools/showcase/notion/)
|
||||||
|
|
||||||
### TH04: Eine DOS-Geschossring-Berechnung wiederherstellen
|
### TH04: Eine DOS-Geschossring-Berechnung wiederherstellen
|
||||||
|
|
||||||
Untersuche die 16-Bit-Anweisungen des ursprünglichen PC-98-Spiels, rekonstruiere die festen und zielgerichteten Winkelberechnungen und vergleiche das rekonstruierte C++ mit der Ausgabe des damaligen Compilers.
|
Untersuche die 16-Bit-Anweisungen des ursprünglichen PC-98-Spiels, rekonstruiere die festen und zielgerichteten Winkelberechnungen und vergleiche das rekonstruierte C++ mit der Ausgabe des damaligen Compilers.
|
||||||
|
|
||||||
[Fallstudie lesen](https://rea.tools/de/showcase/th04/) · [Rekonstruktionsrepository](https://github.com/N0zoM1z0/th04)
|
[Fallstudie lesen](https://rea.tools/showcase/th04/) · [Rekonstruktionsrepository](https://github.com/N0zoM1z0/th04)
|
||||||
|
|
||||||
Wenn du mit REA etwas Interessantes untersucht hast, würden wir es gern sehen. Teile deine Fallstudie in einem [Issue](https://github.com/morluto/rea/issues) oder [Pull Request](https://github.com/morluto/rea/pulls) und beschreibe das Ziel, deine Frage, wie REA geholfen hat und was du herausgefunden hast.
|
Wenn du mit REA etwas Interessantes untersucht hast, würden wir es gern sehen. Teile deine Fallstudie in einem [Issue](https://github.com/morluto/rea/issues) oder [Pull Request](https://github.com/morluto/rea/pulls) und beschreibe das Ziel, deine Frage, wie REA geholfen hat und was du herausgefunden hast.
|
||||||
|
|
||||||
@@ -245,7 +246,7 @@ Wenn du einen Agenten verwendest, schließe die [Aktualisierung der Einrichtung]
|
|||||||
|
|
||||||
## Dokumentation
|
## Dokumentation
|
||||||
|
|
||||||
Beginne mit den [praxisnahen Anleitungen](https://rea.tools/de/guides/) auf der Website. Genaue Optionen, Voraussetzungen und Ergebniskontrakte findest du hier:
|
Beginne mit den [praxisnahen Anleitungen](https://rea.tools/guides/) auf der Website. Genaue Optionen, Voraussetzungen und Ergebniskontrakte findest du hier:
|
||||||
|
|
||||||
- [Installation und Einrichtung](docs/installation.md): Agentenregistrierung, Provider-Konfiguration, Updates und Deinstallation.
|
- [Installation und Einrichtung](docs/installation.md): Agentenregistrierung, Provider-Konfiguration, Updates und Deinstallation.
|
||||||
- [Bereitschaft und Fehlerbehebung](docs/installation.md#check-readiness-for-your-task): Diagnose eines bestimmten Agenten oder einer Analyse-Engine.
|
- [Bereitschaft und Fehlerbehebung](docs/installation.md#check-readiness-for-your-task): Diagnose eines bestimmten Agenten oder einer Analyse-Engine.
|
||||||
@@ -258,7 +259,7 @@ Melde Sicherheitslücken gemäß [SECURITY.md](SECURITY.md).
|
|||||||
|
|
||||||
## Sternverlauf
|
## Sternverlauf
|
||||||
|
|
||||||
🎉 **90.000 GitHub-Sterne – vielen Dank!**
|
🎉 **50.000 GitHub-Sterne – vielen Dank!**
|
||||||
|
|
||||||
Danke an alle, die REA nutzen, Fehler melden, Funktionswünsche äußern, Builds testen und Fehlerbehebungen beitragen.
|
Danke an alle, die REA nutzen, Fehler melden, Funktionswünsche äußern, Builds testen und Fehlerbehebungen beitragen.
|
||||||
|
|
||||||
|
|||||||
+12
-11
@@ -9,6 +9,7 @@
|
|||||||
**¿Ves una función que te gusta? Entiende cómo funciona, hasta el nivel binario.**
|
**¿Ves una función que te gusta? Entiende cómo funciona, hasta el nivel binario.**
|
||||||
|
|
||||||
[](https://www.npmjs.com/package/rea-agents)
|
[](https://www.npmjs.com/package/rea-agents)
|
||||||
|
[](https://github.com/morluto/rea/actions/workflows/ci.yml)
|
||||||
[](docs/mcp-contracts.md#generated-catalog)
|
[](docs/mcp-contracts.md#generated-catalog)
|
||||||
[](#current-status)
|
[](#current-status)
|
||||||
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
||||||
@@ -17,7 +18,7 @@
|
|||||||
|
|
||||||
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
||||||
|
|
||||||
**[Sitio web](https://rea.tools/es/) · [Guías](https://rea.tools/es/guides/) · [Casos prácticos](https://rea.tools/es/showcase/)**
|
**[Sitio web](https://rea.tools/) · [Guías](https://rea.tools/guides/) · [Casos prácticos](https://rea.tools/showcase/)**
|
||||||
|
|
||||||
[Inicio rápido](#inicio-rápido) · [Cómo funciona REA](#cómo-funciona-rea) · [Qué puedes analizar](#qué-puedes-analizar) · [Casos prácticos](#casos-prácticos) · [Preguntas frecuentes](#preguntas-frecuentes) · [Documentación](#documentación)
|
[Inicio rápido](#inicio-rápido) · [Cómo funciona REA](#cómo-funciona-rea) · [Qué puedes analizar](#qué-puedes-analizar) · [Casos prácticos](#casos-prácticos) · [Preguntas frecuentes](#preguntas-frecuentes) · [Documentación](#documentación)
|
||||||
|
|
||||||
@@ -53,7 +54,7 @@ REA conecta tu agente con herramientas para inspeccionar binarios nativos, aplic
|
|||||||
|
|
||||||
La configuración registra REA en tu agente e instala las instrucciones de trabajo correspondientes. El análisis nativo puede usar una instalación existente de Hopper o Ghidra; la configuración también puede instalar Hopper, si lo autorizas. El análisis estático de JavaScript no necesita ninguno de los dos motores.
|
La configuración registra REA en tu agente e instala las instrucciones de trabajo correspondientes. El análisis nativo puede usar una instalación existente de Hopper o Ghidra; la configuración también puede instalar Hopper, si lo autorizas. El análisis estático de JavaScript no necesita ninguno de los dos motores.
|
||||||
|
|
||||||
> **[Visita el sitio web de REA](https://rea.tools/es/)** para encontrar instrucciones de configuración, guías ilustradas y casos reales.
|
> **[Visita el sitio web de REA](https://rea.tools/)** para encontrar instrucciones de configuración, guías ilustradas y casos reales.
|
||||||
|
|
||||||
## Inicio rápido
|
## Inicio rápido
|
||||||
|
|
||||||
@@ -132,12 +133,12 @@ REA requiere Node.js 22.x (>=22.19), 24.x (>=24.11) o 26+, además de npm. Las h
|
|||||||
|
|
||||||
| Objetivo | Qué devuelve REA | Requisitos y guía |
|
| Objetivo | Qué devuelve REA | Requisitos y guía |
|
||||||
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
|
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||||
| Binarios nativos | Pseudocódigo, ensamblador, cadenas, símbolos, llamadas y referencias | Hopper, Ghidra o IDA; [análisis nativo](https://rea.tools/es/guides/native/) |
|
| Binarios nativos | Pseudocódigo, ensamblador, cadenas, símbolos, llamadas y referencias | Hopper, Ghidra o IDA; [análisis nativo](https://rea.tools/guides/native/) |
|
||||||
| Estructura ELF sin ejecutar | Secciones, segmentos, símbolos/reubicaciones originales y posibles medidas de mitigación detectadas mediante análisis estático | pwntools proporcionado por quien llama, en Linux x64; [diagnóstico de binarios](docs/binary-diagnostics.md) |
|
| Estructura ELF sin ejecutar | Secciones, segmentos, símbolos/reubicaciones originales y posibles medidas de mitigación detectadas mediante análisis estático | pwntools proporcionado por quien llama, en Linux x64; [diagnóstico de binarios](docs/binary-diagnostics.md) |
|
||||||
| Bytecode EVM | Selectores de despacho, desplazamientos en bytes, argumentos inferidos y mutabilidad | Entrada local con bytes sin procesar o representación hexadecimal, en Linux x64; [guía de EVM sin ejecutar](docs/evm-bytecode.md) |
|
| Bytecode EVM | Selectores de despacho, desplazamientos en bytes, argumentos inferidos y mutabilidad | Entrada local con bytes sin procesar o representación hexadecimal, en Linux x64; [guía de EVM sin ejecutar](docs/evm-bytecode.md) |
|
||||||
| Fallos de Linux registrados | Registros note sin procesar, registros/señales de cada hilo registrado y posibles correspondencias de memoria opcionales | pwntools proporcionado por quien llama, en Linux x64; GDB/pwndbg opcionales; [fallos registrados](docs/recorded-crashes.md) |
|
| Fallos de Linux registrados | Registros note sin procesar, registros/señales de cada hilo registrado y posibles correspondencias de memoria opcionales | pwntools proporcionado por quien llama, en Linux x64; GDB/pwndbg opcionales; [fallos registrados](docs/recorded-crashes.md) |
|
||||||
| JavaScript / Electron | Módulos, importaciones, mapas de código fuente, rutas, IPC y relaciones con complementos nativos | Node.js y npm; [análisis de aplicaciones](https://rea.tools/es/guides/javascript/) |
|
| JavaScript / Electron | Módulos, importaciones, mapas de código fuente, rutas, IPC y relaciones con complementos nativos | Node.js y npm; [análisis de aplicaciones](https://rea.tools/guides/javascript/) |
|
||||||
| Sitios web | Estructura de la página, scripts, observaciones de red y capturas de pantalla solicitadas | Un navegador de la familia Chrome; [análisis del navegador](https://rea.tools/es/guides/browser/) |
|
| Sitios web | Estructura de la página, scripts, observaciones de red y capturas de pantalla solicitadas | Un navegador de la familia Chrome; [análisis del navegador](https://rea.tools/guides/browser/) |
|
||||||
| Capturas de red guardadas | Solicitudes, respuestas, contenido accesible de las cargas útiles y ubicaciones de origen | HAR; mitmdump en Linux para capturas en formato nativo de mitmproxy; [guía de capturas](docs/web-network-captures.md) |
|
| Capturas de red guardadas | Solicitudes, respuestas, contenido accesible de las cargas útiles y ubicaciones de origen | HAR; mitmdump en Linux para capturas en formato nativo de mitmproxy; [guía de capturas](docs/web-network-captures.md) |
|
||||||
| Ensamblados .NET | Metadatos, instrucciones CIL, dependencias nativas declaradas y comparaciones de compilaciones | Inspección estática; [guía de código administrado](docs/managed-code-analysis.md) |
|
| Ensamblados .NET | Metadatos, instrucciones CIL, dependencias nativas declaradas y comparaciones de compilaciones | Inspección estática; [guía de código administrado](docs/managed-code-analysis.md) |
|
||||||
| APK de Android | Declaraciones del manifiesto, clases, métodos descompilados y referencias | JADX sin interfaz gráfica y un JDK completo en Linux/macOS/Windows x64; [guía de Android](docs/android-analysis.md) |
|
| APK de Android | Declaraciones del manifiesto, clases, métodos descompilados y referencias | JADX sin interfaz gráfica y un JDK completo en Linux/macOS/Windows x64; [guía de Android](docs/android-analysis.md) |
|
||||||
@@ -156,25 +157,25 @@ Los formatos nativos y los sistemas anfitriones compatibles varían según el pr
|
|||||||
|
|
||||||
## Casos prácticos
|
## Casos prácticos
|
||||||
|
|
||||||
[](https://rea.tools/es/showcase/)
|
[](https://rea.tools/showcase/)
|
||||||
|
|
||||||
### DX-Ball: reconstruir un cálculo de panoramización de sonido
|
### DX-Ball: reconstruir un cálculo de panoramización de sonido
|
||||||
|
|
||||||
Sigue una llamada de sonido hasta la función auxiliar que convierte la posición en panoramización, inspecciona las instrucciones y transforma el pseudocódigo incompleto en C. La reconstrucción supera 3.205 casos con el x86 original y reproduce los 63 bytes de la función compilada.
|
Sigue una llamada de sonido hasta la función auxiliar que convierte la posición en panoramización, inspecciona las instrucciones y transforma el pseudocódigo incompleto en C. La reconstrucción supera 3.205 casos con el x86 original y reproduce los 63 bytes de la función compilada.
|
||||||
|
|
||||||
[Lee el caso práctico](https://rea.tools/es/showcase/dx-ball/) · [Repositorio de reconstrucción](https://github.com/N0zoM1z0/dx-ball)
|
[Lee el caso práctico](https://rea.tools/showcase/dx-ball/) · [Repositorio de reconstrucción](https://github.com/N0zoM1z0/dx-ball)
|
||||||
|
|
||||||
### Notion: seguir el puente del portapapeles de Electron
|
### Notion: seguir el puente del portapapeles de Electron
|
||||||
|
|
||||||
Encuentra la API del portapapeles del proceso de renderizado, síguela a través de preload e IPC hasta el proceso principal e inspecciona el formato enriquecido del portapapeles.
|
Encuentra la API del portapapeles del proceso de renderizado, síguela a través de preload e IPC hasta el proceso principal e inspecciona el formato enriquecido del portapapeles.
|
||||||
|
|
||||||
[Lee el caso práctico](https://rea.tools/es/showcase/notion/)
|
[Lee el caso práctico](https://rea.tools/showcase/notion/)
|
||||||
|
|
||||||
### TH04: recuperar el cálculo de un anillo de proyectiles en DOS
|
### TH04: recuperar el cálculo de un anillo de proyectiles en DOS
|
||||||
|
|
||||||
Inspecciona las instrucciones de 16 bits del juego original para PC-98, recupera los cálculos de ángulos fijos y dirigidos, y compara el C++ reconstruido con la salida del compilador de la época.
|
Inspecciona las instrucciones de 16 bits del juego original para PC-98, recupera los cálculos de ángulos fijos y dirigidos, y compara el C++ reconstruido con la salida del compilador de la época.
|
||||||
|
|
||||||
[Lee el caso práctico](https://rea.tools/es/showcase/th04/) · [Repositorio de reconstrucción](https://github.com/N0zoM1z0/th04)
|
[Lee el caso práctico](https://rea.tools/showcase/th04/) · [Repositorio de reconstrucción](https://github.com/N0zoM1z0/th04)
|
||||||
|
|
||||||
Si has usado REA para investigar algo interesante, nos gustaría verlo. Comparte tu caso en una [issue](https://github.com/morluto/rea/issues) o una [pull request](https://github.com/morluto/rea/pulls), incluyendo el objetivo, tu pregunta, cómo te ayudó REA y qué encontraste.
|
Si has usado REA para investigar algo interesante, nos gustaría verlo. Comparte tu caso en una [issue](https://github.com/morluto/rea/issues) o una [pull request](https://github.com/morluto/rea/pulls), incluyendo el objetivo, tu pregunta, cómo te ayudó REA y qué encontraste.
|
||||||
|
|
||||||
@@ -245,7 +246,7 @@ Si usas un agente, completa la [actualización de la configuración](#actualiza-
|
|||||||
|
|
||||||
## Documentación
|
## Documentación
|
||||||
|
|
||||||
Empieza con las [guías prácticas](https://rea.tools/es/guides/) del sitio web. Para opciones exactas, requisitos y contratos de resultados:
|
Empieza con las [guías prácticas](https://rea.tools/guides/) del sitio web. Para opciones exactas, requisitos y contratos de resultados:
|
||||||
|
|
||||||
- [Instalación y configuración](docs/installation.md): registro de agentes, configuración de proveedores, actualizaciones y desinstalación.
|
- [Instalación y configuración](docs/installation.md): registro de agentes, configuración de proveedores, actualizaciones y desinstalación.
|
||||||
- [Preparación y resolución de problemas](docs/installation.md#check-readiness-for-your-task): diagnóstico de un agente o motor de análisis concreto.
|
- [Preparación y resolución de problemas](docs/installation.md#check-readiness-for-your-task): diagnóstico de un agente o motor de análisis concreto.
|
||||||
@@ -258,7 +259,7 @@ Informa de vulnerabilidades siguiendo [SECURITY.md](SECURITY.md).
|
|||||||
|
|
||||||
## Historial de estrellas
|
## Historial de estrellas
|
||||||
|
|
||||||
🎉 **90.000 estrellas en GitHub: ¡gracias!**
|
🎉 **50.000 estrellas en GitHub: ¡gracias!**
|
||||||
|
|
||||||
Gracias a quienes usan REA, informan de errores, solicitan funciones, prueban compilaciones y contribuyen con correcciones.
|
Gracias a quienes usan REA, informan de errores, solicitan funciones, prueban compilaciones y contribuyen con correcciones.
|
||||||
|
|
||||||
|
|||||||
+12
-11
@@ -9,6 +9,7 @@
|
|||||||
**قابلیتی دیدهاید که دوستش دارید؟ سازوکارش را تا سطح باینری درک کنید.**
|
**قابلیتی دیدهاید که دوستش دارید؟ سازوکارش را تا سطح باینری درک کنید.**
|
||||||
|
|
||||||
[](https://www.npmjs.com/package/rea-agents)
|
[](https://www.npmjs.com/package/rea-agents)
|
||||||
|
[](https://github.com/morluto/rea/actions/workflows/ci.yml)
|
||||||
[](docs/mcp-contracts.md#generated-catalog)
|
[](docs/mcp-contracts.md#generated-catalog)
|
||||||
[](#current-status)
|
[](#current-status)
|
||||||
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
||||||
@@ -17,7 +18,7 @@
|
|||||||
|
|
||||||
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55" /></a>
|
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55" /></a>
|
||||||
|
|
||||||
**[وبسایت](https://rea.tools/fa/) · [راهنماها](https://rea.tools/fa/guides/) · [نمونههای عملی](https://rea.tools/fa/showcase/)**
|
**[وبسایت](https://rea.tools/) · [راهنماها](https://rea.tools/guides/) · [نمونههای عملی](https://rea.tools/showcase/)**
|
||||||
|
|
||||||
[شروع سریع](#شروع-سریع) · [REA چگونه کار میکند؟](#rea-چگونه-کار-میکند) · [چه چیزهایی را میتوان تحلیل کرد؟](#چه-چیزهایی-را-میتوان-تحلیل-کرد) · [نمونههای عملی](#نمونههای-عملی) · [پرسشهای متداول](#پرسشهای-متداول) · [مستندات](#مستندات)
|
[شروع سریع](#شروع-سریع) · [REA چگونه کار میکند؟](#rea-چگونه-کار-میکند) · [چه چیزهایی را میتوان تحلیل کرد؟](#چه-چیزهایی-را-میتوان-تحلیل-کرد) · [نمونههای عملی](#نمونههای-عملی) · [پرسشهای متداول](#پرسشهای-متداول) · [مستندات](#مستندات)
|
||||||
|
|
||||||
@@ -45,7 +46,7 @@ REA ایجنت شما را به ابزارهایی برای بررسی باین
|
|||||||
|
|
||||||
فرایند راهاندازی، REA را در ایجنت شما ثبت میکند و دستورالعملهای گردشکار متناظر را نصب میکند. تحلیل بومی میتواند از نصب موجود Hopper یا Ghidra استفاده کند؛ همچنین راهاندازی میتواند با تأیید شما Hopper را بهصورت اختیاری نصب کند. تحلیل ایستای JavaScript به هیچیک از این موتورهای تحلیل نیاز ندارد.
|
فرایند راهاندازی، REA را در ایجنت شما ثبت میکند و دستورالعملهای گردشکار متناظر را نصب میکند. تحلیل بومی میتواند از نصب موجود Hopper یا Ghidra استفاده کند؛ همچنین راهاندازی میتواند با تأیید شما Hopper را بهصورت اختیاری نصب کند. تحلیل ایستای JavaScript به هیچیک از این موتورهای تحلیل نیاز ندارد.
|
||||||
|
|
||||||
> برای دستورالعملهای راهاندازی، راهنماهای تصویری و مطالعات موردی واقعی، **[به وبسایت REA مراجعه کنید](https://rea.tools/fa/)**.
|
> برای دستورالعملهای راهاندازی، راهنماهای تصویری و مطالعات موردی واقعی، **[به وبسایت REA مراجعه کنید](https://rea.tools/)**.
|
||||||
|
|
||||||
## شروع سریع
|
## شروع سریع
|
||||||
|
|
||||||
@@ -124,12 +125,12 @@ REA به Node.js 22.x (>=22.19)، 24.x (>=24.11) یا 26+، بههمراه np
|
|||||||
|
|
||||||
| هدف | خروجی REA | پیشنیازها و راهنما |
|
| هدف | خروجی REA | پیشنیازها و راهنما |
|
||||||
| --------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
|
| --------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| باینریهای بومی | شبهکد، اسمبلی، رشتهها، نمادها، فراخوانیها و ارجاعات | Hopper، Ghidra یا IDA؛ [تحلیل بومی](https://rea.tools/fa/guides/native/) |
|
| باینریهای بومی | شبهکد، اسمبلی، رشتهها، نمادها، فراخوانیها و ارجاعات | Hopper، Ghidra یا IDA؛ [تحلیل بومی](https://rea.tools/guides/native/) |
|
||||||
| ساختار ELF آفلاین | بخشها، سگمنتها، نمادها و relocationهای اصلی و گزینههای احتمالی کاهش آسیبپذیری ایستا | pwntools تأمینشده توسط فراخواننده روی Linux x64؛ [تشخیص باینری](docs/binary-diagnostics.md) |
|
| ساختار ELF آفلاین | بخشها، سگمنتها، نمادها و relocationهای اصلی و گزینههای احتمالی کاهش آسیبپذیری ایستا | pwntools تأمینشده توسط فراخواننده روی Linux x64؛ [تشخیص باینری](docs/binary-diagnostics.md) |
|
||||||
| بایتکد EVM | selectorهای dispatch، offsetهای بایتی، آرگومانهای استنباطشده و قابلیت تغییر وضعیت | دادهٔ خام/hex محلی روی Linux x64؛ [راهنمای EVM آفلاین](docs/evm-bytecode.md) |
|
| بایتکد EVM | selectorهای dispatch، offsetهای بایتی، آرگومانهای استنباطشده و قابلیت تغییر وضعیت | دادهٔ خام/hex محلی روی Linux x64؛ [راهنمای EVM آفلاین](docs/evm-bytecode.md) |
|
||||||
| کرشهای ثبتشدهٔ لینوکس | یادداشتهای خام، رجیسترها/سیگنالهای تمام threadهای ثبتشده و گزینههای احتمالی نگاشت | pwntools تأمینشده توسط فراخواننده روی Linux x64؛ GDB/pwndbg اختیاری؛ [کرشهای ثبتشده](docs/recorded-crashes.md) |
|
| کرشهای ثبتشدهٔ لینوکس | یادداشتهای خام، رجیسترها/سیگنالهای تمام threadهای ثبتشده و گزینههای احتمالی نگاشت | pwntools تأمینشده توسط فراخواننده روی Linux x64؛ GDB/pwndbg اختیاری؛ [کرشهای ثبتشده](docs/recorded-crashes.md) |
|
||||||
| JavaScript / Electron | ماژولها، importها، source mapها، مسیرها، IPC و ارتباط افزونههای بومی | Node.js و npm؛ [تحلیل برنامه](https://rea.tools/fa/guides/javascript/) |
|
| JavaScript / Electron | ماژولها، importها، source mapها، مسیرها، IPC و ارتباط افزونههای بومی | Node.js و npm؛ [تحلیل برنامه](https://rea.tools/guides/javascript/) |
|
||||||
| وبسایتها | ساختار صفحه، اسکریپتها، مشاهدات شبکه و اسکرینشاتهای درخواستی | مرورگر مبتنی بر Chrome؛ [تحلیل مرورگر](https://rea.tools/fa/guides/browser/) |
|
| وبسایتها | ساختار صفحه، اسکریپتها، مشاهدات شبکه و اسکرینشاتهای درخواستی | مرورگر مبتنی بر Chrome؛ [تحلیل مرورگر](https://rea.tools/guides/browser/) |
|
||||||
| دادههای ضبطشدهٔ شبکه | درخواستها، پاسخها، payloadهای آشکارشده و مکان آنها در منبع | HAR؛ ابزار mitmdump در لینوکس برای ضبطهای بومی mitmproxy؛ [راهنمای ضبط شبکه](docs/web-network-captures.md) |
|
| دادههای ضبطشدهٔ شبکه | درخواستها، پاسخها، payloadهای آشکارشده و مکان آنها در منبع | HAR؛ ابزار mitmdump در لینوکس برای ضبطهای بومی mitmproxy؛ [راهنمای ضبط شبکه](docs/web-network-captures.md) |
|
||||||
| اسمبلیهای .NET | فراداده، دستورالعملهای CIL، وابستگیهای بومی اعلامشده و مقایسهٔ buildها | بررسی ایستا؛ [راهنمای کد مدیریتشده](docs/managed-code-analysis.md) |
|
| اسمبلیهای .NET | فراداده، دستورالعملهای CIL، وابستگیهای بومی اعلامشده و مقایسهٔ buildها | بررسی ایستا؛ [راهنمای کد مدیریتشده](docs/managed-code-analysis.md) |
|
||||||
| فایلهای APK اندروید | تعاریف Manifest، کلاسها، متدهای دیکامپایلشده و ارجاعات | JADX بدون رابط گرافیکی و JDK کامل در Linux/macOS/Windows x64؛ [راهنمای اندروید](docs/android-analysis.md) |
|
| فایلهای APK اندروید | تعاریف Manifest، کلاسها، متدهای دیکامپایلشده و ارجاعات | JADX بدون رابط گرافیکی و JDK کامل در Linux/macOS/Windows x64؛ [راهنمای اندروید](docs/android-analysis.md) |
|
||||||
@@ -148,25 +149,25 @@ REA به Node.js 22.x (>=22.19)، 24.x (>=24.11) یا 26+، بههمراه np
|
|||||||
|
|
||||||
## نمونههای عملی
|
## نمونههای عملی
|
||||||
|
|
||||||
[](https://rea.tools/fa/showcase/)
|
[](https://rea.tools/showcase/)
|
||||||
|
|
||||||
### DX-Ball: بازسازی محاسبهٔ موقعیت استریوی صدا
|
### DX-Ball: بازسازی محاسبهٔ موقعیت استریوی صدا
|
||||||
|
|
||||||
یک فراخوانی صوتی را تا تابع کمکی تبدیل موقعیت به pan دنبال کنید، دستورالعملها را بررسی کنید و شبهکد ناقص را به C تبدیل کنید. بازسازی حاصل، هر ۳٬۲۰۵ مورد آزمایش x86 اصلی را با موفقیت پشت سر میگذارد و هر ۶۳ بایت تابع کامپایلشده را دقیقاً بازتولید میکند.
|
یک فراخوانی صوتی را تا تابع کمکی تبدیل موقعیت به pan دنبال کنید، دستورالعملها را بررسی کنید و شبهکد ناقص را به C تبدیل کنید. بازسازی حاصل، هر ۳٬۲۰۵ مورد آزمایش x86 اصلی را با موفقیت پشت سر میگذارد و هر ۶۳ بایت تابع کامپایلشده را دقیقاً بازتولید میکند.
|
||||||
|
|
||||||
[مطالعهٔ موردی](https://rea.tools/fa/showcase/dx-ball/) · [مخزن بازسازی](https://github.com/N0zoM1z0/dx-ball)
|
[مطالعهٔ موردی](https://rea.tools/showcase/dx-ball/) · [مخزن بازسازی](https://github.com/N0zoM1z0/dx-ball)
|
||||||
|
|
||||||
### Notion: ردیابی پل کلیپبورد Electron
|
### Notion: ردیابی پل کلیپبورد Electron
|
||||||
|
|
||||||
API کلیپبورد در renderer را پیدا کنید، مسیر آن را از preload و IPC تا فرایند اصلی دنبال کنید و قالب غنی کلیپبورد را بررسی کنید.
|
API کلیپبورد در renderer را پیدا کنید، مسیر آن را از preload و IPC تا فرایند اصلی دنبال کنید و قالب غنی کلیپبورد را بررسی کنید.
|
||||||
|
|
||||||
[مطالعهٔ موردی](https://rea.tools/fa/showcase/notion/)
|
[مطالعهٔ موردی](https://rea.tools/showcase/notion/)
|
||||||
|
|
||||||
### TH04: بازیابی محاسبهٔ حلقهٔ گلوله در DOS
|
### TH04: بازیابی محاسبهٔ حلقهٔ گلوله در DOS
|
||||||
|
|
||||||
دستورالعملهای ۱۶بیتی بازی اصلی PC-98 را بررسی کنید، محاسبات زاویهٔ ثابت و هدفگیریشده را بازیابی کنید و کد C++ بازسازیشده را با خروجی کامپایلر تاریخی مقایسه کنید.
|
دستورالعملهای ۱۶بیتی بازی اصلی PC-98 را بررسی کنید، محاسبات زاویهٔ ثابت و هدفگیریشده را بازیابی کنید و کد C++ بازسازیشده را با خروجی کامپایلر تاریخی مقایسه کنید.
|
||||||
|
|
||||||
[مطالعهٔ موردی](https://rea.tools/fa/showcase/th04/) · [مخزن بازسازی](https://github.com/N0zoM1z0/th04)
|
[مطالعهٔ موردی](https://rea.tools/showcase/th04/) · [مخزن بازسازی](https://github.com/N0zoM1z0/th04)
|
||||||
|
|
||||||
اگر از REA برای بررسی موضوع جالبی استفاده کردهاید، خوشحال میشویم آن را به اشتراک بگذارید. یک [issue](https://github.com/morluto/rea/issues) یا [pull request](https://github.com/morluto/rea/pulls) ثبت کنید و هدف، پرسش خود، نقش REA و یافتههایتان را توضیح دهید.
|
اگر از REA برای بررسی موضوع جالبی استفاده کردهاید، خوشحال میشویم آن را به اشتراک بگذارید. یک [issue](https://github.com/morluto/rea/issues) یا [pull request](https://github.com/morluto/rea/pulls) ثبت کنید و هدف، پرسش خود، نقش REA و یافتههایتان را توضیح دهید.
|
||||||
|
|
||||||
@@ -230,7 +231,7 @@ npx rea-agents@latest setup
|
|||||||
|
|
||||||
## مستندات
|
## مستندات
|
||||||
|
|
||||||
از [راهنماهای عملی وبسایت](https://rea.tools/fa/guides/) شروع کنید. برای گزینههای دقیق، پیشنیازها و قراردادهای خروجی:
|
از [راهنماهای عملی وبسایت](https://rea.tools/guides/) شروع کنید. برای گزینههای دقیق، پیشنیازها و قراردادهای خروجی:
|
||||||
|
|
||||||
- [نصب و راهاندازی](docs/installation.md): ثبت ایجنت، پیکربندی ارائهدهنده، بهروزرسانی و حذف نصب.
|
- [نصب و راهاندازی](docs/installation.md): ثبت ایجنت، پیکربندی ارائهدهنده، بهروزرسانی و حذف نصب.
|
||||||
- [آمادگی و رفع اشکال](docs/installation.md#check-readiness-for-your-task): عیبیابی یک ایجنت یا موتور تحلیل.
|
- [آمادگی و رفع اشکال](docs/installation.md#check-readiness-for-your-task): عیبیابی یک ایجنت یا موتور تحلیل.
|
||||||
@@ -243,7 +244,7 @@ npx rea-agents@latest setup
|
|||||||
|
|
||||||
## تاریخچهٔ ستارهها
|
## تاریخچهٔ ستارهها
|
||||||
|
|
||||||
🎉 **۹۰٬۰۰۰ ستارهٔ GitHub — سپاسگزاریم!**
|
🎉 **۵۰٬۰۰۰ ستارهٔ GitHub — سپاسگزاریم!**
|
||||||
|
|
||||||
از همهٔ کسانی که از REA استفاده میکنند، خطاها را گزارش میدهند، قابلیتهای جدید پیشنهاد میکنند، buildها را آزمایش میکنند و در بهبود پروژه مشارکت دارند سپاسگزاریم.
|
از همهٔ کسانی که از REA استفاده میکنند، خطاها را گزارش میدهند، قابلیتهای جدید پیشنهاد میکنند، buildها را آزمایش میکنند و در بهبود پروژه مشارکت دارند سپاسگزاریم.
|
||||||
|
|
||||||
|
|||||||
+18
-20
@@ -9,6 +9,7 @@
|
|||||||
**Repérez une fonctionnalité qui vous plaît. Comprenez son fonctionnement, jusqu'au niveau du binaire.**
|
**Repérez une fonctionnalité qui vous plaît. Comprenez son fonctionnement, jusqu'au niveau du binaire.**
|
||||||
|
|
||||||
[](https://www.npmjs.com/package/rea-agents)
|
[](https://www.npmjs.com/package/rea-agents)
|
||||||
|
[](https://github.com/morluto/rea/actions/workflows/ci.yml)
|
||||||
[](docs/mcp-contracts.md#generated-catalog)
|
[](docs/mcp-contracts.md#generated-catalog)
|
||||||
[](#current-status)
|
[](#current-status)
|
||||||
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
||||||
@@ -17,7 +18,7 @@
|
|||||||
|
|
||||||
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
||||||
|
|
||||||
**[Site web](https://rea.tools/fr/) · [Guides](https://rea.tools/fr/guides/) · [Études de cas](https://rea.tools/fr/showcase/)**
|
**[Site web](https://rea.tools/) · [Guides](https://rea.tools/guides/) · [Études de cas](https://rea.tools/showcase/)**
|
||||||
|
|
||||||
[Démarrage rapide](#démarrage-rapide) · [Comment fonctionne REA](#comment-fonctionne-rea) · [Ce que vous pouvez analyser](#ce-que-vous-pouvez-analyser) · [Études de cas](#études-de-cas) · [Questions fréquentes](#questions-fréquentes) · [Documentation](#documentation)
|
[Démarrage rapide](#démarrage-rapide) · [Comment fonctionne REA](#comment-fonctionne-rea) · [Ce que vous pouvez analyser](#ce-que-vous-pouvez-analyser) · [Études de cas](#études-de-cas) · [Questions fréquentes](#questions-fréquentes) · [Documentation](#documentation)
|
||||||
|
|
||||||
@@ -51,9 +52,9 @@ Vous avez repéré dans une application une fonctionnalité que vous aimeriez av
|
|||||||
|
|
||||||
REA connecte votre agent à des outils d'inspection de binaires natifs, d'applications JavaScript et Electron, d'assemblys .NET et de sites web. Les mêmes outils sont aussi disponibles depuis votre terminal. L'analyse s'exécute localement, et chaque conclusion s'accompagne des preuves et des limites sur lesquelles elle repose.
|
REA connecte votre agent à des outils d'inspection de binaires natifs, d'applications JavaScript et Electron, d'assemblys .NET et de sites web. Les mêmes outils sont aussi disponibles depuis votre terminal. L'analyse s'exécute localement, et chaque conclusion s'accompagne des preuves et des limites sur lesquelles elle repose.
|
||||||
|
|
||||||
Setup enregistre REA auprès de votre agent et installe les instructions de workflow correspondantes. L'analyse native peut utiliser une installation existante de Hopper, de Ghidra ou d'IDA ; Setup peut aussi installer Hopper après votre accord. L'analyse statique JavaScript ne nécessite aucun moteur d'analyse natif.
|
Setup enregistre REA auprès de votre agent et installe les instructions de workflow correspondantes. L'analyse native peut utiliser une installation existante de Hopper ou de Ghidra ; Setup peut aussi installer Hopper après votre accord. L'analyse statique JavaScript ne nécessite aucun de ces moteurs.
|
||||||
|
|
||||||
> **[Visitez le site web de REA](https://rea.tools/fr/)** pour les instructions d'installation, des guides illustrés et des études de cas réelles.
|
> **[Visitez le site web de REA](https://rea.tools/)** pour les instructions d'installation, des guides illustrés et des études de cas réelles.
|
||||||
|
|
||||||
## Démarrage rapide
|
## Démarrage rapide
|
||||||
|
|
||||||
@@ -101,14 +102,12 @@ Pour l'analyse native, configurez d'abord un fournisseur. Consultez le [guide CL
|
|||||||
|
|
||||||
REA évolue rapidement, et les nouvelles versions apportent fréquemment des corrections de bugs. Maintenez votre installation à jour.
|
REA évolue rapidement, et les nouvelles versions apportent fréquemment des corrections de bugs. Maintenez votre installation à jour.
|
||||||
|
|
||||||
Pour une CLI installée avec `npm install --global` ou `bun add --global` :
|
Pour une CLI installée avec npm :
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
rea update
|
rea update
|
||||||
```
|
```
|
||||||
|
|
||||||
Les mises à jour globales avec Bun nécessitent Bun 1.2.17 ou une version ultérieure. Avec une version plus ancienne de Bun, mettez à jour Bun manuellement avant d'exécuter `rea update`.
|
|
||||||
|
|
||||||
Pour actualiser les enregistrements de vos agents et le skill, exécutez la commande setup affichée par la mise à jour.
|
Pour actualiser les enregistrements de vos agents et le skill, exécutez la commande setup affichée par la mise à jour.
|
||||||
|
|
||||||
Si vous utilisez `npx`, mettez à jour la configuration de votre agent avec :
|
Si vous utilisez `npx`, mettez à jour la configuration de votre agent avec :
|
||||||
@@ -117,7 +116,7 @@ Si vous utilisez `npx`, mettez à jour la configuration de votre agent avec :
|
|||||||
npx rea-agents@latest setup
|
npx rea-agents@latest setup
|
||||||
```
|
```
|
||||||
|
|
||||||
Vérifiez les modifications proposées par Setup et redémarrez votre agent. Pour des commandes CLI ponctuelles, utilisez `npx rea-agents@latest` suivi de la commande. Avec Bun, utilisez `bunx rea-agents@latest` à la place de `npx rea-agents@latest`.
|
Vérifiez les modifications proposées par Setup et redémarrez votre agent. Pour des commandes CLI ponctuelles, utilisez `npx rea-agents@latest` suivi de la commande.
|
||||||
|
|
||||||
## Comment fonctionne REA
|
## Comment fonctionne REA
|
||||||
|
|
||||||
@@ -135,13 +134,12 @@ REA nécessite Node.js 22.x (>=22.19), 24.x (>=24.11) ou 26+, ainsi que npm. Les
|
|||||||
|
|
||||||
| Cible | Ce que REA renvoie | Prérequis et guide |
|
| Cible | Ce que REA renvoie | Prérequis et guide |
|
||||||
| ---------------------------- | ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
|
| ---------------------------- | ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| Binaires natifs | Pseudo-code, assembleur, chaînes, symboles, appels et références | Hopper, Ghidra ou IDA ; [analyse native](https://rea.tools/fr/guides/native/) |
|
| Binaires natifs | Pseudo-code, assembleur, chaînes, symboles, appels et références | Hopper, Ghidra ou IDA ; [analyse native](https://rea.tools/guides/native/) |
|
||||||
| Structure ELF hors ligne | Sections, segments, symboles et relocations d'origine, et protections statiques candidates | pwntools fourni par l'utilisateur sous Linux x64 ; [diagnostics binaires](docs/binary-diagnostics.md) |
|
| Structure ELF hors ligne | Sections, segments, symboles et relocations d'origine, et protections statiques candidates | pwntools fourni par l'utilisateur sous Linux x64 ; [diagnostics binaires](docs/binary-diagnostics.md) |
|
||||||
| Artefact WASM | Validation, sections, formes WAT exactes d'import/export et WAT décodé | WABT 1.0.42 fourni par l'utilisateur ; `inspect_wasm_artifact` |
|
|
||||||
| Bytecode EVM | Sélecteurs de dispatch, offsets en octets, arguments inférés et mutabilité | Fichier local brut ou hexadécimal sous Linux x64 ; [guide EVM hors ligne](docs/evm-bytecode.md) |
|
| Bytecode EVM | Sélecteurs de dispatch, offsets en octets, arguments inférés et mutabilité | Fichier local brut ou hexadécimal sous Linux x64 ; [guide EVM hors ligne](docs/evm-bytecode.md) |
|
||||||
| Crashs Linux enregistrés | Notes brutes, registres et signaux de chaque thread enregistré, et correspondances de mappings facultatives | pwntools fourni par l'utilisateur sous Linux x64 ; GDB/pwndbg en option ; [crashs enregistrés](docs/recorded-crashes.md) |
|
| Crashs Linux enregistrés | Notes brutes, registres et signaux de chaque thread enregistré, et correspondances de mappings facultatives | pwntools fourni par l'utilisateur sous Linux x64 ; GDB/pwndbg en option ; [crashs enregistrés](docs/recorded-crashes.md) |
|
||||||
| JavaScript / Electron | Modules, imports, source maps, routes, IPC et relations avec les modules natifs | Node.js et npm ; [analyse d'applications](https://rea.tools/fr/guides/javascript/) |
|
| JavaScript / Electron | Modules, imports, source maps, routes, IPC et relations avec les modules natifs | Node.js et npm ; [analyse d'applications](https://rea.tools/guides/javascript/) |
|
||||||
| Sites web | Structure des pages, scripts, observations réseau et captures d'écran demandées | Un navigateur de la famille Chrome ; [analyse du navigateur](https://rea.tools/fr/guides/browser/) |
|
| Sites web | Structure des pages, scripts, observations réseau et captures d'écran demandées | Un navigateur de la famille Chrome ; [analyse du navigateur](https://rea.tools/guides/browser/) |
|
||||||
| Captures réseau enregistrées | Requêtes, réponses, payloads exposés et emplacements dans le code source | HAR ; mitmdump sous Linux pour les captures mitmproxy natives ; [guide des captures](docs/web-network-captures.md) |
|
| Captures réseau enregistrées | Requêtes, réponses, payloads exposés et emplacements dans le code source | HAR ; mitmdump sous Linux pour les captures mitmproxy natives ; [guide des captures](docs/web-network-captures.md) |
|
||||||
| Assemblys .NET | Métadonnées, instructions CIL, dépendances natives déclarées et comparaisons de builds | Inspection statique ; [guide du code managé](docs/managed-code-analysis.md) |
|
| Assemblys .NET | Métadonnées, instructions CIL, dépendances natives déclarées et comparaisons de builds | Inspection statique ; [guide du code managé](docs/managed-code-analysis.md) |
|
||||||
| APK Android | Déclarations du manifeste, classes, méthodes décompilées et références | JADX headless et un JDK complet sous Linux/macOS/Windows x64 ; [guide Android](docs/android-analysis.md) |
|
| APK Android | Déclarations du manifeste, classes, méthodes décompilées et références | JADX headless et un JDK complet sous Linux/macOS/Windows x64 ; [guide Android](docs/android-analysis.md) |
|
||||||
@@ -160,25 +158,25 @@ Les formats natifs et les hôtes pris en charge varient selon le fournisseur. Co
|
|||||||
|
|
||||||
## Études de cas
|
## Études de cas
|
||||||
|
|
||||||
[](https://rea.tools/fr/showcase/)
|
[](https://rea.tools/showcase/)
|
||||||
|
|
||||||
### DX-Ball : reconstruire un calcul de panoramique sonore
|
### DX-Ball : reconstruire un calcul de panoramique sonore
|
||||||
|
|
||||||
Suivez un appel sonore jusqu'à la fonction qui convertit une position en panoramique, inspectez ses instructions et transformez un pseudo-code incomplet en C. La reconstruction réussit 3 205 cas issus du x86 d'origine et reproduit à l'identique les 63 octets de la fonction compilée.
|
Suivez un appel sonore jusqu'à la fonction qui convertit une position en panoramique, inspectez ses instructions et transformez un pseudo-code incomplet en C. La reconstruction réussit 3 205 cas issus du x86 d'origine et reproduit à l'identique les 63 octets de la fonction compilée.
|
||||||
|
|
||||||
[Lire l'étude de cas](https://rea.tools/fr/showcase/dx-ball/) · [Dépôt de la reconstruction](https://github.com/N0zoM1z0/dx-ball)
|
[Lire l'étude de cas](https://rea.tools/showcase/dx-ball/) · [Dépôt de la reconstruction](https://github.com/N0zoM1z0/dx-ball)
|
||||||
|
|
||||||
### Notion : suivre le pont du presse-papiers d'Electron
|
### Notion : suivre le pont du presse-papiers d'Electron
|
||||||
|
|
||||||
Trouvez l'API de presse-papiers du renderer, suivez-la à travers le preload et l'IPC jusqu'au processus principal, puis inspectez le format de presse-papiers enrichi.
|
Trouvez l'API de presse-papiers du renderer, suivez-la à travers le preload et l'IPC jusqu'au processus principal, puis inspectez le format de presse-papiers enrichi.
|
||||||
|
|
||||||
[Lire l'étude de cas](https://rea.tools/fr/showcase/notion/)
|
[Lire l'étude de cas](https://rea.tools/showcase/notion/)
|
||||||
|
|
||||||
### TH04 : retrouver un calcul d'anneau de projectiles sous DOS
|
### TH04 : retrouver un calcul d'anneau de projectiles sous DOS
|
||||||
|
|
||||||
Inspectez les instructions 16 bits du jeu PC-98 d'origine, retrouvez les calculs d'angles fixes et visés, et comparez le C++ reconstruit avec la sortie du compilateur d'époque.
|
Inspectez les instructions 16 bits du jeu PC-98 d'origine, retrouvez les calculs d'angles fixes et visés, et comparez le C++ reconstruit avec la sortie du compilateur d'époque.
|
||||||
|
|
||||||
[Lire l'étude de cas](https://rea.tools/fr/showcase/th04/) · [Dépôt de la reconstruction](https://github.com/N0zoM1z0/th04)
|
[Lire l'étude de cas](https://rea.tools/showcase/th04/) · [Dépôt de la reconstruction](https://github.com/N0zoM1z0/th04)
|
||||||
|
|
||||||
Si vous avez utilisé REA sur un projet intéressant, nous serions ravis de le découvrir. Partagez votre cas dans une [issue](https://github.com/morluto/rea/issues) ou une [pull request](https://github.com/morluto/rea/pulls), en précisant la cible, votre question, la manière dont REA vous a aidé et ce que vous avez découvert.
|
Si vous avez utilisé REA sur un projet intéressant, nous serions ravis de le découvrir. Partagez votre cas dans une [issue](https://github.com/morluto/rea/issues) ou une [pull request](https://github.com/morluto/rea/pulls), en précisant la cible, votre question, la manière dont REA vous a aidé et ce que vous avez découvert.
|
||||||
|
|
||||||
@@ -231,7 +229,7 @@ REA analyse les cibles localement. Votre agent reçoit les résultats des outils
|
|||||||
|
|
||||||
Commencez par mettre à jour ; une version récente l'a peut-être déjà corrigé.
|
Commencez par mettre à jour ; une version récente l'a peut-être déjà corrigé.
|
||||||
|
|
||||||
Pour une CLI installée avec `npm install --global` ou `bun add --global` :
|
Pour une CLI installée avec npm :
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
rea update
|
rea update
|
||||||
@@ -249,10 +247,10 @@ Si vous utilisez un agent, terminez l'[actualisation de la configuration](#mettr
|
|||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
Commencez par les [guides pas à pas](https://rea.tools/fr/guides/) du site web. Pour les options exactes, les prérequis et les contrats de résultats :
|
Commencez par les [guides pas à pas](https://rea.tools/guides/) du site web. Pour les options exactes, les prérequis et les contrats de résultats :
|
||||||
|
|
||||||
- [Installation et configuration](docs/installation.md) : enregistrement des agents, configuration des fournisseurs, mises à jour et désinstallation.
|
- [Installation et configuration](docs/installation.md) : enregistrement des agents, configuration des fournisseurs, mises à jour et désinstallation.
|
||||||
- [Vérification et dépannage](docs/installation.md#check-readiness-for-your-task) : diagnostiquer un agent ou un moteur d'analyse donné.
|
- [Vérification et dépannage](docs/installation.md#check-readiness-for-your-task) : diagnostiquer un agent ou un moteur d'analyse précis.
|
||||||
- [CLI et Evidence](docs/cli.md) : commandes, choix du fournisseur, snapshots, import/export et codes de sortie.
|
- [CLI et Evidence](docs/cli.md) : commandes, choix du fournisseur, snapshots, import/export et codes de sortie.
|
||||||
- [Contrats MCP](docs/mcp-contracts.md) et [prompts pour agents](docs/mcp-prompts.md) : résultats des outils, sessions et investigations guidées.
|
- [Contrats MCP](docs/mcp-contracts.md) et [prompts pour agents](docs/mcp-prompts.md) : résultats des outils, sessions et investigations guidées.
|
||||||
- [Catalogue des outils](docs/mcp-contracts.md#generated-catalog) : inventaire des outils, fournisseurs et commandes CLI, généré lors du build.
|
- [Catalogue des outils](docs/mcp-contracts.md#generated-catalog) : inventaire des outils, fournisseurs et commandes CLI, généré lors du build.
|
||||||
@@ -262,7 +260,7 @@ Signalez les vulnérabilités via [SECURITY.md](SECURITY.md).
|
|||||||
|
|
||||||
## Historique des étoiles
|
## Historique des étoiles
|
||||||
|
|
||||||
🎉 **90 000 étoiles GitHub — merci !**
|
🎉 **50 000 étoiles GitHub — merci !**
|
||||||
|
|
||||||
Merci à toutes les personnes qui utilisent REA, signalent des bugs, proposent des fonctionnalités, testent les builds et contribuent des correctifs.
|
Merci à toutes les personnes qui utilisent REA, signalent des bugs, proposent des fonctionnalités, testent les builds et contribuent des correctifs.
|
||||||
|
|
||||||
@@ -282,7 +280,7 @@ REA fournit des outils destinés à la recherche, à l'analyse et à la reconstr
|
|||||||
|
|
||||||
Votre aide sur REA est la bienvenue ! [Ouvrez une issue](https://github.com/morluto/rea/issues) pour signaler un bug ou proposer une fonctionnalité, ou [envoyez une pull request](https://github.com/morluto/rea/pulls) pour améliorer le code ou la documentation.
|
Votre aide sur REA est la bienvenue ! [Ouvrez une issue](https://github.com/morluto/rea/issues) pour signaler un bug ou proposer une fonctionnalité, ou [envoyez une pull request](https://github.com/morluto/rea/pulls) pour améliorer le code ou la documentation.
|
||||||
|
|
||||||
Consultez [CONTRIBUTING.md](CONTRIBUTING.md) pour l'environnement de développement et les vérifications, la page [tests](docs/testing.md) pour les procédures de vérification, et la [carte de l'architecture](docs/architecture.mermaid) pour la structure du projet.
|
Consultez [CONTRIBUTING.md](CONTRIBUTING.md) pour l'environnement de développement et les vérifications, la page [tests](docs/testing.md) pour les filières de vérification, et la [carte de l'architecture](docs/architecture.mermaid) pour la structure du projet.
|
||||||
|
|
||||||
## Licence
|
## Licence
|
||||||
|
|
||||||
|
|||||||
+15
-17
@@ -9,6 +9,7 @@
|
|||||||
**Melihat fitur yang Anda sukai. Pahami cara kerjanya hingga ke tingkat biner.**
|
**Melihat fitur yang Anda sukai. Pahami cara kerjanya hingga ke tingkat biner.**
|
||||||
|
|
||||||
[](https://www.npmjs.com/package/rea-agents)
|
[](https://www.npmjs.com/package/rea-agents)
|
||||||
|
[](https://github.com/morluto/rea/actions/workflows/ci.yml)
|
||||||
[](docs/mcp-contracts.md#generated-catalog)
|
[](docs/mcp-contracts.md#generated-catalog)
|
||||||
[](#current-status)
|
[](#current-status)
|
||||||
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
||||||
@@ -17,7 +18,7 @@
|
|||||||
|
|
||||||
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
||||||
|
|
||||||
**[Situs Web](https://rea.tools/id/) · [Panduan](https://rea.tools/id/guides/) · [Contoh Penggunaan](https://rea.tools/id/showcase/)**
|
**[Situs Web](https://rea.tools/) · [Panduan](https://rea.tools/guides/) · [Contoh Penggunaan](https://rea.tools/showcase/)**
|
||||||
|
|
||||||
[Mulai Cepat](#mulai-cepat) · [Cara Kerja REA](#cara-kerja-rea) · [Hal yang Dapat Anda Analisis](#hal-yang-dapat-anda-analisis) · [Contoh Penggunaan](#contoh-penggunaan) · [FAQ](#faq) · [Dokumentasi](#dokumentasi)
|
[Mulai Cepat](#mulai-cepat) · [Cara Kerja REA](#cara-kerja-rea) · [Hal yang Dapat Anda Analisis](#hal-yang-dapat-anda-analisis) · [Contoh Penggunaan](#contoh-penggunaan) · [FAQ](#faq) · [Dokumentasi](#dokumentasi)
|
||||||
|
|
||||||
@@ -53,7 +54,7 @@ REA menghubungkan agen Anda dengan berbagai alat untuk memeriksa biner native, a
|
|||||||
|
|
||||||
Proses penyiapan mendaftarkan REA ke agen Anda dan memasang instruksi alur kerja yang sesuai. Analisis native dapat menggunakan instalasi Hopper, Ghidra, atau IDA yang sudah ada. Proses penyiapan juga dapat memasang Hopper secara opsional setelah mendapatkan persetujuan. Analisis JavaScript statis tidak memerlukan mesin analisis native.
|
Proses penyiapan mendaftarkan REA ke agen Anda dan memasang instruksi alur kerja yang sesuai. Analisis native dapat menggunakan instalasi Hopper, Ghidra, atau IDA yang sudah ada. Proses penyiapan juga dapat memasang Hopper secara opsional setelah mendapatkan persetujuan. Analisis JavaScript statis tidak memerlukan mesin analisis native.
|
||||||
|
|
||||||
> **[Kunjungi situs web REA](https://rea.tools/id/)** untuk mendapatkan petunjuk penyiapan, panduan bergambar, dan studi kasus nyata.
|
> **[Kunjungi situs web REA](https://rea.tools/)** untuk mendapatkan petunjuk penyiapan, panduan bergambar, dan studi kasus nyata.
|
||||||
|
|
||||||
## Mulai Cepat
|
## Mulai Cepat
|
||||||
|
|
||||||
@@ -100,14 +101,12 @@ Untuk analisis native, konfigurasikan penyedia terlebih dahulu. Lihat [Panduan C
|
|||||||
|
|
||||||
REA berkembang dengan cepat, dan rilis baru sering menyertakan perbaikan bug. Pastikan instalasi Anda selalu diperbarui.
|
REA berkembang dengan cepat, dan rilis baru sering menyertakan perbaikan bug. Pastikan instalasi Anda selalu diperbarui.
|
||||||
|
|
||||||
Untuk CLI yang dipasang melalui `npm install --global` atau `bun add --global`:
|
Untuk CLI yang dipasang melalui npm:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
rea update
|
rea update
|
||||||
```
|
```
|
||||||
|
|
||||||
Pembaruan global dengan Bun memerlukan Bun 1.2.17 atau yang lebih baru. Pada rilis Bun yang lebih lama, perbarui Bun secara manual sebelum menjalankan `rea update`.
|
|
||||||
|
|
||||||
Untuk memperbarui pendaftaran agen dan skill Anda, jalankan perintah penyiapan yang ditampilkan oleh proses pembaruan.
|
Untuk memperbarui pendaftaran agen dan skill Anda, jalankan perintah penyiapan yang ditampilkan oleh proses pembaruan.
|
||||||
|
|
||||||
Jika Anda menggunakan `npx`, perbarui penyiapan agen dengan:
|
Jika Anda menggunakan `npx`, perbarui penyiapan agen dengan:
|
||||||
@@ -116,7 +115,7 @@ Jika Anda menggunakan `npx`, perbarui penyiapan agen dengan:
|
|||||||
npx rea-agents@latest setup
|
npx rea-agents@latest setup
|
||||||
```
|
```
|
||||||
|
|
||||||
Tinjau perubahan penyiapan dan mulai ulang agen Anda. Untuk menjalankan perintah CLI sekali pakai, gunakan `npx rea-agents@latest` diikuti dengan perintah yang diinginkan. Dengan Bun, gunakan `bunx rea-agents@latest` sebagai pengganti `npx rea-agents@latest`.
|
Tinjau perubahan penyiapan dan mulai ulang agen Anda. Untuk menjalankan perintah CLI sekali pakai, gunakan `npx rea-agents@latest` diikuti dengan perintah yang diinginkan.
|
||||||
|
|
||||||
## Cara Kerja REA
|
## Cara Kerja REA
|
||||||
|
|
||||||
@@ -138,13 +137,12 @@ Alat tambahan dan dukungan sistem host bergantung pada target yang dianalisis:
|
|||||||
|
|
||||||
| Target | Hasil yang diberikan REA | Persyaratan dan panduan |
|
| Target | Hasil yang diberikan REA | Persyaratan dan panduan |
|
||||||
| -------------------------- | ----------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
|
| -------------------------- | ----------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| Biner native | Pseudocode, assembly, string, simbol, pemanggilan, dan referensi | Hopper, Ghidra, atau IDA; [analisis native](https://rea.tools/id/guides/native/) |
|
| Biner native | Pseudocode, assembly, string, simbol, pemanggilan, dan referensi | Hopper, Ghidra, atau IDA; [analisis native](https://rea.tools/guides/native/) |
|
||||||
| Tata letak ELF offline | Bagian, segmen, simbol/relokasi asli, dan kandidat mitigasi statis | pwntools yang disediakan pemanggil pada Linux x64; [diagnostik biner](docs/binary-diagnostics.md) |
|
| Tata letak ELF offline | Bagian, segmen, simbol/relokasi asli, dan kandidat mitigasi statis | pwntools yang disediakan pemanggil pada Linux x64; [diagnostik biner](docs/binary-diagnostics.md) |
|
||||||
| Artefak WASM | Validasi, bagian, bentuk WAT import/ekspor yang tepat, dan WAT yang didekode | WABT 1.0.42 yang disediakan pemanggil; `inspect_wasm_artifact` |
|
|
||||||
| Bytecode EVM | Selector dispatch, offset byte, argumen yang disimpulkan, dan sifat mutabilitas | Pembawa data raw/hex lokal; [panduan EVM offline](docs/evm-bytecode.md) |
|
| Bytecode EVM | Selector dispatch, offset byte, argumen yang disimpulkan, dan sifat mutabilitas | Pembawa data raw/hex lokal; [panduan EVM offline](docs/evm-bytecode.md) |
|
||||||
| Crash Linux yang direkam | Catatan mentah, register/sinyal setiap thread yang direkam, dan kandidat pemetaan opsional | pwntools yang disediakan pemanggil; GDB/pwndbg opsional; [crash yang direkam](docs/recorded-crashes.md) |
|
| Crash Linux yang direkam | Catatan mentah, register/sinyal setiap thread yang direkam, dan kandidat pemetaan opsional | pwntools yang disediakan pemanggil; GDB/pwndbg opsional; [crash yang direkam](docs/recorded-crashes.md) |
|
||||||
| JavaScript / Electron | Modul, impor, source map, rute, IPC, dan hubungan add-on native | Node.js dan npm; [analisis aplikasi](https://rea.tools/id/guides/javascript/) |
|
| JavaScript / Electron | Modul, impor, source map, rute, IPC, dan hubungan add-on native | Node.js dan npm; [analisis aplikasi](https://rea.tools/guides/javascript/) |
|
||||||
| Situs web | Struktur halaman, skrip, pengamatan jaringan, dan tangkapan layar yang diminta | Peramban berbasis Chrome; [analisis peramban](https://rea.tools/id/guides/browser/) |
|
| Situs web | Struktur halaman, skrip, pengamatan jaringan, dan tangkapan layar yang diminta | Peramban berbasis Chrome; [analisis peramban](https://rea.tools/guides/browser/) |
|
||||||
| Rekaman jaringan tersimpan | Permintaan, respons, payload yang terekspos, dan lokasi sumber | HAR; mitmdump di Linux untuk rekaman native mitmproxy; [panduan rekaman](docs/web-network-captures.md) |
|
| Rekaman jaringan tersimpan | Permintaan, respons, payload yang terekspos, dan lokasi sumber | HAR; mitmdump di Linux untuk rekaman native mitmproxy; [panduan rekaman](docs/web-network-captures.md) |
|
||||||
| Assembly .NET | Metadata, instruksi CIL, dependensi native yang dideklarasikan, dan perbandingan build | Tidak ada (hanya analisis statis); [panduan kode terkelola](docs/managed-code-analysis.md) |
|
| Assembly .NET | Metadata, instruksi CIL, dependensi native yang dideklarasikan, dan perbandingan build | Tidak ada (hanya analisis statis); [panduan kode terkelola](docs/managed-code-analysis.md) |
|
||||||
| APK Android | Deklarasi manifest, kelas, metode hasil dekompilasi, dan referensi | JADX mode headless dan JDK lengkap di Linux/macOS/Windows x64; [panduan Android](docs/android-analysis.md) |
|
| APK Android | Deklarasi manifest, kelas, metode hasil dekompilasi, dan referensi | JADX mode headless dan JDK lengkap di Linux/macOS/Windows x64; [panduan Android](docs/android-analysis.md) |
|
||||||
@@ -171,25 +169,25 @@ Periksa [ketersediaan rilis](docs/installation.md#released-package-and-main) unt
|
|||||||
|
|
||||||
## Contoh Penggunaan
|
## Contoh Penggunaan
|
||||||
|
|
||||||
[](https://rea.tools/id/showcase/)
|
[](https://rea.tools/showcase/)
|
||||||
|
|
||||||
### DX-Ball: merekonstruksi perhitungan sound-pan
|
### DX-Ball: merekonstruksi perhitungan sound-pan
|
||||||
|
|
||||||
Ikuti pemanggilan suara hingga ke fungsi pembantu yang mengubah posisi menjadi nilai pan, periksa instruksinya, lalu ubah pseudocode yang belum lengkap menjadi C. Hasil rekonstruksi tersebut lolos pada 3.205 kasus x86 asli dan mereproduksi seluruh 63 byte fungsi hasil kompilasi.
|
Ikuti pemanggilan suara hingga ke fungsi pembantu yang mengubah posisi menjadi nilai pan, periksa instruksinya, lalu ubah pseudocode yang belum lengkap menjadi C. Hasil rekonstruksi tersebut lolos pada 3.205 kasus x86 asli dan mereproduksi seluruh 63 byte fungsi hasil kompilasi.
|
||||||
|
|
||||||
[Baca studi kasus](https://rea.tools/id/showcase/dx-ball/) · [Repositori rekonstruksi](https://github.com/N0zoM1z0/dx-ball)
|
[Baca studi kasus](https://rea.tools/showcase/dx-ball/) · [Repositori rekonstruksi](https://github.com/N0zoM1z0/dx-ball)
|
||||||
|
|
||||||
### Notion: menelusuri jembatan clipboard Electron
|
### Notion: menelusuri jembatan clipboard Electron
|
||||||
|
|
||||||
Temukan API clipboard pada renderer, telusuri jalurnya melalui preload dan IPC hingga ke proses utama, lalu periksa format clipboard kaya.
|
Temukan API clipboard pada renderer, telusuri jalurnya melalui preload dan IPC hingga ke proses utama, lalu periksa format clipboard kaya.
|
||||||
|
|
||||||
[Baca studi kasus](https://rea.tools/id/showcase/notion/)
|
[Baca studi kasus](https://rea.tools/showcase/notion/)
|
||||||
|
|
||||||
### TH04: memulihkan perhitungan bullet-ring DOS
|
### TH04: memulihkan perhitungan bullet-ring DOS
|
||||||
|
|
||||||
Periksa instruksi 16-bit dari gim PC-98 asli, pulihkan perhitungan sudut tetap dan sudut yang diarahkan, lalu bandingkan C++ hasil rekonstruksi dengan keluaran historis kompiler.
|
Periksa instruksi 16-bit dari gim PC-98 asli, pulihkan perhitungan sudut tetap dan sudut yang diarahkan, lalu bandingkan C++ hasil rekonstruksi dengan keluaran historis kompiler.
|
||||||
|
|
||||||
[Baca studi kasus](https://rea.tools/id/showcase/th04/) · [Repositori rekonstruksi](https://github.com/N0zoM1z0/th04)
|
[Baca studi kasus](https://rea.tools/showcase/th04/) · [Repositori rekonstruksi](https://github.com/N0zoM1z0/th04)
|
||||||
|
|
||||||
Jika Anda telah menggunakan REA untuk menganalisis sesuatu yang menarik, kami ingin melihat hasilnya. Bagikan kasus Anda melalui [issue](https://github.com/morluto/rea/issues) atau [pull request](https://github.com/morluto/rea/pulls), sertakan target, pertanyaan Anda, bagaimana REA membantu, dan apa yang Anda temukan.
|
Jika Anda telah menggunakan REA untuk menganalisis sesuatu yang menarik, kami ingin melihat hasilnya. Bagikan kasus Anda melalui [issue](https://github.com/morluto/rea/issues) atau [pull request](https://github.com/morluto/rea/pulls), sertakan target, pertanyaan Anda, bagaimana REA membantu, dan apa yang Anda temukan.
|
||||||
|
|
||||||
@@ -248,7 +246,7 @@ REA menganalisis target secara lokal. Agen Anda menerima hasil alat, sedangkan p
|
|||||||
|
|
||||||
Perbarui terlebih dahulu. Rilis terbaru mungkin sudah memperbaiki masalah tersebut.
|
Perbarui terlebih dahulu. Rilis terbaru mungkin sudah memperbaiki masalah tersebut.
|
||||||
|
|
||||||
Untuk CLI yang dipasang melalui `npm install --global` atau `bun add --global`:
|
Untuk CLI yang dipasang melalui npm:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
rea update
|
rea update
|
||||||
@@ -268,7 +266,7 @@ Coba kembali tugas yang sama. Jika masalah masih terjadi, [buat issue](https://g
|
|||||||
|
|
||||||
## Dokumentasi
|
## Dokumentasi
|
||||||
|
|
||||||
Mulailah dengan [panduan praktik di situs web](https://rea.tools/id/guides/).
|
Mulailah dengan [panduan praktik di situs web](https://rea.tools/guides/).
|
||||||
|
|
||||||
Untuk mengetahui opsi, prasyarat, dan kontrak hasil secara tepat:
|
Untuk mengetahui opsi, prasyarat, dan kontrak hasil secara tepat:
|
||||||
|
|
||||||
@@ -283,7 +281,7 @@ Laporkan kerentanan melalui [SECURITY.md](SECURITY.md).
|
|||||||
|
|
||||||
## Riwayat Bintang
|
## Riwayat Bintang
|
||||||
|
|
||||||
🎉 **90.000 bintang GitHub, terima kasih!**
|
🎉 **50.000 bintang GitHub, terima kasih!**
|
||||||
|
|
||||||
Terima kasih kepada semua orang yang menggunakan REA, melaporkan bug, meminta fitur, menguji build, dan berkontribusi dalam perbaikan.
|
Terima kasih kepada semua orang yang menggunakan REA, melaporkan bug, meminta fitur, menguji build, dan berkontribusi dalam perbaikan.
|
||||||
|
|
||||||
|
|||||||
+17
-19
@@ -9,6 +9,7 @@
|
|||||||
**Vedi una funzionalità che ti piace. Capisci come funziona, fino al livello binario.**
|
**Vedi una funzionalità che ti piace. Capisci come funziona, fino al livello binario.**
|
||||||
|
|
||||||
[](https://www.npmjs.com/package/rea-agents)
|
[](https://www.npmjs.com/package/rea-agents)
|
||||||
|
[](https://github.com/morluto/rea/actions/workflows/ci.yml)
|
||||||
[](docs/mcp-contracts.md#generated-catalog)
|
[](docs/mcp-contracts.md#generated-catalog)
|
||||||
[](#cosa-puoi-analizzare)
|
[](#cosa-puoi-analizzare)
|
||||||
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
||||||
@@ -17,9 +18,9 @@
|
|||||||
|
|
||||||
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
||||||
|
|
||||||
**[Sito web](https://rea.tools/it/) · [Guide](https://rea.tools/it/guides/) · [Showcase](https://rea.tools/it/showcase/)**
|
**[Sito web](https://rea.tools/) · [Guide](https://rea.tools/guides/) · [Showcase](https://rea.tools/showcase/)**
|
||||||
|
|
||||||
[Avvio rapido](#avvio-rapido) · [Come funziona REA](#come-funziona-rea) · [Cosa puoi analizzare](#cosa-puoi-analizzare) · [Showcase](#showcase) · [FAQ](#faq) · [Documentazione](#documentazione)
|
[Quick start](#quick-start) · [Come funziona REA](#come-funziona-rea) · [Cosa puoi analizzare](#cosa-puoi-analizzare) · [Showcase](#showcase) · [FAQ](#faq) · [Documentazione](#documentazione)
|
||||||
|
|
||||||
<code>npx rea-agents setup</code>
|
<code>npx rea-agents setup</code>
|
||||||
|
|
||||||
@@ -53,9 +54,9 @@ REA collega il tuo agente a strumenti per ispezionare binari nativi, app JavaScr
|
|||||||
|
|
||||||
La configurazione registra REA con il tuo agente e installa le istruzioni di workflow corrispondenti. L'analisi nativa può usare un'installazione esistente di Hopper, Ghidra o IDA; la configurazione può installare opzionalmente Hopper previa approvazione. L'analisi statica JavaScript non richiede alcun motore di analisi nativo.
|
La configurazione registra REA con il tuo agente e installa le istruzioni di workflow corrispondenti. L'analisi nativa può usare un'installazione esistente di Hopper, Ghidra o IDA; la configurazione può installare opzionalmente Hopper previa approvazione. L'analisi statica JavaScript non richiede alcun motore di analisi nativo.
|
||||||
|
|
||||||
> **[Visita il sito web di REA](https://rea.tools/it/)** per istruzioni di configurazione, guide illustrate e veri casi studio.
|
> **[Visita il sito web di REA](https://rea.tools/)** per istruzioni di configurazione, guide illustrate e veri casi studio.
|
||||||
|
|
||||||
## Avvio rapido
|
## Quick start
|
||||||
|
|
||||||
### Configura il tuo agente
|
### Configura il tuo agente
|
||||||
|
|
||||||
@@ -101,14 +102,12 @@ Per l'analisi nativa, configura prima un provider. Vedi la [guida CLI ed Evidenc
|
|||||||
|
|
||||||
REA cambia rapidamente e le nuove versioni includono correzioni di bug frequenti. Tieni aggiornata la tua installazione.
|
REA cambia rapidamente e le nuove versioni includono correzioni di bug frequenti. Tieni aggiornata la tua installazione.
|
||||||
|
|
||||||
Per una CLI installata con `npm install --global` o `bun add --global`:
|
Per una CLI installata via npm:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
rea update
|
rea update
|
||||||
```
|
```
|
||||||
|
|
||||||
Gli aggiornamenti globali con Bun richiedono Bun 1.2.17 o versioni successive. Con una versione precedente di Bun, aggiorna Bun manualmente prima di eseguire `rea update`.
|
|
||||||
|
|
||||||
Per aggiornare le registrazioni del tuo agente e lo skill, esegui il comando di configurazione mostrato dall'aggiornamento.
|
Per aggiornare le registrazioni del tuo agente e lo skill, esegui il comando di configurazione mostrato dall'aggiornamento.
|
||||||
|
|
||||||
Se usi `npx`, aggiorna la configurazione del tuo agente con:
|
Se usi `npx`, aggiorna la configurazione del tuo agente con:
|
||||||
@@ -117,7 +116,7 @@ Se usi `npx`, aggiorna la configurazione del tuo agente con:
|
|||||||
npx rea-agents@latest setup
|
npx rea-agents@latest setup
|
||||||
```
|
```
|
||||||
|
|
||||||
Rivedi le modifiche di configurazione e riavvia il tuo agente. Per comandi CLI singoli, usa `npx rea-agents@latest` seguito dal comando. Con Bun, usa `bunx rea-agents@latest` al posto di `npx rea-agents@latest`.
|
Rivedi le modifiche di configurazione e riavvia il tuo agente. Per comandi CLI singoli, usa `npx rea-agents@latest` seguito dal comando.
|
||||||
|
|
||||||
## Come funziona REA
|
## Come funziona REA
|
||||||
|
|
||||||
@@ -135,13 +134,12 @@ REA richiede Node.js 22.x (>=22.19), 24.x (>=24.11) o 26+, oltre a npm. Strument
|
|||||||
|
|
||||||
| Obiettivo | Cosa restituisce REA | Requisiti e guida |
|
| Obiettivo | Cosa restituisce REA | Requisiti e guida |
|
||||||
| ---------------------------- | ------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
|
| ---------------------------- | ------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| Binari nativi | Pseudocodice, assembly, stringhe, simboli, chiamate e riferimenti | Hopper, Ghidra o IDA; [analisi nativa](https://rea.tools/it/guides/native/) |
|
| Binari nativi | Pseudocodice, assembly, stringhe, simboli, chiamate e riferimenti | Hopper, Ghidra o IDA; [analisi nativa](https://rea.tools/guides/native/) |
|
||||||
| Layout ELF offline | Sezioni, segmenti, simboli/relocazioni originali e candidati mitigazioni statiche | pwntools fornito dal chiamante su Linux x64; [diagnostica binaria](docs/binary-diagnostics.md) |
|
| Layout ELF offline | Sezioni, segmenti, simboli/relocazioni originali e candidati mitigazioni statiche | pwntools fornito dal chiamante su Linux x64; [diagnostica binaria](docs/binary-diagnostics.md) |
|
||||||
| Artefatto WASM | Convalida, sezioni, forme WAT di import/export esatte e WAT decodificato | WABT 1.0.42 fornito dal chiamante; `inspect_wasm_artifact` |
|
|
||||||
| Bytecode EVM | Selettori di dispatch, offset dei byte, argomenti inferiti e mutabilità | Carrier raw/hex locale; [guida EVM offline](docs/evm-bytecode.md) |
|
| Bytecode EVM | Selettori di dispatch, offset dei byte, argomenti inferiti e mutabilità | Carrier raw/hex locale; [guida EVM offline](docs/evm-bytecode.md) |
|
||||||
| Crash Linux registrati | Note grezze, registri/segnai di ogni thread registrato e candidati mapping opzionali | pwntools fornito dal chiamante; GDB/pwndbg opzionale; [crash registrati](docs/recorded-crashes.md) |
|
| Crash Linux registrati | Note grezze, registri/segnai di ogni thread registrato e candidati mapping opzionali | pwntools fornito dal chiamante; GDB/pwndbg opzionale; [crash registrati](docs/recorded-crashes.md) |
|
||||||
| JavaScript / Electron | Moduli, import, source map, route, IPC e relazioni con add-on nativi | Node.js e npm; [analisi delle applicazioni](https://rea.tools/it/guides/javascript/) |
|
| JavaScript / Electron | Moduli, import, source map, route, IPC e relazioni con add-on nativi | Node.js e npm; [analisi delle applicazioni](https://rea.tools/guides/javascript/) |
|
||||||
| Siti web | Struttura della pagina, script, osservazioni di rete e screenshot richiesti | Un browser della famiglia Chrome; [analisi browser](https://rea.tools/it/guides/browser/) |
|
| Siti web | Struttura della pagina, script, osservazioni di rete e screenshot richiesti | Un browser della famiglia Chrome; [analisi browser](https://rea.tools/guides/browser/) |
|
||||||
| Acquisizioni di rete salvate | Richieste, risposte, payload esposti e posizioni sorgente | HAR; mitmdump su Linux per acquisizioni mitmproxy native; [guida alle acquisizioni](docs/web-network-captures.md) |
|
| Acquisizioni di rete salvate | Richieste, risposte, payload esposti e posizioni sorgente | HAR; mitmdump su Linux per acquisizioni mitmproxy native; [guida alle acquisizioni](docs/web-network-captures.md) |
|
||||||
| Assembly .NET | Metadati, istruzioni CIL, dipendenze native dichiarate e confronti di build | Nessuno (solo statico); [guida managed-code](docs/managed-code-analysis.md) |
|
| Assembly .NET | Metadati, istruzioni CIL, dipendenze native dichiarate e confronti di build | Nessuno (solo statico); [guida managed-code](docs/managed-code-analysis.md) |
|
||||||
| APK Android | Dichiarazioni manifest, classi, metodi decompilati e riferimenti | JADX headless e un JDK completo su Linux/macOS/Windows x64; [guida Android](docs/android-analysis.md) |
|
| APK Android | Dichiarazioni manifest, classi, metodi decompilati e riferimenti | JADX headless e un JDK completo su Linux/macOS/Windows x64; [guida Android](docs/android-analysis.md) |
|
||||||
@@ -160,25 +158,25 @@ I formati nativi e il supporto host variano in base al provider. Vedi la [config
|
|||||||
|
|
||||||
## Showcase
|
## Showcase
|
||||||
|
|
||||||
[](https://rea.tools/it/showcase/)
|
[](https://rea.tools/showcase/)
|
||||||
|
|
||||||
### DX-Ball: ricostruisci un calcolo sound-pan
|
### DX-Ball: ricostruisci un calcolo sound-pan
|
||||||
|
|
||||||
Segui una chiamata sonora fino al suo helper posizione-to-pan, ispeziona le istruzioni e trasforma il pseudocodice incompleto in C. La ricostruzione supera 3.205 casi x86 originali e riproduce tutti i 63 byte di funzione compilati.
|
Segui una chiamata sonora fino al suo helper posizione-to-pan, ispeziona le istruzioni e trasforma il pseudocodice incompleto in C. La ricostruzione supera 3.205 casi x86 originali e riproduce tutti i 63 byte di funzione compilati.
|
||||||
|
|
||||||
[Leggi il case study](https://rea.tools/it/showcase/dx-ball/) · [Repository di ricostruzione](https://github.com/N0zoM1z0/dx-ball)
|
[Leggi il case study](https://rea.tools/showcase/dx-ball/) · [Repository di ricostruzione](https://github.com/N0zoM1z0/dx-ball)
|
||||||
|
|
||||||
### Notion: traccia il clipboard bridge di Electron
|
### Notion: traccia il clipboard bridge di Electron
|
||||||
|
|
||||||
Trova l'API clipboard del renderer, seguila attraverso preload e IPC fino al processo principale e ispeziona il formato rich clipboard.
|
Trova l'API clipboard del renderer, seguila attraverso preload e IPC fino al processo principale e ispeziona il formato rich clipboard.
|
||||||
|
|
||||||
[Leggi il case study](https://rea.tools/it/showcase/notion/)
|
[Leggi il case study](https://rea.tools/showcase/notion/)
|
||||||
|
|
||||||
### TH04: recupera un calcolo dell'anello di proiettili DOS
|
### TH04: recupera un calcolo dell'anello di proiettili DOS
|
||||||
|
|
||||||
Ispeziona le istruzioni a 16 bit del gioco PC-98 originale, recupera i calcoli dell'angolo fisso e mirato e confronta il C++ ricostruito con l'output del compilatore storico.
|
Ispeziona le istruzioni a 16 bit del gioco PC-98 originale, recupera i calcoli dell'angolo fisso e mirato e confronta il C++ ricostruito con l'output del compilatore storico.
|
||||||
|
|
||||||
[Leggi il case study](https://rea.tools/it/showcase/th04/) · [Repository di ricostruzione](https://github.com/N0zoM1z0/th04)
|
[Leggi il case study](https://rea.tools/showcase/th04/) · [Repository di ricostruzione](https://github.com/N0zoM1z0/th04)
|
||||||
|
|
||||||
Se hai usato REA su qualcosa di interessante, ci piacerebbe vederlo. Condividi il tuo caso in una [issue](https://github.com/morluto/rea/issues) o in una [pull request](https://github.com/morluto/rea/pulls), includendo il bersaglio, la tua domanda, come REA ti ha aiutato e cosa hai scoperto.
|
Se hai usato REA su qualcosa di interessante, ci piacerebbe vederlo. Condividi il tuo caso in una [issue](https://github.com/morluto/rea/issues) o in una [pull request](https://github.com/morluto/rea/pulls), includendo il bersaglio, la tua domanda, come REA ti ha aiutato e cosa hai scoperto.
|
||||||
|
|
||||||
@@ -231,7 +229,7 @@ REA analizza i bersagli localmente. Il tuo agente riceve i risultati degli strum
|
|||||||
|
|
||||||
Aggiorna prima; una release recente potrebbe averlo già risolto.
|
Aggiorna prima; una release recente potrebbe averlo già risolto.
|
||||||
|
|
||||||
Per una CLI installata con `npm install --global` o `bun add --global`:
|
Per una CLI installata via npm:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
rea update
|
rea update
|
||||||
@@ -249,7 +247,7 @@ Se stai usando un agente, completa l'[aggiornamento della configurazione](#aggio
|
|||||||
|
|
||||||
## Documentazione
|
## Documentazione
|
||||||
|
|
||||||
Inizia dalle [guide pratiche](https://rea.tools/it/guides/) del sito web. Per opzioni esatte, prerequisiti e contratti dei risultati:
|
Inizia dalle [guide pratiche](https://rea.tools/guides/) del sito web. Per opzioni esatte, prerequisiti e contratti dei risultati:
|
||||||
|
|
||||||
- [Installazione e configurazione](docs/installation.md): registrazione agente, configurazione provider, aggiornamenti e disinstallazione.
|
- [Installazione e configurazione](docs/installation.md): registrazione agente, configurazione provider, aggiornamenti e disinstallazione.
|
||||||
- [Pronto all'uso e risoluzione dei problemi](docs/installation.md#check-readiness-for-your-task): diagnostica un agente o un motore di analisi.
|
- [Pronto all'uso e risoluzione dei problemi](docs/installation.md#check-readiness-for-your-task): diagnostica un agente o un motore di analisi.
|
||||||
@@ -262,7 +260,7 @@ Segnala vulnerabilità tramite [SECURITY.md](SECURITY.md).
|
|||||||
|
|
||||||
## Cronologia delle stelle
|
## Cronologia delle stelle
|
||||||
|
|
||||||
🎉 **90.000 stelle su GitHub — grazie!**
|
🎉 **50.000 stelle su GitHub — grazie!**
|
||||||
|
|
||||||
Grazie a tutti coloro che usano REA, segnalano bug, propongono funzionalità, testano le build e contribuiscono con correzioni.
|
Grazie a tutti coloro che usano REA, segnalano bug, propongono funzionalità, testano le build e contribuiscono con correzioni.
|
||||||
|
|
||||||
|
|||||||
+12
-11
@@ -9,6 +9,7 @@
|
|||||||
**気に入った機能を見つけたら、その仕組みをバイナリのレベルまで理解する。**
|
**気に入った機能を見つけたら、その仕組みをバイナリのレベルまで理解する。**
|
||||||
|
|
||||||
[](https://www.npmjs.com/package/rea-agents)
|
[](https://www.npmjs.com/package/rea-agents)
|
||||||
|
[](https://github.com/morluto/rea/actions/workflows/ci.yml)
|
||||||
[](docs/mcp-contracts.md#generated-catalog)
|
[](docs/mcp-contracts.md#generated-catalog)
|
||||||
[](#current-status)
|
[](#current-status)
|
||||||
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
||||||
@@ -17,7 +18,7 @@
|
|||||||
|
|
||||||
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
||||||
|
|
||||||
**[ウェブサイト](https://rea.tools/ja/) · [ガイド](https://rea.tools/ja/guides/) · [事例](https://rea.tools/ja/showcase/)**
|
**[ウェブサイト](https://rea.tools/) · [ガイド](https://rea.tools/guides/) · [事例](https://rea.tools/showcase/)**
|
||||||
|
|
||||||
[クイックスタート](#クイックスタート) · [REA の仕組み](#rea-の仕組み) · [分析できる対象](#分析できる対象) · [事例](#事例) · [よくある質問](#よくある質問) · [ドキュメント](#ドキュメント)
|
[クイックスタート](#クイックスタート) · [REA の仕組み](#rea-の仕組み) · [分析できる対象](#分析できる対象) · [事例](#事例) · [よくある質問](#よくある質問) · [ドキュメント](#ドキュメント)
|
||||||
|
|
||||||
@@ -53,7 +54,7 @@ REA はエージェントを分析ツールにつなぎ、ネイティブバイ
|
|||||||
|
|
||||||
セットアップはエージェントに REA を登録し、対応するワークフローの手順をインストールします。ネイティブ分析には既存の Hopper または Ghidra を使えます。承認すれば、セットアップで Hopper をインストールすることもできます。静的な JavaScript 分析には、どちらのエンジンも必要ありません。
|
セットアップはエージェントに REA を登録し、対応するワークフローの手順をインストールします。ネイティブ分析には既存の Hopper または Ghidra を使えます。承認すれば、セットアップで Hopper をインストールすることもできます。静的な JavaScript 分析には、どちらのエンジンも必要ありません。
|
||||||
|
|
||||||
> **[REA のウェブサイト](https://rea.tools/ja/)**で、セットアップ手順、図解ガイド、実際の事例を確認できます。
|
> **[REA のウェブサイト](https://rea.tools/)**で、セットアップ手順、図解ガイド、実際の事例を確認できます。
|
||||||
|
|
||||||
## クイックスタート
|
## クイックスタート
|
||||||
|
|
||||||
@@ -132,12 +133,12 @@ REA には Node.js 22.x(>=22.19)、24.x(>=24.11)、または 26+ と npm
|
|||||||
|
|
||||||
| 対象 | REA が返すもの | 要件とガイド |
|
| 対象 | REA が返すもの | 要件とガイド |
|
||||||
| -------------------------------- | ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| -------------------------------- | ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| ネイティブバイナリ | 疑似コード、アセンブリ、文字列、シンボル、呼び出し、参照 | Hopper、Ghidra、または IDA;[ネイティブ分析](https://rea.tools/ja/guides/native/) |
|
| ネイティブバイナリ | 疑似コード、アセンブリ、文字列、シンボル、呼び出し、参照 | Hopper、Ghidra、または IDA;[ネイティブ分析](https://rea.tools/guides/native/) |
|
||||||
| オフライン ELF レイアウト | セクション、セグメント、元のシンボル/再配置情報、静的解析によるセキュリティ対策の候補 | Linux x64 で利用者が用意する pwntools;[バイナリ診断](docs/binary-diagnostics.md) |
|
| オフライン ELF レイアウト | セクション、セグメント、元のシンボル/再配置情報、静的解析によるセキュリティ対策の候補 | Linux x64 で利用者が用意する pwntools;[バイナリ診断](docs/binary-diagnostics.md) |
|
||||||
| EVM バイトコード | ディスパッチセレクター、バイトオフセット、推定された引数と状態変更の可否 | Linux x64 上のローカルの生バイト/16 進数の入力ファイル;[オフライン EVM ガイド](docs/evm-bytecode.md) |
|
| EVM バイトコード | ディスパッチセレクター、バイトオフセット、推定された引数と状態変更の可否 | Linux x64 上のローカルの生バイト/16 進数の入力ファイル;[オフライン EVM ガイド](docs/evm-bytecode.md) |
|
||||||
| 記録済みの Linux クラッシュ | 生の note レコード、記録された全スレッドのレジスター/シグナル、任意のマッピング候補 | Linux x64 で利用者が用意する pwntools;GDB/pwndbg は任意;[記録済みクラッシュ](docs/recorded-crashes.md) |
|
| 記録済みの Linux クラッシュ | 生の note レコード、記録された全スレッドのレジスター/シグナル、任意のマッピング候補 | Linux x64 で利用者が用意する pwntools;GDB/pwndbg は任意;[記録済みクラッシュ](docs/recorded-crashes.md) |
|
||||||
| JavaScript / Electron | モジュール、インポート、ソースマップ、ルート、IPC、ネイティブアドオンの関係 | Node.js と npm;[アプリケーション分析](https://rea.tools/ja/guides/javascript/) |
|
| JavaScript / Electron | モジュール、インポート、ソースマップ、ルート、IPC、ネイティブアドオンの関係 | Node.js と npm;[アプリケーション分析](https://rea.tools/guides/javascript/) |
|
||||||
| ウェブサイト | ページ構造、スクリプト、ネットワークの観測結果、依頼されたスクリーンショット | Chrome 系ブラウザー;[ブラウザー分析](https://rea.tools/ja/guides/browser/) |
|
| ウェブサイト | ページ構造、スクリプト、ネットワークの観測結果、依頼されたスクリーンショット | Chrome 系ブラウザー;[ブラウザー分析](https://rea.tools/guides/browser/) |
|
||||||
| 保存済みのネットワークキャプチャ | リクエスト、レスポンス、取得可能なペイロード、ソース内の位置 | HAR;mitmproxy ネイティブ形式のキャプチャには Linux 上の mitmdump;[キャプチャガイド](docs/web-network-captures.md) |
|
| 保存済みのネットワークキャプチャ | リクエスト、レスポンス、取得可能なペイロード、ソース内の位置 | HAR;mitmproxy ネイティブ形式のキャプチャには Linux 上の mitmdump;[キャプチャガイド](docs/web-network-captures.md) |
|
||||||
| .NET アセンブリ | メタデータ、CIL 命令、宣言されたネイティブ依存関係、ビルドの比較 | 静的な検査;[マネージドコードのガイド](docs/managed-code-analysis.md) |
|
| .NET アセンブリ | メタデータ、CIL 命令、宣言されたネイティブ依存関係、ビルドの比較 | 静的な検査;[マネージドコードのガイド](docs/managed-code-analysis.md) |
|
||||||
| Android APK | マニフェストの宣言、クラス、逆コンパイルされたメソッド、参照 | Linux/macOS/Windows x64 上のヘッドレス JADX と完全な JDK;[Android ガイド](docs/android-analysis.md) |
|
| Android APK | マニフェストの宣言、クラス、逆コンパイルされたメソッド、参照 | Linux/macOS/Windows x64 上のヘッドレス JADX と完全な JDK;[Android ガイド](docs/android-analysis.md) |
|
||||||
@@ -156,26 +157,26 @@ REA には Node.js 22.x(>=22.19)、24.x(>=24.11)、または 26+ と npm
|
|||||||
|
|
||||||
## 事例
|
## 事例
|
||||||
|
|
||||||
[](https://rea.tools/ja/showcase/)
|
[](https://rea.tools/showcase/)
|
||||||
|
|
||||||
### DX-Ball:音声のパン計算を再構築する
|
### DX-Ball:音声のパン計算を再構築する
|
||||||
|
|
||||||
音声の呼び出しから位置をパンに変換する補助関数をたどり、命令を調べ、不完全な疑似コードを C に書き直します。再構築した実装は、元の x86 に対する 3,205 ケースの検証を通過し、コンパイル後の関数の全 63 バイトを再現しています。
|
音声の呼び出しから位置をパンに変換する補助関数をたどり、命令を調べ、不完全な疑似コードを C に書き直します。再構築した実装は、元の x86 に対する 3,205 ケースの検証を通過し、コンパイル後の関数の全 63 バイトを再現しています。
|
||||||
|
|
||||||
[事例を読む](https://rea.tools/ja/showcase/dx-ball/) ·
|
[事例を読む](https://rea.tools/showcase/dx-ball/) ·
|
||||||
[再構築リポジトリ](https://github.com/N0zoM1z0/dx-ball)
|
[再構築リポジトリ](https://github.com/N0zoM1z0/dx-ball)
|
||||||
|
|
||||||
### Notion:Electron のクリップボードブリッジを追跡する
|
### Notion:Electron のクリップボードブリッジを追跡する
|
||||||
|
|
||||||
レンダラーのクリップボード API を見つけ、preload と IPC を経由してメインプロセスまでたどり、リッチなクリップボード形式を調べます。
|
レンダラーのクリップボード API を見つけ、preload と IPC を経由してメインプロセスまでたどり、リッチなクリップボード形式を調べます。
|
||||||
|
|
||||||
[事例を読む](https://rea.tools/ja/showcase/notion/)
|
[事例を読む](https://rea.tools/showcase/notion/)
|
||||||
|
|
||||||
### TH04:DOS の弾幕リングの計算を復元する
|
### TH04:DOS の弾幕リングの計算を復元する
|
||||||
|
|
||||||
元の PC-98 ゲームの 16 ビット命令を調べ、固定角度と自機を狙う角度の計算を復元し、再構築した C++ を当時のコンパイラーの出力と比較します。
|
元の PC-98 ゲームの 16 ビット命令を調べ、固定角度と自機を狙う角度の計算を復元し、再構築した C++ を当時のコンパイラーの出力と比較します。
|
||||||
|
|
||||||
[事例を読む](https://rea.tools/ja/showcase/th04/) ·
|
[事例を読む](https://rea.tools/showcase/th04/) ·
|
||||||
[再構築リポジトリ](https://github.com/N0zoM1z0/th04)
|
[再構築リポジトリ](https://github.com/N0zoM1z0/th04)
|
||||||
|
|
||||||
REA で興味深い対象を調べたら、ぜひ共有してください。[issue](https://github.com/morluto/rea/issues) または [pull request](https://github.com/morluto/rea/pulls) に、対象、調べたかったこと、REA がどう役立ったか、何が分かったかを記載してください。
|
REA で興味深い対象を調べたら、ぜひ共有してください。[issue](https://github.com/morluto/rea/issues) または [pull request](https://github.com/morluto/rea/pulls) に、対象、調べたかったこと、REA がどう役立ったか、何が分かったかを記載してください。
|
||||||
@@ -247,7 +248,7 @@ npx rea-agents@latest setup
|
|||||||
|
|
||||||
## ドキュメント
|
## ドキュメント
|
||||||
|
|
||||||
まずはウェブサイトの[実践ガイド](https://rea.tools/ja/guides/)を参照してください。正確なオプション、前提条件、結果の契約については、以下を参照してください。
|
まずはウェブサイトの[実践ガイド](https://rea.tools/guides/)を参照してください。正確なオプション、前提条件、結果の契約については、以下を参照してください。
|
||||||
|
|
||||||
- [インストールとセットアップ](docs/installation.md):エージェントの登録、プロバイダーの設定、更新、アンインストール。
|
- [インストールとセットアップ](docs/installation.md):エージェントの登録、プロバイダーの設定、更新、アンインストール。
|
||||||
- [準備状況の確認とトラブルシューティング](docs/installation.md#check-readiness-for-your-task):特定のエージェントや分析エンジンを診断。
|
- [準備状況の確認とトラブルシューティング](docs/installation.md#check-readiness-for-your-task):特定のエージェントや分析エンジンを診断。
|
||||||
@@ -260,7 +261,7 @@ npx rea-agents@latest setup
|
|||||||
|
|
||||||
## スター履歴
|
## スター履歴
|
||||||
|
|
||||||
🎉 **GitHub スター 90,000 件、ありがとうございます!**
|
🎉 **GitHub スター 50,000 件、ありがとうございます!**
|
||||||
|
|
||||||
REA の利用、バグ報告、機能の要望、ビルドのテスト、修正への貢献に感謝します。
|
REA の利用、バグ報告、機能の要望、ビルドのテスト、修正への貢献に感謝します。
|
||||||
|
|
||||||
|
|||||||
+12
-11
@@ -9,6 +9,7 @@
|
|||||||
**마음에 드는 기능을 발견했다면, 바이너리 수준까지 작동 원리를 이해하세요.**
|
**마음에 드는 기능을 발견했다면, 바이너리 수준까지 작동 원리를 이해하세요.**
|
||||||
|
|
||||||
[](https://www.npmjs.com/package/rea-agents)
|
[](https://www.npmjs.com/package/rea-agents)
|
||||||
|
[](https://github.com/morluto/rea/actions/workflows/ci.yml)
|
||||||
[](docs/mcp-contracts.md#generated-catalog)
|
[](docs/mcp-contracts.md#generated-catalog)
|
||||||
[](#current-status)
|
[](#current-status)
|
||||||
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
||||||
@@ -17,7 +18,7 @@
|
|||||||
|
|
||||||
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
||||||
|
|
||||||
**[웹사이트](https://rea.tools/ko/) · [가이드](https://rea.tools/ko/guides/) · [사례](https://rea.tools/ko/showcase/)**
|
**[웹사이트](https://rea.tools/) · [가이드](https://rea.tools/guides/) · [사례](https://rea.tools/showcase/)**
|
||||||
|
|
||||||
[빠른 시작](#빠른-시작) · [REA의 작동 방식](#rea의-작동-방식) · [분석할 수 있는 대상](#분석할-수-있는-대상) · [사례](#사례) · [자주 묻는 질문](#자주-묻는-질문) · [문서](#문서)
|
[빠른 시작](#빠른-시작) · [REA의 작동 방식](#rea의-작동-방식) · [분석할 수 있는 대상](#분석할-수-있는-대상) · [사례](#사례) · [자주 묻는 질문](#자주-묻는-질문) · [문서](#문서)
|
||||||
|
|
||||||
@@ -53,7 +54,7 @@ REA는 에이전트를 분석 도구에 연결해 네이티브 바이너리, Jav
|
|||||||
|
|
||||||
설정 과정은 에이전트에 REA를 등록하고 해당 버전에 맞는 워크플로 지침을 설치합니다. 네이티브 분석에는 기존 Hopper 또는 Ghidra 설치를 사용할 수 있습니다. 승인하면 설정 과정에서 Hopper를 설치할 수도 있습니다. 정적 JavaScript 분석에는 두 엔진 모두 필요하지 않습니다.
|
설정 과정은 에이전트에 REA를 등록하고 해당 버전에 맞는 워크플로 지침을 설치합니다. 네이티브 분석에는 기존 Hopper 또는 Ghidra 설치를 사용할 수 있습니다. 승인하면 설정 과정에서 Hopper를 설치할 수도 있습니다. 정적 JavaScript 분석에는 두 엔진 모두 필요하지 않습니다.
|
||||||
|
|
||||||
> **[REA 웹사이트](https://rea.tools/ko/)**에서 설정 방법, 그림으로 설명한 가이드, 실제 사례를 확인하세요.
|
> **[REA 웹사이트](https://rea.tools/)**에서 설정 방법, 그림으로 설명한 가이드, 실제 사례를 확인하세요.
|
||||||
|
|
||||||
## 빠른 시작
|
## 빠른 시작
|
||||||
|
|
||||||
@@ -132,12 +133,12 @@ REA에는 Node.js 22.x(>=22.19), 24.x(>=24.11) 또는 26+와 npm이 필요합니
|
|||||||
|
|
||||||
| 대상 | REA가 반환하는 내용 | 요구 사항 및 가이드 |
|
| 대상 | REA가 반환하는 내용 | 요구 사항 및 가이드 |
|
||||||
| --------------------- | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
|
| --------------------- | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| 네이티브 바이너리 | 의사 코드, 어셈블리, 문자열, 심볼, 호출, 참조 | Hopper, Ghidra 또는 IDA; [네이티브 분석](https://rea.tools/ko/guides/native/) |
|
| 네이티브 바이너리 | 의사 코드, 어셈블리, 문자열, 심볼, 호출, 참조 | Hopper, Ghidra 또는 IDA; [네이티브 분석](https://rea.tools/guides/native/) |
|
||||||
| 오프라인 ELF 레이아웃 | 섹션, 세그먼트, 원본 심볼/재배치 정보, 정적 분석으로 얻은 보안 완화 기법 후보 | Linux x64에서 호출자가 제공하는 pwntools; [바이너리 진단](docs/binary-diagnostics.md) |
|
| 오프라인 ELF 레이아웃 | 섹션, 세그먼트, 원본 심볼/재배치 정보, 정적 분석으로 얻은 보안 완화 기법 후보 | Linux x64에서 호출자가 제공하는 pwntools; [바이너리 진단](docs/binary-diagnostics.md) |
|
||||||
| EVM 바이트코드 | 디스패치 선택자, 바이트 오프셋, 추론한 인자와 상태 변경 가능 여부 | Linux x64의 로컬 원시 바이트/16진수 입력 파일; [오프라인 EVM 가이드](docs/evm-bytecode.md) |
|
| EVM 바이트코드 | 디스패치 선택자, 바이트 오프셋, 추론한 인자와 상태 변경 가능 여부 | Linux x64의 로컬 원시 바이트/16진수 입력 파일; [오프라인 EVM 가이드](docs/evm-bytecode.md) |
|
||||||
| 기록된 Linux 크래시 | 원시 note 레코드, 기록된 모든 스레드의 레지스터/시그널, 선택적 매핑 후보 | Linux x64에서 호출자가 제공하는 pwntools; GDB/pwndbg는 선택 사항; [기록된 크래시](docs/recorded-crashes.md) |
|
| 기록된 Linux 크래시 | 원시 note 레코드, 기록된 모든 스레드의 레지스터/시그널, 선택적 매핑 후보 | Linux x64에서 호출자가 제공하는 pwntools; GDB/pwndbg는 선택 사항; [기록된 크래시](docs/recorded-crashes.md) |
|
||||||
| JavaScript / Electron | 모듈, 임포트, 소스 맵, 라우트, IPC, 네이티브 애드온 관계 | Node.js와 npm; [애플리케이션 분석](https://rea.tools/ko/guides/javascript/) |
|
| JavaScript / Electron | 모듈, 임포트, 소스 맵, 라우트, IPC, 네이티브 애드온 관계 | Node.js와 npm; [애플리케이션 분석](https://rea.tools/guides/javascript/) |
|
||||||
| 웹사이트 | 페이지 구조, 스크립트, 네트워크 관찰 결과, 요청한 스크린샷 | Chrome 계열 브라우저; [브라우저 분석](https://rea.tools/ko/guides/browser/) |
|
| 웹사이트 | 페이지 구조, 스크립트, 네트워크 관찰 결과, 요청한 스크린샷 | Chrome 계열 브라우저; [브라우저 분석](https://rea.tools/guides/browser/) |
|
||||||
| 저장된 네트워크 캡처 | 요청, 응답, 접근 가능한 페이로드, 소스 위치 | HAR; mitmproxy 네이티브 캡처에는 Linux의 mitmdump; [캡처 가이드](docs/web-network-captures.md) |
|
| 저장된 네트워크 캡처 | 요청, 응답, 접근 가능한 페이로드, 소스 위치 | HAR; mitmproxy 네이티브 캡처에는 Linux의 mitmdump; [캡처 가이드](docs/web-network-captures.md) |
|
||||||
| .NET 어셈블리 | 메타데이터, CIL 명령, 선언된 네이티브 의존성, 빌드 비교 | 정적 검사; [관리 코드 가이드](docs/managed-code-analysis.md) |
|
| .NET 어셈블리 | 메타데이터, CIL 명령, 선언된 네이티브 의존성, 빌드 비교 | 정적 검사; [관리 코드 가이드](docs/managed-code-analysis.md) |
|
||||||
| Android APK | 매니페스트 선언, 클래스, 디컴파일된 메서드, 참조 | Linux/macOS/Windows x64의 헤드리스 JADX와 전체 JDK; [Android 가이드](docs/android-analysis.md) |
|
| Android APK | 매니페스트 선언, 클래스, 디컴파일된 메서드, 참조 | Linux/macOS/Windows x64의 헤드리스 JADX와 전체 JDK; [Android 가이드](docs/android-analysis.md) |
|
||||||
@@ -156,26 +157,26 @@ REA에는 Node.js 22.x(>=22.19), 24.x(>=24.11) 또는 26+와 npm이 필요합니
|
|||||||
|
|
||||||
## 사례
|
## 사례
|
||||||
|
|
||||||
[](https://rea.tools/ko/showcase/)
|
[](https://rea.tools/showcase/)
|
||||||
|
|
||||||
### DX-Ball: 사운드 패닝 계산 재구현
|
### DX-Ball: 사운드 패닝 계산 재구현
|
||||||
|
|
||||||
사운드 호출에서 위치를 패닝 값으로 변환하는 보조 함수까지 추적하고, 명령을 검사하여 불완전한 의사 코드를 C로 옮깁니다. 재구현한 코드는 원본 x86에 대한 3,205개 테스트 케이스를 통과했으며, 컴파일된 함수의 63바이트 전체를 재현합니다.
|
사운드 호출에서 위치를 패닝 값으로 변환하는 보조 함수까지 추적하고, 명령을 검사하여 불완전한 의사 코드를 C로 옮깁니다. 재구현한 코드는 원본 x86에 대한 3,205개 테스트 케이스를 통과했으며, 컴파일된 함수의 63바이트 전체를 재현합니다.
|
||||||
|
|
||||||
[사례 읽기](https://rea.tools/ko/showcase/dx-ball/) ·
|
[사례 읽기](https://rea.tools/showcase/dx-ball/) ·
|
||||||
[재구현 저장소](https://github.com/N0zoM1z0/dx-ball)
|
[재구현 저장소](https://github.com/N0zoM1z0/dx-ball)
|
||||||
|
|
||||||
### Notion: Electron 클립보드 브리지 추적
|
### Notion: Electron 클립보드 브리지 추적
|
||||||
|
|
||||||
렌더러의 클립보드 API를 찾고, preload와 IPC를 거쳐 메인 프로세스까지 추적한 뒤, 서식 있는 클립보드 형식을 검사합니다.
|
렌더러의 클립보드 API를 찾고, preload와 IPC를 거쳐 메인 프로세스까지 추적한 뒤, 서식 있는 클립보드 형식을 검사합니다.
|
||||||
|
|
||||||
[사례 읽기](https://rea.tools/ko/showcase/notion/)
|
[사례 읽기](https://rea.tools/showcase/notion/)
|
||||||
|
|
||||||
### TH04: DOS 원형 탄막 계산 복원
|
### TH04: DOS 원형 탄막 계산 복원
|
||||||
|
|
||||||
원본 PC-98 게임의 16비트 명령을 검사하고 고정 각도와 조준 각도의 계산을 복원합니다. 재구현한 C++를 당시 컴파일러의 출력과 비교합니다.
|
원본 PC-98 게임의 16비트 명령을 검사하고 고정 각도와 조준 각도의 계산을 복원합니다. 재구현한 C++를 당시 컴파일러의 출력과 비교합니다.
|
||||||
|
|
||||||
[사례 읽기](https://rea.tools/ko/showcase/th04/) ·
|
[사례 읽기](https://rea.tools/showcase/th04/) ·
|
||||||
[재구현 저장소](https://github.com/N0zoM1z0/th04)
|
[재구현 저장소](https://github.com/N0zoM1z0/th04)
|
||||||
|
|
||||||
REA로 흥미로운 대상을 분석했다면 알려 주세요. [issue](https://github.com/morluto/rea/issues) 또는 [pull request](https://github.com/morluto/rea/pulls)에 대상, 조사하려던 질문, REA가 어떻게 도움이 되었는지, 무엇을 알아냈는지를 담아 공유하세요.
|
REA로 흥미로운 대상을 분석했다면 알려 주세요. [issue](https://github.com/morluto/rea/issues) 또는 [pull request](https://github.com/morluto/rea/pulls)에 대상, 조사하려던 질문, REA가 어떻게 도움이 되었는지, 무엇을 알아냈는지를 담아 공유하세요.
|
||||||
@@ -247,7 +248,7 @@ npx rea-agents@latest setup
|
|||||||
|
|
||||||
## 문서
|
## 문서
|
||||||
|
|
||||||
웹사이트의 [실습 가이드](https://rea.tools/ko/guides/)부터 읽어 보세요. 정확한 옵션, 사전 요구 사항, 결과 계약은 다음 문서를 참고하세요.
|
웹사이트의 [실습 가이드](https://rea.tools/guides/)부터 읽어 보세요. 정확한 옵션, 사전 요구 사항, 결과 계약은 다음 문서를 참고하세요.
|
||||||
|
|
||||||
- [설치 및 설정](docs/installation.md): 에이전트 등록, 제공자 설정, 업데이트, 제거.
|
- [설치 및 설정](docs/installation.md): 에이전트 등록, 제공자 설정, 업데이트, 제거.
|
||||||
- [준비 상태 확인 및 문제 해결](docs/installation.md#check-readiness-for-your-task): 특정 에이전트 또는 분석 엔진 진단.
|
- [준비 상태 확인 및 문제 해결](docs/installation.md#check-readiness-for-your-task): 특정 에이전트 또는 분석 엔진 진단.
|
||||||
@@ -260,7 +261,7 @@ npx rea-agents@latest setup
|
|||||||
|
|
||||||
## 스타 기록
|
## 스타 기록
|
||||||
|
|
||||||
🎉 **GitHub 스타 90,000개, 감사합니다!**
|
🎉 **GitHub 스타 50,000개, 감사합니다!**
|
||||||
|
|
||||||
REA를 사용하고, 버그를 보고하고, 기능을 요청하고, 빌드를 테스트하고, 수정에 기여해 주신 모든 분께 감사드립니다.
|
REA를 사용하고, 버그를 보고하고, 기능을 요청하고, 빌드를 테스트하고, 수정에 기여해 주신 모든 분께 감사드립니다.
|
||||||
|
|
||||||
|
|||||||
+12
-11
@@ -9,6 +9,7 @@
|
|||||||
**Widzisz funkcję, która Ci się podoba? Dowiedz się, jak działa, aż do poziomu kodu binarnego.**
|
**Widzisz funkcję, która Ci się podoba? Dowiedz się, jak działa, aż do poziomu kodu binarnego.**
|
||||||
|
|
||||||
[](https://www.npmjs.com/package/rea-agents)
|
[](https://www.npmjs.com/package/rea-agents)
|
||||||
|
[](https://github.com/morluto/rea/actions/workflows/ci.yml)
|
||||||
[](docs/mcp-contracts.md#generated-catalog)
|
[](docs/mcp-contracts.md#generated-catalog)
|
||||||
[](#current-status)
|
[](#current-status)
|
||||||
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
||||||
@@ -17,7 +18,7 @@
|
|||||||
|
|
||||||
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
||||||
|
|
||||||
**[Strona internetowa](https://rea.tools/pl/) · [Przewodniki](https://rea.tools/pl/guides/) · [Przykłady zastosowań](https://rea.tools/pl/showcase/)**
|
**[Strona internetowa](https://rea.tools/) · [Przewodniki](https://rea.tools/guides/) · [Przykłady zastosowań](https://rea.tools/showcase/)**
|
||||||
|
|
||||||
[Szybki start](#szybki-start) · [Jak działa REA](#jak-działa-rea) · [Co możesz analizować](#co-możesz-analizować) · [Przykłady zastosowań](#przykłady-zastosowań) · [FAQ](#faq) · [Dokumentacja](#dokumentacja)
|
[Szybki start](#szybki-start) · [Jak działa REA](#jak-działa-rea) · [Co możesz analizować](#co-możesz-analizować) · [Przykłady zastosowań](#przykłady-zastosowań) · [FAQ](#faq) · [Dokumentacja](#dokumentacja)
|
||||||
|
|
||||||
@@ -53,7 +54,7 @@ REA łączy Twojego agenta z narzędziami do analizy natywnych plików binarnych
|
|||||||
|
|
||||||
Konfigurator rejestruje REA w Twoim agencie i instaluje pasujące instrukcje pracy. Analiza kodu natywnego może korzystać z istniejącej instalacji Hoppera lub Ghidry; konfigurator może też zainstalować Hoppera po uzyskaniu zgody. Statyczna analiza JavaScript nie wymaga żadnego z tych silników.
|
Konfigurator rejestruje REA w Twoim agencie i instaluje pasujące instrukcje pracy. Analiza kodu natywnego może korzystać z istniejącej instalacji Hoppera lub Ghidry; konfigurator może też zainstalować Hoppera po uzyskaniu zgody. Statyczna analiza JavaScript nie wymaga żadnego z tych silników.
|
||||||
|
|
||||||
> **[Odwiedź stronę REA](https://rea.tools/pl/)**, aby znaleźć instrukcje konfiguracji, ilustrowane przewodniki i rzeczywiste studia przypadków.
|
> **[Odwiedź stronę REA](https://rea.tools/)**, aby znaleźć instrukcje konfiguracji, ilustrowane przewodniki i rzeczywiste studia przypadków.
|
||||||
|
|
||||||
## Szybki start
|
## Szybki start
|
||||||
|
|
||||||
@@ -132,12 +133,12 @@ REA wymaga Node.js 22.x (>=22.19), 24.x (>=24.11) lub 26+ oraz npm. Dodatkowe na
|
|||||||
|
|
||||||
| Cel | Co zwraca REA | Wymagania i przewodnik |
|
| Cel | Co zwraca REA | Wymagania i przewodnik |
|
||||||
| --------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
|
| --------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| Natywne pliki binarne | Pseudokod, kod asemblera, ciągi znaków, symbole, wywołania i odwołania | Hopper, Ghidra lub IDA; [analiza kodu natywnego](https://rea.tools/pl/guides/native/) |
|
| Natywne pliki binarne | Pseudokod, kod asemblera, ciągi znaków, symbole, wywołania i odwołania | Hopper, Ghidra lub IDA; [analiza kodu natywnego](https://rea.tools/guides/native/) |
|
||||||
| Układ pliku ELF w trybie offline | Sekcje, segmenty, oryginalne symbole/relokacje i potencjalne mechanizmy zabezpieczeń wskazane przez analizę statyczną | pwntools dostarczone przez użytkownika w systemie Linux x64; [diagnostyka plików binarnych](docs/binary-diagnostics.md) |
|
| Układ pliku ELF w trybie offline | Sekcje, segmenty, oryginalne symbole/relokacje i potencjalne mechanizmy zabezpieczeń wskazane przez analizę statyczną | pwntools dostarczone przez użytkownika w systemie Linux x64; [diagnostyka plików binarnych](docs/binary-diagnostics.md) |
|
||||||
| Kod bajtowy EVM | Selektory wywołań, przesunięcia bajtowe, wywnioskowane argumenty i mutowalność | Lokalny plik z surowymi bajtami lub zapisem szesnastkowym w systemie Linux x64; [przewodnik EVM offline](docs/evm-bytecode.md) |
|
| Kod bajtowy EVM | Selektory wywołań, przesunięcia bajtowe, wywnioskowane argumenty i mutowalność | Lokalny plik z surowymi bajtami lub zapisem szesnastkowym w systemie Linux x64; [przewodnik EVM offline](docs/evm-bytecode.md) |
|
||||||
| Zarejestrowane awarie systemu Linux | Surowe rekordy note, rejestry/sygnały każdego zarejestrowanego wątku i opcjonalni kandydaci na mapowania | pwntools dostarczone przez użytkownika w systemie Linux x64; opcjonalnie GDB/pwndbg; [zarejestrowane awarie](docs/recorded-crashes.md) |
|
| Zarejestrowane awarie systemu Linux | Surowe rekordy note, rejestry/sygnały każdego zarejestrowanego wątku i opcjonalni kandydaci na mapowania | pwntools dostarczone przez użytkownika w systemie Linux x64; opcjonalnie GDB/pwndbg; [zarejestrowane awarie](docs/recorded-crashes.md) |
|
||||||
| JavaScript / Electron | Moduły, importy, mapy źródeł, trasy, IPC i powiązania z natywnymi dodatkami | Node.js i npm; [analiza aplikacji](https://rea.tools/pl/guides/javascript/) |
|
| JavaScript / Electron | Moduły, importy, mapy źródeł, trasy, IPC i powiązania z natywnymi dodatkami | Node.js i npm; [analiza aplikacji](https://rea.tools/guides/javascript/) |
|
||||||
| Strony internetowe | Struktura strony, skrypty, obserwacje sieciowe i zamówione zrzuty ekranu | Przeglądarka z rodziny Chrome; [analiza w przeglądarce](https://rea.tools/pl/guides/browser/) |
|
| Strony internetowe | Struktura strony, skrypty, obserwacje sieciowe i zamówione zrzuty ekranu | Przeglądarka z rodziny Chrome; [analiza w przeglądarce](https://rea.tools/guides/browser/) |
|
||||||
| Zapisane przechwycenia ruchu sieciowego | Żądania, odpowiedzi, dostępne dane przesyłane i lokalizacje źródłowe | HAR; mitmdump w systemie Linux dla natywnych przechwyceń mitmproxy; [przewodnik przechwytywania](docs/web-network-captures.md) |
|
| Zapisane przechwycenia ruchu sieciowego | Żądania, odpowiedzi, dostępne dane przesyłane i lokalizacje źródłowe | HAR; mitmdump w systemie Linux dla natywnych przechwyceń mitmproxy; [przewodnik przechwytywania](docs/web-network-captures.md) |
|
||||||
| Zestawy .NET | Metadane, instrukcje CIL, zadeklarowane zależności natywne i porównania kompilacji | Analiza statyczna; [przewodnik kodu zarządzanego](docs/managed-code-analysis.md) |
|
| Zestawy .NET | Metadane, instrukcje CIL, zadeklarowane zależności natywne i porównania kompilacji | Analiza statyczna; [przewodnik kodu zarządzanego](docs/managed-code-analysis.md) |
|
||||||
| Pakiety APK dla Androida | Deklaracje manifestu, klasy, zdekompilowane metody i odwołania | JADX bez interfejsu graficznego i pełny JDK w systemach Linux/macOS/Windows x64; [przewodnik Androida](docs/android-analysis.md) |
|
| Pakiety APK dla Androida | Deklaracje manifestu, klasy, zdekompilowane metody i odwołania | JADX bez interfejsu graficznego i pełny JDK w systemach Linux/macOS/Windows x64; [przewodnik Androida](docs/android-analysis.md) |
|
||||||
@@ -156,25 +157,25 @@ Obsługiwane formaty natywne i platformy zależą od dostawcy analizy. Zobacz [k
|
|||||||
|
|
||||||
## Przykłady zastosowań
|
## Przykłady zastosowań
|
||||||
|
|
||||||
[](https://rea.tools/pl/showcase/)
|
[](https://rea.tools/showcase/)
|
||||||
|
|
||||||
### DX-Ball: odtworzenie obliczania panoramy dźwięku
|
### DX-Ball: odtworzenie obliczania panoramy dźwięku
|
||||||
|
|
||||||
Prześledź wywołanie dźwięku do funkcji pomocniczej przeliczającej pozycję na panoramę, sprawdź instrukcje i przekształć niepełny pseudokod w C. Odtworzona implementacja przechodzi 3 205 przypadków dla oryginalnego x86 i odtwarza wszystkie 63 bajty skompilowanej funkcji.
|
Prześledź wywołanie dźwięku do funkcji pomocniczej przeliczającej pozycję na panoramę, sprawdź instrukcje i przekształć niepełny pseudokod w C. Odtworzona implementacja przechodzi 3 205 przypadków dla oryginalnego x86 i odtwarza wszystkie 63 bajty skompilowanej funkcji.
|
||||||
|
|
||||||
[Przeczytaj studium przypadku](https://rea.tools/pl/showcase/dx-ball/) · [Repozytorium odtworzonej implementacji](https://github.com/N0zoM1z0/dx-ball)
|
[Przeczytaj studium przypadku](https://rea.tools/showcase/dx-ball/) · [Repozytorium odtworzonej implementacji](https://github.com/N0zoM1z0/dx-ball)
|
||||||
|
|
||||||
### Notion: śledzenie mostu schowka w Electron
|
### Notion: śledzenie mostu schowka w Electron
|
||||||
|
|
||||||
Znajdź API schowka w procesie renderującym, prześledź je przez preload i IPC do procesu głównego, a następnie sprawdź format schowka wraz z danymi formatowania.
|
Znajdź API schowka w procesie renderującym, prześledź je przez preload i IPC do procesu głównego, a następnie sprawdź format schowka wraz z danymi formatowania.
|
||||||
|
|
||||||
[Przeczytaj studium przypadku](https://rea.tools/pl/showcase/notion/)
|
[Przeczytaj studium przypadku](https://rea.tools/showcase/notion/)
|
||||||
|
|
||||||
### TH04: odtworzenie obliczania pierścienia pocisków w DOS-ie
|
### TH04: odtworzenie obliczania pierścienia pocisków w DOS-ie
|
||||||
|
|
||||||
Sprawdź 16-bitowe instrukcje oryginalnej gry na PC-98, odtwórz obliczenia kątów stałych i skierowanych na cel oraz porównaj odtworzony C++ z wynikiem historycznego kompilatora.
|
Sprawdź 16-bitowe instrukcje oryginalnej gry na PC-98, odtwórz obliczenia kątów stałych i skierowanych na cel oraz porównaj odtworzony C++ z wynikiem historycznego kompilatora.
|
||||||
|
|
||||||
[Przeczytaj studium przypadku](https://rea.tools/pl/showcase/th04/) · [Repozytorium odtworzonej implementacji](https://github.com/N0zoM1z0/th04)
|
[Przeczytaj studium przypadku](https://rea.tools/showcase/th04/) · [Repozytorium odtworzonej implementacji](https://github.com/N0zoM1z0/th04)
|
||||||
|
|
||||||
Jeśli użyłeś REA do czegoś ciekawego, chętnie to zobaczymy. Opisz swój przypadek w [zgłoszeniu](https://github.com/morluto/rea/issues) lub [pull requeście](https://github.com/morluto/rea/pulls), podając cel analizy, pytanie, sposób, w jaki REA pomogło, i swoje ustalenia.
|
Jeśli użyłeś REA do czegoś ciekawego, chętnie to zobaczymy. Opisz swój przypadek w [zgłoszeniu](https://github.com/morluto/rea/issues) lub [pull requeście](https://github.com/morluto/rea/pulls), podając cel analizy, pytanie, sposób, w jaki REA pomogło, i swoje ustalenia.
|
||||||
|
|
||||||
@@ -245,7 +246,7 @@ Jeśli używasz agenta, wykonaj [odświeżenie konfiguracji](#zaktualizuj-rea) i
|
|||||||
|
|
||||||
## Dokumentacja
|
## Dokumentacja
|
||||||
|
|
||||||
Zacznij od [przewodników z przykładami](https://rea.tools/pl/guides/) na stronie internetowej. Dokładne opcje, wymagania wstępne i kontrakty wyników opisano tutaj:
|
Zacznij od [przewodników z przykładami](https://rea.tools/guides/) na stronie internetowej. Dokładne opcje, wymagania wstępne i kontrakty wyników opisano tutaj:
|
||||||
|
|
||||||
- [Instalacja i konfiguracja](docs/installation.md): rejestracja agentów, konfiguracja dostawców analizy, aktualizacje i odinstalowanie.
|
- [Instalacja i konfiguracja](docs/installation.md): rejestracja agentów, konfiguracja dostawców analizy, aktualizacje i odinstalowanie.
|
||||||
- [Gotowość i rozwiązywanie problemów](docs/installation.md#check-readiness-for-your-task): diagnostyka jednego agenta lub silnika analizy.
|
- [Gotowość i rozwiązywanie problemów](docs/installation.md#check-readiness-for-your-task): diagnostyka jednego agenta lub silnika analizy.
|
||||||
@@ -258,7 +259,7 @@ Zgłaszaj podatności zgodnie z [SECURITY.md](SECURITY.md).
|
|||||||
|
|
||||||
## Historia gwiazdek
|
## Historia gwiazdek
|
||||||
|
|
||||||
🎉 **90 000 gwiazdek na GitHubie — dziękujemy!**
|
🎉 **50 000 gwiazdek na GitHubie — dziękujemy!**
|
||||||
|
|
||||||
Dziękujemy wszystkim, którzy używają REA, zgłaszają błędy, proponują nowe funkcje, testują kompilacje i przesyłają poprawki.
|
Dziękujemy wszystkim, którzy używają REA, zgłaszają błędy, proponują nowe funkcje, testują kompilacje i przesyłają poprawki.
|
||||||
|
|
||||||
|
|||||||
+12
-11
@@ -9,6 +9,7 @@
|
|||||||
**Viu uma funcionalidade de que gostou? Entenda como ela funciona, até o nível binário.**
|
**Viu uma funcionalidade de que gostou? Entenda como ela funciona, até o nível binário.**
|
||||||
|
|
||||||
[](https://www.npmjs.com/package/rea-agents)
|
[](https://www.npmjs.com/package/rea-agents)
|
||||||
|
[](https://github.com/morluto/rea/actions/workflows/ci.yml)
|
||||||
[](docs/mcp-contracts.md#generated-catalog)
|
[](docs/mcp-contracts.md#generated-catalog)
|
||||||
[](#current-status)
|
[](#current-status)
|
||||||
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
||||||
@@ -17,7 +18,7 @@
|
|||||||
|
|
||||||
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
||||||
|
|
||||||
**[Site](https://rea.tools/pt-BR/) · [Guias](https://rea.tools/pt-BR/guides/) · [Casos de uso](https://rea.tools/pt-BR/showcase/)**
|
**[Site](https://rea.tools/) · [Guias](https://rea.tools/guides/) · [Casos de uso](https://rea.tools/showcase/)**
|
||||||
|
|
||||||
[Início rápido](#início-rápido) · [Como o REA funciona](#como-o-rea-funciona) · [O que você pode analisar](#o-que-você-pode-analisar) · [Casos de uso](#casos-de-uso) · [Perguntas frequentes](#perguntas-frequentes) · [Documentação](#documentação)
|
[Início rápido](#início-rápido) · [Como o REA funciona](#como-o-rea-funciona) · [O que você pode analisar](#o-que-você-pode-analisar) · [Casos de uso](#casos-de-uso) · [Perguntas frequentes](#perguntas-frequentes) · [Documentação](#documentação)
|
||||||
|
|
||||||
@@ -53,7 +54,7 @@ O REA conecta seu agente a ferramentas para inspecionar binários nativos, aplic
|
|||||||
|
|
||||||
A configuração registra o REA no seu agente e instala as instruções de fluxo de trabalho correspondentes. A análise nativa pode usar uma instalação existente do Hopper ou do Ghidra; a configuração também pode instalar o Hopper opcionalmente, mediante aprovação. A análise estática de JavaScript não precisa de nenhum dos dois motores.
|
A configuração registra o REA no seu agente e instala as instruções de fluxo de trabalho correspondentes. A análise nativa pode usar uma instalação existente do Hopper ou do Ghidra; a configuração também pode instalar o Hopper opcionalmente, mediante aprovação. A análise estática de JavaScript não precisa de nenhum dos dois motores.
|
||||||
|
|
||||||
> **[Visite o site do REA](https://rea.tools/pt-BR/)** para instruções de configuração, guias ilustrados e estudos de caso reais.
|
> **[Visite o site do REA](https://rea.tools/)** para instruções de configuração, guias ilustrados e estudos de caso reais.
|
||||||
|
|
||||||
## Início rápido
|
## Início rápido
|
||||||
|
|
||||||
@@ -132,12 +133,12 @@ O REA requer Node.js 22.x (>=22.19), 24.x (>=24.11) ou 26+, além do npm. As fer
|
|||||||
|
|
||||||
| Alvo | O que o REA retorna | Requisitos e guia |
|
| Alvo | O que o REA retorna | Requisitos e guia |
|
||||||
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
|
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| Binários nativos | Pseudocódigo, assembly, strings, símbolos, chamadas e referências | Hopper, Ghidra ou IDA; [análise nativa](https://rea.tools/pt-BR/guides/native/) |
|
| Binários nativos | Pseudocódigo, assembly, strings, símbolos, chamadas e referências | Hopper, Ghidra ou IDA; [análise nativa](https://rea.tools/guides/native/) |
|
||||||
| Estrutura ELF sem execução | Seções, segmentos, símbolos/relocações originais e possíveis mecanismos de mitigação identificados por análise estática | pwntools fornecido pelo chamador no Linux x64; [diagnóstico de binários](docs/binary-diagnostics.md) |
|
| Estrutura ELF sem execução | Seções, segmentos, símbolos/relocações originais e possíveis mecanismos de mitigação identificados por análise estática | pwntools fornecido pelo chamador no Linux x64; [diagnóstico de binários](docs/binary-diagnostics.md) |
|
||||||
| Bytecode EVM | Seletores de despacho, offsets de bytes, argumentos inferidos e mutabilidade | Entrada local com bytes brutos ou representação hexadecimal no Linux x64; [guia de EVM sem execução](docs/evm-bytecode.md) |
|
| Bytecode EVM | Seletores de despacho, offsets de bytes, argumentos inferidos e mutabilidade | Entrada local com bytes brutos ou representação hexadecimal no Linux x64; [guia de EVM sem execução](docs/evm-bytecode.md) |
|
||||||
| Falhas do Linux registradas | Registros note brutos, registradores/sinais de cada thread registrada e candidatos opcionais a mapeamentos | pwntools fornecido pelo chamador no Linux x64; GDB/pwndbg opcionais; [falhas registradas](docs/recorded-crashes.md) |
|
| Falhas do Linux registradas | Registros note brutos, registradores/sinais de cada thread registrada e candidatos opcionais a mapeamentos | pwntools fornecido pelo chamador no Linux x64; GDB/pwndbg opcionais; [falhas registradas](docs/recorded-crashes.md) |
|
||||||
| JavaScript / Electron | Módulos, importações, source maps, rotas, IPC e relações com complementos nativos | Node.js e npm; [análise de aplicativos](https://rea.tools/pt-BR/guides/javascript/) |
|
| JavaScript / Electron | Módulos, importações, source maps, rotas, IPC e relações com complementos nativos | Node.js e npm; [análise de aplicativos](https://rea.tools/guides/javascript/) |
|
||||||
| Sites | Estrutura da página, scripts, observações de rede e capturas de tela solicitadas | Um navegador da família Chrome; [análise do navegador](https://rea.tools/pt-BR/guides/browser/) |
|
| Sites | Estrutura da página, scripts, observações de rede e capturas de tela solicitadas | Um navegador da família Chrome; [análise do navegador](https://rea.tools/guides/browser/) |
|
||||||
| Capturas de rede salvas | Requisições, respostas, payloads acessíveis e localizações de origem | HAR; mitmdump no Linux para capturas no formato nativo do mitmproxy; [guia de capturas](docs/web-network-captures.md) |
|
| Capturas de rede salvas | Requisições, respostas, payloads acessíveis e localizações de origem | HAR; mitmdump no Linux para capturas no formato nativo do mitmproxy; [guia de capturas](docs/web-network-captures.md) |
|
||||||
| Assemblies .NET | Metadados, instruções CIL, dependências nativas declaradas e comparações de builds | Inspeção estática; [guia de código gerenciado](docs/managed-code-analysis.md) |
|
| Assemblies .NET | Metadados, instruções CIL, dependências nativas declaradas e comparações de builds | Inspeção estática; [guia de código gerenciado](docs/managed-code-analysis.md) |
|
||||||
| APKs Android | Declarações do manifesto, classes, métodos descompilados e referências | JADX sem interface gráfica e um JDK completo no Linux/macOS/Windows x64; [guia de Android](docs/android-analysis.md) |
|
| APKs Android | Declarações do manifesto, classes, métodos descompilados e referências | JADX sem interface gráfica e um JDK completo no Linux/macOS/Windows x64; [guia de Android](docs/android-analysis.md) |
|
||||||
@@ -156,25 +157,25 @@ Os formatos nativos e os sistemas anfitriões compatíveis variam por provedor.
|
|||||||
|
|
||||||
## Casos de uso
|
## Casos de uso
|
||||||
|
|
||||||
[](https://rea.tools/pt-BR/showcase/)
|
[](https://rea.tools/showcase/)
|
||||||
|
|
||||||
### DX-Ball: reconstruir um cálculo de panorâmica de áudio
|
### DX-Ball: reconstruir um cálculo de panorâmica de áudio
|
||||||
|
|
||||||
Siga uma chamada de áudio até a função auxiliar que converte posição em panorâmica, inspecione as instruções e transforme pseudocódigo incompleto em C. A reconstrução passa em 3.205 casos com o x86 original e reproduz todos os 63 bytes da função compilada.
|
Siga uma chamada de áudio até a função auxiliar que converte posição em panorâmica, inspecione as instruções e transforme pseudocódigo incompleto em C. A reconstrução passa em 3.205 casos com o x86 original e reproduz todos os 63 bytes da função compilada.
|
||||||
|
|
||||||
[Leia o estudo de caso](https://rea.tools/pt-BR/showcase/dx-ball/) · [Repositório da reconstrução](https://github.com/N0zoM1z0/dx-ball)
|
[Leia o estudo de caso](https://rea.tools/showcase/dx-ball/) · [Repositório da reconstrução](https://github.com/N0zoM1z0/dx-ball)
|
||||||
|
|
||||||
### Notion: rastrear a ponte da área de transferência do Electron
|
### Notion: rastrear a ponte da área de transferência do Electron
|
||||||
|
|
||||||
Encontre a API da área de transferência do renderizador, siga-a por preload e IPC até o processo principal e inspecione o formato da área de transferência com seus dados de formatação.
|
Encontre a API da área de transferência do renderizador, siga-a por preload e IPC até o processo principal e inspecione o formato da área de transferência com seus dados de formatação.
|
||||||
|
|
||||||
[Leia o estudo de caso](https://rea.tools/pt-BR/showcase/notion/)
|
[Leia o estudo de caso](https://rea.tools/showcase/notion/)
|
||||||
|
|
||||||
### TH04: recuperar o cálculo de um anel de projéteis no DOS
|
### TH04: recuperar o cálculo de um anel de projéteis no DOS
|
||||||
|
|
||||||
Inspecione as instruções de 16 bits do jogo original para PC-98, recupere os cálculos de ângulos fixos e direcionados e compare o C++ reconstruído com a saída do compilador da época.
|
Inspecione as instruções de 16 bits do jogo original para PC-98, recupere os cálculos de ângulos fixos e direcionados e compare o C++ reconstruído com a saída do compilador da época.
|
||||||
|
|
||||||
[Leia o estudo de caso](https://rea.tools/pt-BR/showcase/th04/) · [Repositório da reconstrução](https://github.com/N0zoM1z0/th04)
|
[Leia o estudo de caso](https://rea.tools/showcase/th04/) · [Repositório da reconstrução](https://github.com/N0zoM1z0/th04)
|
||||||
|
|
||||||
Se você usou o REA em algo interessante, gostaríamos de conhecer. Compartilhe seu caso em uma [issue](https://github.com/morluto/rea/issues) ou um [pull request](https://github.com/morluto/rea/pulls), incluindo o alvo, sua pergunta, como o REA ajudou e o que descobriu.
|
Se você usou o REA em algo interessante, gostaríamos de conhecer. Compartilhe seu caso em uma [issue](https://github.com/morluto/rea/issues) ou um [pull request](https://github.com/morluto/rea/pulls), incluindo o alvo, sua pergunta, como o REA ajudou e o que descobriu.
|
||||||
|
|
||||||
@@ -245,7 +246,7 @@ Se você usa um agente, conclua a [atualização da configuração](#atualize-o-
|
|||||||
|
|
||||||
## Documentação
|
## Documentação
|
||||||
|
|
||||||
Comece pelos [guias práticos](https://rea.tools/pt-BR/guides/) do site. Para opções exatas, pré-requisitos e contratos dos resultados:
|
Comece pelos [guias práticos](https://rea.tools/guides/) do site. Para opções exatas, pré-requisitos e contratos dos resultados:
|
||||||
|
|
||||||
- [Instalação e configuração](docs/installation.md): registro de agentes, configuração de provedores, atualizações e desinstalação.
|
- [Instalação e configuração](docs/installation.md): registro de agentes, configuração de provedores, atualizações e desinstalação.
|
||||||
- [Prontidão e solução de problemas](docs/installation.md#check-readiness-for-your-task): diagnóstico de um agente ou motor de análise específico.
|
- [Prontidão e solução de problemas](docs/installation.md#check-readiness-for-your-task): diagnóstico de um agente ou motor de análise específico.
|
||||||
@@ -258,7 +259,7 @@ Relate vulnerabilidades conforme [SECURITY.md](SECURITY.md).
|
|||||||
|
|
||||||
## Histórico de estrelas
|
## Histórico de estrelas
|
||||||
|
|
||||||
🎉 **90.000 estrelas no GitHub — muito obrigado!**
|
🎉 **50.000 estrelas no GitHub — muito obrigado!**
|
||||||
|
|
||||||
Obrigado a todos que usam o REA, relatam bugs, sugerem funcionalidades, testam builds e contribuem com correções.
|
Obrigado a todos que usam o REA, relatam bugs, sugerem funcionalidades, testam builds e contribuem com correções.
|
||||||
|
|
||||||
|
|||||||
+12
-11
@@ -9,6 +9,7 @@
|
|||||||
**Нашли интересную функцию? Разберитесь, как она работает, вплоть до двоичного кода.**
|
**Нашли интересную функцию? Разберитесь, как она работает, вплоть до двоичного кода.**
|
||||||
|
|
||||||
[](https://www.npmjs.com/package/rea-agents)
|
[](https://www.npmjs.com/package/rea-agents)
|
||||||
|
[](https://github.com/morluto/rea/actions/workflows/ci.yml)
|
||||||
[](docs/mcp-contracts.md#generated-catalog)
|
[](docs/mcp-contracts.md#generated-catalog)
|
||||||
[](#current-status)
|
[](#current-status)
|
||||||
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
||||||
@@ -17,7 +18,7 @@
|
|||||||
|
|
||||||
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
||||||
|
|
||||||
**[Сайт](https://rea.tools/ru/) · [Руководства](https://rea.tools/ru/guides/) · [Примеры](https://rea.tools/ru/showcase/)**
|
**[Сайт](https://rea.tools/) · [Руководства](https://rea.tools/guides/) · [Примеры](https://rea.tools/showcase/)**
|
||||||
|
|
||||||
[Быстрый старт](#быстрый-старт) · [Как работает REA](#как-работает-rea) · [Что можно анализировать](#что-можно-анализировать) · [Примеры](#примеры) · [Частые вопросы](#частые-вопросы) · [Документация](#документация)
|
[Быстрый старт](#быстрый-старт) · [Как работает REA](#как-работает-rea) · [Что можно анализировать](#что-можно-анализировать) · [Примеры](#примеры) · [Частые вопросы](#частые-вопросы) · [Документация](#документация)
|
||||||
|
|
||||||
@@ -53,7 +54,7 @@ REA подключает вашего агента к инструментам
|
|||||||
|
|
||||||
Настройка регистрирует REA в вашем агенте и устанавливает соответствующие инструкции по работе. Для нативного анализа можно использовать уже установленный Hopper или Ghidra; настройка также может установить Hopper с вашего согласия. Для статического анализа JavaScript не нужен ни один из этих движков.
|
Настройка регистрирует REA в вашем агенте и устанавливает соответствующие инструкции по работе. Для нативного анализа можно использовать уже установленный Hopper или Ghidra; настройка также может установить Hopper с вашего согласия. Для статического анализа JavaScript не нужен ни один из этих движков.
|
||||||
|
|
||||||
> **[Посетите сайт REA](https://rea.tools/ru/)**: там есть инструкции по настройке, иллюстрированные руководства и реальные исследования.
|
> **[Посетите сайт REA](https://rea.tools/)**: там есть инструкции по настройке, иллюстрированные руководства и реальные исследования.
|
||||||
|
|
||||||
## Быстрый старт
|
## Быстрый старт
|
||||||
|
|
||||||
@@ -132,12 +133,12 @@ REA требует Node.js 22.x (>=22.19), 24.x (>=24.11) или 26+, а так
|
|||||||
|
|
||||||
| Цель | Что возвращает REA | Требования и руководство |
|
| Цель | Что возвращает REA | Требования и руководство |
|
||||||
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
|
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| Нативные бинарные файлы | Псевдокод, ассемблер, строки, символы, вызовы и ссылки | Hopper, Ghidra или IDA; [нативный анализ](https://rea.tools/ru/guides/native/) |
|
| Нативные бинарные файлы | Псевдокод, ассемблер, строки, символы, вызовы и ссылки | Hopper, Ghidra или IDA; [нативный анализ](https://rea.tools/guides/native/) |
|
||||||
| Структура ELF без запуска | Секции, сегменты, исходные символы/релокации и возможные механизмы защиты по данным статического анализа | pwntools, предоставленный вызывающей стороной, в Linux x64; [диагностика бинарных файлов](docs/binary-diagnostics.md) |
|
| Структура ELF без запуска | Секции, сегменты, исходные символы/релокации и возможные механизмы защиты по данным статического анализа | pwntools, предоставленный вызывающей стороной, в Linux x64; [диагностика бинарных файлов](docs/binary-diagnostics.md) |
|
||||||
| Байт-код EVM | Селекторы диспетчеризации, смещения байтов, предполагаемые аргументы и изменяемость состояния | Локальные необработанные байты или шестнадцатеричное представление в Linux x64; [руководство по EVM без запуска](docs/evm-bytecode.md) |
|
| Байт-код EVM | Селекторы диспетчеризации, смещения байтов, предполагаемые аргументы и изменяемость состояния | Локальные необработанные байты или шестнадцатеричное представление в Linux x64; [руководство по EVM без запуска](docs/evm-bytecode.md) |
|
||||||
| Записанные сбои Linux | Необработанные записи note, регистры/сигналы каждого записанного потока и необязательные кандидаты сопоставления с памятью | pwntools, предоставленный вызывающей стороной, в Linux x64; необязательные GDB/pwndbg; [записанные сбои](docs/recorded-crashes.md) |
|
| Записанные сбои Linux | Необработанные записи note, регистры/сигналы каждого записанного потока и необязательные кандидаты сопоставления с памятью | pwntools, предоставленный вызывающей стороной, в Linux x64; необязательные GDB/pwndbg; [записанные сбои](docs/recorded-crashes.md) |
|
||||||
| JavaScript / Electron | Модули, импорты, карты исходного кода, маршруты, IPC и связи с нативными дополнениями | Node.js и npm; [анализ приложений](https://rea.tools/ru/guides/javascript/) |
|
| JavaScript / Electron | Модули, импорты, карты исходного кода, маршруты, IPC и связи с нативными дополнениями | Node.js и npm; [анализ приложений](https://rea.tools/guides/javascript/) |
|
||||||
| Сайты | Структура страницы, скрипты, наблюдения за сетью и запрошенные снимки экрана | Браузер семейства Chrome; [анализ браузера](https://rea.tools/ru/guides/browser/) |
|
| Сайты | Структура страницы, скрипты, наблюдения за сетью и запрошенные снимки экрана | Браузер семейства Chrome; [анализ браузера](https://rea.tools/guides/browser/) |
|
||||||
| Сохранённые сетевые захваты | Запросы, ответы, доступные полезные данные и позиции в источнике | HAR; mitmdump в Linux для захватов в собственном формате mitmproxy; [руководство по сетевым захватам](docs/web-network-captures.md) |
|
| Сохранённые сетевые захваты | Запросы, ответы, доступные полезные данные и позиции в источнике | HAR; mitmdump в Linux для захватов в собственном формате mitmproxy; [руководство по сетевым захватам](docs/web-network-captures.md) |
|
||||||
| Сборки .NET | Метаданные, инструкции CIL, объявленные нативные зависимости и сравнения сборок | Статическое исследование; [руководство по управляемому коду](docs/managed-code-analysis.md) |
|
| Сборки .NET | Метаданные, инструкции CIL, объявленные нативные зависимости и сравнения сборок | Статическое исследование; [руководство по управляемому коду](docs/managed-code-analysis.md) |
|
||||||
| Android APK | Объявления манифеста, классы, декомпилированные методы и ссылки | JADX без графического интерфейса и полный JDK в Linux/macOS/Windows x64; [руководство по Android](docs/android-analysis.md) |
|
| Android APK | Объявления манифеста, классы, декомпилированные методы и ссылки | JADX без графического интерфейса и полный JDK в Linux/macOS/Windows x64; [руководство по Android](docs/android-analysis.md) |
|
||||||
@@ -156,25 +157,25 @@ REA требует Node.js 22.x (>=22.19), 24.x (>=24.11) или 26+, а так
|
|||||||
|
|
||||||
## Примеры
|
## Примеры
|
||||||
|
|
||||||
[](https://rea.tools/ru/showcase/)
|
[](https://rea.tools/showcase/)
|
||||||
|
|
||||||
### DX-Ball: восстановление расчёта звуковой панорамы
|
### DX-Ball: восстановление расчёта звуковой панорамы
|
||||||
|
|
||||||
Проследите звуковой вызов до функции, преобразующей координату в значение панорамы, изучите инструкции и превратите неполный псевдокод в C. Восстановленная реализация проходит 3 205 тестов с исходным x86-кодом и воспроизводит все 63 байта скомпилированной функции.
|
Проследите звуковой вызов до функции, преобразующей координату в значение панорамы, изучите инструкции и превратите неполный псевдокод в C. Восстановленная реализация проходит 3 205 тестов с исходным x86-кодом и воспроизводит все 63 байта скомпилированной функции.
|
||||||
|
|
||||||
[Прочитать исследование](https://rea.tools/ru/showcase/dx-ball/) · [Репозиторий реконструкции](https://github.com/N0zoM1z0/dx-ball)
|
[Прочитать исследование](https://rea.tools/showcase/dx-ball/) · [Репозиторий реконструкции](https://github.com/N0zoM1z0/dx-ball)
|
||||||
|
|
||||||
### Notion: исследование моста буфера обмена Electron
|
### Notion: исследование моста буфера обмена Electron
|
||||||
|
|
||||||
Найдите API буфера обмена в процессе рендеринга, проследите его через preload и IPC до основного процесса и изучите формат буфера обмена с форматированием.
|
Найдите API буфера обмена в процессе рендеринга, проследите его через preload и IPC до основного процесса и изучите формат буфера обмена с форматированием.
|
||||||
|
|
||||||
[Прочитать исследование](https://rea.tools/ru/showcase/notion/)
|
[Прочитать исследование](https://rea.tools/showcase/notion/)
|
||||||
|
|
||||||
### TH04: восстановление расчёта кольца пуль в DOS
|
### TH04: восстановление расчёта кольца пуль в DOS
|
||||||
|
|
||||||
Изучите 16-битные инструкции оригинальной игры для PC-98, восстановите расчёты фиксированных и прицельных углов и сравните восстановленный C++ с выводом компилятора того времени.
|
Изучите 16-битные инструкции оригинальной игры для PC-98, восстановите расчёты фиксированных и прицельных углов и сравните восстановленный C++ с выводом компилятора того времени.
|
||||||
|
|
||||||
[Прочитать исследование](https://rea.tools/ru/showcase/th04/) · [Репозиторий реконструкции](https://github.com/N0zoM1z0/th04)
|
[Прочитать исследование](https://rea.tools/showcase/th04/) · [Репозиторий реконструкции](https://github.com/N0zoM1z0/th04)
|
||||||
|
|
||||||
Если вы исследовали с REA что-то интересное, поделитесь результатом. Создайте [issue](https://github.com/morluto/rea/issues) или [pull request](https://github.com/morluto/rea/pulls) и укажите цель, ваш вопрос, как помог REA и что удалось узнать.
|
Если вы исследовали с REA что-то интересное, поделитесь результатом. Создайте [issue](https://github.com/morluto/rea/issues) или [pull request](https://github.com/morluto/rea/pulls) и укажите цель, ваш вопрос, как помог REA и что удалось узнать.
|
||||||
|
|
||||||
@@ -245,7 +246,7 @@ npx rea-agents@latest setup
|
|||||||
|
|
||||||
## Документация
|
## Документация
|
||||||
|
|
||||||
Начните с [практических руководств](https://rea.tools/ru/guides/) на сайте. Точные параметры, требования и контракты результатов описаны здесь:
|
Начните с [практических руководств](https://rea.tools/guides/) на сайте. Точные параметры, требования и контракты результатов описаны здесь:
|
||||||
|
|
||||||
- [Установка и настройка](docs/installation.md): регистрация агентов, настройка провайдеров, обновление и удаление.
|
- [Установка и настройка](docs/installation.md): регистрация агентов, настройка провайдеров, обновление и удаление.
|
||||||
- [Готовность и устранение неполадок](docs/installation.md#check-readiness-for-your-task): диагностика конкретного агента или движка анализа.
|
- [Готовность и устранение неполадок](docs/installation.md#check-readiness-for-your-task): диагностика конкретного агента или движка анализа.
|
||||||
@@ -258,7 +259,7 @@ npx rea-agents@latest setup
|
|||||||
|
|
||||||
## История звёзд
|
## История звёзд
|
||||||
|
|
||||||
🎉 **90 000 звёзд на GitHub — спасибо!**
|
🎉 **50 000 звёзд на GitHub — спасибо!**
|
||||||
|
|
||||||
Спасибо всем, кто использует REA, сообщает об ошибках, предлагает новые функции, тестирует сборки и помогает с исправлениями.
|
Спасибо всем, кто использует REA, сообщает об ошибках, предлагает новые функции, тестирует сборки и помогает с исправлениями.
|
||||||
|
|
||||||
|
|||||||
+12
-11
@@ -9,6 +9,7 @@
|
|||||||
**เห็นฟีเจอร์ที่ชอบแล้วอยากรู้ว่าทำงานอย่างไร? เข้าใจได้ลึกถึงระดับไบนารี**
|
**เห็นฟีเจอร์ที่ชอบแล้วอยากรู้ว่าทำงานอย่างไร? เข้าใจได้ลึกถึงระดับไบนารี**
|
||||||
|
|
||||||
[](https://www.npmjs.com/package/rea-agents)
|
[](https://www.npmjs.com/package/rea-agents)
|
||||||
|
[](https://github.com/morluto/rea/actions/workflows/ci.yml)
|
||||||
[](docs/mcp-contracts.md#generated-catalog)
|
[](docs/mcp-contracts.md#generated-catalog)
|
||||||
[](#current-status)
|
[](#current-status)
|
||||||
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
||||||
@@ -17,7 +18,7 @@
|
|||||||
|
|
||||||
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
||||||
|
|
||||||
**[เว็บไซต์](https://rea.tools/th/) · [คู่มือ](https://rea.tools/th/guides/) · [ตัวอย่างการใช้งาน](https://rea.tools/th/showcase/)**
|
**[เว็บไซต์](https://rea.tools/) · [คู่มือ](https://rea.tools/guides/) · [ตัวอย่างการใช้งาน](https://rea.tools/showcase/)**
|
||||||
|
|
||||||
[เริ่มต้นอย่างรวดเร็ว](#เริ่มต้นอย่างรวดเร็ว) · [REA ทำงานอย่างไร](#rea-ทำงานอย่างไร) · [สิ่งที่วิเคราะห์ได้](#สิ่งที่วิเคราะห์ได้) · [ตัวอย่างการใช้งาน](#ตัวอย่างการใช้งาน) · [คำถามที่พบบ่อย](#คำถามที่พบบ่อย) · [เอกสาร](#เอกสาร)
|
[เริ่มต้นอย่างรวดเร็ว](#เริ่มต้นอย่างรวดเร็ว) · [REA ทำงานอย่างไร](#rea-ทำงานอย่างไร) · [สิ่งที่วิเคราะห์ได้](#สิ่งที่วิเคราะห์ได้) · [ตัวอย่างการใช้งาน](#ตัวอย่างการใช้งาน) · [คำถามที่พบบ่อย](#คำถามที่พบบ่อย) · [เอกสาร](#เอกสาร)
|
||||||
|
|
||||||
@@ -53,7 +54,7 @@ REA เชื่อมเอเจนต์ของคุณกับเคร
|
|||||||
|
|
||||||
ขั้นตอนตั้งค่าจะลงทะเบียน REA กับเอเจนต์และติดตั้งคำแนะนำการทำงานที่ตรงกัน การวิเคราะห์เนทีฟใช้ Hopper หรือ Ghidra ที่ติดตั้งอยู่แล้วได้ และขั้นตอนตั้งค่าสามารถติดตั้ง Hopper เพิ่มเติมเมื่อได้รับอนุมัติ การวิเคราะห์ JavaScript แบบสถิตไม่ต้องใช้เอนจินทั้งสองนี้
|
ขั้นตอนตั้งค่าจะลงทะเบียน REA กับเอเจนต์และติดตั้งคำแนะนำการทำงานที่ตรงกัน การวิเคราะห์เนทีฟใช้ Hopper หรือ Ghidra ที่ติดตั้งอยู่แล้วได้ และขั้นตอนตั้งค่าสามารถติดตั้ง Hopper เพิ่มเติมเมื่อได้รับอนุมัติ การวิเคราะห์ JavaScript แบบสถิตไม่ต้องใช้เอนจินทั้งสองนี้
|
||||||
|
|
||||||
> **[เยี่ยมชมเว็บไซต์ REA](https://rea.tools/th/)** เพื่อดูคำแนะนำการตั้งค่า คู่มือพร้อมภาพประกอบ และกรณีศึกษาจริง
|
> **[เยี่ยมชมเว็บไซต์ REA](https://rea.tools/)** เพื่อดูคำแนะนำการตั้งค่า คู่มือพร้อมภาพประกอบ และกรณีศึกษาจริง
|
||||||
|
|
||||||
## เริ่มต้นอย่างรวดเร็ว
|
## เริ่มต้นอย่างรวดเร็ว
|
||||||
|
|
||||||
@@ -132,12 +133,12 @@ REA ต้องใช้ Node.js 22.x (>=22.19), 24.x (>=24.11) หรือ 26
|
|||||||
|
|
||||||
| เป้าหมาย | สิ่งที่ REA ส่งกลับ | ข้อกำหนดและคู่มือ |
|
| เป้าหมาย | สิ่งที่ REA ส่งกลับ | ข้อกำหนดและคู่มือ |
|
||||||
| ---------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
|
| ---------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
|
||||||
| ไบนารีเนทีฟ | โค้ดเทียม แอสเซมบลี สตริง สัญลักษณ์ การเรียก และการอ้างอิง | Hopper, Ghidra หรือ IDA; [การวิเคราะห์เนทีฟ](https://rea.tools/th/guides/native/) |
|
| ไบนารีเนทีฟ | โค้ดเทียม แอสเซมบลี สตริง สัญลักษณ์ การเรียก และการอ้างอิง | Hopper, Ghidra หรือ IDA; [การวิเคราะห์เนทีฟ](https://rea.tools/guides/native/) |
|
||||||
| โครงสร้าง ELF แบบออฟไลน์ | เซกชัน เซกเมนต์ สัญลักษณ์/รีโลเคชันต้นฉบับ และตัวเลือกกลไกป้องกันที่พบจากการวิเคราะห์แบบสถิต | pwntools ที่ผู้ใช้จัดเตรียมบน Linux x64; [การวินิจฉัยไบนารี](docs/binary-diagnostics.md) |
|
| โครงสร้าง ELF แบบออฟไลน์ | เซกชัน เซกเมนต์ สัญลักษณ์/รีโลเคชันต้นฉบับ และตัวเลือกกลไกป้องกันที่พบจากการวิเคราะห์แบบสถิต | pwntools ที่ผู้ใช้จัดเตรียมบน Linux x64; [การวินิจฉัยไบนารี](docs/binary-diagnostics.md) |
|
||||||
| ไบต์โค้ด EVM | ตัวเลือกฟังก์ชันสำหรับการเรียก ออฟเซ็ตไบต์ อาร์กิวเมนต์และความสามารถในการเปลี่ยนสถานะที่อนุมานได้ | ไฟล์บนเครื่องที่มีไบต์ดิบหรือข้อมูลเลขฐานสิบหกบน Linux x64; [คู่มือ EVM แบบออฟไลน์](docs/evm-bytecode.md) |
|
| ไบต์โค้ด EVM | ตัวเลือกฟังก์ชันสำหรับการเรียก ออฟเซ็ตไบต์ อาร์กิวเมนต์และความสามารถในการเปลี่ยนสถานะที่อนุมานได้ | ไฟล์บนเครื่องที่มีไบต์ดิบหรือข้อมูลเลขฐานสิบหกบน Linux x64; [คู่มือ EVM แบบออฟไลน์](docs/evm-bytecode.md) |
|
||||||
| ข้อมูลการแครชของ Linux ที่บันทึกไว้ | ระเบียน note ดิบ รีจิสเตอร์/สัญญาณของทุกเธรดที่บันทึกไว้ และตัวเลือกการแมปเพิ่มเติม | pwntools ที่ผู้ใช้จัดเตรียมบน Linux x64; เลือกใช้ GDB/pwndbg เพิ่มเติมได้; [การแครชที่บันทึกไว้](docs/recorded-crashes.md) |
|
| ข้อมูลการแครชของ Linux ที่บันทึกไว้ | ระเบียน note ดิบ รีจิสเตอร์/สัญญาณของทุกเธรดที่บันทึกไว้ และตัวเลือกการแมปเพิ่มเติม | pwntools ที่ผู้ใช้จัดเตรียมบน Linux x64; เลือกใช้ GDB/pwndbg เพิ่มเติมได้; [การแครชที่บันทึกไว้](docs/recorded-crashes.md) |
|
||||||
| JavaScript / Electron | โมดูล การนำเข้า ซอร์สแมป เส้นทาง IPC และความสัมพันธ์กับส่วนเสริมเนทีฟ | Node.js และ npm; [การวิเคราะห์แอปพลิเคชัน](https://rea.tools/th/guides/javascript/) |
|
| JavaScript / Electron | โมดูล การนำเข้า ซอร์สแมป เส้นทาง IPC และความสัมพันธ์กับส่วนเสริมเนทีฟ | Node.js และ npm; [การวิเคราะห์แอปพลิเคชัน](https://rea.tools/guides/javascript/) |
|
||||||
| เว็บไซต์ | โครงสร้างหน้า สคริปต์ ข้อมูลเครือข่ายที่สังเกตได้ และภาพหน้าจอที่ร้องขอ | เบราว์เซอร์ในตระกูล Chrome; [การวิเคราะห์ผ่านเบราว์เซอร์](https://rea.tools/th/guides/browser/) |
|
| เว็บไซต์ | โครงสร้างหน้า สคริปต์ ข้อมูลเครือข่ายที่สังเกตได้ และภาพหน้าจอที่ร้องขอ | เบราว์เซอร์ในตระกูล Chrome; [การวิเคราะห์ผ่านเบราว์เซอร์](https://rea.tools/guides/browser/) |
|
||||||
| ข้อมูลเครือข่ายที่บันทึกไว้ | คำขอ คำตอบ เพย์โหลดที่ปรากฏ และตำแหน่งต้นทาง | HAR; mitmdump บน Linux สำหรับข้อมูลที่บันทึกในรูปแบบเนทีฟของ mitmproxy; [คู่มือการบันทึกข้อมูล](docs/web-network-captures.md) |
|
| ข้อมูลเครือข่ายที่บันทึกไว้ | คำขอ คำตอบ เพย์โหลดที่ปรากฏ และตำแหน่งต้นทาง | HAR; mitmdump บน Linux สำหรับข้อมูลที่บันทึกในรูปแบบเนทีฟของ mitmproxy; [คู่มือการบันทึกข้อมูล](docs/web-network-captures.md) |
|
||||||
| แอสเซมบลี .NET | เมทาดาทา คำสั่ง CIL การพึ่งพาเนทีฟที่ประกาศไว้ และการเปรียบเทียบผลการบิลด์ | การตรวจสอบแบบสถิต; [คู่มือโค้ดแบบจัดการ](docs/managed-code-analysis.md) |
|
| แอสเซมบลี .NET | เมทาดาทา คำสั่ง CIL การพึ่งพาเนทีฟที่ประกาศไว้ และการเปรียบเทียบผลการบิลด์ | การตรวจสอบแบบสถิต; [คู่มือโค้ดแบบจัดการ](docs/managed-code-analysis.md) |
|
||||||
| APK ของ Android | การประกาศใน manifest คลาส เมธอดที่ดีคอมไพล์ และการอ้างอิง | JADX แบบไม่มี GUI และ JDK แบบเต็มบน Linux/macOS/Windows x64; [คู่มือ Android](docs/android-analysis.md) |
|
| APK ของ Android | การประกาศใน manifest คลาส เมธอดที่ดีคอมไพล์ และการอ้างอิง | JADX แบบไม่มี GUI และ JDK แบบเต็มบน Linux/macOS/Windows x64; [คู่มือ Android](docs/android-analysis.md) |
|
||||||
@@ -156,25 +157,25 @@ REA ต้องใช้ Node.js 22.x (>=22.19), 24.x (>=24.11) หรือ 26
|
|||||||
|
|
||||||
## ตัวอย่างการใช้งาน
|
## ตัวอย่างการใช้งาน
|
||||||
|
|
||||||
[](https://rea.tools/th/showcase/)
|
[](https://rea.tools/showcase/)
|
||||||
|
|
||||||
### DX-Ball: สร้างการคำนวณแพนเสียงขึ้นใหม่
|
### DX-Ball: สร้างการคำนวณแพนเสียงขึ้นใหม่
|
||||||
|
|
||||||
ติดตามการเรียกเสียงไปยังฟังก์ชันช่วยแปลงตำแหน่งเป็นค่าแพน ตรวจสอบคำสั่ง และแปลงโค้ดเทียมที่ยังไม่สมบูรณ์เป็น C การสร้างขึ้นใหม่นี้ผ่านการทดสอบ 3,205 กรณีเทียบกับ x86 ต้นฉบับ และสร้างไบต์ทั้ง 63 ไบต์ของฟังก์ชันที่คอมไพล์แล้วได้ตรงกัน
|
ติดตามการเรียกเสียงไปยังฟังก์ชันช่วยแปลงตำแหน่งเป็นค่าแพน ตรวจสอบคำสั่ง และแปลงโค้ดเทียมที่ยังไม่สมบูรณ์เป็น C การสร้างขึ้นใหม่นี้ผ่านการทดสอบ 3,205 กรณีเทียบกับ x86 ต้นฉบับ และสร้างไบต์ทั้ง 63 ไบต์ของฟังก์ชันที่คอมไพล์แล้วได้ตรงกัน
|
||||||
|
|
||||||
[อ่านกรณีศึกษา](https://rea.tools/th/showcase/dx-ball/) · [รีโพซิทอรีการสร้างขึ้นใหม่](https://github.com/N0zoM1z0/dx-ball)
|
[อ่านกรณีศึกษา](https://rea.tools/showcase/dx-ball/) · [รีโพซิทอรีการสร้างขึ้นใหม่](https://github.com/N0zoM1z0/dx-ball)
|
||||||
|
|
||||||
### Notion: ติดตามบริดจ์คลิปบอร์ดของ Electron
|
### Notion: ติดตามบริดจ์คลิปบอร์ดของ Electron
|
||||||
|
|
||||||
ค้นหา API คลิปบอร์ดของ renderer ติดตามผ่าน preload และ IPC ไปยังโปรเซสหลัก แล้วตรวจสอบรูปแบบคลิปบอร์ดที่มีข้อมูลการจัดรูปแบบ
|
ค้นหา API คลิปบอร์ดของ renderer ติดตามผ่าน preload และ IPC ไปยังโปรเซสหลัก แล้วตรวจสอบรูปแบบคลิปบอร์ดที่มีข้อมูลการจัดรูปแบบ
|
||||||
|
|
||||||
[อ่านกรณีศึกษา](https://rea.tools/th/showcase/notion/)
|
[อ่านกรณีศึกษา](https://rea.tools/showcase/notion/)
|
||||||
|
|
||||||
### TH04: กู้คืนการคำนวณวงแหวนกระสุนของ DOS
|
### TH04: กู้คืนการคำนวณวงแหวนกระสุนของ DOS
|
||||||
|
|
||||||
ตรวจสอบคำสั่ง 16 บิตของเกมต้นฉบับบน PC-98 กู้คืนการคำนวณมุมคงที่และมุมเล็งเป้าหมาย แล้วเปรียบเทียบ C++ ที่สร้างขึ้นใหม่กับผลลัพธ์จากคอมไพเลอร์ในยุคนั้น
|
ตรวจสอบคำสั่ง 16 บิตของเกมต้นฉบับบน PC-98 กู้คืนการคำนวณมุมคงที่และมุมเล็งเป้าหมาย แล้วเปรียบเทียบ C++ ที่สร้างขึ้นใหม่กับผลลัพธ์จากคอมไพเลอร์ในยุคนั้น
|
||||||
|
|
||||||
[อ่านกรณีศึกษา](https://rea.tools/th/showcase/th04/) · [รีโพซิทอรีการสร้างขึ้นใหม่](https://github.com/N0zoM1z0/th04)
|
[อ่านกรณีศึกษา](https://rea.tools/showcase/th04/) · [รีโพซิทอรีการสร้างขึ้นใหม่](https://github.com/N0zoM1z0/th04)
|
||||||
|
|
||||||
หากคุณใช้ REA กับสิ่งที่น่าสนใจ เราอยากเห็นผลงานของคุณ แบ่งปันกรณีของคุณผ่าน [issue](https://github.com/morluto/rea/issues) หรือ [pull request](https://github.com/morluto/rea/pulls) พร้อมระบุเป้าหมาย คำถามของคุณ REA ช่วยอย่างไร และสิ่งที่คุณค้นพบ
|
หากคุณใช้ REA กับสิ่งที่น่าสนใจ เราอยากเห็นผลงานของคุณ แบ่งปันกรณีของคุณผ่าน [issue](https://github.com/morluto/rea/issues) หรือ [pull request](https://github.com/morluto/rea/pulls) พร้อมระบุเป้าหมาย คำถามของคุณ REA ช่วยอย่างไร และสิ่งที่คุณค้นพบ
|
||||||
|
|
||||||
@@ -245,7 +246,7 @@ npx rea-agents@latest setup
|
|||||||
|
|
||||||
## เอกสาร
|
## เอกสาร
|
||||||
|
|
||||||
เริ่มจาก[คู่มือพร้อมตัวอย่าง](https://rea.tools/th/guides/) บนเว็บไซต์ สำหรับตัวเลือก ข้อกำหนดเบื้องต้น และสัญญาผลลัพธ์ที่แน่นอน:
|
เริ่มจาก[คู่มือพร้อมตัวอย่าง](https://rea.tools/guides/) บนเว็บไซต์ สำหรับตัวเลือก ข้อกำหนดเบื้องต้น และสัญญาผลลัพธ์ที่แน่นอน:
|
||||||
|
|
||||||
- [การติดตั้งและตั้งค่า](docs/installation.md): การลงทะเบียนเอเจนต์ การตั้งค่าผู้ให้บริการ การอัปเดต และการถอนการติดตั้ง
|
- [การติดตั้งและตั้งค่า](docs/installation.md): การลงทะเบียนเอเจนต์ การตั้งค่าผู้ให้บริการ การอัปเดต และการถอนการติดตั้ง
|
||||||
- [ความพร้อมใช้งานและการแก้ไขปัญหา](docs/installation.md#check-readiness-for-your-task): ตรวจวินิจฉัยเอเจนต์หรือเอนจินวิเคราะห์หนึ่งตัว
|
- [ความพร้อมใช้งานและการแก้ไขปัญหา](docs/installation.md#check-readiness-for-your-task): ตรวจวินิจฉัยเอเจนต์หรือเอนจินวิเคราะห์หนึ่งตัว
|
||||||
@@ -258,7 +259,7 @@ npx rea-agents@latest setup
|
|||||||
|
|
||||||
## ประวัติดาว
|
## ประวัติดาว
|
||||||
|
|
||||||
🎉 **90,000 ดาวบน GitHub — ขอบคุณทุกคน!**
|
🎉 **50,000 ดาวบน GitHub — ขอบคุณทุกคน!**
|
||||||
|
|
||||||
ขอบคุณทุกคนที่ใช้ REA รายงานบั๊ก เสนอฟีเจอร์ ทดสอบบิลด์ และช่วยแก้ไข
|
ขอบคุณทุกคนที่ใช้ REA รายงานบั๊ก เสนอฟีเจอร์ ทดสอบบิลด์ และช่วยแก้ไข
|
||||||
|
|
||||||
|
|||||||
+12
-11
@@ -9,6 +9,7 @@
|
|||||||
**Beğendiğiniz bir özellik mi gördünüz? İkili kod düzeyine kadar nasıl çalıştığını anlayın.**
|
**Beğendiğiniz bir özellik mi gördünüz? İkili kod düzeyine kadar nasıl çalıştığını anlayın.**
|
||||||
|
|
||||||
[](https://www.npmjs.com/package/rea-agents)
|
[](https://www.npmjs.com/package/rea-agents)
|
||||||
|
[](https://github.com/morluto/rea/actions/workflows/ci.yml)
|
||||||
[](docs/mcp-contracts.md#generated-catalog)
|
[](docs/mcp-contracts.md#generated-catalog)
|
||||||
[](#current-status)
|
[](#current-status)
|
||||||
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
||||||
@@ -17,7 +18,7 @@
|
|||||||
|
|
||||||
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
||||||
|
|
||||||
**[Web sitesi](https://rea.tools/tr/) · [Rehberler](https://rea.tools/tr/guides/) · [Örnek çalışmalar](https://rea.tools/tr/showcase/)**
|
**[Web sitesi](https://rea.tools/) · [Rehberler](https://rea.tools/guides/) · [Örnek çalışmalar](https://rea.tools/showcase/)**
|
||||||
|
|
||||||
[Hızlı başlangıç](#hızlı-başlangıç) · [REA nasıl çalışır](#rea-nasıl-çalışır) · [Neleri analiz edebilirsiniz](#neleri-analiz-edebilirsiniz) · [Örnek çalışmalar](#örnek-çalışmalar) · [Sık sorulan sorular](#sık-sorulan-sorular) · [Belgeler](#belgeler)
|
[Hızlı başlangıç](#hızlı-başlangıç) · [REA nasıl çalışır](#rea-nasıl-çalışır) · [Neleri analiz edebilirsiniz](#neleri-analiz-edebilirsiniz) · [Örnek çalışmalar](#örnek-çalışmalar) · [Sık sorulan sorular](#sık-sorulan-sorular) · [Belgeler](#belgeler)
|
||||||
|
|
||||||
@@ -53,7 +54,7 @@ REA, ajanınızı yerel makine kodu içeren ikili dosyaları, JavaScript ve Elec
|
|||||||
|
|
||||||
Kurulum, REA'yı ajanınıza kaydeder ve uyumlu iş akışı talimatlarını yükler. Yerel makine kodu analizi mevcut bir Hopper veya Ghidra kurulumunu kullanabilir; kurulum işlemi, onayınızla isteğe bağlı olarak Hopper da yükleyebilir. Statik JavaScript analizi bu iki motora da ihtiyaç duymaz.
|
Kurulum, REA'yı ajanınıza kaydeder ve uyumlu iş akışı talimatlarını yükler. Yerel makine kodu analizi mevcut bir Hopper veya Ghidra kurulumunu kullanabilir; kurulum işlemi, onayınızla isteğe bağlı olarak Hopper da yükleyebilir. Statik JavaScript analizi bu iki motora da ihtiyaç duymaz.
|
||||||
|
|
||||||
> Kurulum talimatları, görselli rehberler ve gerçek örnek çalışmalar için **[REA web sitesini ziyaret edin](https://rea.tools/tr/)**.
|
> Kurulum talimatları, görselli rehberler ve gerçek örnek çalışmalar için **[REA web sitesini ziyaret edin](https://rea.tools/)**.
|
||||||
|
|
||||||
## Hızlı başlangıç
|
## Hızlı başlangıç
|
||||||
|
|
||||||
@@ -132,12 +133,12 @@ REA; Node.js 22.x (>=22.19), 24.x (>=24.11) veya 26+ ve npm gerektirir. Ek araç
|
|||||||
|
|
||||||
| Hedef | REA'nın döndürdükleri | Gereksinimler ve rehber |
|
| Hedef | REA'nın döndürdükleri | Gereksinimler ve rehber |
|
||||||
| --------------------------------------- | ----------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
|
| --------------------------------------- | ----------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| Yerel makine kodu içeren ikili dosyalar | Sözde kod, assembly kodu, dizeler, semboller, çağrılar ve referanslar | Hopper, Ghidra veya IDA; [yerel kod analizi](https://rea.tools/tr/guides/native/) |
|
| Yerel makine kodu içeren ikili dosyalar | Sözde kod, assembly kodu, dizeler, semboller, çağrılar ve referanslar | Hopper, Ghidra veya IDA; [yerel kod analizi](https://rea.tools/guides/native/) |
|
||||||
| Çevrimdışı ELF yapısı | Bölümler, segmentler, özgün semboller/yeniden konumlandırmalar ve statik analizden olası güvenlik önlemleri | Linux x64 üzerinde çağıranın sağladığı pwntools; [ikili dosya tanılama](docs/binary-diagnostics.md) |
|
| Çevrimdışı ELF yapısı | Bölümler, segmentler, özgün semboller/yeniden konumlandırmalar ve statik analizden olası güvenlik önlemleri | Linux x64 üzerinde çağıranın sağladığı pwntools; [ikili dosya tanılama](docs/binary-diagnostics.md) |
|
||||||
| EVM bayt kodu | Yönlendirme seçicileri, bayt ofsetleri, çıkarımla belirlenen argümanlar ve durum değiştirilebilirliği | Linux x64 üzerinde yerel ham bayt/onaltılık girdi; [çevrimdışı EVM rehberi](docs/evm-bytecode.md) |
|
| EVM bayt kodu | Yönlendirme seçicileri, bayt ofsetleri, çıkarımla belirlenen argümanlar ve durum değiştirilebilirliği | Linux x64 üzerinde yerel ham bayt/onaltılık girdi; [çevrimdışı EVM rehberi](docs/evm-bytecode.md) |
|
||||||
| Kaydedilmiş Linux çökmeleri | Ham note kayıtları, kaydedilen her iş parçacığının yazmaçları/sinyalleri ve isteğe bağlı eşleme adayları | Linux x64 üzerinde çağıranın sağladığı pwntools; isteğe bağlı GDB/pwndbg; [kaydedilmiş çökmeler](docs/recorded-crashes.md) |
|
| Kaydedilmiş Linux çökmeleri | Ham note kayıtları, kaydedilen her iş parçacığının yazmaçları/sinyalleri ve isteğe bağlı eşleme adayları | Linux x64 üzerinde çağıranın sağladığı pwntools; isteğe bağlı GDB/pwndbg; [kaydedilmiş çökmeler](docs/recorded-crashes.md) |
|
||||||
| JavaScript / Electron | Modüller, içe aktarmalar, kaynak haritaları, rotalar, IPC ve yerel eklenti ilişkileri | Node.js ve npm; [uygulama analizi](https://rea.tools/tr/guides/javascript/) |
|
| JavaScript / Electron | Modüller, içe aktarmalar, kaynak haritaları, rotalar, IPC ve yerel eklenti ilişkileri | Node.js ve npm; [uygulama analizi](https://rea.tools/guides/javascript/) |
|
||||||
| Web siteleri | Sayfa yapısı, betikler, ağ gözlemleri ve istenen ekran görüntüleri | Chrome ailesinden bir tarayıcı; [tarayıcı analizi](https://rea.tools/tr/guides/browser/) |
|
| Web siteleri | Sayfa yapısı, betikler, ağ gözlemleri ve istenen ekran görüntüleri | Chrome ailesinden bir tarayıcı; [tarayıcı analizi](https://rea.tools/guides/browser/) |
|
||||||
| Kaydedilmiş ağ yakalamaları | İstekler, yanıtlar, erişilebilir yük içerikleri ve kaynak konumları | HAR; mitmproxy'nin kendi biçimindeki yakalamalar için Linux üzerinde mitmdump; [ağ yakalama rehberi](docs/web-network-captures.md) |
|
| Kaydedilmiş ağ yakalamaları | İstekler, yanıtlar, erişilebilir yük içerikleri ve kaynak konumları | HAR; mitmproxy'nin kendi biçimindeki yakalamalar için Linux üzerinde mitmdump; [ağ yakalama rehberi](docs/web-network-captures.md) |
|
||||||
| .NET derlemeleri | Meta veriler, CIL talimatları, bildirilmiş yerel bağımlılıklar ve derleme karşılaştırmaları | Statik inceleme; [yönetilen kod rehberi](docs/managed-code-analysis.md) |
|
| .NET derlemeleri | Meta veriler, CIL talimatları, bildirilmiş yerel bağımlılıklar ve derleme karşılaştırmaları | Statik inceleme; [yönetilen kod rehberi](docs/managed-code-analysis.md) |
|
||||||
| Android APK'leri | Manifest bildirimleri, sınıflar, tersine derlenmiş metotlar ve referanslar | Linux/macOS/Windows x64 üzerinde arayüzsüz JADX ve tam bir JDK; [Android rehberi](docs/android-analysis.md) |
|
| Android APK'leri | Manifest bildirimleri, sınıflar, tersine derlenmiş metotlar ve referanslar | Linux/macOS/Windows x64 üzerinde arayüzsüz JADX ve tam bir JDK; [Android rehberi](docs/android-analysis.md) |
|
||||||
@@ -156,25 +157,25 @@ Yerel makine kodu içeren ikili dosya biçimleri ve ana bilgisayar desteği sağ
|
|||||||
|
|
||||||
## Örnek çalışmalar
|
## Örnek çalışmalar
|
||||||
|
|
||||||
[](https://rea.tools/tr/showcase/)
|
[](https://rea.tools/showcase/)
|
||||||
|
|
||||||
### DX-Ball: Sesin stereo konumlandırma hesabını yeniden oluşturma
|
### DX-Ball: Sesin stereo konumlandırma hesabını yeniden oluşturma
|
||||||
|
|
||||||
Bir ses çağrısından konumu stereo konumlandırmaya dönüştüren yardımcı fonksiyona ilerleyin, talimatları inceleyin ve eksik sözde kodu C'ye dönüştürün. Yeniden oluşturulan kod, özgün x86 üzerinde 3.205 test durumunu geçer ve derlenmiş fonksiyonun 63 baytının tamamını yeniden üretir.
|
Bir ses çağrısından konumu stereo konumlandırmaya dönüştüren yardımcı fonksiyona ilerleyin, talimatları inceleyin ve eksik sözde kodu C'ye dönüştürün. Yeniden oluşturulan kod, özgün x86 üzerinde 3.205 test durumunu geçer ve derlenmiş fonksiyonun 63 baytının tamamını yeniden üretir.
|
||||||
|
|
||||||
[Örnek çalışmayı okuyun](https://rea.tools/tr/showcase/dx-ball/) · [Yeniden oluşturma deposu](https://github.com/N0zoM1z0/dx-ball)
|
[Örnek çalışmayı okuyun](https://rea.tools/showcase/dx-ball/) · [Yeniden oluşturma deposu](https://github.com/N0zoM1z0/dx-ball)
|
||||||
|
|
||||||
### Notion: Electron pano köprüsünü izleme
|
### Notion: Electron pano köprüsünü izleme
|
||||||
|
|
||||||
İşleyici sürecin pano API'sini bulun, preload ve IPC üzerinden ana sürece kadar izleyin ve zengin pano biçimini inceleyin.
|
İşleyici sürecin pano API'sini bulun, preload ve IPC üzerinden ana sürece kadar izleyin ve zengin pano biçimini inceleyin.
|
||||||
|
|
||||||
[Örnek çalışmayı okuyun](https://rea.tools/tr/showcase/notion/)
|
[Örnek çalışmayı okuyun](https://rea.tools/showcase/notion/)
|
||||||
|
|
||||||
### TH04: DOS mermi halkası hesabını geri çıkarma
|
### TH04: DOS mermi halkası hesabını geri çıkarma
|
||||||
|
|
||||||
Özgün PC-98 oyununun 16 bit talimatlarını inceleyin, sabit ve hedefe yönelik açı hesaplarını geri çıkarın ve yeniden oluşturulan C++ kodunu dönemin derleyici çıktısıyla karşılaştırın.
|
Özgün PC-98 oyununun 16 bit talimatlarını inceleyin, sabit ve hedefe yönelik açı hesaplarını geri çıkarın ve yeniden oluşturulan C++ kodunu dönemin derleyici çıktısıyla karşılaştırın.
|
||||||
|
|
||||||
[Örnek çalışmayı okuyun](https://rea.tools/tr/showcase/th04/) · [Yeniden oluşturma deposu](https://github.com/N0zoM1z0/th04)
|
[Örnek çalışmayı okuyun](https://rea.tools/showcase/th04/) · [Yeniden oluşturma deposu](https://github.com/N0zoM1z0/th04)
|
||||||
|
|
||||||
REA'yı ilginç bir konuda kullandıysanız görmek isteriz. Hedefi, sorunuzu, REA'nın nasıl yardımcı olduğunu ve bulgularınızı bir [issue](https://github.com/morluto/rea/issues) veya [pull request](https://github.com/morluto/rea/pulls) ile paylaşın.
|
REA'yı ilginç bir konuda kullandıysanız görmek isteriz. Hedefi, sorunuzu, REA'nın nasıl yardımcı olduğunu ve bulgularınızı bir [issue](https://github.com/morluto/rea/issues) veya [pull request](https://github.com/morluto/rea/pulls) ile paylaşın.
|
||||||
|
|
||||||
@@ -245,7 +246,7 @@ Ajan kullanıyorsanız [kurulum yenilemesini](#reayı-güncelleyin) tamamlayın
|
|||||||
|
|
||||||
## Belgeler
|
## Belgeler
|
||||||
|
|
||||||
Web sitesindeki [uygulamalı rehberlerden](https://rea.tools/tr/guides/) başlayın. Kesin seçenekler, ön koşullar ve sonuç sözleşmeleri için:
|
Web sitesindeki [uygulamalı rehberlerden](https://rea.tools/guides/) başlayın. Kesin seçenekler, ön koşullar ve sonuç sözleşmeleri için:
|
||||||
|
|
||||||
- [Yükleme ve kurulum](docs/installation.md): ajan kaydı, sağlayıcı yapılandırması, güncellemeler ve kaldırma.
|
- [Yükleme ve kurulum](docs/installation.md): ajan kaydı, sağlayıcı yapılandırması, güncellemeler ve kaldırma.
|
||||||
- [Hazırlık ve sorun giderme](docs/installation.md#check-readiness-for-your-task): belirli bir ajanı veya analiz motorunu tanılama.
|
- [Hazırlık ve sorun giderme](docs/installation.md#check-readiness-for-your-task): belirli bir ajanı veya analiz motorunu tanılama.
|
||||||
@@ -258,7 +259,7 @@ Güvenlik açıklarını [SECURITY.md](SECURITY.md) üzerinden bildirin.
|
|||||||
|
|
||||||
## Yıldız geçmişi
|
## Yıldız geçmişi
|
||||||
|
|
||||||
🎉 **GitHub'da 90.000 yıldız — teşekkürler!**
|
🎉 **GitHub'da 50.000 yıldız — teşekkürler!**
|
||||||
|
|
||||||
REA'yı kullanan, hata bildiren, özellik talep eden, derlemeleri test eden ve düzeltmelere katkıda bulunan herkese teşekkürler.
|
REA'yı kullanan, hata bildiren, özellik talep eden, derlemeleri test eden ve düzeltmelere katkıda bulunan herkese teşekkürler.
|
||||||
|
|
||||||
|
|||||||
+12
-11
@@ -9,6 +9,7 @@
|
|||||||
**Побачили цікаву функцію? Зрозумійте, як вона працює, аж до рівня двійкового коду.**
|
**Побачили цікаву функцію? Зрозумійте, як вона працює, аж до рівня двійкового коду.**
|
||||||
|
|
||||||
[](https://www.npmjs.com/package/rea-agents)
|
[](https://www.npmjs.com/package/rea-agents)
|
||||||
|
[](https://github.com/morluto/rea/actions/workflows/ci.yml)
|
||||||
[](docs/mcp-contracts.md#generated-catalog)
|
[](docs/mcp-contracts.md#generated-catalog)
|
||||||
[](#current-status)
|
[](#current-status)
|
||||||
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
||||||
@@ -17,7 +18,7 @@
|
|||||||
|
|
||||||
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
||||||
|
|
||||||
**[Сайт](https://rea.tools/uk/) · [Посібники](https://rea.tools/uk/guides/) · [Приклади](https://rea.tools/uk/showcase/)**
|
**[Сайт](https://rea.tools/) · [Посібники](https://rea.tools/guides/) · [Приклади](https://rea.tools/showcase/)**
|
||||||
|
|
||||||
[Швидкий старт](#швидкий-старт) · [Як працює REA](#як-працює-rea) · [Що можна аналізувати](#що-можна-аналізувати) · [Приклади](#приклади) · [Поширені запитання](#поширені-запитання) · [Документація](#документація)
|
[Швидкий старт](#швидкий-старт) · [Як працює REA](#як-працює-rea) · [Що можна аналізувати](#що-можна-аналізувати) · [Приклади](#приклади) · [Поширені запитання](#поширені-запитання) · [Документація](#документація)
|
||||||
|
|
||||||
@@ -53,7 +54,7 @@ REA підключає вашого агента до інструментів
|
|||||||
|
|
||||||
Налаштування реєструє REA у вашому агенті та встановлює відповідні інструкції робочих процесів. Для нативного аналізу можна використати вже встановлений Hopper або Ghidra; налаштування також може встановити Hopper за вашою згодою. Статичному аналізу JavaScript не потрібен жоден із цих рушіїв.
|
Налаштування реєструє REA у вашому агенті та встановлює відповідні інструкції робочих процесів. Для нативного аналізу можна використати вже встановлений Hopper або Ghidra; налаштування також може встановити Hopper за вашою згодою. Статичному аналізу JavaScript не потрібен жоден із цих рушіїв.
|
||||||
|
|
||||||
> **[Відвідайте сайт REA](https://rea.tools/uk/)**, щоб знайти інструкції налаштування, ілюстровані посібники та реальні дослідження.
|
> **[Відвідайте сайт REA](https://rea.tools/)**, щоб знайти інструкції налаштування, ілюстровані посібники та реальні дослідження.
|
||||||
|
|
||||||
## Швидкий старт
|
## Швидкий старт
|
||||||
|
|
||||||
@@ -132,12 +133,12 @@ REA потребує Node.js 22.x (>=22.19), 24.x (>=24.11) або 26+, а та
|
|||||||
|
|
||||||
| Ціль | Що повертає REA | Вимоги й посібник |
|
| Ціль | Що повертає REA | Вимоги й посібник |
|
||||||
| ------------------------------------ | ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| ------------------------------------ | ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| Нативні бінарні файли | Псевдокод, асемблерний код, рядки, символи, виклики й посилання | Hopper, Ghidra або IDA; [нативний аналіз](https://rea.tools/uk/guides/native/) |
|
| Нативні бінарні файли | Псевдокод, асемблерний код, рядки, символи, виклики й посилання | Hopper, Ghidra або IDA; [нативний аналіз](https://rea.tools/guides/native/) |
|
||||||
| Структура ELF без запуску | Секції, сегменти, початкові символи/релокації та можливі захисні механізми за даними статичного аналізу | pwntools, наданий стороною, що викликає інструмент, у Linux x64; [діагностика бінарних файлів](docs/binary-diagnostics.md) |
|
| Структура ELF без запуску | Секції, сегменти, початкові символи/релокації та можливі захисні механізми за даними статичного аналізу | pwntools, наданий стороною, що викликає інструмент, у Linux x64; [діагностика бінарних файлів](docs/binary-diagnostics.md) |
|
||||||
| Байт-код EVM | Селектори диспетчеризації, зміщення байтів, виведені припущення про аргументи та змінюваність стану | Локальні необроблені байти або шістнадцяткове представлення у Linux x64; [посібник EVM без запуску](docs/evm-bytecode.md) |
|
| Байт-код EVM | Селектори диспетчеризації, зміщення байтів, виведені припущення про аргументи та змінюваність стану | Локальні необроблені байти або шістнадцяткове представлення у Linux x64; [посібник EVM без запуску](docs/evm-bytecode.md) |
|
||||||
| Записані аварійні завершення в Linux | Необроблені записи note, регістри/сигнали кожного записаного потоку й необов'язкові кандидати зіставлення пам'яті | pwntools, наданий стороною, що викликає інструмент, у Linux x64; необов'язкові GDB/pwndbg; [записані аварійні завершення](docs/recorded-crashes.md) |
|
| Записані аварійні завершення в Linux | Необроблені записи note, регістри/сигнали кожного записаного потоку й необов'язкові кандидати зіставлення пам'яті | pwntools, наданий стороною, що викликає інструмент, у Linux x64; необов'язкові GDB/pwndbg; [записані аварійні завершення](docs/recorded-crashes.md) |
|
||||||
| JavaScript / Electron | Модулі, імпорти, карти вихідного коду, маршрути, IPC і зв'язки з нативними доповненнями | Node.js і npm; [аналіз застосунків](https://rea.tools/uk/guides/javascript/) |
|
| JavaScript / Electron | Модулі, імпорти, карти вихідного коду, маршрути, IPC і зв'язки з нативними доповненнями | Node.js і npm; [аналіз застосунків](https://rea.tools/guides/javascript/) |
|
||||||
| Сайти | Структура сторінки, скрипти, мережеві спостереження й запитані знімки екрана | Браузер сімейства Chrome; [аналіз браузера](https://rea.tools/uk/guides/browser/) |
|
| Сайти | Структура сторінки, скрипти, мережеві спостереження й запитані знімки екрана | Браузер сімейства Chrome; [аналіз браузера](https://rea.tools/guides/browser/) |
|
||||||
| Збережені мережеві захоплення | Запити, відповіді, доступні корисні дані та місця в джерелі | HAR; mitmdump у Linux для захоплень у власному форматі mitmproxy; [посібник мережевих захоплень](docs/web-network-captures.md) |
|
| Збережені мережеві захоплення | Запити, відповіді, доступні корисні дані та місця в джерелі | HAR; mitmdump у Linux для захоплень у власному форматі mitmproxy; [посібник мережевих захоплень](docs/web-network-captures.md) |
|
||||||
| Збірки .NET | Метадані, інструкції CIL, оголошені нативні залежності й порівняння збірок | Статична перевірка; [посібник керованого коду](docs/managed-code-analysis.md) |
|
| Збірки .NET | Метадані, інструкції CIL, оголошені нативні залежності й порівняння збірок | Статична перевірка; [посібник керованого коду](docs/managed-code-analysis.md) |
|
||||||
| Android APK | Оголошення маніфесту, класи, декомпільовані методи й посилання | JADX без графічного інтерфейсу й повний JDK у Linux/macOS/Windows x64; [посібник Android](docs/android-analysis.md) |
|
| Android APK | Оголошення маніфесту, класи, декомпільовані методи й посилання | JADX без графічного інтерфейсу й повний JDK у Linux/macOS/Windows x64; [посібник Android](docs/android-analysis.md) |
|
||||||
@@ -156,25 +157,25 @@ REA потребує Node.js 22.x (>=22.19), 24.x (>=24.11) або 26+, а та
|
|||||||
|
|
||||||
## Приклади
|
## Приклади
|
||||||
|
|
||||||
[](https://rea.tools/uk/showcase/)
|
[](https://rea.tools/showcase/)
|
||||||
|
|
||||||
### DX-Ball: відновлення розрахунку звукової панорами
|
### DX-Ball: відновлення розрахунку звукової панорами
|
||||||
|
|
||||||
Простежте звуковий виклик до допоміжної функції, що перетворює координату на панорамування, перевірте інструкції та перетворіть неповний псевдокод на C. Відновлена реалізація проходить 3 205 тестів з оригінальним x86-кодом і відтворює всі 63 байти скомпільованої функції.
|
Простежте звуковий виклик до допоміжної функції, що перетворює координату на панорамування, перевірте інструкції та перетворіть неповний псевдокод на C. Відновлена реалізація проходить 3 205 тестів з оригінальним x86-кодом і відтворює всі 63 байти скомпільованої функції.
|
||||||
|
|
||||||
[Прочитати дослідження](https://rea.tools/uk/showcase/dx-ball/) · [Репозиторій реконструкції](https://github.com/N0zoM1z0/dx-ball)
|
[Прочитати дослідження](https://rea.tools/showcase/dx-ball/) · [Репозиторій реконструкції](https://github.com/N0zoM1z0/dx-ball)
|
||||||
|
|
||||||
### Notion: відстеження мосту буфера обміну Electron
|
### Notion: відстеження мосту буфера обміну Electron
|
||||||
|
|
||||||
Знайдіть API буфера обміну в процесі рендерингу, простежте його через preload та IPC до головного процесу й перевірте формат буфера обміну з даними форматування.
|
Знайдіть API буфера обміну в процесі рендерингу, простежте його через preload та IPC до головного процесу й перевірте формат буфера обміну з даними форматування.
|
||||||
|
|
||||||
[Прочитати дослідження](https://rea.tools/uk/showcase/notion/)
|
[Прочитати дослідження](https://rea.tools/showcase/notion/)
|
||||||
|
|
||||||
### TH04: відновлення розрахунку кільця куль у DOS
|
### TH04: відновлення розрахунку кільця куль у DOS
|
||||||
|
|
||||||
Перевірте 16-бітні інструкції оригінальної гри для PC-98, відновіть розрахунки фіксованих і прицільних кутів та порівняйте відновлений C++ із виводом тогочасного компілятора.
|
Перевірте 16-бітні інструкції оригінальної гри для PC-98, відновіть розрахунки фіксованих і прицільних кутів та порівняйте відновлений C++ із виводом тогочасного компілятора.
|
||||||
|
|
||||||
[Прочитати дослідження](https://rea.tools/uk/showcase/th04/) · [Репозиторій реконструкції](https://github.com/N0zoM1z0/th04)
|
[Прочитати дослідження](https://rea.tools/showcase/th04/) · [Репозиторій реконструкції](https://github.com/N0zoM1z0/th04)
|
||||||
|
|
||||||
Якщо ви дослідили з REA щось цікаве, поділіться результатом. Створіть [issue](https://github.com/morluto/rea/issues) або [pull request](https://github.com/morluto/rea/pulls) і вкажіть ціль, ваше запитання, як допоміг REA та що ви з'ясували.
|
Якщо ви дослідили з REA щось цікаве, поділіться результатом. Створіть [issue](https://github.com/morluto/rea/issues) або [pull request](https://github.com/morluto/rea/pulls) і вкажіть ціль, ваше запитання, як допоміг REA та що ви з'ясували.
|
||||||
|
|
||||||
@@ -245,7 +246,7 @@ npx rea-agents@latest setup
|
|||||||
|
|
||||||
## Документація
|
## Документація
|
||||||
|
|
||||||
Почніть із [практичних посібників](https://rea.tools/uk/guides/) на сайті. Точні параметри, передумови й контракти результатів описано тут:
|
Почніть із [практичних посібників](https://rea.tools/guides/) на сайті. Точні параметри, передумови й контракти результатів описано тут:
|
||||||
|
|
||||||
- [Встановлення й налаштування](docs/installation.md): реєстрація агентів, конфігурація провайдерів, оновлення та видалення.
|
- [Встановлення й налаштування](docs/installation.md): реєстрація агентів, конфігурація провайдерів, оновлення та видалення.
|
||||||
- [Готовність та усунення неполадок](docs/installation.md#check-readiness-for-your-task): діагностика конкретного агента або рушія аналізу.
|
- [Готовність та усунення неполадок](docs/installation.md#check-readiness-for-your-task): діагностика конкретного агента або рушія аналізу.
|
||||||
@@ -258,7 +259,7 @@ npx rea-agents@latest setup
|
|||||||
|
|
||||||
## Історія зірок
|
## Історія зірок
|
||||||
|
|
||||||
🎉 **90 000 зірок на GitHub — дякуємо!**
|
🎉 **50 000 зірок на GitHub — дякуємо!**
|
||||||
|
|
||||||
Дякуємо всім, хто використовує REA, повідомляє про помилки, пропонує нові функції, тестує збірки й допомагає з виправленнями.
|
Дякуємо всім, хто використовує REA, повідомляє про помилки, пропонує нові функції, тестує збірки й допомагає з виправленнями.
|
||||||
|
|
||||||
|
|||||||
+12
-11
@@ -9,6 +9,7 @@
|
|||||||
**Thấy một tính năng bạn thích? Hiểu cách nó hoạt động, đến tận mức mã nhị phân.**
|
**Thấy một tính năng bạn thích? Hiểu cách nó hoạt động, đến tận mức mã nhị phân.**
|
||||||
|
|
||||||
[](https://www.npmjs.com/package/rea-agents)
|
[](https://www.npmjs.com/package/rea-agents)
|
||||||
|
[](https://github.com/morluto/rea/actions/workflows/ci.yml)
|
||||||
[](docs/mcp-contracts.md#generated-catalog)
|
[](docs/mcp-contracts.md#generated-catalog)
|
||||||
[](#current-status)
|
[](#current-status)
|
||||||
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
||||||
@@ -17,7 +18,7 @@
|
|||||||
|
|
||||||
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
||||||
|
|
||||||
**[Trang web](https://rea.tools/vi/) · [Hướng dẫn](https://rea.tools/vi/guides/) · [Các nghiên cứu điển hình](https://rea.tools/vi/showcase/)**
|
**[Trang web](https://rea.tools/) · [Hướng dẫn](https://rea.tools/guides/) · [Các nghiên cứu điển hình](https://rea.tools/showcase/)**
|
||||||
|
|
||||||
[Bắt đầu nhanh](#bắt-đầu-nhanh) · [Cách REA hoạt động](#cách-rea-hoạt-động) · [Những gì bạn có thể phân tích](#những-gì-bạn-có-thể-phân-tích) · [Các nghiên cứu điển hình](#các-nghiên-cứu-điển-hình) · [Câu hỏi thường gặp](#câu-hỏi-thường-gặp) · [Tài liệu](#tài-liệu)
|
[Bắt đầu nhanh](#bắt-đầu-nhanh) · [Cách REA hoạt động](#cách-rea-hoạt-động) · [Những gì bạn có thể phân tích](#những-gì-bạn-có-thể-phân-tích) · [Các nghiên cứu điển hình](#các-nghiên-cứu-điển-hình) · [Câu hỏi thường gặp](#câu-hỏi-thường-gặp) · [Tài liệu](#tài-liệu)
|
||||||
|
|
||||||
@@ -53,7 +54,7 @@ REA kết nối tác nhân của bạn với các công cụ kiểm tra tệp nh
|
|||||||
|
|
||||||
Quá trình thiết lập đăng ký REA với tác nhân và cài đặt các hướng dẫn quy trình tương ứng. Phân tích mã máy có thể sử dụng Hopper hoặc Ghidra đã cài sẵn; quá trình thiết lập cũng có thể cài Hopper nếu bạn chấp thuận. Phân tích tĩnh JavaScript không cần công cụ nào trong hai công cụ này.
|
Quá trình thiết lập đăng ký REA với tác nhân và cài đặt các hướng dẫn quy trình tương ứng. Phân tích mã máy có thể sử dụng Hopper hoặc Ghidra đã cài sẵn; quá trình thiết lập cũng có thể cài Hopper nếu bạn chấp thuận. Phân tích tĩnh JavaScript không cần công cụ nào trong hai công cụ này.
|
||||||
|
|
||||||
> **[Truy cập trang web REA](https://rea.tools/vi/)** để xem cách thiết lập, hướng dẫn có hình minh họa và các nghiên cứu điển hình thực tế.
|
> **[Truy cập trang web REA](https://rea.tools/)** để xem cách thiết lập, hướng dẫn có hình minh họa và các nghiên cứu điển hình thực tế.
|
||||||
|
|
||||||
## Bắt đầu nhanh
|
## Bắt đầu nhanh
|
||||||
|
|
||||||
@@ -132,12 +133,12 @@ REA yêu cầu Node.js 22.x (>=22.19), 24.x (>=24.11) hoặc 26+, cùng với np
|
|||||||
|
|
||||||
| Mục tiêu | REA trả về gì | Yêu cầu và hướng dẫn |
|
| Mục tiêu | REA trả về gì | Yêu cầu và hướng dẫn |
|
||||||
| ----------------------------- | --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
|
| ----------------------------- | --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| Tệp nhị phân mã máy | Mã giả, hợp ngữ, chuỗi, ký hiệu, lời gọi và tham chiếu | Hopper, Ghidra hoặc IDA; [phân tích mã máy](https://rea.tools/vi/guides/native/) |
|
| Tệp nhị phân mã máy | Mã giả, hợp ngữ, chuỗi, ký hiệu, lời gọi và tham chiếu | Hopper, Ghidra hoặc IDA; [phân tích mã máy](https://rea.tools/guides/native/) |
|
||||||
| Bố cục ELF ngoại tuyến | Các section, segment, ký hiệu/thông tin tái định vị gốc và các biện pháp giảm thiểu có thể có từ phân tích tĩnh | pwntools do bên gọi cung cấp trên Linux x64; [chẩn đoán tệp nhị phân](docs/binary-diagnostics.md) |
|
| Bố cục ELF ngoại tuyến | Các section, segment, ký hiệu/thông tin tái định vị gốc và các biện pháp giảm thiểu có thể có từ phân tích tĩnh | pwntools do bên gọi cung cấp trên Linux x64; [chẩn đoán tệp nhị phân](docs/binary-diagnostics.md) |
|
||||||
| Bytecode EVM | Bộ chọn điều phối, độ lệch byte, tham số suy luận và khả năng thay đổi trạng thái | Đầu vào cục bộ chứa byte thô hoặc dạng thập lục phân trên Linux x64; [hướng dẫn EVM ngoại tuyến](docs/evm-bytecode.md) |
|
| Bytecode EVM | Bộ chọn điều phối, độ lệch byte, tham số suy luận và khả năng thay đổi trạng thái | Đầu vào cục bộ chứa byte thô hoặc dạng thập lục phân trên Linux x64; [hướng dẫn EVM ngoại tuyến](docs/evm-bytecode.md) |
|
||||||
| Sự cố Linux đã ghi lại | Bản ghi note thô, thanh ghi/tín hiệu của mọi luồng được ghi lại và các ứng viên ánh xạ tùy chọn | pwntools do bên gọi cung cấp trên Linux x64; GDB/pwndbg tùy chọn; [sự cố đã ghi lại](docs/recorded-crashes.md) |
|
| Sự cố Linux đã ghi lại | Bản ghi note thô, thanh ghi/tín hiệu của mọi luồng được ghi lại và các ứng viên ánh xạ tùy chọn | pwntools do bên gọi cung cấp trên Linux x64; GDB/pwndbg tùy chọn; [sự cố đã ghi lại](docs/recorded-crashes.md) |
|
||||||
| JavaScript / Electron | Mô-đun, các khai báo import, source map, tuyến, IPC và quan hệ với tiện ích mở rộng mã máy | Node.js và npm; [phân tích ứng dụng](https://rea.tools/vi/guides/javascript/) |
|
| JavaScript / Electron | Mô-đun, các khai báo import, source map, tuyến, IPC và quan hệ với tiện ích mở rộng mã máy | Node.js và npm; [phân tích ứng dụng](https://rea.tools/guides/javascript/) |
|
||||||
| Trang web | Cấu trúc trang, script, quan sát mạng và ảnh chụp màn hình được yêu cầu | Trình duyệt thuộc họ Chrome; [phân tích trình duyệt](https://rea.tools/vi/guides/browser/) |
|
| Trang web | Cấu trúc trang, script, quan sát mạng và ảnh chụp màn hình được yêu cầu | Trình duyệt thuộc họ Chrome; [phân tích trình duyệt](https://rea.tools/guides/browser/) |
|
||||||
| Bản ghi lưu lượng mạng đã lưu | Yêu cầu, phản hồi, payload có thể truy cập và vị trí nguồn | HAR; mitmdump trên Linux cho bản ghi định dạng gốc của mitmproxy; [hướng dẫn bản ghi mạng](docs/web-network-captures.md) |
|
| Bản ghi lưu lượng mạng đã lưu | Yêu cầu, phản hồi, payload có thể truy cập và vị trí nguồn | HAR; mitmdump trên Linux cho bản ghi định dạng gốc của mitmproxy; [hướng dẫn bản ghi mạng](docs/web-network-captures.md) |
|
||||||
| Assembly .NET | Siêu dữ liệu, lệnh CIL, các phụ thuộc mã máy được khai báo và so sánh bản dựng | Kiểm tra tĩnh; [hướng dẫn mã được quản lý](docs/managed-code-analysis.md) |
|
| Assembly .NET | Siêu dữ liệu, lệnh CIL, các phụ thuộc mã máy được khai báo và so sánh bản dựng | Kiểm tra tĩnh; [hướng dẫn mã được quản lý](docs/managed-code-analysis.md) |
|
||||||
| APK Android | Khai báo manifest, lớp, phương thức được dịch ngược và tham chiếu | JADX không giao diện đồ họa và JDK đầy đủ trên Linux/macOS/Windows x64; [hướng dẫn Android](docs/android-analysis.md) |
|
| APK Android | Khai báo manifest, lớp, phương thức được dịch ngược và tham chiếu | JADX không giao diện đồ họa và JDK đầy đủ trên Linux/macOS/Windows x64; [hướng dẫn Android](docs/android-analysis.md) |
|
||||||
@@ -156,25 +157,25 @@ Kiểm tra tĩnh JavaScript và .NET đọc các tệp được cung cấp mà k
|
|||||||
|
|
||||||
## Các nghiên cứu điển hình
|
## Các nghiên cứu điển hình
|
||||||
|
|
||||||
[](https://rea.tools/vi/showcase/)
|
[](https://rea.tools/showcase/)
|
||||||
|
|
||||||
### DX-Ball: tái tạo phép tính phân bố âm thanh trái phải
|
### DX-Ball: tái tạo phép tính phân bố âm thanh trái phải
|
||||||
|
|
||||||
Lần theo lời gọi âm thanh đến hàm hỗ trợ chuyển vị trí thành giá trị phân bố âm thanh, kiểm tra các lệnh và chuyển mã giả chưa đầy đủ sang C. Bản tái tạo vượt qua 3.205 trường hợp kiểm thử với x86 gốc và tái tạo đủ 63 byte của hàm đã biên dịch.
|
Lần theo lời gọi âm thanh đến hàm hỗ trợ chuyển vị trí thành giá trị phân bố âm thanh, kiểm tra các lệnh và chuyển mã giả chưa đầy đủ sang C. Bản tái tạo vượt qua 3.205 trường hợp kiểm thử với x86 gốc và tái tạo đủ 63 byte của hàm đã biên dịch.
|
||||||
|
|
||||||
[Đọc nghiên cứu điển hình](https://rea.tools/vi/showcase/dx-ball/) · [Kho mã tái tạo](https://github.com/N0zoM1z0/dx-ball)
|
[Đọc nghiên cứu điển hình](https://rea.tools/showcase/dx-ball/) · [Kho mã tái tạo](https://github.com/N0zoM1z0/dx-ball)
|
||||||
|
|
||||||
### Notion: lần theo cầu nối clipboard của Electron
|
### Notion: lần theo cầu nối clipboard của Electron
|
||||||
|
|
||||||
Tìm API clipboard trong tiến trình kết xuất, lần theo qua preload và IPC đến tiến trình chính, rồi kiểm tra định dạng clipboard có dữ liệu định dạng phong phú.
|
Tìm API clipboard trong tiến trình kết xuất, lần theo qua preload và IPC đến tiến trình chính, rồi kiểm tra định dạng clipboard có dữ liệu định dạng phong phú.
|
||||||
|
|
||||||
[Đọc nghiên cứu điển hình](https://rea.tools/vi/showcase/notion/)
|
[Đọc nghiên cứu điển hình](https://rea.tools/showcase/notion/)
|
||||||
|
|
||||||
### TH04: khôi phục phép tính vòng đạn trong DOS
|
### TH04: khôi phục phép tính vòng đạn trong DOS
|
||||||
|
|
||||||
Kiểm tra các lệnh 16 bit của trò chơi PC-98 gốc, khôi phục phép tính góc cố định và góc nhắm mục tiêu, rồi so sánh C++ được tái tạo với đầu ra của trình biên dịch thời đó.
|
Kiểm tra các lệnh 16 bit của trò chơi PC-98 gốc, khôi phục phép tính góc cố định và góc nhắm mục tiêu, rồi so sánh C++ được tái tạo với đầu ra của trình biên dịch thời đó.
|
||||||
|
|
||||||
[Đọc nghiên cứu điển hình](https://rea.tools/vi/showcase/th04/) · [Kho mã tái tạo](https://github.com/N0zoM1z0/th04)
|
[Đọc nghiên cứu điển hình](https://rea.tools/showcase/th04/) · [Kho mã tái tạo](https://github.com/N0zoM1z0/th04)
|
||||||
|
|
||||||
Nếu bạn dùng REA cho một mục tiêu thú vị, chúng tôi muốn biết. Chia sẻ trường hợp của bạn qua [issue](https://github.com/morluto/rea/issues) hoặc [pull request](https://github.com/morluto/rea/pulls), nêu mục tiêu, câu hỏi, cách REA giúp bạn và những gì tìm được.
|
Nếu bạn dùng REA cho một mục tiêu thú vị, chúng tôi muốn biết. Chia sẻ trường hợp của bạn qua [issue](https://github.com/morluto/rea/issues) hoặc [pull request](https://github.com/morluto/rea/pulls), nêu mục tiêu, câu hỏi, cách REA giúp bạn và những gì tìm được.
|
||||||
|
|
||||||
@@ -245,7 +246,7 @@ Nếu dùng tác nhân, hãy hoàn tất [làm mới thiết lập](#cập-nhậ
|
|||||||
|
|
||||||
## Tài liệu
|
## Tài liệu
|
||||||
|
|
||||||
Bắt đầu với [hướng dẫn thực hành](https://rea.tools/vi/guides/) trên trang web. Để biết tùy chọn cụ thể, điều kiện tiên quyết và hợp đồng kết quả:
|
Bắt đầu với [hướng dẫn thực hành](https://rea.tools/guides/) trên trang web. Để biết tùy chọn cụ thể, điều kiện tiên quyết và hợp đồng kết quả:
|
||||||
|
|
||||||
- [Cài đặt và thiết lập](docs/installation.md): đăng ký tác nhân, cấu hình trình phân tích, cập nhật và gỡ cài đặt.
|
- [Cài đặt và thiết lập](docs/installation.md): đăng ký tác nhân, cấu hình trình phân tích, cập nhật và gỡ cài đặt.
|
||||||
- [Kiểm tra mức sẵn sàng và khắc phục sự cố](docs/installation.md#check-readiness-for-your-task): chẩn đoán một tác nhân hoặc bộ máy phân tích cụ thể.
|
- [Kiểm tra mức sẵn sàng và khắc phục sự cố](docs/installation.md#check-readiness-for-your-task): chẩn đoán một tác nhân hoặc bộ máy phân tích cụ thể.
|
||||||
@@ -258,7 +259,7 @@ Báo cáo lỗ hổng theo [SECURITY.md](SECURITY.md).
|
|||||||
|
|
||||||
## Lịch sử sao
|
## Lịch sử sao
|
||||||
|
|
||||||
🎉 **90.000 sao trên GitHub — xin cảm ơn!**
|
🎉 **50.000 sao trên GitHub — xin cảm ơn!**
|
||||||
|
|
||||||
Cảm ơn mọi người đã sử dụng REA, báo lỗi, đề xuất tính năng, kiểm thử bản dựng và đóng góp bản sửa lỗi.
|
Cảm ơn mọi người đã sử dụng REA, báo lỗi, đề xuất tính năng, kiểm thử bản dựng và đóng góp bản sửa lỗi.
|
||||||
|
|
||||||
|
|||||||
+12
-11
@@ -9,6 +9,7 @@
|
|||||||
**看到喜歡的功能,弄清它的工作原理,深入到二進位層面。**
|
**看到喜歡的功能,弄清它的工作原理,深入到二進位層面。**
|
||||||
|
|
||||||
[](https://www.npmjs.com/package/rea-agents)
|
[](https://www.npmjs.com/package/rea-agents)
|
||||||
|
[](https://github.com/morluto/rea/actions/workflows/ci.yml)
|
||||||
[](docs/mcp-contracts.md#generated-catalog)
|
[](docs/mcp-contracts.md#generated-catalog)
|
||||||
[](#current-status)
|
[](#current-status)
|
||||||
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
||||||
@@ -17,7 +18,7 @@
|
|||||||
|
|
||||||
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
||||||
|
|
||||||
**[網站](https://rea.tools/zh-TW/) · [指南](https://rea.tools/zh-TW/guides/) · [案例](https://rea.tools/zh-TW/showcase/)**
|
**[網站](https://rea.tools/) · [指南](https://rea.tools/guides/) · [案例](https://rea.tools/showcase/)**
|
||||||
|
|
||||||
[快速開始](#快速開始) · [REA 的工作原理](#rea-的工作原理) · [可以分析什麼](#可以分析什麼) · [案例](#案例) · [常見問題](#常見問題) · [文件](#文件)
|
[快速開始](#快速開始) · [REA 的工作原理](#rea-的工作原理) · [可以分析什麼](#可以分析什麼) · [案例](#案例) · [常見問題](#常見問題) · [文件](#文件)
|
||||||
|
|
||||||
@@ -53,7 +54,7 @@ REA 將 AI 代理連接到分析工具,用於檢查原生二進位檔案、Jav
|
|||||||
|
|
||||||
設定流程會向 AI 代理註冊 REA,並安裝對應的工作流程指引。原生分析可以使用已有的 Hopper 或 Ghidra;設定流程也可以在你核准後安裝 Hopper。靜態 JavaScript 分析不需要這兩個引擎。
|
設定流程會向 AI 代理註冊 REA,並安裝對應的工作流程指引。原生分析可以使用已有的 Hopper 或 Ghidra;設定流程也可以在你核准後安裝 Hopper。靜態 JavaScript 分析不需要這兩個引擎。
|
||||||
|
|
||||||
> **[訪問 REA 網站](https://rea.tools/zh-TW/)**,查看設定說明、圖解指南和真實案例。
|
> **[訪問 REA 網站](https://rea.tools/)**,查看設定說明、圖解指南和真實案例。
|
||||||
|
|
||||||
## 快速開始
|
## 快速開始
|
||||||
|
|
||||||
@@ -132,12 +133,12 @@ REA 需要 Node.js 22.x(>=22.19)、24.x(>=24.11)或 26+,以及 npm。
|
|||||||
|
|
||||||
| 目標 | REA 返回的內容 | 要求與指南 |
|
| 目標 | REA 返回的內容 | 要求與指南 |
|
||||||
| --------------------- | --------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
|
| --------------------- | --------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
|
||||||
| 原生二進位檔案 | 偽程式碼、組合語言、字串、符號、呼叫和引用 | Hopper、Ghidra 或 IDA;[原生分析](https://rea.tools/zh-TW/guides/native/) |
|
| 原生二進位檔案 | 偽程式碼、組合語言、字串、符號、呼叫和引用 | Hopper、Ghidra 或 IDA;[原生分析](https://rea.tools/guides/native/) |
|
||||||
| 離線 ELF 佈局 | 節、段、原始符號/重定位資訊及靜態防護機制候選項 | Linux x64 上由呼叫方提供的 pwntools;[二進位診斷](docs/binary-diagnostics.md) |
|
| 離線 ELF 佈局 | 節、段、原始符號/重定位資訊及靜態防護機制候選項 | Linux x64 上由呼叫方提供的 pwntools;[二進位診斷](docs/binary-diagnostics.md) |
|
||||||
| EVM 位元組碼 | 分派選擇器、位元組偏移、推斷的參數和狀態可變性 | Linux x64 上的本地原始位元組/十六進位輸入載體;[離線 EVM 指南](docs/evm-bytecode.md) |
|
| EVM 位元組碼 | 分派選擇器、位元組偏移、推斷的參數和狀態可變性 | Linux x64 上的本地原始位元組/十六進位輸入載體;[離線 EVM 指南](docs/evm-bytecode.md) |
|
||||||
| 已記錄的 Linux 崩潰 | 原始 note 記錄、每個已記錄執行緒的暫存器/訊號及可選的對映候選項 | Linux x64 上由呼叫方提供的 pwntools;可選的 GDB/pwndbg;[已記錄崩潰](docs/recorded-crashes.md) |
|
| 已記錄的 Linux 崩潰 | 原始 note 記錄、每個已記錄執行緒的暫存器/訊號及可選的對映候選項 | Linux x64 上由呼叫方提供的 pwntools;可選的 GDB/pwndbg;[已記錄崩潰](docs/recorded-crashes.md) |
|
||||||
| JavaScript / Electron | 模組、匯入、source map、路由、IPC 和原生附加元件關係 | Node.js 和 npm;[應用分析](https://rea.tools/zh-TW/guides/javascript/) |
|
| JavaScript / Electron | 模組、匯入、source map、路由、IPC 和原生附加元件關係 | Node.js 和 npm;[應用分析](https://rea.tools/guides/javascript/) |
|
||||||
| 網站 | 頁面結構、腳本、網路觀察結果和按請求獲取的螢幕擷取畫面 | Chrome 系瀏覽器;[瀏覽器分析](https://rea.tools/zh-TW/guides/browser/) |
|
| 網站 | 頁面結構、腳本、網路觀察結果和按請求獲取的螢幕擷取畫面 | Chrome 系瀏覽器;[瀏覽器分析](https://rea.tools/guides/browser/) |
|
||||||
| 已保存的網路擷取 | 請求、回應、可訪問的酬載和來源位置 | HAR;原生 mitmproxy 擷取需要 Linux 上的 mitmdump;[擷取指南](docs/web-network-captures.md) |
|
| 已保存的網路擷取 | 請求、回應、可訪問的酬載和來源位置 | HAR;原生 mitmproxy 擷取需要 Linux 上的 mitmdump;[擷取指南](docs/web-network-captures.md) |
|
||||||
| .NET 程式集 | 中繼資料、CIL 指令、聲明的原生依賴和建置對比 | 靜態檢查;[托管程式碼指南](docs/managed-code-analysis.md) |
|
| .NET 程式集 | 中繼資料、CIL 指令、聲明的原生依賴和建置對比 | 靜態檢查;[托管程式碼指南](docs/managed-code-analysis.md) |
|
||||||
| Android APK | 清單聲明、類別、反編譯的方法和引用 | Linux/macOS/Windows x64 上的無界面 JADX 和完整 JDK;[Android 指南](docs/android-analysis.md) |
|
| Android APK | 清單聲明、類別、反編譯的方法和引用 | Linux/macOS/Windows x64 上的無界面 JADX 和完整 JDK;[Android 指南](docs/android-analysis.md) |
|
||||||
@@ -156,26 +157,26 @@ REA 需要 Node.js 22.x(>=22.19)、24.x(>=24.11)或 26+,以及 npm。
|
|||||||
|
|
||||||
## 案例
|
## 案例
|
||||||
|
|
||||||
[](https://rea.tools/zh-TW/showcase/)
|
[](https://rea.tools/showcase/)
|
||||||
|
|
||||||
### DX-Ball:重建聲像計算
|
### DX-Ball:重建聲像計算
|
||||||
|
|
||||||
沿聲音呼叫追蹤到根據位置計算聲像的輔助函數,檢查指令,將不完整的偽程式碼轉為 C。重建結果通過了 3,205 個原始 x86 測試用例,並復現了編譯後函數的全部 63 個位元組。
|
沿聲音呼叫追蹤到根據位置計算聲像的輔助函數,檢查指令,將不完整的偽程式碼轉為 C。重建結果通過了 3,205 個原始 x86 測試用例,並復現了編譯後函數的全部 63 個位元組。
|
||||||
|
|
||||||
[閱讀案例](https://rea.tools/zh-TW/showcase/dx-ball/) ·
|
[閱讀案例](https://rea.tools/showcase/dx-ball/) ·
|
||||||
[重建專案儲存庫](https://github.com/N0zoM1z0/dx-ball)
|
[重建專案儲存庫](https://github.com/N0zoM1z0/dx-ball)
|
||||||
|
|
||||||
### Notion:追蹤 Electron 剪貼簿橋
|
### Notion:追蹤 Electron 剪貼簿橋
|
||||||
|
|
||||||
找到渲染處理程序的剪貼簿 API,沿 preload 和 IPC 追蹤到主處理程序,並檢查富格式剪貼簿資料。
|
找到渲染處理程序的剪貼簿 API,沿 preload 和 IPC 追蹤到主處理程序,並檢查富格式剪貼簿資料。
|
||||||
|
|
||||||
[閱讀案例](https://rea.tools/zh-TW/showcase/notion/)
|
[閱讀案例](https://rea.tools/showcase/notion/)
|
||||||
|
|
||||||
### TH04:恢復 DOS 環形子彈的計算
|
### TH04:恢復 DOS 環形子彈的計算
|
||||||
|
|
||||||
檢查原始 PC-98 遊戲的 16 位指令,恢復固定角度和瞄準角度的計算,並將重建的 C++ 與當年的編譯器輸出進行對比。
|
檢查原始 PC-98 遊戲的 16 位指令,恢復固定角度和瞄準角度的計算,並將重建的 C++ 與當年的編譯器輸出進行對比。
|
||||||
|
|
||||||
[閱讀案例](https://rea.tools/zh-TW/showcase/th04/) ·
|
[閱讀案例](https://rea.tools/showcase/th04/) ·
|
||||||
[重建專案儲存庫](https://github.com/N0zoM1z0/th04)
|
[重建專案儲存庫](https://github.com/N0zoM1z0/th04)
|
||||||
|
|
||||||
如果你用 REA 分析了有趣的目標,我們很想瞭解。歡迎通過 [issue](https://github.com/morluto/rea/issues) 或 [pull request](https://github.com/morluto/rea/pulls) 分享案例,說明目標、你的問題、REA 如何提供幫助,以及你的發現。
|
如果你用 REA 分析了有趣的目標,我們很想瞭解。歡迎通過 [issue](https://github.com/morluto/rea/issues) 或 [pull request](https://github.com/morluto/rea/pulls) 分享案例,說明目標、你的問題、REA 如何提供幫助,以及你的發現。
|
||||||
@@ -247,7 +248,7 @@ npx rea-agents@latest setup
|
|||||||
|
|
||||||
## 文件
|
## 文件
|
||||||
|
|
||||||
可以先閱讀網站上的[實操指南](https://rea.tools/zh-TW/guides/)。具體選項、前提條件和結果契約見:
|
可以先閱讀網站上的[實操指南](https://rea.tools/guides/)。具體選項、前提條件和結果契約見:
|
||||||
|
|
||||||
- [安裝與設定](docs/installation.md):AI 代理註冊、提供者組態、更新和卸載。
|
- [安裝與設定](docs/installation.md):AI 代理註冊、提供者組態、更新和卸載。
|
||||||
- [就緒檢查與故障排查](docs/installation.md#check-readiness-for-your-task):診斷特定 AI 代理或分析引擎。
|
- [就緒檢查與故障排查](docs/installation.md#check-readiness-for-your-task):診斷特定 AI 代理或分析引擎。
|
||||||
@@ -260,7 +261,7 @@ npx rea-agents@latest setup
|
|||||||
|
|
||||||
## Star 歷史
|
## Star 歷史
|
||||||
|
|
||||||
🎉 **GitHub Star 達到 90,000 個,感謝大家!**
|
🎉 **GitHub Star 達到 50,000 個,感謝大家!**
|
||||||
|
|
||||||
感謝每一位使用 REA、報告錯誤、提出功能需求、測試建置和貢獻修復的朋友。
|
感謝每一位使用 REA、報告錯誤、提出功能需求、測試建置和貢獻修復的朋友。
|
||||||
|
|
||||||
|
|||||||
+12
-11
@@ -9,6 +9,7 @@
|
|||||||
**看到喜欢的功能,弄清它的工作原理,深入到二进制层面。**
|
**看到喜欢的功能,弄清它的工作原理,深入到二进制层面。**
|
||||||
|
|
||||||
[](https://www.npmjs.com/package/rea-agents)
|
[](https://www.npmjs.com/package/rea-agents)
|
||||||
|
[](https://github.com/morluto/rea/actions/workflows/ci.yml)
|
||||||
[](docs/mcp-contracts.md#generated-catalog)
|
[](docs/mcp-contracts.md#generated-catalog)
|
||||||
[](#current-status)
|
[](#current-status)
|
||||||
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
||||||
@@ -17,7 +18,7 @@
|
|||||||
|
|
||||||
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
||||||
|
|
||||||
**[网站](https://rea.tools/zh-CN/) · [指南](https://rea.tools/zh-CN/guides/) · [案例](https://rea.tools/zh-CN/showcase/)**
|
**[网站](https://rea.tools/) · [指南](https://rea.tools/guides/) · [案例](https://rea.tools/showcase/)**
|
||||||
|
|
||||||
[快速开始](#快速开始) · [REA 的工作原理](#rea-的工作原理) · [可以分析什么](#可以分析什么) · [案例](#案例) · [常见问题](#常见问题) · [文档](#文档)
|
[快速开始](#快速开始) · [REA 的工作原理](#rea-的工作原理) · [可以分析什么](#可以分析什么) · [案例](#案例) · [常见问题](#常见问题) · [文档](#文档)
|
||||||
|
|
||||||
@@ -53,7 +54,7 @@ REA 将智能体连接到分析工具,用于检查原生二进制文件、Java
|
|||||||
|
|
||||||
设置流程会向智能体注册 REA,并安装匹配的工作流指引。原生分析可以使用已有的 Hopper 或 Ghidra;设置流程也可以在你批准后安装 Hopper。静态 JavaScript 分析不需要这两个引擎。
|
设置流程会向智能体注册 REA,并安装匹配的工作流指引。原生分析可以使用已有的 Hopper 或 Ghidra;设置流程也可以在你批准后安装 Hopper。静态 JavaScript 分析不需要这两个引擎。
|
||||||
|
|
||||||
> **[访问 REA 网站](https://rea.tools/zh-CN/)**,查看设置说明、图解指南和真实案例。
|
> **[访问 REA 网站](https://rea.tools/)**,查看设置说明、图解指南和真实案例。
|
||||||
|
|
||||||
## 快速开始
|
## 快速开始
|
||||||
|
|
||||||
@@ -132,12 +133,12 @@ REA 需要 Node.js 22.x(>=22.19)、24.x(>=24.11)或 26+,以及 npm。
|
|||||||
|
|
||||||
| 目标 | REA 返回的内容 | 要求与指南 |
|
| 目标 | REA 返回的内容 | 要求与指南 |
|
||||||
| --------------------- | ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
|
| --------------------- | ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
|
||||||
| 原生二进制文件 | 伪代码、汇编、字符串、符号、调用和引用 | Hopper、Ghidra 或 IDA;[原生分析](https://rea.tools/zh-CN/guides/native/) |
|
| 原生二进制文件 | 伪代码、汇编、字符串、符号、调用和引用 | Hopper、Ghidra 或 IDA;[原生分析](https://rea.tools/guides/native/) |
|
||||||
| 离线 ELF 布局 | 节、段、原始符号/重定位信息及静态防护机制候选项 | Linux x64 上由调用方提供的 pwntools;[二进制诊断](docs/binary-diagnostics.md) |
|
| 离线 ELF 布局 | 节、段、原始符号/重定位信息及静态防护机制候选项 | Linux x64 上由调用方提供的 pwntools;[二进制诊断](docs/binary-diagnostics.md) |
|
||||||
| EVM 字节码 | 分派选择器、字节偏移、推断的参数和状态可变性 | Linux x64 上的本地原始字节/十六进制输入载体;[离线 EVM 指南](docs/evm-bytecode.md) |
|
| EVM 字节码 | 分派选择器、字节偏移、推断的参数和状态可变性 | Linux x64 上的本地原始字节/十六进制输入载体;[离线 EVM 指南](docs/evm-bytecode.md) |
|
||||||
| 已记录的 Linux 崩溃 | 原始 note 记录、每个已记录线程的寄存器/信号及可选的映射候选项 | Linux x64 上由调用方提供的 pwntools;可选的 GDB/pwndbg;[已记录崩溃](docs/recorded-crashes.md) |
|
| 已记录的 Linux 崩溃 | 原始 note 记录、每个已记录线程的寄存器/信号及可选的映射候选项 | Linux x64 上由调用方提供的 pwntools;可选的 GDB/pwndbg;[已记录崩溃](docs/recorded-crashes.md) |
|
||||||
| JavaScript / Electron | 模块、导入、source map、路由、IPC 和原生扩展关系 | Node.js 和 npm;[应用分析](https://rea.tools/zh-CN/guides/javascript/) |
|
| JavaScript / Electron | 模块、导入、source map、路由、IPC 和原生扩展关系 | Node.js 和 npm;[应用分析](https://rea.tools/guides/javascript/) |
|
||||||
| 网站 | 页面结构、脚本、网络观察结果和按请求获取的截图 | Chrome 系浏览器;[浏览器分析](https://rea.tools/zh-CN/guides/browser/) |
|
| 网站 | 页面结构、脚本、网络观察结果和按请求获取的截图 | Chrome 系浏览器;[浏览器分析](https://rea.tools/guides/browser/) |
|
||||||
| 已保存的网络捕获 | 请求、响应、可访问的载荷和来源位置 | HAR;原生 mitmproxy 捕获需要 Linux 上的 mitmdump;[捕获指南](docs/web-network-captures.md) |
|
| 已保存的网络捕获 | 请求、响应、可访问的载荷和来源位置 | HAR;原生 mitmproxy 捕获需要 Linux 上的 mitmdump;[捕获指南](docs/web-network-captures.md) |
|
||||||
| .NET 程序集 | 元数据、CIL 指令、声明的原生依赖和构建对比 | 静态检查;[托管代码指南](docs/managed-code-analysis.md) |
|
| .NET 程序集 | 元数据、CIL 指令、声明的原生依赖和构建对比 | 静态检查;[托管代码指南](docs/managed-code-analysis.md) |
|
||||||
| Android APK | 清单声明、类、反编译的方法和引用 | Linux/macOS/Windows x64 上的无界面 JADX 和完整 JDK;[Android 指南](docs/android-analysis.md) |
|
| Android APK | 清单声明、类、反编译的方法和引用 | Linux/macOS/Windows x64 上的无界面 JADX 和完整 JDK;[Android 指南](docs/android-analysis.md) |
|
||||||
@@ -156,26 +157,26 @@ REA 需要 Node.js 22.x(>=22.19)、24.x(>=24.11)或 26+,以及 npm。
|
|||||||
|
|
||||||
## 案例
|
## 案例
|
||||||
|
|
||||||
[](https://rea.tools/zh-CN/showcase/)
|
[](https://rea.tools/showcase/)
|
||||||
|
|
||||||
### DX-Ball:重建声像计算
|
### DX-Ball:重建声像计算
|
||||||
|
|
||||||
沿声音调用追踪到根据位置计算声像的辅助函数,检查指令,将不完整的伪代码转为 C。重建结果通过了 3,205 个原始 x86 测试用例,并复现了编译后函数的全部 63 个字节。
|
沿声音调用追踪到根据位置计算声像的辅助函数,检查指令,将不完整的伪代码转为 C。重建结果通过了 3,205 个原始 x86 测试用例,并复现了编译后函数的全部 63 个字节。
|
||||||
|
|
||||||
[阅读案例](https://rea.tools/zh-CN/showcase/dx-ball/) ·
|
[阅读案例](https://rea.tools/showcase/dx-ball/) ·
|
||||||
[重建项目仓库](https://github.com/N0zoM1z0/dx-ball)
|
[重建项目仓库](https://github.com/N0zoM1z0/dx-ball)
|
||||||
|
|
||||||
### Notion:追踪 Electron 剪贴板桥
|
### Notion:追踪 Electron 剪贴板桥
|
||||||
|
|
||||||
找到渲染进程的剪贴板 API,沿 preload 和 IPC 追踪到主进程,并检查富格式剪贴板数据。
|
找到渲染进程的剪贴板 API,沿 preload 和 IPC 追踪到主进程,并检查富格式剪贴板数据。
|
||||||
|
|
||||||
[阅读案例](https://rea.tools/zh-CN/showcase/notion/)
|
[阅读案例](https://rea.tools/showcase/notion/)
|
||||||
|
|
||||||
### TH04:恢复 DOS 环形子弹的计算
|
### TH04:恢复 DOS 环形子弹的计算
|
||||||
|
|
||||||
检查原始 PC-98 游戏的 16 位指令,恢复固定角度和瞄准角度的计算,并将重建的 C++ 与当年的编译器输出进行对比。
|
检查原始 PC-98 游戏的 16 位指令,恢复固定角度和瞄准角度的计算,并将重建的 C++ 与当年的编译器输出进行对比。
|
||||||
|
|
||||||
[阅读案例](https://rea.tools/zh-CN/showcase/th04/) ·
|
[阅读案例](https://rea.tools/showcase/th04/) ·
|
||||||
[重建项目仓库](https://github.com/N0zoM1z0/th04)
|
[重建项目仓库](https://github.com/N0zoM1z0/th04)
|
||||||
|
|
||||||
如果你用 REA 分析了有趣的目标,我们很想了解。欢迎通过 [issue](https://github.com/morluto/rea/issues) 或 [pull request](https://github.com/morluto/rea/pulls) 分享案例,说明目标、你的问题、REA 如何提供帮助,以及你的发现。
|
如果你用 REA 分析了有趣的目标,我们很想了解。欢迎通过 [issue](https://github.com/morluto/rea/issues) 或 [pull request](https://github.com/morluto/rea/pulls) 分享案例,说明目标、你的问题、REA 如何提供帮助,以及你的发现。
|
||||||
@@ -247,7 +248,7 @@ npx rea-agents@latest setup
|
|||||||
|
|
||||||
## 文档
|
## 文档
|
||||||
|
|
||||||
可以先阅读网站上的[实操指南](https://rea.tools/zh-CN/guides/)。具体选项、前提条件和结果契约见:
|
可以先阅读网站上的[实操指南](https://rea.tools/guides/)。具体选项、前提条件和结果契约见:
|
||||||
|
|
||||||
- [安装与设置](docs/installation.md):智能体注册、提供方配置、更新和卸载。
|
- [安装与设置](docs/installation.md):智能体注册、提供方配置、更新和卸载。
|
||||||
- [就绪检查与故障排查](docs/installation.md#check-readiness-for-your-task):诊断特定智能体或分析引擎。
|
- [就绪检查与故障排查](docs/installation.md#check-readiness-for-your-task):诊断特定智能体或分析引擎。
|
||||||
@@ -260,7 +261,7 @@ npx rea-agents@latest setup
|
|||||||
|
|
||||||
## Star 历史
|
## Star 历史
|
||||||
|
|
||||||
🎉 **GitHub Star 达到 90,000 个,感谢大家!**
|
🎉 **GitHub Star 达到 50,000 个,感谢大家!**
|
||||||
|
|
||||||
感谢每一位使用 REA、报告错误、提出功能需求、测试构建和贡献修复的朋友。
|
感谢每一位使用 REA、报告错误、提出功能需求、测试构建和贡献修复的朋友。
|
||||||
|
|
||||||
|
|||||||
@@ -126,20 +126,6 @@ class ReaJadxBridge {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private JadxSession.SmartCode methodBody(JadxSession current, ClassSnapshot cls,
|
|
||||||
MethodSnapshot selected, JavaMethod method) {
|
|
||||||
if (!selected.shortId().equals("<clinit>()V"))
|
|
||||||
return current.getMethodBodySmart(method, current.getMaxSourceBytes(), true);
|
|
||||||
// Java code generation can fold all or part of <clinit> into field declarations.
|
|
||||||
// Its method text cannot establish coverage, even when a static block remains.
|
|
||||||
JadxSession.MethodSmali smali = current.getMethodSmali(cls.node(), method.getName());
|
|
||||||
if (!smali.getFound() || smali.getBlocks().size() != 1)
|
|
||||||
throw new IllegalArgumentException("Static initializer disassembly requires one exact method: " + selected.shortId());
|
|
||||||
return new JadxSession.SmartCode(
|
|
||||||
TextUtilKt.truncateToBytes(smali.getBlocks().get(0), current.getMaxSourceBytes()),
|
|
||||||
"smali", true, List.of("static_initializer_disassembly"));
|
|
||||||
}
|
|
||||||
|
|
||||||
private CallToolResult handle(String name, JsonObject args) {
|
private CallToolResult handle(String name, JsonObject args) {
|
||||||
if (name.equals("rea_jvm_status")) return json(Map.of(
|
if (name.equals("rea_jvm_status")) return json(Map.of(
|
||||||
"engine_reported_version", BuildInfo.VERSION,
|
"engine_reported_version", BuildInfo.VERSION,
|
||||||
@@ -164,7 +150,7 @@ class ReaJadxBridge {
|
|||||||
int index = integer(args, "overload_index", 0);
|
int index = integer(args, "overload_index", 0);
|
||||||
if (index >= overloads.size()) throw new InputFailure("overload_index", "overload_index out of range: " + index);
|
if (index >= overloads.size()) throw new InputFailure("overload_index", "overload_index out of range: " + index);
|
||||||
JavaMethod method = method(cls, overloads.get(index));
|
JavaMethod method = method(cls, overloads.get(index));
|
||||||
JadxSession.SmartCode code = methodBody(current, cls, overloads.get(index), method);
|
JadxSession.SmartCode code = current.getMethodBodySmart(method, current.getMaxSourceBytes(), true);
|
||||||
return json(Map.of("class_name", cls.summary().get("full_name"),
|
return json(Map.of("class_name", cls.summary().get("full_name"),
|
||||||
"method_name", overloads.get(index).name(), "full_name", method.getFullName(),
|
"method_name", overloads.get(index).name(), "full_name", method.getFullName(),
|
||||||
"overload_index", index, "overload_count", overloads.size(),
|
"overload_index", index, "overload_count", overloads.size(),
|
||||||
@@ -225,7 +211,7 @@ class ReaJadxBridge {
|
|||||||
String description = switch (name) {
|
String description = switch (name) {
|
||||||
case "list_classes" -> "Indexed pages of all top-level class names, with offset and limit.";
|
case "list_classes" -> "Indexed pages of all top-level class names, with offset and limit.";
|
||||||
case "get_class_summary" -> "Parsed member metadata for one exact class name; no source generation.";
|
case "get_class_summary" -> "Parsed member metadata for one exact class name; no source generation.";
|
||||||
case "get_method_body" -> "Source for an exact class and stable same-name overload index; static initializers use smali to preserve folded field initialization.";
|
case "get_method_body" -> "Source for an exact class and stable same-name overload index, with smali fallback.";
|
||||||
default -> "Complete static references to an exact class or unique method; source lines are unresolved.";
|
default -> "Complete static references to an exact class or unique method; source lines are unresolved.";
|
||||||
};
|
};
|
||||||
Tool narrowed = new Tool(name, new ToolSchema(null, new JsonObject(properties),
|
Tool narrowed = new Tool(name, new ToolSchema(null, new JsonObject(properties),
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import ghidra.app.plugin.core.analysis.AutoAnalysisManager;
|
|
||||||
import ghidra.app.util.headless.HeadlessScript;
|
|
||||||
|
|
||||||
/** Disable the named auto-analyzers before default auto-analysis. */
|
|
||||||
public final class ReaGhidraAnalysisOptions extends HeadlessScript {
|
|
||||||
@Override
|
|
||||||
public void run() throws Exception {
|
|
||||||
String[] arguments = getScriptArgs();
|
|
||||||
if (arguments.length != 1 || arguments[0].isBlank()) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"ReaGhidraAnalysisOptions requires one comma-separated analyzer-name argument");
|
|
||||||
}
|
|
||||||
String[] names = arguments[0].split(",");
|
|
||||||
AutoAnalysisManager analysis = AutoAnalysisManager.getAnalysisManager(currentProgram);
|
|
||||||
Map<String, String> options = getCurrentAnalysisOptionsAndValues(currentProgram);
|
|
||||||
for (String requestedName : names) {
|
|
||||||
monitor.checkCancelled();
|
|
||||||
String name = requestedName.trim();
|
|
||||||
if (analysis.getAnalyzer(name) == null || !options.containsKey(name)) {
|
|
||||||
throw new IllegalArgumentException("Unknown Ghidra analyzer for this program: " + name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (String requestedName : names) {
|
|
||||||
monitor.checkCancelled();
|
|
||||||
setAnalysisOption(currentProgram, requestedName.trim(), "false");
|
|
||||||
}
|
|
||||||
options = getCurrentAnalysisOptionsAndValues(currentProgram);
|
|
||||||
for (String requestedName : names) {
|
|
||||||
monitor.checkCancelled();
|
|
||||||
String name = requestedName.trim();
|
|
||||||
if (!"false".equals(options.get(name))) {
|
|
||||||
throw new IllegalStateException("Ghidra analyzer remained enabled: " + name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -182,17 +182,10 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|||||||
}
|
}
|
||||||
sessionDefaultAddressSpace =
|
sessionDefaultAddressSpace =
|
||||||
currentProgram.getAddressFactory().getDefaultAddressSpace();
|
currentProgram.getAddressFactory().getDefaultAddressSpace();
|
||||||
if (currentProgram.getExecutableFormat().equals("Raw Binary")) {
|
if (currentProgram.getExecutableFormat().equals("Raw Binary") &&
|
||||||
boolean dosCom = currentProgram.getLanguageID().getIdAsString()
|
!currentProgram.getOptions(ghidra.program.model.listing.Program.PROGRAM_INFO)
|
||||||
.equals("x86:LE:16:Real Mode");
|
.getBoolean("REA DOS COM prepared", false)) {
|
||||||
String preparation = dosCom ? "REA DOS COM prepared" : "REA raw binary prepared";
|
throw new IllegalStateException("REA DOS COM entry/context preparation failed");
|
||||||
if (!currentProgram.getOptions(ghidra.program.model.listing.Program.PROGRAM_INFO)
|
|
||||||
.getBoolean(preparation, false)) {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
dosCom ? "REA DOS COM entry/context preparation failed" :
|
|
||||||
"REA raw binary entry preparation failed"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!Application.getApplicationVersion().equals(descriptor.providerVersion)) {
|
if (!Application.getApplicationVersion().equals(descriptor.providerVersion)) {
|
||||||
throw new IllegalStateException("Ghidra provider version does not match the session");
|
throw new IllegalStateException("Ghidra provider version does not match the session");
|
||||||
@@ -382,7 +375,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|||||||
case "search_procedures" -> search(request.params, true);
|
case "search_procedures" -> search(request.params, true);
|
||||||
case "search_strings" -> search(request.params, false);
|
case "search_strings" -> search(request.params, false);
|
||||||
case "inspect_native_data_type" -> inspectNativeDataType(request.params);
|
case "inspect_native_data_type" -> inspectNativeDataType(request.params);
|
||||||
case "inspect_native_instruction" -> inspectNativeInstruction(request.params, true);
|
case "inspect_native_instruction" -> inspectNativeInstruction(request.params);
|
||||||
case "resolve_native_call_targets" -> resolveNativeCallTargets(request.params);
|
case "resolve_native_call_targets" -> resolveNativeCallTargets(request.params);
|
||||||
case "xrefs" -> xrefs(request.params);
|
case "xrefs" -> xrefs(request.params);
|
||||||
case "analyze_function" -> {
|
case "analyze_function" -> {
|
||||||
@@ -450,11 +443,6 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|||||||
String seeds = currentProgram.getOptions(ghidra.program.model.listing.Program.PROGRAM_INFO)
|
String seeds = currentProgram.getOptions(ghidra.program.model.listing.Program.PROGRAM_INFO)
|
||||||
.getString("REA analysis seeds", null);
|
.getString("REA analysis seeds", null);
|
||||||
if (seeds != null) result.add("analysis_seeds", JsonParser.parseString(seeds));
|
if (seeds != null) result.add("analysis_seeds", JsonParser.parseString(seeds));
|
||||||
// Written by ReaGhidraMipsSoftFloat after analysis; REA requires it
|
|
||||||
// exactly when the committed profile declares soft-float storage.
|
|
||||||
String softFloat = currentProgram.getOptions(ghidra.program.model.listing.Program.PROGRAM_INFO)
|
|
||||||
.getString("REA MIPS soft-float storage", null);
|
|
||||||
if (softFloat != null) result.add("mips_soft_float_storage", JsonParser.parseString(softFloat));
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -897,7 +885,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
private JsonObject inspectNativeInstruction(JsonObject params, boolean includeIncoming) throws Exception {
|
private JsonObject inspectNativeInstruction(JsonObject params) throws Exception {
|
||||||
requireKeys(params, Set.of("document", "address"));
|
requireKeys(params, Set.of("document", "address"));
|
||||||
requireDocument(params);
|
requireDocument(params);
|
||||||
Address address = requireAddress(params, "address");
|
Address address = requireAddress(params, "address");
|
||||||
@@ -980,19 +968,6 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|||||||
result.add("operands", operands);
|
result.add("operands", operands);
|
||||||
result.add("flow", flow);
|
result.add("flow", flow);
|
||||||
result.add("references", references);
|
result.add("references", references);
|
||||||
if (includeIncoming) {
|
|
||||||
TreeMap<String, Reference> incoming = new TreeMap<>();
|
|
||||||
ReferenceIterator incomingIterator = currentProgram.getReferenceManager().getReferencesTo(address);
|
|
||||||
while (incomingIterator.hasNext()) {
|
|
||||||
monitor.checkCancelled();
|
|
||||||
addReference(incoming, incomingIterator.next());
|
|
||||||
}
|
|
||||||
List<Reference> orderedIncoming = new ArrayList<>(incoming.values());
|
|
||||||
orderedIncoming.sort(REFERENCE_ORDER);
|
|
||||||
JsonArray incomingReferences = new JsonArray();
|
|
||||||
for (Reference reference : orderedIncoming) incomingReferences.add(instructionReference(reference));
|
|
||||||
result.add("incoming_references", incomingReferences);
|
|
||||||
}
|
|
||||||
List<String> limitations = new ArrayList<>(List.of("Operand components are Ghidra Listing decoder tokens; effective memory base/index/displacement roles and per-instruction context mode are unavailable. The mode field is the program language variant."));
|
List<String> limitations = new ArrayList<>(List.of("Operand components are Ghidra Listing decoder tokens; effective memory base/index/displacement roles and per-instruction context mode are unavailable. The mode field is the program language variant."));
|
||||||
if (flow.get("kind").getAsString().equals("terminal")) limitations.add("No RETURN operation was observed in the provider's instruction p-code; terminal classification remains generic.");
|
if (flow.get("kind").getAsString().equals("terminal")) limitations.add("No RETURN operation was observed in the provider's instruction p-code; terminal classification remains generic.");
|
||||||
result.add("limitations", GSON.toJsonTree(limitations));
|
result.add("limitations", GSON.toJsonTree(limitations));
|
||||||
@@ -1000,7 +975,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private JsonObject resolveNativeCallTargets(JsonObject params) throws Exception {
|
private JsonObject resolveNativeCallTargets(JsonObject params) throws Exception {
|
||||||
JsonObject instruction = inspectNativeInstruction(params, false);
|
JsonObject instruction = inspectNativeInstruction(params);
|
||||||
JsonObject result = new JsonObject();
|
JsonObject result = new JsonObject();
|
||||||
result.add("call_site", instruction.get("address"));
|
result.add("call_site", instruction.get("address"));
|
||||||
result.add("procedure", instruction.get("procedure"));
|
result.add("procedure", instruction.get("procedure"));
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
import org.osgi.framework.BundleActivator;
|
|
||||||
import org.osgi.framework.BundleContext;
|
|
||||||
|
|
||||||
// Compile the no-op activator with REA's scripts. Otherwise Ghidra generates
|
|
||||||
// one afterward and opens a second Java compiler and file manager.
|
|
||||||
public final class ReaGhidraBundleActivator implements BundleActivator {
|
|
||||||
@Override
|
|
||||||
public void start(BundleContext context) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void stop(BundleContext context) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,176 +0,0 @@
|
|||||||
import ghidra.app.script.GhidraScript;
|
|
||||||
import ghidra.program.database.SpecExtension;
|
|
||||||
import ghidra.program.model.data.AbstractFloatDataType;
|
|
||||||
import ghidra.program.model.data.DataType;
|
|
||||||
import ghidra.program.model.data.DoubleDataType;
|
|
||||||
import ghidra.program.model.data.FloatDataType;
|
|
||||||
import ghidra.program.model.data.FunctionDefinition;
|
|
||||||
import ghidra.program.model.data.IntegerDataType;
|
|
||||||
import ghidra.program.model.data.ParameterDefinition;
|
|
||||||
import ghidra.program.model.data.TypeDef;
|
|
||||||
import ghidra.program.model.lang.CompilerSpec;
|
|
||||||
import ghidra.program.model.lang.PrototypeModel;
|
|
||||||
import ghidra.program.model.lang.Register;
|
|
||||||
import ghidra.program.model.listing.Function;
|
|
||||||
import ghidra.program.model.listing.Parameter;
|
|
||||||
import ghidra.program.model.listing.Program;
|
|
||||||
import ghidra.program.model.listing.VariableStorage;
|
|
||||||
import ghidra.program.model.pcode.XmlEncode;
|
|
||||||
import java.io.StringReader;
|
|
||||||
import java.io.StringWriter;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
|
||||||
import javax.xml.transform.OutputKeys;
|
|
||||||
import javax.xml.transform.TransformerFactory;
|
|
||||||
import javax.xml.transform.dom.DOMSource;
|
|
||||||
import javax.xml.transform.stream.StreamResult;
|
|
||||||
import org.w3c.dom.Document;
|
|
||||||
import org.w3c.dom.Element;
|
|
||||||
import org.w3c.dom.Node;
|
|
||||||
import org.w3c.dom.NodeList;
|
|
||||||
import org.xml.sax.InputSource;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Soft-float o32 passes and returns float/double values exactly where same-size integers go.
|
|
||||||
* Ghidra's MIPS32 compiler specifications model only hard-float o32, so every typed float
|
|
||||||
* prototype (functions, externals, thunks via their targets, and function-pointer definitions)
|
|
||||||
* would otherwise read $f12/$f14/$f0. Derive a program-specific prototype model from the
|
|
||||||
* program's own default o32 model with its floating-point entries and rules removed, install it
|
|
||||||
* as a specification extension, and assign it to every callable whose formal types use floats.
|
|
||||||
*/
|
|
||||||
public final class ReaGhidraMipsSoftFloat extends GhidraScript {
|
|
||||||
static final String REPORT_KEY = "REA MIPS soft-float storage";
|
|
||||||
static final String POLICY = "o32-soft-float-prototype-v1";
|
|
||||||
static final String PROTOTYPE = "__rea_soft_float";
|
|
||||||
private static final Pattern FPU_REGISTER = Pattern.compile("f\\d+(_\\d+)?");
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() throws Exception {
|
|
||||||
String processor = currentProgram.getLanguage().getProcessor().toString();
|
|
||||||
if (!processor.equals("MIPS") || currentProgram.getDefaultPointerSize() != 4)
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"REA soft-float storage requires a 32-bit MIPS program, not " + processor);
|
|
||||||
CompilerSpec spec = currentProgram.getCompilerSpec();
|
|
||||||
PrototypeModel base = spec.getDefaultCallingConvention();
|
|
||||||
new SpecExtension(currentProgram)
|
|
||||||
.addReplaceCompilerSpecExtension(softFloatPrototype(base, spec), monitor);
|
|
||||||
PrototypeModel soft = currentProgram.getCompilerSpec().getCallingConvention(PROTOTYPE);
|
|
||||||
if (soft == null)
|
|
||||||
throw new IllegalStateException("REA soft-float prototype was not installed");
|
|
||||||
requireIntegerStorage(
|
|
||||||
soft.getStorageLocations(
|
|
||||||
currentProgram,
|
|
||||||
new DataType[] {
|
|
||||||
FloatDataType.dataType, IntegerDataType.dataType, DoubleDataType.dataType,
|
|
||||||
FloatDataType.dataType, DoubleDataType.dataType
|
|
||||||
},
|
|
||||||
false),
|
|
||||||
"soft-float prototype self-check");
|
|
||||||
int functions = 0;
|
|
||||||
List<Function> callables = new ArrayList<>();
|
|
||||||
currentProgram.getFunctionManager().getFunctions(true).forEach(callables::add);
|
|
||||||
currentProgram.getFunctionManager().getExternalFunctions().forEach(callables::add);
|
|
||||||
for (Function function : callables) {
|
|
||||||
// A thunk's signature is its target's; the target is in this list.
|
|
||||||
if (function.isThunk() || !usesFloat(function)) continue;
|
|
||||||
if (function.hasCustomVariableStorage()) function.setCustomVariableStorage(false);
|
|
||||||
function.setCallingConvention(PROTOTYPE);
|
|
||||||
List<VariableStorage> storage = new ArrayList<>();
|
|
||||||
storage.add(function.getReturn().getVariableStorage());
|
|
||||||
for (Parameter parameter : function.getParameters()) storage.add(parameter.getVariableStorage());
|
|
||||||
requireIntegerStorage(storage.toArray(VariableStorage[]::new), function.getName(true));
|
|
||||||
functions += 1;
|
|
||||||
}
|
|
||||||
int definitions = 0;
|
|
||||||
Iterator<DataType> types = currentProgram.getDataTypeManager().getAllDataTypes();
|
|
||||||
while (types.hasNext()) {
|
|
||||||
if (!(types.next() instanceof FunctionDefinition definition) || !usesFloat(definition))
|
|
||||||
continue;
|
|
||||||
definition.setCallingConvention(PROTOTYPE);
|
|
||||||
definitions += 1;
|
|
||||||
}
|
|
||||||
// Written last: any failure above leaves no report, and REA refuses the session.
|
|
||||||
currentProgram.getOptions(Program.PROGRAM_INFO).setString(
|
|
||||||
REPORT_KEY,
|
|
||||||
"{\"policy\":\"" + POLICY + "\",\"functions\":" + functions +
|
|
||||||
",\"definitions\":" + definitions + "}");
|
|
||||||
println("REA MIPS soft-float prototype: functions=" + functions + " definitions=" + definitions);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The default o32 model without floating-point registers or float-consuming rules. */
|
|
||||||
private static String softFloatPrototype(PrototypeModel base, CompilerSpec spec) throws Exception {
|
|
||||||
XmlEncode encoder = new XmlEncode();
|
|
||||||
base.encode(encoder, spec.getPcodeInjectLibrary());
|
|
||||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
|
||||||
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
|
|
||||||
Document document =
|
|
||||||
factory.newDocumentBuilder().parse(new InputSource(new StringReader(encoder.toString())));
|
|
||||||
Element root = document.getDocumentElement();
|
|
||||||
if (!root.getTagName().equals("prototype"))
|
|
||||||
throw new IllegalStateException("Unexpected default prototype encoding " + root.getTagName());
|
|
||||||
root.setAttribute("name", PROTOTYPE);
|
|
||||||
List<Node> removed = new ArrayList<>();
|
|
||||||
collect(root.getElementsByTagName("pentry"), "metatype", "float", null, removed);
|
|
||||||
collect(root.getElementsByTagName("consume"), "storage", "float", "rule", removed);
|
|
||||||
if (removed.isEmpty())
|
|
||||||
throw new IllegalStateException("Default prototype has no floating-point entries to remove");
|
|
||||||
for (Node node : removed) node.getParentNode().removeChild(node);
|
|
||||||
StringWriter xml = new StringWriter();
|
|
||||||
var transformer = TransformerFactory.newInstance().newTransformer();
|
|
||||||
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
|
|
||||||
transformer.transform(new DOMSource(document), new StreamResult(xml));
|
|
||||||
return xml.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Select matching elements, or their nearest `ancestor` element when one is named. */
|
|
||||||
private static void collect(
|
|
||||||
NodeList nodes, String attribute, String value, String ancestor, List<Node> selected) {
|
|
||||||
for (int index = 0; index < nodes.getLength(); index += 1) {
|
|
||||||
Element element = (Element) nodes.item(index);
|
|
||||||
if (!value.equals(element.getAttribute(attribute))) continue;
|
|
||||||
Node target = element;
|
|
||||||
while (ancestor != null && target != null && !ancestor.equals(target.getNodeName()))
|
|
||||||
target = target.getParentNode();
|
|
||||||
if (target != null && !selected.contains(target)) selected.add(target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void requireIntegerStorage(VariableStorage[] storage, String owner) {
|
|
||||||
for (VariableStorage item : storage) {
|
|
||||||
if (item.isBadStorage() || item.isUnassignedStorage())
|
|
||||||
throw new IllegalStateException("REA soft-float storage unresolved for " + owner);
|
|
||||||
List<Register> registers = item.getRegisters();
|
|
||||||
if (registers == null) continue; // stack-only storage
|
|
||||||
for (Register register : registers) {
|
|
||||||
if (FPU_REGISTER.matcher(register.getName()).matches())
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"REA soft-float storage still uses " + register.getName() + " for " + owner);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean usesFloat(Function function) {
|
|
||||||
if (isFloat(function.getReturn().getFormalDataType())) return true;
|
|
||||||
for (Parameter parameter : function.getParameters()) {
|
|
||||||
if (isFloat(parameter.getFormalDataType())) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean usesFloat(FunctionDefinition definition) {
|
|
||||||
if (isFloat(definition.getReturnType())) return true;
|
|
||||||
for (ParameterDefinition argument : definition.getArguments()) {
|
|
||||||
if (isFloat(argument.getDataType())) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isFloat(DataType type) {
|
|
||||||
DataType current = type;
|
|
||||||
while (current instanceof TypeDef typeDef) current = typeDef.getBaseDataType();
|
|
||||||
return current instanceof AbstractFloatDataType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
import ghidra.app.script.GhidraScript;
|
|
||||||
import ghidra.program.model.address.Address;
|
|
||||||
import ghidra.program.model.listing.Program;
|
|
||||||
|
|
||||||
/** Seed the caller-supplied raw-binary entry before default auto-analysis. */
|
|
||||||
public final class ReaGhidraPrepareRaw extends GhidraScript {
|
|
||||||
@Override
|
|
||||||
public void run() throws Exception {
|
|
||||||
String[] arguments = getScriptArgs();
|
|
||||||
if (arguments.length != 2) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Raw binary preparation requires the committed language and entry address"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
String expectedLanguage = arguments[0];
|
|
||||||
String entryHex = arguments[1];
|
|
||||||
if (!currentProgram.getLanguageID().getIdAsString().equals(expectedLanguage) ||
|
|
||||||
!currentProgram.getExecutableFormat().equals("Raw Binary")) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Raw binary preparation requires the committed language and BinaryLoader import"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Address entry = currentProgram.getAddressFactory().getDefaultAddressSpace().getAddress(entryHex);
|
|
||||||
Address start = currentProgram.getMinAddress();
|
|
||||||
if (entry == null || !entry.equals(start)) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Raw binary import must map file offset 0 at the caller-supplied entry"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
addEntryPoint(entry);
|
|
||||||
if (!disassemble(entry) || createFunction(entry, "entry") == null) {
|
|
||||||
throw new IllegalStateException("Raw binary entry cannot be decoded as a function");
|
|
||||||
}
|
|
||||||
currentProgram.getOptions(Program.PROGRAM_INFO).setBoolean("REA raw binary prepared", true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+68
-91
@@ -1016,87 +1016,73 @@ def _dispatch(method, params):
|
|||||||
def _serve_connection(connection):
|
def _serve_connection(connection):
|
||||||
"""Serve one capability-authenticated NDJSON connection."""
|
"""Serve one capability-authenticated NDJSON connection."""
|
||||||
file = connection.makefile("rwb")
|
file = connection.makefile("rwb")
|
||||||
should_stop = False
|
while True:
|
||||||
try:
|
line = file.readline()
|
||||||
while True:
|
if not line:
|
||||||
line = file.readline()
|
break
|
||||||
if not line:
|
request_id = None
|
||||||
break
|
authenticated = False
|
||||||
request_id = None
|
should_stop = False
|
||||||
authenticated = False
|
|
||||||
should_stop = False
|
|
||||||
try:
|
|
||||||
try:
|
|
||||||
request = json.loads(line.decode("utf-8"))
|
|
||||||
except (UnicodeDecodeError, json.JSONDecodeError) as error:
|
|
||||||
raise InvalidRequestError("Invalid bridge request JSON") from error
|
|
||||||
if not isinstance(request, dict) or set(request) != {"id", "token", "method", "params"}:
|
|
||||||
raise InvalidRequestError("Invalid bridge request shape")
|
|
||||||
request_id = request["id"]
|
|
||||||
if isinstance(request_id, bool) or not isinstance(request_id, int) or request_id < 0:
|
|
||||||
raise InvalidRequestError("Invalid bridge request id")
|
|
||||||
if (
|
|
||||||
not isinstance(request["method"], str) or not request["method"]
|
|
||||||
or not isinstance(request["params"], dict)
|
|
||||||
):
|
|
||||||
raise InvalidRequestError("Invalid bridge method or parameters")
|
|
||||||
if (
|
|
||||||
not isinstance(request["token"], str) or not request["token"].isascii()
|
|
||||||
or not hmac.compare_digest(request["token"], REA_TOKEN)
|
|
||||||
):
|
|
||||||
raise PermissionError("Invalid bridge capability")
|
|
||||||
authenticated = True
|
|
||||||
_write_message(file, {"id": request_id, "event": {
|
|
||||||
"type": "progress",
|
|
||||||
"phase": "hopper_bridge",
|
|
||||||
"completed": 0,
|
|
||||||
"total": 1,
|
|
||||||
"message": "Hopper bridge started request",
|
|
||||||
}})
|
|
||||||
result = _dispatch(request["method"], request["params"])
|
|
||||||
should_stop = request["method"] in ("shutdown", "shutdown_document") and (
|
|
||||||
result.get("shutdown") is True and (
|
|
||||||
(result.get("document_closed") is True and result.get("analysis_stopped") is True)
|
|
||||||
or (result.get("document_closed") is False and result.get("document_retained") is True)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
safe_result = _json_safe(result)
|
|
||||||
_write_message(file, {"id": request_id, "event": {
|
|
||||||
"type": "progress",
|
|
||||||
"phase": "hopper_bridge",
|
|
||||||
"completed": 1,
|
|
||||||
"total": 1,
|
|
||||||
"message": "Hopper bridge completed request",
|
|
||||||
"terminal": True,
|
|
||||||
}})
|
|
||||||
response = {"id": request_id, "result": safe_result}
|
|
||||||
except Exception as error:
|
|
||||||
diagnostic = _safe_diagnostic(error)
|
|
||||||
if authenticated:
|
|
||||||
_write_message(file, {"id": request_id, "event": {
|
|
||||||
"type": "diagnostic",
|
|
||||||
"error": diagnostic,
|
|
||||||
}})
|
|
||||||
response_id = request_id if (
|
|
||||||
isinstance(request_id, int)
|
|
||||||
and not isinstance(request_id, bool)
|
|
||||||
and request_id >= 0
|
|
||||||
) else 0
|
|
||||||
response = {"id": response_id, "error": diagnostic}
|
|
||||||
_write_message(file, response)
|
|
||||||
if should_stop:
|
|
||||||
break
|
|
||||||
except (ConnectionError, OSError):
|
|
||||||
# A lost client cannot confirm document closure or revoke this run.
|
|
||||||
pass
|
|
||||||
finally:
|
|
||||||
try:
|
try:
|
||||||
file.close()
|
try:
|
||||||
except OSError:
|
request = json.loads(line.decode("utf-8"))
|
||||||
# Closing a failed writer can repeat the same disconnected-pipe error.
|
except (UnicodeDecodeError, json.JSONDecodeError) as error:
|
||||||
pass
|
raise InvalidRequestError("Invalid bridge request JSON") from error
|
||||||
connection.close()
|
if not isinstance(request, dict) or set(request) != {"id", "token", "method", "params"}:
|
||||||
return should_stop
|
raise InvalidRequestError("Invalid bridge request shape")
|
||||||
|
request_id = request["id"]
|
||||||
|
if isinstance(request_id, bool) or not isinstance(request_id, int) or request_id < 0:
|
||||||
|
raise InvalidRequestError("Invalid bridge request id")
|
||||||
|
if (
|
||||||
|
not isinstance(request["method"], str) or not request["method"]
|
||||||
|
or not isinstance(request["params"], dict)
|
||||||
|
):
|
||||||
|
raise InvalidRequestError("Invalid bridge method or parameters")
|
||||||
|
if (
|
||||||
|
not isinstance(request["token"], str) or not request["token"].isascii()
|
||||||
|
or not hmac.compare_digest(request["token"], REA_TOKEN)
|
||||||
|
):
|
||||||
|
raise PermissionError("Invalid bridge capability")
|
||||||
|
authenticated = True
|
||||||
|
_write_message(file, {"id": request_id, "event": {
|
||||||
|
"type": "progress",
|
||||||
|
"phase": "hopper_bridge",
|
||||||
|
"completed": 0,
|
||||||
|
"total": 1,
|
||||||
|
"message": "Hopper bridge started request",
|
||||||
|
}})
|
||||||
|
result = _dispatch(request["method"], request["params"])
|
||||||
|
should_stop = request["method"] == "shutdown_document" or (
|
||||||
|
request["method"] == "shutdown" and not result.get("cleanup_required", False)
|
||||||
|
)
|
||||||
|
safe_result = _json_safe(result)
|
||||||
|
_write_message(file, {"id": request_id, "event": {
|
||||||
|
"type": "progress",
|
||||||
|
"phase": "hopper_bridge",
|
||||||
|
"completed": 1,
|
||||||
|
"total": 1,
|
||||||
|
"message": "Hopper bridge completed request",
|
||||||
|
"terminal": True,
|
||||||
|
}})
|
||||||
|
response = {"id": request_id, "result": safe_result}
|
||||||
|
except Exception as error:
|
||||||
|
diagnostic = _safe_diagnostic(error)
|
||||||
|
if authenticated:
|
||||||
|
_write_message(file, {"id": request_id, "event": {
|
||||||
|
"type": "diagnostic",
|
||||||
|
"error": diagnostic,
|
||||||
|
}})
|
||||||
|
response_id = request_id if (
|
||||||
|
isinstance(request_id, int)
|
||||||
|
and not isinstance(request_id, bool)
|
||||||
|
and request_id >= 0
|
||||||
|
) else 0
|
||||||
|
response = {"id": response_id, "error": diagnostic}
|
||||||
|
_write_message(file, response)
|
||||||
|
if should_stop:
|
||||||
|
break
|
||||||
|
file.close()
|
||||||
|
connection.close()
|
||||||
|
|
||||||
|
|
||||||
def _write_message(file, message):
|
def _write_message(file, message):
|
||||||
@@ -1138,17 +1124,8 @@ def _run():
|
|||||||
os.chmod(REA_SOCKET, 0o600)
|
os.chmod(REA_SOCKET, 0o600)
|
||||||
server.listen(1)
|
server.listen(1)
|
||||||
try:
|
try:
|
||||||
while True:
|
connection, _ = server.accept()
|
||||||
try:
|
_serve_connection(connection)
|
||||||
connection, _ = server.accept()
|
|
||||||
except socket.timeout:
|
|
||||||
break
|
|
||||||
connection.settimeout(None)
|
|
||||||
if _serve_connection(connection):
|
|
||||||
break
|
|
||||||
# Match REA's cleanup handshake budget without pinning Hopper's
|
|
||||||
# Python thread indefinitely after a client disappears.
|
|
||||||
server.settimeout(REA_RECONNECT_TIMEOUT_SECONDS)
|
|
||||||
finally:
|
finally:
|
||||||
server.close()
|
server.close()
|
||||||
if os.path.exists(REA_SOCKET):
|
if os.path.exists(REA_SOCKET):
|
||||||
|
|||||||
@@ -54,7 +54,6 @@ export default defineConfig({
|
|||||||
{ text: "IDA", link: "/ida-provider" },
|
{ text: "IDA", link: "/ida-provider" },
|
||||||
{ text: "Ghidra on Windows", link: "/windows-ghidra-p0" },
|
{ text: "Ghidra on Windows", link: "/windows-ghidra-p0" },
|
||||||
{ text: "Ghidra DOS analysis", link: "/ghidra-dos" },
|
{ text: "Ghidra DOS analysis", link: "/ghidra-dos" },
|
||||||
{ text: "Ghidra raw binary", link: "/raw-binary" },
|
|
||||||
{ text: "Ghidra NativeAOT", link: "/ghidra-nativeaot" },
|
{ text: "Ghidra NativeAOT", link: "/ghidra-nativeaot" },
|
||||||
{ text: "Ghidra semantics", link: "/ghidra-provider" },
|
{ text: "Ghidra semantics", link: "/ghidra-provider" },
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -108,13 +108,7 @@ existing analysis families directly, for example
|
|||||||
`ro.kernel.qemu` value, `null` when absent.
|
`ro.kernel.qemu` value, `null` when absent.
|
||||||
- **Device paths are not host paths.** `base_apk_device_path` values live on
|
- **Device paths are not host paths.** `base_apk_device_path` values live on
|
||||||
the device filesystem. Only pulls and captures produce host-local paths,
|
the device filesystem. Only pulls and captures produce host-local paths,
|
||||||
each paired with byte size and SHA-256 digest. A pulled file's host name is
|
each paired with byte size and SHA-256 digest.
|
||||||
the device path's last segment, accepted only when every host can store it:
|
|
||||||
a `pull_adb_file` whose device path ends in a separator, `.`/`..`, a
|
|
||||||
control or reserved character, a Windows reserved device name, a trailing
|
|
||||||
dot or space, or a `:` alternate-data-stream marker is refused as
|
|
||||||
`invalid_request` before any `adb pull` runs, and REA never renames a
|
|
||||||
device-reported file.
|
|
||||||
- **Splits are part of the answer.** `pm path` enumerates the base APK and
|
- **Splits are part of the answer.** `pm path` enumerates the base APK and
|
||||||
every installed split; pulls cover the whole set. System packages whose
|
every installed split; pulls cover the whole set. System packages whose
|
||||||
APKs keep other names report the `unknown` role rather than guessing.
|
APKs keep other names report the `unknown` role rather than guessing.
|
||||||
|
|||||||
@@ -94,12 +94,6 @@ fallback for an overloaded method instead of attributing all bodies to one
|
|||||||
selected overload. Native/abstract methods with no decompiled body report
|
selected overload. Native/abstract methods with no decompiled body report
|
||||||
`body_status: "not_available"` without inferring which implementation flag caused it.
|
`body_status: "not_available"` without inferring which implementation flag caused it.
|
||||||
|
|
||||||
Static initializers (`<clinit>`) return smali with the
|
|
||||||
`static_initializer_disassembly` marker. Java decompilation can move their
|
|
||||||
instructions into field declarations, leaving an empty or incomplete method
|
|
||||||
body. The selected method's disassembly preserves those instructions and retains
|
|
||||||
the same source byte limit and explicit truncation reporting.
|
|
||||||
|
|
||||||
## Interpret the result
|
## Interpret the result
|
||||||
|
|
||||||
- Package inspection retains decoded manifest XML, summary declarations,
|
- Package inspection retains decoded manifest XML, summary declarations,
|
||||||
|
|||||||
@@ -22,14 +22,6 @@ reports the resolved launcher, its selection source, and its version. A
|
|||||||
missing launcher reports `capability_unavailable` with the
|
missing launcher reports `capability_unavailable` with the
|
||||||
`REA_APKTOOL_COMMAND` remediation rather than attempting an installation.
|
`REA_APKTOOL_COMMAND` remediation rather than attempting an installation.
|
||||||
|
|
||||||
On Windows, a `.bat` or `.cmd` launcher (such as Chocolatey's `apktool.bat`)
|
|
||||||
runs through an explicit `cmd.exe /d /s /c` call. That call has no AutoRun,
|
|
||||||
no delayed expansion, and quotes every argument. A launcher path that
|
|
||||||
contains `"`, `%`, `^`, `!`, `&`, `|`, `<` or `>` is reported as
|
|
||||||
`not_configured` instead of being passed to `cmd.exe`. If REA's temporary
|
|
||||||
decode paths contain those characters, decoding through a batch launcher
|
|
||||||
reports `capability_unavailable`.
|
|
||||||
|
|
||||||
## Answer an analyst question
|
## Answer an analyst question
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
|||||||
@@ -181,8 +181,7 @@ payload ranges are supported. The supported tree has three levels: type, name,
|
|||||||
and language. Other resource payload formats remain opaque.
|
and language. Other resource payload formats remain opaque.
|
||||||
|
|
||||||
`max_file_bytes` defaults to 64 MiB (maximum 512 MiB); `max_entries` defaults to
|
`max_file_bytes` defaults to 64 MiB (maximum 512 MiB); `max_entries` defaults to
|
||||||
16384, the largest stock Windows resource image measured with headroom
|
4096 (maximum 65536). CLI options are `--max-file-bytes` and `--max-entries`.
|
||||||
(maximum 65536). CLI options are `--max-file-bytes` and `--max-entries`.
|
|
||||||
Metadata is bounded to 8 MiB; exceeding any budget fails without truncation.
|
Metadata is bounded to 8 MiB; exceeding any budget fails without truncation.
|
||||||
Large Evidence envelopes may require a caller-configured MCP transport receive
|
Large Evidence envelopes may require a caller-configured MCP transport receive
|
||||||
buffer because envelope copies add overhead. Requests honor cancellation during
|
buffer because envelope copies add overhead. Requests honor cancellation during
|
||||||
|
|||||||
@@ -199,17 +199,6 @@ Network and console coverage starts only after REA attaches and enables the rele
|
|||||||
|
|
||||||
Source maps are not fetched by inspection. Bundle analysis fetches them only when `fetch_source_maps` is selected, with exact-origin redirect checks and no credentials, cookies, or referrer. Each fetch operation has a 30-second deadline and a 64 MiB aggregate streamed-response budget across redirects. A deadline or byte-limit failure remains explicitly unavailable and makes bundle completeness partial. Source-map decoding also bounds raw resolved identities to 64 MiB and aggregate inline evidence to 32 MiB. Failed maps preserve their failure context when it fits; if another context cannot fit, collection stops with the full requested count, the returned processed count, and an explicit unknown-results limitation. Retained mappings and original sources are returned inline. See [source-location limits](web-source-location.md) for the structural decoder bounds. Original source artifacts with `.ts`, `.tsx`, `.mts`, or `.cts` suffixes carry `text/typescript`; other source names retain `text/javascript`.
|
Source maps are not fetched by inspection. Bundle analysis fetches them only when `fetch_source_maps` is selected, with exact-origin redirect checks and no credentials, cookies, or referrer. Each fetch operation has a 30-second deadline and a 64 MiB aggregate streamed-response budget across redirects. A deadline or byte-limit failure remains explicitly unavailable and makes bundle completeness partial. Source-map decoding also bounds raw resolved identities to 64 MiB and aggregate inline evidence to 32 MiB. Failed maps preserve their failure context when it fits; if another context cannot fit, collection stops with the full requested count, the returned processed count, and an explicit unknown-results limitation. Retained mappings and original sources are returned inline. See [source-location limits](web-source-location.md) for the structural decoder bounds. Original source artifacts with `.ts`, `.tsx`, `.mts`, or `.cts` suffixes carry `text/typescript`; other source names retain `text/javascript`.
|
||||||
|
|
||||||
source-map items retain the script's `declared_url` separately from the observed
|
|
||||||
`effective_url`. successful maps use the latter as their source-resolution base.
|
|
||||||
failed fetches retain the last response URL observed within the approved origins;
|
|
||||||
`effective_url` is `null` when no response was observed. query parameters are
|
|
||||||
preserved, and both URLs count toward the inline evidence budget.
|
|
||||||
Current fetches emit a string or null; historical observations may omit
|
|
||||||
`effective_url` without changing their stored content or Evidence identity.
|
|
||||||
An observed URL must fit before its response body is read. If it cannot fit,
|
|
||||||
remaining map results are explicitly unknown; failed cancellation retains its
|
|
||||||
cleanup context and resource constraint.
|
|
||||||
|
|
||||||
## Non-goals and threat model
|
## Non-goals and threat model
|
||||||
|
|
||||||
The browser provider deliberately does not expose generic CDP commands, `Runtime.evaluate`, WebMCP invocation, navigation, input, downloads, page closure, or browser closure. Screenshot capture is the sole pixel surface and returns an image only when requested. REA disables the domains it enabled, detaches the target session, and closes only its own WebSocket.
|
The browser provider deliberately does not expose generic CDP commands, `Runtime.evaluate`, WebMCP invocation, navigation, input, downloads, page closure, or browser closure. Screenshot capture is the sole pixel surface and returns an image only when requested. REA disables the domains it enabled, detaches the target session, and closes only its own WebSocket.
|
||||||
|
|||||||
+1
-2
@@ -59,8 +59,7 @@ alone, use `rea instructions`. A macOS `.app` bundle can be supplied directly.
|
|||||||
Run `rea --help` or a command's `--help` for arguments and output options.
|
Run `rea --help` or a command's `--help` for arguments and output options.
|
||||||
The [generated catalog](product-catalog.json) lists all CLI commands and MCP
|
The [generated catalog](product-catalog.json) lists all CLI commands and MCP
|
||||||
tools. Provider-specific target support is described in the
|
tools. Provider-specific target support is described in the
|
||||||
[native guide](native-investigation.md), [DOS guide](ghidra-dos.md),
|
[native guide](native-investigation.md), [DOS guide](ghidra-dos.md), and
|
||||||
[raw binary guide](raw-binary.md), and
|
|
||||||
[Windows Ghidra guide](windows-ghidra-p0.md).
|
[Windows Ghidra guide](windows-ghidra-p0.md).
|
||||||
|
|
||||||
## Choose a provider
|
## Choose a provider
|
||||||
|
|||||||
+16
-100
@@ -3,7 +3,7 @@
|
|||||||
This lane extends native ELF analysis; it does not execute MIPS code or rehost
|
This lane extends native ELF analysis; it does not execute MIPS code or rehost
|
||||||
firmware. It advances the generic-MIPS portion of
|
firmware. It advances the generic-MIPS portion of
|
||||||
[#718](https://github.com/morluto/rea/issues/718), not the whole firmware roadmap.
|
[#718](https://github.com/morluto/rea/issues/718), not the whole firmware roadmap.
|
||||||
PSP/Allegrex has a [separate static-ELF profile](ghidra-psp.md) tracked in
|
PSP/Allegrex remains a separate specialization tracked in
|
||||||
[#1330](https://github.com/morluto/rea/issues/1330).
|
[#1330](https://github.com/morluto/rea/issues/1330).
|
||||||
|
|
||||||
## Admission boundary
|
## Admission boundary
|
||||||
@@ -13,13 +13,13 @@ retains class, byte order, `e_type`, raw `e_flags`, and inspected ABI declaratio
|
|||||||
Recognition does not mean every provider or MIPS variant is supported. Existing
|
Recognition does not mean every provider or MIPS variant is supported. Existing
|
||||||
PE, managed and Mach-O architecture sets are unchanged.
|
PE, managed and Mach-O architecture sets are unchanged.
|
||||||
|
|
||||||
The Ghidra lane admits ELF32 `ET_EXEC` and `ET_REL`, little or big endian, with
|
The first Ghidra lane admits ELF32 `ET_EXEC`, little or big endian, with explicit
|
||||||
explicit o32 and `EF_MIPS_ARCH_32R2` flags and no machine-specific or ASE
|
o32 and `EF_MIPS_ARCH_32R2` flags and no machine-specific or ASE encoding flags.
|
||||||
encoding flags. These are header declarations, not proof that every instruction
|
These are header declarations, not proof that every instruction conforms to
|
||||||
conforms to that ISA. ELF64, n32/n64, unspecified ABI, MIPS16/microMIPS,
|
that ISA. ELF64, n32/n64, unspecified ABI, MIPS16/microMIPS, machine-specific
|
||||||
machine-specific variants, shared objects and PSP PRX are not covered by this
|
variants, shared/relocatable objects and PSP PRX are not covered by this lane.
|
||||||
lane. Their family may be identified, but provider selection returns the
|
Their family may be identified, but provider selection returns the specific
|
||||||
specific unsupported constraint rather than guessing a compatible profile.
|
unsupported constraint rather than guessing a compatible profile.
|
||||||
|
|
||||||
Explicit `EF_MIPS_FP64` and `EF_MIPS_NAN2008` declarations are refused. Their
|
Explicit `EF_MIPS_FP64` and `EF_MIPS_NAN2008` declarations are refused. Their
|
||||||
absence is insufficient: Clang can emit identical `e_flags` for FP32, FP64 and
|
absence is insufficient: Clang can emit identical `e_flags` for FP32, FP64 and
|
||||||
@@ -39,14 +39,12 @@ absent or supply a default ABI.
|
|||||||
The field layout follows
|
The field layout follows
|
||||||
[`Elf_MIPS_ABIFlags_v0`](https://github.com/bminor/glibc/blob/master/elf/elf.h).
|
[`Elf_MIPS_ABIFlags_v0`](https://github.com/bminor/glibc/blob/master/elf/elf.h).
|
||||||
|
|
||||||
Provider admission requires record version 0, MIPS32r2, 32-bit GPRs, no CPR2,
|
Provider admission requires record version 0, MIPS32r2, 32-bit GPR/CPR1, no CPR2,
|
||||||
no ISA extension, ASE or unknown general flags, and one of two floating-point
|
and a double-precision or FPXX ABI declaration with no ISA extension, ASE or
|
||||||
declarations: 32-bit CPR1 with a double-precision or FPXX ABI, or no CPR1 with
|
unknown general flags. Missing records remain unknown rather than defaulting
|
||||||
the soft-float ABI. Other combinations, including single-float, FP64 and
|
to a compatible ABI, and this initial lane refuses them. Unknown record values
|
||||||
unspecified ABIs, are refused. Missing records remain unknown rather than
|
are retained for diagnosis but do not gain provider support. These checks bind
|
||||||
defaulting to a compatible ABI, and this lane refuses them. Unknown record
|
the declared interpretation; the integer-only fixture does not establish full
|
||||||
values are retained for diagnosis but do not gain provider support. These checks
|
|
||||||
bind the declared interpretation; the fixtures do not establish full
|
|
||||||
floating-point behavioral conformance.
|
floating-point behavioral conformance.
|
||||||
|
|
||||||
MIPS header and ABI record facts are committed in the analysis profile so
|
MIPS header and ABI record facts are committed in the analysis profile so
|
||||||
@@ -55,51 +53,6 @@ identity is versioned independently of file identity. Evidence, lifecycle
|
|||||||
outputs and saved snapshots preserve the `mips` family. Hopper and IDA adapters
|
outputs and saved snapshots preserve the `mips` family. Hopper and IDA adapters
|
||||||
do not implicitly gain MIPS support. Windows Ghidra P0 remains PE x86/x86-64 only.
|
do not implicitly gain MIPS support. Windows Ghidra P0 remains PE x86/x86-64 only.
|
||||||
|
|
||||||
### Soft-float prototype
|
|
||||||
|
|
||||||
Ghidra's MIPS32 compiler specifications model hard-float o32 only: a typed
|
|
||||||
`float` or `double` parameter is bound to `$f12`/`$f14` and returned in `$f0`.
|
|
||||||
Soft-float o32 passes those values in integer registers and stack slots, so a
|
|
||||||
typed prototype (for example from DWARF) would make the decompiler read FPU
|
|
||||||
registers the code never writes and drop the real dataflow. That applies to
|
|
||||||
functions, external functions and indirect calls through typed function
|
|
||||||
pointers alike.
|
|
||||||
|
|
||||||
For soft-float targets REA commits
|
|
||||||
`mips_soft_float_storage: o32-soft-float-prototype-v1` in the analysis profile
|
|
||||||
and runs `ReaGhidraMipsSoftFloat.java` after auto-analysis. The script encodes
|
|
||||||
the program's own default o32 prototype, removes its floating-point parameter
|
|
||||||
and return entries and the rules that consume floating-point storage, and
|
|
||||||
installs the result as the program-specific `__rea_soft_float` prototype through
|
|
||||||
a Ghidra specification extension. Deriving it keeps the byte-order-specific
|
|
||||||
aggregate rules and the hidden struct-return pointer. The script then assigns
|
|
||||||
that prototype, with dynamic storage, to every non-thunk function and external
|
|
||||||
function, and to every function-pointer definition, whose declared types use
|
|
||||||
`float` or `double`. Thunks follow their targets. Types are kept.
|
|
||||||
|
|
||||||
The script fails, and writes no report, if the derived prototype still places a
|
|
||||||
float in an FPU register or any reassigned function does. It records the
|
|
||||||
function and definition counts last; REA requires that report exactly when the
|
|
||||||
profile commits the policy and refuses the session otherwise, before serving any
|
|
||||||
operation. Session Evidence carries the policy and counts as limitations.
|
|
||||||
Callables without typed float signatures keep Ghidra's default prototype, under
|
|
||||||
which Ghidra already infers integer-register parameters. Hard-float profiles do
|
|
||||||
not gain the policy, so their digests are unchanged.
|
|
||||||
|
|
||||||
### Relocatable objects
|
|
||||||
|
|
||||||
`ET_REL` objects, such as Linux kernel modules (`.ko`), are imported by Ghidra's
|
|
||||||
ELF loader, which assigns each allocated section an analysis address and applies
|
|
||||||
the object's REL relocations there. Undefined symbols are placed in Ghidra's
|
|
||||||
`EXTERNAL` block: a thunk for code, a label for data. These addresses are
|
|
||||||
analysis coordinates, not the addresses a kernel or linker would choose, and
|
|
||||||
session Evidence says so. `inspect_native_load_image` reports each relocation
|
|
||||||
with Ghidra's status; HI16 entries report `PARTIAL` because Ghidra applies them
|
|
||||||
together with their paired LO16. Relocatable targets commit
|
|
||||||
`mips_support_lane: elf32-rel-o32-arch32r2-standard-v1`, separate from the
|
|
||||||
executable lane, whose identity executable targets keep. Kernel modules are
|
|
||||||
usually soft-float and therefore also use the soft-float storage policy.
|
|
||||||
|
|
||||||
## Use
|
## Use
|
||||||
|
|
||||||
With a caller-installed Ghidra and compatible JDK on a supported Linux/macOS host:
|
With a caller-installed Ghidra and compatible JDK on a supported Linux/macOS host:
|
||||||
@@ -117,10 +70,7 @@ REA's ELF parser.
|
|||||||
|
|
||||||
## Verification
|
## Verification
|
||||||
|
|
||||||
### Executables
|
The source-owned freestanding fixture is `tests/conformance/c/mips.c`. The
|
||||||
|
|
||||||
The source-owned freestanding fixture is `tests/conformance/c/mips.c`; the
|
|
||||||
soft-float variant also links `tests/conformance/c/mips-soft-float.c`. The
|
|
||||||
optional cross-target lane requires a caller-supplied Clang with MIPS targets,
|
optional cross-target lane requires a caller-supplied Clang with MIPS targets,
|
||||||
LLD, GNU `readelf`, Ghidra and its compatible JDK; ordinary host-native checks
|
LLD, GNU `readelf`, Ghidra and its compatible JDK; ordinary host-native checks
|
||||||
do not acquire these tools. `REA_MIPS_CLANG` selects Clang and
|
do not acquire these tools. `REA_MIPS_CLANG` selects Clang and
|
||||||
@@ -131,8 +81,7 @@ These are test-time prerequisites, not REA runtime providers.
|
|||||||
GHIDRA_INSTALL_DIR=/absolute/path/to/ghidra npm run verify:ghidra:mips
|
GHIDRA_INSTALL_DIR=/absolute/path/to/ghidra npm run verify:ghidra:mips
|
||||||
```
|
```
|
||||||
|
|
||||||
The lane compiles both byte orders with hard-float and soft-float ABIs and never
|
The lane compiles both byte orders and never executes the targets. GNU readelf
|
||||||
executes the targets. GNU readelf
|
|
||||||
independently supplies header/ABI facts and symbol addresses, compared with the
|
independently supplies header/ABI facts and symbol addresses, compared with the
|
||||||
production REA target resolver before provider startup. Its version, bounded
|
production REA target resolver before provider startup. Its version, bounded
|
||||||
command output and selected tool path are retained in the verification report.
|
command output and selected tool path are retained in the verification report.
|
||||||
@@ -155,42 +104,9 @@ all program-header payloads. It checks the actual Ghidra language, entry-address
|
|||||||
decompilation, distinct artifact digest and missing-section limitations through
|
decompilation, distinct artifact digest and missing-section limitations through
|
||||||
CLI Evidence and an MCP-produced snapshot. Caller-selected Ghidra heap limits
|
CLI Evidence and an MCP-produced snapshot. Caller-selected Ghidra heap limits
|
||||||
are passed to these child workflows.
|
are passed to these child workflows.
|
||||||
For soft-float fixtures the lane also checks, through `inspect_native_api`, the
|
|
||||||
exact parameter and return types and storage of float, double, mixed (pair
|
|
||||||
alignment and stack spill) and struct-returning functions; that a caller's
|
|
||||||
decompilation receives every source float constant without FPU inputs,
|
|
||||||
including an indirect call through a typed function pointer; and that the
|
|
||||||
snapshot profile and Evidence retain the policy and outcome counts.
|
|
||||||
Pseudocode presence is a liveness check, not proof of semantic equivalence.
|
Pseudocode presence is a liveness check, not proof of semantic equivalence.
|
||||||
Instruction decoding and reader agreement likewise do not establish runtime,
|
Instruction decoding and reader agreement likewise do not establish runtime,
|
||||||
delay-slot execution or complete floating-point semantics. Assertion regressions
|
delay-slot execution or complete floating-point semantics. Assertion regressions
|
||||||
reject incorrect byte order, constants, destinations and loaded identities.
|
reject incorrect byte order, constants, destinations and loaded identities.
|
||||||
Parser/profile tests are narrower checks, not substitutes for this real-provider
|
Parser/profile tests are narrower checks, not substitutes for this real-provider
|
||||||
run. Report the actual lanes run and leave unexecuted verification pending.
|
run. Report the actual lanes run and leave unexecuted verification pending.
|
||||||
|
|
||||||
### Relocatable objects
|
|
||||||
|
|
||||||
This lane has its own command and fixture:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
GHIDRA_INSTALL_DIR=/absolute/path/to/ghidra npm run verify:ghidra:mips-relocatable
|
|
||||||
```
|
|
||||||
|
|
||||||
It compiles `tests/conformance/c/mips-relocatable.c` with `-c -G0` in both byte
|
|
||||||
orders, plus a little-endian soft-float `-mlong-calls` variant matching Linux
|
|
||||||
module options. GNU readelf independently supplies sections, symbols and REL
|
|
||||||
entries. For every relocation in an allocated section, the lane reads the
|
|
||||||
loaded word through `read_bytes` and requires it to encode `S + A`: `S` from
|
|
||||||
Ghidra's own section placement (`list_segments`) or `EXTERNAL` placement, `A`
|
|
||||||
from the original file bytes. HI16/LO16 are checked as the effective address
|
|
||||||
each LO16 forms with each HI16 it resolves, including several HI16s before one
|
|
||||||
LO16, so a missing signed-low carry fails and a HI16 without a following LO16
|
|
||||||
fails. The lane also requires matching Ghidra relocation entries and statuses,
|
|
||||||
section file offsets and sizes, coverage of a shared HI16, a LO16 carry,
|
|
||||||
external code and data and `R_MIPS_32` words, direct calls from the entry
|
|
||||||
function, the relocatable support lane in the snapshot profile, the
|
|
||||||
relocatable limitation in Evidence and an unchanged source object. The fixture
|
|
||||||
also calls `powf`, an external whose float prototype comes from Ghidra's C
|
|
||||||
library archive; every variant must decompile `powf(1.5,2.5)` without FPU
|
|
||||||
inputs, and the soft-float variant must report that the soft-float prototype
|
|
||||||
covered it.
|
|
||||||
|
|||||||
@@ -1,105 +0,0 @@
|
|||||||
# PSP static ELF analysis through Ghidra
|
|
||||||
|
|
||||||
This specialization builds on [generic MIPS support](ghidra-mips.md) for
|
|
||||||
[#1330](https://github.com/morluto/rea/issues/1330). It reuses REA's existing
|
|
||||||
CLI/MCP, Ghidra bridge, Evidence and snapshot workflows. Allegrex instructions,
|
|
||||||
PSP loading and calling conventions remain owned by
|
|
||||||
[ghidra-allegrex](https://github.com/kotcrab/ghidra-allegrex).
|
|
||||||
|
|
||||||
## Initial boundary
|
|
||||||
|
|
||||||
The initial profile is limited to Linux x64, little-endian ELF32 `ET_EXEC`,
|
|
||||||
`EM_MIPS` and the PSPSDK declaration `e_flags=0x10a23001`. Those bits declare
|
|
||||||
MIPS II, Allegrex, EABI32 and NOREORDER; they are not proof of every instruction's
|
|
||||||
semantics. The profile also requires an inspected version-0 MIPS ABI flags
|
|
||||||
record declaring ISA level 2/revision 0, 32-bit GPR and CPR1, no CPR2,
|
|
||||||
single-precision hard float (`fpAbi=2`), no ISA extension or ASEs,
|
|
||||||
`flags1=1` and `flags2=0`. These are the declarations independently reported by
|
|
||||||
PSPDEV v20261001's GNU readelf 2.44 and its 24-byte section dump. Missing,
|
|
||||||
uninspected, contradictory and other producer declarations are refused.
|
|
||||||
The PSP profile is not an exception to the generic MIPS32r2/o32 policy; that
|
|
||||||
separate gate is unchanged. Profile revision v2 records this corrected boundary.
|
|
||||||
|
|
||||||
PRX, relocatable/shared images, PBP/ISO/CSO containers, runtime emulation and live
|
|
||||||
code overlays are outside this first profile. Other hosts and flag combinations
|
|
||||||
are not silently admitted. File names do not identify a PSP target.
|
|
||||||
|
|
||||||
## Bring your own compatible extension
|
|
||||||
|
|
||||||
Install the extension in the selected Ghidra distribution at
|
|
||||||
`$GHIDRA_INSTALL_DIR/Ghidra/Extensions/ghidra-allegrex`, with its
|
|
||||||
`Module.manifest`, `extension.properties`, language files and loader JARs.
|
|
||||||
User-home installations are not searched because REA uses an isolated analysis
|
|
||||||
home. REA never downloads, installs, rebuilds or vendors the extension.
|
|
||||||
|
|
||||||
The published compatibility experiment used Ghidra **12.1.3**, extension
|
|
||||||
**v21.4**, PSPDEV **v20261001** and JDK 21. New public-provider results must be
|
|
||||||
reported separately from that historical bridge experiment. The extension's
|
|
||||||
`version` property declares its compatible **Ghidra version**, not its release
|
|
||||||
tag; the property must match the selected installation. Other same-version
|
|
||||||
builds are not described as independently verified merely because they pass
|
|
||||||
this metadata check. A malformed or unloadable extension still fails real import.
|
|
||||||
|
|
||||||
REA fingerprints installed extension files before resolving the analysis
|
|
||||||
profile and checks that identity again immediately before launch. Symlinks,
|
|
||||||
nonregular files, missing components and incompatible metadata are refused.
|
|
||||||
Inspection is bounded to 1,024 entries, 16 directory levels and 64 MiB, with
|
|
||||||
streamed file hashing and 64 KiB properties. Rebuilds or content changes yield a
|
|
||||||
different profile; an old snapshot is not silently reused with the new profile.
|
|
||||||
This is content identity, not a signature or a sandbox for installed code.
|
|
||||||
Do not modify the Ghidra installation while a session is running.
|
|
||||||
|
|
||||||
## Ordinary public interfaces
|
|
||||||
|
|
||||||
```bash
|
|
||||||
rea analyze /absolute/path/to/psp.elf --provider ghidra --json
|
|
||||||
rea function /absolute/path/to/psp.elf function_name --provider ghidra --json
|
|
||||||
```
|
|
||||||
|
|
||||||
MCP uses `open_binary` with an absolute path and `provider_id: "ghidra"`, then
|
|
||||||
ordinary inventory and function operations. The loader is explicitly
|
|
||||||
`PspElfLoader`, language `Allegrex:LE:32:default`, compiler `default`. The
|
|
||||||
handshake must confirm the language and compiler before serving observations.
|
|
||||||
Missing prerequisites return `PSP_EXTENSION_UNAVAILABLE` with an installation
|
|
||||||
remedy; no provider fallback or automatic installation occurs.
|
|
||||||
|
|
||||||
Evidence retains the `mips` architecture family and its PSP-specific profile,
|
|
||||||
including extension content identity. It also carries the VFPU and static-only
|
|
||||||
limitations. The extension does not model VFPU prefix effects completely;
|
|
||||||
nonempty decompiled code is not proof of correct vector behavior. Existing
|
|
||||||
session-local metadata editing does not change executable bytes or turn a
|
|
||||||
snapshot into a persistent Ghidra project.
|
|
||||||
|
|
||||||
## Verification
|
|
||||||
|
|
||||||
Use the existing real MIPS verifier with its PSP option. Required tools are
|
|
||||||
caller-supplied `make`, `psp-config`, `psp-gcc`, `psp-readelf`, `psp-objdump`,
|
|
||||||
`PSPDEV`, `GHIDRA_INSTALL_DIR` and a compatible `JAVA_HOME`.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm run build:cached
|
|
||||||
node scripts/verify-real-ghidra-mips.mjs --psp
|
|
||||||
# In a disposable installation without Allegrex, test actual public refusals:
|
|
||||||
node scripts/verify-real-ghidra-mips.mjs --psp-missing-extension
|
|
||||||
# Generic MIPS must remain generic with Allegrex installed:
|
|
||||||
npm run verify:ghidra:mips
|
|
||||||
```
|
|
||||||
|
|
||||||
The generic verifier also exercises a section-truncated firmware fixture. That
|
|
||||||
check uses generic MIPS symbols and language expectations and runs only in generic
|
|
||||||
mode; the PSP report explicitly records carved-PSP coverage as not run.
|
|
||||||
|
|
||||||
The maintained PSP fixture builds from `tests/conformance/psp/`, never executes,
|
|
||||||
and is independent of commercial game data. PSP GNU tools supply ELF/ABI,
|
|
||||||
raw ABI-record, symbol and encoding observations; REA's parsed target and saved
|
|
||||||
snapshot must agree with the independent ABI declaration. Public CLI/MCP must
|
|
||||||
recover known functions, a direct
|
|
||||||
call, the immediate `0x1234`, BITREV, a global word and a marker. The verifier
|
|
||||||
checks observed loader/language, original bytes, Evidence, snapshot reopening,
|
|
||||||
and an A-B-A target switch with different global contents at the same address.
|
|
||||||
A snapshot for A must not open B. Cleanup must finish before success is reported.
|
|
||||||
|
|
||||||
These checks are selected static facts, not full behavioral equivalence, VFPU
|
|
||||||
semantics or arbitrary PSP compatibility. Independently published PSP binaries
|
|
||||||
are supplemental calibration targets after payload classification and license
|
|
||||||
review; unsupported PRX/PBP must not count as a successful static-ELF case.
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
# Static HarmonyOS package inventory
|
|
||||||
|
|
||||||
REA inventories HarmonyOS application packages through the shared hardened
|
|
||||||
ZIP artifact reader in `src/artifacts/`, then projects the authenticated
|
|
||||||
inventory into an execution-free application graph. This is the first
|
|
||||||
increment of the HarmonyOS roadmap (#1431): package identification and
|
|
||||||
component inventory only.
|
|
||||||
|
|
||||||
Recognized root formats:
|
|
||||||
|
|
||||||
- `.hap` — installable application module
|
|
||||||
- `.hsp` — runtime shared package
|
|
||||||
- `.app` — distribution App Pack (HAP/HSP children are listed by path). The
|
|
||||||
App Pack classification applies to verified-ZIP-magic root inputs only; a
|
|
||||||
nested ZIP member ending in `.app` inside another package, such as an IPA,
|
|
||||||
keeps the generic `zip` classification.
|
|
||||||
|
|
||||||
HarmonyOS `.har` shared libraries are intentionally not classified by suffix:
|
|
||||||
`.har` also names HTTP Archive JSON, so a Harmony shared archive requires
|
|
||||||
verified ZIP bytes and is deferred with an explicit limitation.
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
No external SDK, toolchain, or engine is required. Inventory the package and
|
|
||||||
project the graph; CLI and MCP use the same workflow and return
|
|
||||||
artifact-bound Evidence inline:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
rea inspect-artifact /path/to/Example.hap --format json > inspection.json
|
|
||||||
node --input-type=module -e 'import { readFileSync } from "node:fs"; console.log(JSON.stringify({ inventory_evidence: [JSON.parse(readFileSync("inspection.json", "utf8"))] }));' > projection-input.json
|
|
||||||
rea project-harmony-application-graph projection-input.json --format json
|
|
||||||
```
|
|
||||||
|
|
||||||
The MCP tool `project_harmony_application_graph` takes the same
|
|
||||||
`inventory_evidence` input. The projection reports:
|
|
||||||
|
|
||||||
- exact component paths, artifact IDs, and hashes (manifests, Ark bytecode,
|
|
||||||
resources, native libraries, JavaScript, signing)
|
|
||||||
- a packaging-model hint: Stage is claimed only from a `module.json` entry,
|
|
||||||
FA only from `config.json`, otherwise `unknown`
|
|
||||||
- FA resources under `assets/<module>/resources/` as well as Stage `resources/`
|
|
||||||
- unavailable component paths with unknown IDs and hashes, including encrypted entries; these make projection coverage partial
|
|
||||||
- App Pack child package paths without recursive inventory
|
|
||||||
- runtime-family hints (`ark`, `native`, `javascript`) from paths and formats
|
|
||||||
- path-based N-API bridge hypotheses between bytecode and `libs/<abi>` native
|
|
||||||
libraries
|
|
||||||
|
|
||||||
Every claim is path-presence only. Manifest semantics (module identity,
|
|
||||||
abilities, entry points, permissions, dependencies), Ark bytecode contents and
|
|
||||||
versions, resource resolution, signing verification, and observed native
|
|
||||||
boundaries are out of scope for this increment and stay in the projection's
|
|
||||||
`limitations` array until a dedicated HarmonyOS provider exists. REA fails
|
|
||||||
closed on packages whose inventory cannot be authenticated.
|
|
||||||
|
|
||||||
## Verification lane
|
|
||||||
|
|
||||||
`npm run fixtures:harmony` downloads the SHA-256-pinned 1.0.1 HAP release
|
|
||||||
from the MIT-licensed [harmony-next-pipeline source repository](https://github.com/ohosvscode/harmony-next-pipeline)
|
|
||||||
into ignored `_reference/harmony-integration/`. The pin records the source
|
|
||||||
revision, release asset ID, size, and digest. The downloaded artifact is not
|
|
||||||
redistributed; bundled component licenses have not been independently audited.
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm run fixtures:harmony
|
|
||||||
REA_HARMONY_TEST_HAP=_reference/harmony-integration/entry-default-unsigned.hap \
|
|
||||||
npm run verify:harmony
|
|
||||||
```
|
|
||||||
|
|
||||||
The lane exercises the compiled CLI and actual SDK-connected stdio MCP:
|
|
||||||
`inspect_artifact` authenticity, projection determinism, Stage-model path hints,
|
|
||||||
exact manifest/bytecode/resource component sets, empty native and bridge sets,
|
|
||||||
complete-inventory coverage, and CLI/MCP parity. It checks that this fixture has
|
|
||||||
no META-INF signing entries; that does not establish whether the package is signed.
|
|
||||||
|
|
||||||
The release artifact's compiler/SDK versions and reproducible source build have
|
|
||||||
not been independently established. This lane does not complete the pinned
|
|
||||||
toolchain acceptance in #1431 and does not verify Ark decoding or signatures.
|
|
||||||
Set `REA_HARMONY_ENTRYPOINT` to an installed package's `scripts/rea.mjs` to run
|
|
||||||
the same checks against that package; the default lane uses the repository build.
|
|
||||||
@@ -32,8 +32,6 @@ Open the **original input binary** in REA, not an `.idb` or `.i64` database. Its
|
|||||||
|
|
||||||
REA's close operation releases its MCP connection or proxy. It never saves or closes the existing GUI database. External edits remain visible because results are live and are not replayed from snapshots. These checks do not lock the GUI or prove that the database is unpatched.
|
REA's close operation releases its MCP connection or proxy. It never saves or closes the existing GUI database. External edits remain visible because results are live and are not replayed from snapshots. These checks do not lock the GUI or prove that the database is unpatched.
|
||||||
|
|
||||||
The legacy producer moves the active GUI as a side effect: assembly and raw function instructions jump to the function, and successful pseudocode opens or reuses a pseudocode view. A function dossier does both. `binary_session` reports these operations with `effects.may_show_ui: true` in attached mode; headless operations and the other attached operations report `false`.
|
|
||||||
|
|
||||||
## Give REA a target for headless analysis
|
## Give REA a target for headless analysis
|
||||||
|
|
||||||
The headless profile supports upstream's **database supervisor** API: `idb_open`, `idb_list`, `idb_close`, explicit `database` arguments, and modern analysis tools. Legacy 1.4.0 `idalib-mcp`, which accepts one initial filename and serves SSE, does not implement this profile. Follow the [upstream headless instructions](https://github.com/mrexodia/ida-pro-mcp#headless-idalib-session-model) for an installation with the supervisor API.
|
The headless profile supports upstream's **database supervisor** API: `idb_open`, `idb_list`, `idb_close`, explicit `database` arguments, and modern analysis tools. Legacy 1.4.0 `idalib-mcp`, which accepts one initial filename and serves SSE, does not implement this profile. Follow the [upstream headless instructions](https://github.com/mrexodia/ida-pro-mcp#headless-idalib-session-model) for an installation with the supervisor API.
|
||||||
@@ -92,17 +90,17 @@ Use a package version that actually includes this adapter; repository main can b
|
|||||||
{"name":"close_binary","arguments":{}}
|
{"name":"close_binary","arguments":{}}
|
||||||
```
|
```
|
||||||
|
|
||||||
Opening an MCP target starts its selected provider session; headless opening waits for auto-analysis. Set the agent's MCP request deadline long enough for the target. The registration's optional `timeoutMs` defaults to 300000 for upstream requests. A freshly opened headless worker can briefly report `status: "busy"` from `server_health`; REA re-reads the health every 100 ms until the worker answers, the caller cancels, or `timeoutMs` has elapsed since the first read. Only expiry while the worker is still busy produces a retryable `provider_timeout`; no further read is started once the deadline has passed. That error names the busy tool of the last observation, or `unknown` when the worker reported none or a value that is not tool-name-shaped. Cancellation during the wait produces `cancelled`. Any other unexpected health payload, including a busy payload with an invalid shape, remains `unreadable_output`. Cancellation drains the current upstream request before cleanup; it does not force-stop GUI analysis. An open request that times out without a completed response retains the private workspace because worker inventory alone cannot prove the request has stopped. `binary_session` reports actual tool availability. Repeated doctor/setup calls are unnecessary when the registration already works.
|
Opening an MCP target starts its selected provider session; headless opening waits for auto-analysis. Set the agent's MCP request deadline long enough for the target. The registration's optional `timeoutMs` defaults to 300000 for upstream requests. Cancellation drains the current upstream request before cleanup; it does not force-stop GUI analysis. An open request that times out without a completed response retains the private workspace because worker inventory alone cannot prove the request has stopped. `binary_session` reports actual tool availability. Repeated doctor/setup calls are unnecessary when the registration already works.
|
||||||
|
|
||||||
For guided registration, set `REA_IDA_MCP_CONFIG` before `rea setup --client <client>`. Setup includes that file reference in its reviewed plan and preserves it after approval; it does not copy upstream credentials into the agent configuration. `rea doctor --provider ida --json` validates the registration without starting IDA and explicitly leaves runtime compatibility and target binding for analysis.
|
For guided registration, set `REA_IDA_MCP_CONFIG` before `rea setup --client <client>`. Setup includes that file reference in its reviewed plan and preserves it after approval; it does not copy upstream credentials into the agent configuration. `rea doctor --provider ida --json` validates the registration without starting IDA and explicitly leaves runtime compatibility and target binding for analysis.
|
||||||
|
|
||||||
## Coverage and evidence
|
## Coverage and evidence
|
||||||
|
|
||||||
Both profiles support procedure/string inventory and literal or regex search, procedure resolution, pseudocode, assembly, raw function instructions, resolved callees, incoming address references, and a function dossier. Inventories and modern pseudocode/assembly follow upstream pagination. Upstream limits on modern xrefs and callees are retained as explicit truncation limitations. In the modern headless profile, targets that are not proven x86-only use processor-neutral `callgraph` edges instead of the x86 instruction checks in upstream `callees` (mrexodia/ida-pro-mcp#549). REA requests depth zero: the pinned upstream emits the root's outgoing edges without scanning child functions, then REA batches function-name lookup for those addresses. The graph covers recognized function destinations only; imports and other non-function targets remain unknown. A server without `callgraph` returns an empty relationship list with an explicit coverage limitation. Graph and path workflows retain those limitations alongside observed edges. A failed or inconsistent graph reply remains an error. A transport-level truncated preview is rejected rather than reported as complete evidence; the error preserves upstream retrieval guidance.
|
Both profiles support procedure/string inventory and literal or regex search, procedure resolution, pseudocode, assembly, raw function instructions, resolved callees, incoming address references, and a function dossier. Inventories and modern pseudocode/assembly follow upstream pagination. Upstream limits on modern xrefs and callees are retained as explicit truncation limitations. A transport-level truncated preview is rejected rather than reported as complete evidence; the error preserves upstream retrieval guidance.
|
||||||
|
|
||||||
The legacy profile additionally supports direct callers. Its producer may report call-site or interior addresses; REA resolves the reported function symbol to its canonical entry. The modern profile does not prove direct callers from its code/data xref labels, so that capability is unavailable and the dossier marks it unknown.
|
The legacy profile additionally supports direct callers. Its producer may report call-site or interior addresses; REA resolves the reported function symbol to its canonical entry. The modern profile does not prove direct callers from its code/data xref labels, so that capability is unavailable and the dossier marks it unknown.
|
||||||
|
|
||||||
Complete body ranges, typed reference edges, CFG, referenced data, source locals, comment kinds, and database revision are unavailable. Empty unsupported dossier facets mean **unknown**, not observed absence. `binary_overview`, whole-symbol inventory, mutation, debugging, arbitrary Python forwarding, and requested GUI navigation are outside this adapter's coverage. Check session availability before composing a workflow that needs those facets.
|
Complete body ranges, typed reference edges, CFG, referenced data, source locals, comment kinds, and database revision are unavailable. Empty unsupported dossier facets mean **unknown**, not observed absence. `binary_overview`, whole-symbol inventory, mutation, debugging, arbitrary Python forwarding, and GUI navigation are outside this adapter's coverage. Check session availability before composing a workflow that needs those facets.
|
||||||
|
|
||||||
`provider.version` identifies the REA adapter; the profile explicitly records `version_scope: "rea-ida-adapter"`. The MCP handshake's `serverInfo` is separate and does not establish IDA or Python distribution versions. Raw observations preserve producer metadata and output. Attached hashes identify the recorded original input; headless identity uses the digest-verified private copy and observed worker input path. Neither proves source-code recovery or an unmodified analysis database.
|
`provider.version` identifies the REA adapter; the profile explicitly records `version_scope: "rea-ida-adapter"`. The MCP handshake's `serverInfo` is separate and does not establish IDA or Python distribution versions. Raw observations preserve producer metadata and output. Attached hashes identify the recorded original input; headless identity uses the digest-verified private copy and observed worker input path. Neither proves source-code recovery or an unmodified analysis database.
|
||||||
|
|
||||||
@@ -110,4 +108,4 @@ Complete body ranges, typed reference edges, CFG, referenced data, source locals
|
|||||||
|
|
||||||
Run `npm run verify:ida -- --target /absolute/path/to/program --procedure main` with a configured upstream server. It exercises production CLI and MCP tools, validates their output contracts and Evidence, checks original-input preservation and session cleanup, and keeps local target data out of its console summary. Supply `--package-root` to verify an extracted or installed package. See [testing](testing.md) for the distinction between adapter tests and real-provider evidence.
|
Run `npm run verify:ida -- --target /absolute/path/to/program --procedure main` with a configured upstream server. It exercises production CLI and MCP tools, validates their output contracts and Evidence, checks original-input preservation and session cleanup, and keeps local target data out of its console summary. Supply `--package-root` to verify an extracted or installed package. See [testing](testing.md) for the distinction between adapter tests and real-provider evidence.
|
||||||
|
|
||||||
The initial real workflows use stdio registrations for the legacy Windows GUI profile and a Windows x64 headless supervisor with IDA 9.3. The headless workflow has also passed on macOS arm64 with IDA Professional 9.1 (build 9.1.250226) against the same upstream commit `c133c3853faa111a9b00ee615c013b720d0c4acd`, using a source-built arm64 Mach-O fixture; Mach-O C symbols carry a leading underscore, so the procedure name is `_rea_fixture_add`. Streamable HTTP is tested against a loopback MCP fixture with the pinned client SDK; a real IDA HTTP-supervisor workflow remains unverified. Linux headless engine operation, other IDA releases, architectures, and modern attached GUI tools require their corresponding real workflows before support is claimed.
|
The initial real workflows use stdio registrations for the legacy Windows GUI profile and a Windows x64 headless supervisor with IDA 9.3. Streamable HTTP is tested against a loopback MCP fixture with the pinned client SDK; a real IDA HTTP-supervisor workflow remains unverified. Linux/macOS headless engine operation, other IDA releases, architectures, and modern attached GUI tools require their corresponding real workflows before support is claimed.
|
||||||
|
|||||||
+10
-98
@@ -36,27 +36,8 @@ Setup continues to pin persistent MCP registrations to the exact version that
|
|||||||
performed setup. Running current setup later migrates unversioned or older
|
performed setup. Running current setup later migrates unversioned or older
|
||||||
managed registrations through the normal reviewed setup transaction.
|
managed registrations through the normal reviewed setup transaction.
|
||||||
|
|
||||||
With Bun, `bunx rea-agents setup` (or `bunx rea-agents@latest setup`) is the
|
|
||||||
equivalent entry point. Setup run through `npx` registers
|
|
||||||
`npx -y rea-agents@<version> mcp`; setup run through `bunx` or `bun x` registers
|
|
||||||
`bunx rea-agents@<version> mcp`. On Windows, setup wraps either command in
|
|
||||||
`cmd.exe /d /c` so clients can start the runner's command shim. Neither
|
|
||||||
registration points into the runner's temporary package cache.
|
|
||||||
|
|
||||||
REA supports Node.js 22.x (>=22.19), 24.x (>=24.11), and 26+. Node.js 23, 25, and prereleases are unsupported. It uses the npm already paired with that runtime and never upgrades Node.js, npm, or Homebrew.
|
REA supports Node.js 22.x (>=22.19), 24.x (>=24.11), and 26+. Node.js 23, 25, and prereleases are unsupported. It uses the npm already paired with that runtime and never upgrades Node.js, npm, or Homebrew.
|
||||||
|
|
||||||
When REA runs on Bun, the `rea doctor` `node` check reports the Bun version and
|
|
||||||
the Node.js compatibility version Bun declares, and passes when that
|
|
||||||
compatibility version is in the supported range. Bun does not enforce the V8
|
|
||||||
heap flags REA gives its owned helper processes, so Evidence that reports those
|
|
||||||
limits on Node.js records them as unavailable under Bun. On Windows, the owned
|
|
||||||
Job Object of each JavaScript helper (source analyzer, source-map codec and HAR
|
|
||||||
decoder) instead limits its committed memory to that helper's heap budget plus
|
|
||||||
a 512 MiB reserve for Bun itself, and Evidence reports that limit. This needs
|
|
||||||
the matching bundled Windows native artifact; an artifact without the control
|
|
||||||
refuses to start the helper rather than running it unlimited. CI tests Node.js
|
|
||||||
only.
|
|
||||||
|
|
||||||
Running `npm install rea-agents` without `--global` installs the executable only
|
Running `npm install rea-agents` without `--global` installs the executable only
|
||||||
in the current project's `node_modules/.bin`; it does not make `rea` available
|
in the current project's `node_modules/.bin`; it does not make `rea` available
|
||||||
on the shell `PATH`. Use the setup command above for the guided setup
|
on the shell `PATH`. Use the setup command above for the guided setup
|
||||||
@@ -352,12 +333,6 @@ Other integrations, including Qwen Code, use `~/.agents/skills`.
|
|||||||
A mixed selection plans each distinct destination. Selecting the skill without a client uses the shared
|
A mixed selection plans each distinct destination. Selecting the skill without a client uses the shared
|
||||||
directory. Setup leaves existing skill copies in other locations untouched.
|
directory. Setup leaves existing skill copies in other locations untouched.
|
||||||
|
|
||||||
`rea setup --skill-client claude_code --yes --json` refreshes and verifies the
|
|
||||||
selected skill destination independently of MCP registration selection. The
|
|
||||||
final `doctor.scope.skill_clients` records which skill destinations were
|
|
||||||
checked; `doctor.scope.clients` continues to describe required registrations.
|
|
||||||
An unselected shared skill does not affect a client-only refresh.
|
|
||||||
|
|
||||||
`doctor --skill --json` verifies the selected copies against the bundled
|
`doctor --skill --json` verifies the selected copies against the bundled
|
||||||
instructions and references. Consumers should use `identity.skill.state`,
|
instructions and references. Consumers should use `identity.skill.state`,
|
||||||
`installed_version`, and `installed_tool_count` for skill readiness. The
|
`installed_version`, and `installed_tool_count` for skill readiness. The
|
||||||
@@ -425,21 +400,9 @@ rea setup --yes --all-detected --install-hopper --json
|
|||||||
Setup pins package-runner MCP registrations to the exact installed REA version,
|
Setup pins package-runner MCP registrations to the exact installed REA version,
|
||||||
installs the matching skill and on-demand references in the same plan, and adds
|
installs the matching skill and on-demand references in the same plan, and adds
|
||||||
`startup_timeout_sec = 30` for Codex and Grok Build. `rea update` installs the exact resolved
|
`startup_timeout_sec = 30` for Codex and Grok Build. `rea update` installs the exact resolved
|
||||||
release into the npm prefix or Bun global directory that owns the running
|
release into the npm prefix that owns the running package, then checks the new
|
||||||
package, then checks the new executable's version before reporting success. It
|
executable's version before reporting success. It does not reopen onboarding.
|
||||||
does not reopen onboarding. For npm installations, release lookup and
|
Release lookup and installation both use npm's configured registry.
|
||||||
installation both use npm's configured registry. Bun global updates require
|
|
||||||
Bun 1.2.17 or later, which introduced `bun info`. The updater checks `bun --version`
|
|
||||||
first and stops with an instruction to upgrade Bun manually if the version is
|
|
||||||
older or cannot be parsed; it does not upgrade Bun itself.
|
|
||||||
For supported Bun global installations, `bun info` and
|
|
||||||
`bun add --global --ignore-scripts` use Bun's configured registry
|
|
||||||
and run inside the owning Bun global directory (`BUN_INSTALL_GLOBAL_DIR`, else
|
|
||||||
`$BUN_INSTALL/install/global`, else `$XDG_CACHE_HOME/.bun/install/global`,
|
|
||||||
else `~/.bun/install/global`), never in the caller's current project. A Bun
|
|
||||||
global directory without its `package.json` is not treated as an owned
|
|
||||||
installation, because Bun would install into the nearest ancestor project
|
|
||||||
instead.
|
|
||||||
Its maintenance plan selects only existing REA registrations and an already
|
Its maintenance plan selects only existing REA registrations and an already
|
||||||
installed REA skill. Run the returned scoped setup command to review and approve
|
installed REA skill. Run the returned scoped setup command to review and approve
|
||||||
those changes, then restart affected agents. The plan is returned in terminal,
|
those changes, then restart affected agents. The plan is returned in terminal,
|
||||||
@@ -537,25 +500,6 @@ export HOPPER_LAUNCHER_PATH=/absolute/path/to/Hopper
|
|||||||
rea doctor --provider hopper --json
|
rea doctor --provider hopper --json
|
||||||
```
|
```
|
||||||
|
|
||||||
Hopper startup allows 120,000 ms for launch, initial analysis, and authenticated
|
|
||||||
bridge readiness. For large targets, set `REA_HOPPER_STARTUP_TIMEOUT_MS` to a
|
|
||||||
decimal integer from 1 to 2,147,483,647 milliseconds in the environment that
|
|
||||||
starts REA. CLI and MCP use the same setting; invalid values fail configuration
|
|
||||||
validation. An MCP client's own request timeout must also allow enough time.
|
|
||||||
|
|
||||||
If macOS denies Apple Events, allow the application that starts REA under
|
|
||||||
**System Settings → Privacy & Security → Automation**, then retry. REA releases
|
|
||||||
the target reservation when the native helper reports its complete authorization
|
|
||||||
rejection and its arguments cannot alter the helper's generated AppleScript.
|
|
||||||
Arguments containing quotes, backslashes, or line breaks remain unchanged but
|
|
||||||
cannot establish that a failed handoff opened no document. Other failed handoffs
|
|
||||||
retain ownership until document closure is confirmed. If a timed-out bridge
|
|
||||||
becomes ready later, `close_binary` connects to that run, authenticates its
|
|
||||||
identity, and requests document shutdown. After a connection drops, the bridge
|
|
||||||
allows 30 seconds for an authenticated cleanup reconnect, then releases Hopper's
|
|
||||||
Python execution thread. Expiry does not establish document closure, so REA
|
|
||||||
retains unconfirmed ownership. Retry close while the bridge remains available.
|
|
||||||
|
|
||||||
If a Linux launcher exists but cannot start, inspect its shared libraries:
|
If a Linux launcher exists but cannot start, inspect its shared libraries:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -567,13 +511,8 @@ need Xvfb, Python 3, X11 and XTEST; approved setup installs those dependencies
|
|||||||
on supported distributions. Add the curl installer's reported executable
|
on supported distributions. Add the curl installer's reported executable
|
||||||
directory, commonly `~/.local/bin`, to your shell `PATH` if needed.
|
directory, commonly `~/.local/bin`, to your shell `PATH` if needed.
|
||||||
|
|
||||||
REA starts Hopper when needed. On macOS, complete its demo or license prompt in
|
REA starts Hopper when needed. On macOS, its launcher can bring a window or
|
||||||
the same user session before the first CLI/MCP operation or unattended job. Open
|
first-run dialog forward; choose demo mode or activate your existing license.
|
||||||
Hopper manually if needed; its launcher can also bring the dialog forward.
|
|
||||||
If startup reports `Cannot launch Hopper! Connection is invalid.` or waits for
|
|
||||||
bridge readiness, check Hopper for a pending demo, license, or loader dialog.
|
|
||||||
Complete the dialog and retry. If REA reports `cleanup_incomplete`, follow the
|
|
||||||
retained-resource guidance below before reopening the target.
|
|
||||||
Hopper serializes analysis requests. Cancelling a wait can leave provider work
|
Hopper serializes analysis requests. Cancelling a wait can leave provider work
|
||||||
running, which the session reports. Successful decompilation is cached until
|
running, which the session reports. Successful decompilation is cached until
|
||||||
a relevant rename or comment changes it.
|
a relevant rename or comment changes it.
|
||||||
@@ -602,11 +541,6 @@ if document closure is unconfirmed, REA retains the backing image and reports
|
|||||||
MCP-exit behavior.
|
MCP-exit behavior.
|
||||||
Startup deadlines report missing bridge readiness and preserve the launcher
|
Startup deadlines report missing bridge readiness and preserve the launcher
|
||||||
outcome; a successful helper exit does not prove that a loader dialog completed.
|
outcome; a successful helper exit does not prove that a loader dialog completed.
|
||||||
If an owned provider process exits, request failures preserve its observed exit
|
|
||||||
code or signal and bounded output in `details.launcher`. An exit can precede
|
|
||||||
output-stream closure; `output_closed: false` keeps that uncertainty explicit.
|
|
||||||
Later requests retain the known exit instead of reducing it to socket loss.
|
|
||||||
An external GUI's helper exit does not establish that the GUI itself exited.
|
|
||||||
Cursor navigation returns the observed object start when Hopper snaps an interior
|
Cursor navigation returns the observed object start when Hopper snaps an interior
|
||||||
address; adjacent-object navigation rejects unmapped inputs and document ends.
|
address; adjacent-object navigation rejects unmapped inputs and document ends.
|
||||||
Native API text rejects NUL characters and unpaired Unicode surrogates before
|
Native API text rejects NUL characters and unpaired Unicode surrogates before
|
||||||
@@ -723,7 +657,7 @@ rea providers --json
|
|||||||
|
|
||||||
`rea setup` can configure supported Windows agents and install the bundled
|
`rea setup` can configure supported Windows agents and install the bundled
|
||||||
REA skill after approval. Direct registrations use Node to launch REA's entry
|
REA skill after approval. Direct registrations use Node to launch REA's entry
|
||||||
script; package-runner registrations use the pinned `npx` or `bunx` command. Hopper
|
script; package-runner registrations use the pinned `npx` command. Hopper
|
||||||
installation remains unavailable on Windows. Setup never installs Ghidra,
|
installation remains unavailable on Windows. Setup never installs Ghidra,
|
||||||
Java, or Python. It preserves valid detected Ghidra/JDK settings in agent
|
Java, or Python. It preserves valid detected Ghidra/JDK settings in agent
|
||||||
registrations. See [Windows Ghidra P0](windows-ghidra-p0.md) for provider diagnostics.
|
registrations. See [Windows Ghidra P0](windows-ghidra-p0.md) for provider diagnostics.
|
||||||
@@ -800,27 +734,6 @@ Each line is `address<TAB>kind[<TAB>name]`, where kind is `function`, `code` or
|
|||||||
|
|
||||||
Label seeds can name mapped uninitialized storage such as `.bss`; function and code seeds require initialized bytes.
|
Label seeds can name mapped uninitialized storage such as `.bss`; function and code seeds require initialized bytes.
|
||||||
|
|
||||||
To skip a named Ghidra auto-analyzer (for example, when default auto-analysis
|
|
||||||
stalls in one analyzer on a Swift/Objective-C arm64 Mach-O):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
export REA_GHIDRA_DISABLED_ANALYZERS="Objective-C Message Analyzer"
|
|
||||||
```
|
|
||||||
|
|
||||||
The value is a comma-separated list of exact Ghidra analyzer names. A pre-script
|
|
||||||
disables each name before auto-analysis, the analysis profile records the
|
|
||||||
override in `analyzer_preset` (for example
|
|
||||||
`ghidra-default+disabled:Objective-C Message Analyzer`), and a session fails to
|
|
||||||
open when its committed profile and the setting differ. A name starts with a
|
|
||||||
letter or digit and contains only letters, digits, spaces, periods, underscores,
|
|
||||||
and hyphens; at most 32 names are admitted, each at most 120 characters.
|
|
||||||
Names must identify analyzers registered for the selected program. Unknown names
|
|
||||||
or options that remain enabled abort the headless import before auto-analysis
|
|
||||||
and the bridge, so an unsuccessful override cannot produce a session claiming
|
|
||||||
that the analyzer was disabled. For Windows PE resource analysis, the exact name
|
|
||||||
is `WindowsResourceReference`. Disabling an analyzer skips the facts it would
|
|
||||||
have produced.
|
|
||||||
|
|
||||||
### Ghidra heap and CPU controls
|
### Ghidra heap and CPU controls
|
||||||
|
|
||||||
Set resource controls in the environment that launches the CLI or MCP server,
|
Set resource controls in the environment that launches the CLI or MCP server,
|
||||||
@@ -911,7 +824,7 @@ Ghidra/JDK installation; neither is inferred from startup alone.
|
|||||||
|
|
||||||
## Diagnose, update, and remove
|
## Diagnose, update, and remove
|
||||||
|
|
||||||
`rea doctor --json` is strictly read-only. `rea update` updates only the npm or Bun global installation that owns the running CLI. Source checkouts and package-runner copies must be updated through the mechanism that owns them; a fresh package-runner invocation can use `npx rea-agents@latest` or `bunx rea-agents@latest`. `rea uninstall` removes only REA-owned agent registrations and skill files; `--purge-data` additionally removes REA cache and state paths.
|
`rea doctor --json` is strictly read-only. `rea update` updates only the npm installation that owns the running CLI. Source checkouts and package-runner copies must be updated through the mechanism that owns them; a fresh package-runner invocation can use `npx rea-agents@latest`. `rea uninstall` removes only REA-owned agent registrations and skill files; `--purge-data` additionally removes REA cache and state paths.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
rea update
|
rea update
|
||||||
@@ -956,7 +869,6 @@ For a client that requires manual configuration, use:
|
|||||||
<!-- x-release-please-end -->
|
<!-- x-release-please-end -->
|
||||||
|
|
||||||
Persistent registrations should use one exact package version. `rea setup`
|
Persistent registrations should use one exact package version. `rea setup`
|
||||||
writes the same package-runner shape, or `bunx rea-agents@<version> mcp` when
|
writes the same package-runner shape and pins it to the exact version that
|
||||||
setup runs through `bunx`, and pins it to the exact version that performed
|
performed setup. Run current setup to refresh an older registration, then
|
||||||
setup. Run current setup to refresh an older registration, then restart the
|
restart the client.
|
||||||
client.
|
|
||||||
|
|||||||
@@ -66,45 +66,6 @@ code-point order. Dependency manifests remain package observations but do not
|
|||||||
declare Electron main or renderer entries. If only dependency manifests are
|
declare Electron main or renderer entries. If only dependency manifests are
|
||||||
present, the inventory artifact remains the graph root.
|
present, the inventory artifact remains the graph root.
|
||||||
|
|
||||||
## Select sources before analysis
|
|
||||||
|
|
||||||
For a question about known entry sources, supply exact artifact-relative file
|
|
||||||
paths in `source_paths`, or repeat `--source-path` on either CLI route:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
rea analyze /absolute/path/to/app.asar \
|
|
||||||
--source-path package.json --source-path main.js --json
|
|
||||||
```
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"input_path": "/absolute/path/to/app.asar",
|
|
||||||
"source_paths": ["package.json", "main.js"],
|
|
||||||
"detail": "summary"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
REA inventories and verifies the complete artifact, including unselected bytes,
|
|
||||||
but allocates source text and performs static analysis only for selected files.
|
|
||||||
Include supporting manifests, HTML or source maps explicitly when needed;
|
|
||||||
imports do not expand the selection. Paths must match relevant inventoried
|
|
||||||
files exactly, including nested ASAR prefixes. Unknown paths, aliases and globs
|
|
||||||
return an `invalid_request` correction. Selected files are analyzed in request
|
|
||||||
order before unselected scopes are projected. Repeated paths preserve the
|
|
||||||
caller's request and first-occurrence priority, analyzing the file once.
|
|
||||||
Omit the selection for the existing complete
|
|
||||||
application workflow.
|
|
||||||
|
|
||||||
The result and summary retain `source_selection.requested_paths` and
|
|
||||||
`source_selection.unselected_files`. Every relevant file keeps its original
|
|
||||||
inventory identity; unselected files report `text_status:
|
|
||||||
"outside-analysis-scope"`. Their relationships remain unknown, and application
|
|
||||||
coverage is partial while any file remains outside scope. Selection does not
|
|
||||||
claim whole-application completeness or change integrity policy. Summary detail
|
|
||||||
only reduces delivery; source selection reduces text acquisition and analysis.
|
|
||||||
Explicit native provider or snapshot routing rejects `--source-path` rather
|
|
||||||
than ignoring it.
|
|
||||||
|
|
||||||
## ASAR integrity
|
## ASAR integrity
|
||||||
|
|
||||||
ASAR inventory checks Electron integrity metadata for embedded archive entries
|
ASAR inventory checks Electron integrity metadata for embedded archive entries
|
||||||
@@ -165,14 +126,7 @@ deadline per source, including startup and fact transfer. Select
|
|||||||
`max_heap_mb` and `analysis_timeout_ms` through MCP, or `--max-heap-mb` and
|
`max_heap_mb` and `analysis_timeout_ms` through MCP, or `--max-heap-mb` and
|
||||||
`--analysis-timeout-ms` on the dedicated CLI command. These choices control the
|
`--analysis-timeout-ms` on the dedicated CLI command. These choices control the
|
||||||
analyzer; the caller's `NODE_OPTIONS` still controls the CLI/MCP process heap.
|
analyzer; the caller's `NODE_OPTIONS` still controls the CLI/MCP process heap.
|
||||||
V8 old-space limits do not impose a process RSS limit. When REA runs on Bun,
|
V8 old-space limits do not impose a process RSS limit.
|
||||||
the analyzer ignores the V8 heap flags; resource failures then report
|
|
||||||
`worker_heap_limit_bytes` as null instead of a requested or V8-reported limit.
|
|
||||||
On Windows, the analyzer's owned Job Object instead limits its committed
|
|
||||||
memory to `max_heap_mb` plus a 512 MiB reserve for Bun itself (1536 MiB by
|
|
||||||
default). Reaching it fails the current source with the same memory resource
|
|
||||||
failure and reports `worker_process_memory_limit_bytes`, also a coverage limit;
|
|
||||||
the next source starts a new analyzer. Bun elsewhere enforces no analyzer limit.
|
|
||||||
|
|
||||||
A source that exhausts the analyzer heap does not terminate the CLI/MCP
|
A source that exhausts the analyzer heap does not terminate the CLI/MCP
|
||||||
process. Completed static facts are retained, other files can still be analyzed,
|
process. Completed static facts are retained, other files can still be analyzed,
|
||||||
@@ -198,11 +152,9 @@ completed partial Evidence. MCP failure details return
|
|||||||
after recording succeeds, so `inspect_analysis_view` can open that analysis
|
after recording succeeds, so `inspect_analysis_view` can open that analysis
|
||||||
directly without serializing the entire partial graph into the error response.
|
directly without serializing the entire partial graph into the error response.
|
||||||
CLI failure output retains the complete partial Evidence.
|
CLI failure output retains the complete partial Evidence.
|
||||||
Cancellation after source analysis begins likewise retains completed facts,
|
Cancellation after source analysis begins likewise
|
||||||
including cancellation during analyzer cleanup, graph construction, or Evidence
|
retains completed facts; an SDK client may reject its cancelled request before
|
||||||
sealing. REA finishes projecting those owned facts cooperatively to return partial
|
receiving that reply. On the same MCP connection, inspect the Evidence bundle
|
||||||
Evidence. An SDK client may reject its cancelled request before receiving that
|
|
||||||
reply. On the same MCP connection, inspect the Evidence bundle
|
|
||||||
and use the retained analysis ID with `inspect_analysis_view`. Owned analyzer
|
and use the retained analysis ID with `inspect_analysis_view`. Owned analyzer
|
||||||
cleanup is verified before its private files are released. Cleanup uncertainty
|
cleanup is verified before its private files are released. Cleanup uncertainty
|
||||||
is reported separately and retains ownership for retry.
|
is reported separately and retains ownership for retry.
|
||||||
@@ -272,11 +224,6 @@ unknown instead of silently treating them as absent or verified.
|
|||||||
Plain `.ts` artifact sources use TypeScript syntax without JSX, including
|
Plain `.ts` artifact sources use TypeScript syntax without JSX, including
|
||||||
angle-bracket type assertions. `.tsx` and `.jsx` retain JSX parsing.
|
angle-bracket type assertions. `.tsx` and `.jsx` retain JSX parsing.
|
||||||
|
|
||||||
Relative TypeScript imports can name their emitted `.js`, `.mjs`, or `.cjs`
|
|
||||||
counterparts while resolving to inventoried source files. This substitution
|
|
||||||
requires import or require semantics. Literal Electron preload, renderer, and
|
|
||||||
utility-process runtime paths retain the runtime filename selected by the caller.
|
|
||||||
|
|
||||||
Selected bounded text is then parsed as inert data to recover:
|
Selected bounded text is then parsed as inert data to recover:
|
||||||
|
|
||||||
- `package.json` metadata and declared main or renderer entrypoints;
|
- `package.json` metadata and declared main or renderer entrypoints;
|
||||||
@@ -369,44 +316,8 @@ substitute version-dependent Electron defaults for omitted `webPreferences`.
|
|||||||
Dynamic option objects, bridge keys, API objects, and IPC channel expressions
|
Dynamic option objects, bridge keys, API objects, and IPC channel expressions
|
||||||
remain unknown and make coverage partial.
|
remain unknown and make coverage partial.
|
||||||
|
|
||||||
Electron API identity follows proven lexical module aliases. Namespace interop
|
Electron API identity follows proven lexical module aliases. Reassigned bindings,
|
||||||
also preserves identity when the complete Rolldown helper operations, lexical
|
dynamic selections, and visibly overwritten namespace members are unresolved.
|
||||||
roles, live getters, and captured intrinsic origins match, or when a stable
|
|
||||||
helper simply returns its module parameter. Harmless single-statement control
|
|
||||||
blocks preserve recognition; added operations still require proof. Literal
|
|
||||||
member and destructuring projections are retained from proven results.
|
|
||||||
Omitted or literal node-mode arguments preserve named exports; a module-valued
|
|
||||||
default projection requires a truthy literal node mode. Computed or extra
|
|
||||||
arguments remain unresolved.
|
|
||||||
Recognition uses structure rather than emitted names; other helper bodies and ambiguous
|
|
||||||
runtime fallbacks remain unresolved. Captured function identities survive later global-property
|
|
||||||
replacement, including copies through initialized aliases. Reads before an
|
|
||||||
alias initializer remain unresolved. Visible intrinsic writes before capture or
|
|
||||||
conversion are checked in their owning callable scope, including identifier leaves in nested/default/rest
|
|
||||||
destructuring and loop targets. Property keys and shadowed local bindings do not
|
|
||||||
overwrite the global intrinsic identity. Cross-call side effects, including
|
|
||||||
writes inside directly invoked local functions, are not evaluated. Other
|
|
||||||
reassignments, dynamic selections, and visibly overwritten namespace members
|
|
||||||
are unresolved.
|
|
||||||
Known Object/Reflect mutators remain recognizable through literal destructuring
|
|
||||||
of intrinsic objects and stable bound-function aliases. Calls retain bound
|
|
||||||
argument prefixes and the original bound receiver through `call`, `apply`, and
|
|
||||||
`Reflect.apply`, including generic `Function.prototype` invocation and binding
|
|
||||||
creation. Arguments follow each actual callable invocation rather than property
|
|
||||||
chain depth; rebinding retains the original bound receiver.
|
|
||||||
Visibly replaced invocation intrinsics produce unknown effects instead
|
|
||||||
of using their former call semantics; captured function aliases retain their
|
|
||||||
earlier identity. Unexamined targets remain unresolved. `Reflect.set` examines
|
|
||||||
its explicit receiver as well as its target, retaining unknown receiver effects.
|
|
||||||
Creating an unused binding does not itself mutate an intrinsic. Variable
|
|
||||||
redeclarations retain a single unconditional initializer
|
|
||||||
when they introduce no assignment or second initializer.
|
|
||||||
Stable identifier chains to fresh object, array, function,
|
|
||||||
undecorated class or RegExp syntax keep those targets separate from intrinsic
|
|
||||||
objects when initialized before use; opaque, decorated, reassigned or
|
|
||||||
not-yet-initialized targets remain unresolved. Writes during class initialization
|
|
||||||
are still retained. Function declarations are available before their textual
|
|
||||||
position; variable and class initializers must precede use.
|
|
||||||
Direct and destructuring assignment, loop, update, and delete targets are checked
|
Direct and destructuring assignment, loop, update, and delete targets are checked
|
||||||
through namespace aliases; unrelated member writes do not discard observed API
|
through namespace aliases; unrelated member writes do not discard observed API
|
||||||
identity. This static check does
|
identity. This static check does
|
||||||
@@ -500,53 +411,16 @@ such as `./web3:app.js` still names a local artifact.
|
|||||||
Package `exports` fallback arrays are supported both at the top level and under
|
Package `exports` fallback arrays are supported both at the top level and under
|
||||||
the root `"."` entry. The resolver selects targets in declared order using the
|
the root `"."` entry. The resolver selects targets in declared order using the
|
||||||
same conditional and invalid-entry handling as nested exports arrays.
|
same conditional and invalid-entry handling as nested exports arrays.
|
||||||
Nonempty arrays containing only inactive conditions remain unmatched, allowing
|
|
||||||
the enclosing condition object to continue to a later active condition.
|
|
||||||
Empty arrays and explicit null targets keep their blocking outcome.
|
|
||||||
Refusal evidence distinguishes those source values and retains condition names
|
|
||||||
from unmatched nested targets rather than reporting array indices.
|
|
||||||
For imports and requires, the active Node conditions include `module-sync`;
|
For imports and requires, the active Node conditions include `module-sync`;
|
||||||
earlier active conditions retain precedence over later ones.
|
earlier active conditions retain precedence over later ones.
|
||||||
|
|
||||||
Package self-references use the importer's enclosing package scope before
|
ESM relative module paths and selected package exports targets use URL suffix handling
|
||||||
installed dependencies. ESM requires the parsed package name to equal the
|
and one percent-decoding pass. CommonJS relative paths and legacy package main
|
||||||
metadata name; a scope-only name such as `@scope` cannot capture `@scope/pkg`.
|
|
||||||
CommonJS retains Node's raw-request name/prefix matching. Both paths preserve
|
|
||||||
the original specifier and select exports under their own loader conditions.
|
|
||||||
|
|
||||||
Exact package-private `#alias` specifiers resolve against the importer's
|
|
||||||
enclosing `package.json` `imports` map — the nearest same-container package
|
|
||||||
scope, stopping at a `node_modules` directory so a nested package cannot inherit
|
|
||||||
an ancestor's aliases. Selected targets are package-local `./` files with no
|
|
||||||
extension or index fallback, using the same condition, array, and null selection
|
|
||||||
as exports subpaths. A missing key, explicit null, or out-of-scope alias keeps
|
|
||||||
an unresolved edge with that reason. Wildcard keys (`#internal/*`), recursive
|
|
||||||
`#` targets, and external-package import targets remain unresolved.
|
|
||||||
|
|
||||||
Exact keys such as `#/x` are literal lookup identities. `#` and names ending
|
|
||||||
in `/` are invalid. Imports arrays skip invalid parent-relative, absolute, and
|
|
||||||
URL targets before selecting a later package-local file; an unsupported bare
|
|
||||||
package or recursive alias keeps its unresolved outcome rather than selecting
|
|
||||||
a later fallback.
|
|
||||||
|
|
||||||
ESM relative module paths, legacy package subpaths without exports, and selected
|
|
||||||
package exports targets use URL suffix handling and one percent-decoding pass.
|
|
||||||
Bare specifiers retain their complete query/fragment text for exports key matching.
|
|
||||||
For dependency lookup, ESM constructs a package metadata URL instead of treating
|
|
||||||
the parsed package name as a literal directory. A root request such as `legacy?x`
|
|
||||||
does not load either `node_modules/legacy?x` or `node_modules/legacy`; an exact
|
|
||||||
self-reference with that metadata name can still select its exports first.
|
|
||||||
Without an exports map, ESM subpaths select exact files; directory imports and
|
|
||||||
extension fallback are refused. CommonJS relative paths and legacy package main
|
|
||||||
fields retain literal filename punctuation. Exports targets must start with
|
fields retain literal filename punctuation. Exports targets must start with
|
||||||
`./` and exclude `.`, `..`, and `node_modules` path segments, including their
|
`./` and exclude `.`, `..`, and `node_modules` path segments, including their
|
||||||
encoded forms, before URL normalization. Arrays skip invalid exports targets
|
encoded forms, before URL normalization. Arrays skip invalid exports targets
|
||||||
in declared order, including URLs that escape the package root after normalization.
|
in declared order; URL decoding and file lookup failures for a selected target
|
||||||
Selected package targets use the normalized URL path for lookup; tabs and
|
do not select a later entry. Rejected references retain the package metadata
|
||||||
newlines in the URL text are removed by the URL parser. CommonJS package targets
|
|
||||||
reject encoded separators anywhere in the selected URL; ESM checks its pathname.
|
|
||||||
URL decoding and file lookup failures for a selected target do not select a
|
|
||||||
later entry. Rejected references retain the package metadata
|
|
||||||
path, original target, failed constraint, and importing source location.
|
path, original target, failed constraint, and importing source location.
|
||||||
|
|
||||||
HTML script references resolve to exact inventoried files after applying the
|
HTML script references resolve to exact inventoried files after applying the
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# JavaScript source recovery
|
# JavaScript source recovery
|
||||||
|
|
||||||
`recover_javascript_sources` / `recover-javascript-sources` derives readable
|
`recover_javascript_sources` / `recover-javascript-sources` derives readable
|
||||||
modules from explicitly selected UTF-8 JavaScript files or bundles. Use it on
|
modules from one explicitly selected UTF-8 JavaScript file or bundle. Use it on
|
||||||
files returned by `export_web_scripts` or other local scripts. The operation
|
files returned by `export_web_scripts` or other local scripts. The operation
|
||||||
never executes the selected or recovered application code.
|
never executes the selected or recovered application code.
|
||||||
|
|
||||||
@@ -52,58 +52,35 @@ Both give the same binary (SHA-256
|
|||||||
```sh
|
```sh
|
||||||
rea recover-javascript-sources /tmp/web-scripts/app.js /tmp/recovered-app --json
|
rea recover-javascript-sources /tmp/web-scripts/app.js /tmp/recovered-app --json
|
||||||
rea analyze-javascript-application /tmp/recovered-app/modules --json
|
rea analyze-javascript-application /tmp/recovered-app/modules --json
|
||||||
|
|
||||||
# Recover related code-split chunks together; repeat --additional-path.
|
|
||||||
rea recover-javascript-sources /tmp/web-scripts/main.js /tmp/recovered-chunks \
|
|
||||||
--additional-path /tmp/web-scripts/runtime.js \
|
|
||||||
--additional-path /tmp/web-scripts/shared.js \
|
|
||||||
--additional-path /tmp/web-scripts/checkout.chunk.js --json
|
|
||||||
```
|
```
|
||||||
|
|
||||||
MCP input:
|
MCP input:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"path": "/tmp/web-scripts/main.js",
|
"path": "/tmp/web-scripts/app.js",
|
||||||
"additional_paths": [
|
"output_directory": "/tmp/recovered-app"
|
||||||
"/tmp/web-scripts/runtime.js",
|
|
||||||
"/tmp/web-scripts/shared.js",
|
|
||||||
"/tmp/web-scripts/checkout.chunk.js"
|
|
||||||
],
|
|
||||||
"output_directory": "/tmp/recovered-chunks"
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The output directory must be absent, absolute, and have an existing parent.
|
The output directory must be absent, absolute, and have an existing parent.
|
||||||
Each source is snapshotted separately in a private workspace. Multiple inputs
|
The source is snapshotted in a private workspace, and the engine writes only to
|
||||||
retain their relative directory layout and are passed together to one Wakaru
|
|
||||||
invocation, allowing cross-chunk module IDs to resolve. Inputs must be distinct;
|
|
||||||
`additional_paths` accepts up to 16 additional files. The engine writes only to
|
|
||||||
its own staging directory. Reported module paths, input identities, UTF-8 byte
|
its own staging directory. Reported module paths, input identities, UTF-8 byte
|
||||||
ranges, regular files and emitted map representations are validated before
|
ranges, regular files and emitted map representations are validated before
|
||||||
publication. REA writes verified bytes to an exclusively owned output tree and
|
publication. REA writes verified bytes to an exclusively owned output tree and
|
||||||
rolls it back on failure. It also checks that the original source and engine
|
rolls it back on failure. It also checks that the original source and engine
|
||||||
bytes remain unchanged before committing. The existing output is never overwritten.
|
bytes remain unchanged before committing. The existing output is never overwritten.
|
||||||
|
|
||||||
Multi-input relative filenames must be representable unchanged as artifact paths:
|
|
||||||
NFC Unicode spelling and no literal backslashes. Unsupported layouts fail before
|
|
||||||
invoking the engine rather than silently renaming inputs referenced by source maps.
|
|
||||||
|
|
||||||
Published contents:
|
Published contents:
|
||||||
|
|
||||||
- `inputs/bundle.js`: exact original snapshot for a single input. Multiple inputs
|
- `inputs/bundle.js`: exact original snapshot; its digest binds the Evidence.
|
||||||
retain paths relative to their common parent under `inputs/`.
|
|
||||||
- `modules/`: derived modules and any upstream-emitted source maps.
|
- `modules/`: derived modules and any upstream-emitted source maps.
|
||||||
- `reports/stdout.json` and `reports/provenance.json`: exact producer reports.
|
- `reports/stdout.json` and `reports/provenance.json`: exact producer reports.
|
||||||
- `manifest.json`: identities, modules, transform choices, warnings and limitations.
|
- `manifest.json`: identities, modules, transform choices, warnings and limitations.
|
||||||
|
|
||||||
The inline result includes complete file paths/digests/sizes, extraction ranges,
|
The inline result includes complete file paths/digests/sizes, extraction ranges,
|
||||||
warnings and `analysis_input`, directly usable as the arguments to
|
warnings and `analysis_input`, directly usable as the arguments to
|
||||||
`analyze_javascript_application`. `source` identifies the primary input and binds
|
`analyze_javascript_application`. Raw Evidence retains selected command arguments,
|
||||||
the Evidence subject; `additional_sources` records the other snapshots and their
|
|
||||||
published copies when selected. Each module names its owning snapshot, original
|
|
||||||
path and original digest; all extraction and context ranges refer to that input.
|
|
||||||
Raw Evidence retains selected command arguments,
|
|
||||||
reported input paths, exit status, stderr and reports; temporary paths are recorded
|
reported input paths, exit status, stderr and reports; temporary paths are recorded
|
||||||
as historical execution coordinates after their workspace is removed.
|
as historical execution coordinates after their workspace is removed.
|
||||||
|
|
||||||
@@ -130,8 +107,7 @@ equivalence remain unknown. No network fetching occurs.
|
|||||||
## Resource policy and verification
|
## Resource policy and verification
|
||||||
|
|
||||||
Each operation uses one worker, a 1 GiB address-space ceiling and a 120-second
|
Each operation uses one worker, a 1 GiB address-space ceiling and a 120-second
|
||||||
deadline; it accepts up to 64 MiB of total input across all selected files and
|
deadline; it accepts up to 64 MiB of input and 128 MiB/10000 entries of staged
|
||||||
128 MiB/10000 entries of staged
|
|
||||||
output, with 8 MiB per diagnostic/report stream. Exceeding a limit is an explicit
|
output, with 8 MiB per diagnostic/report stream. Exceeding a limit is an explicit
|
||||||
failure with rollback. These limits apply per operation and do not claim aggregate
|
failure with rollback. These limits apply per operation and do not claim aggregate
|
||||||
host containment across concurrent callers.
|
host containment across concurrent callers.
|
||||||
|
|||||||
@@ -38,12 +38,6 @@ Inspect separately obtained components explicitly and preserve their identities.
|
|||||||
A valid implementation marker establishes a candidate native boundary, not
|
A valid implementation marker establishes a candidate native boundary, not
|
||||||
recovered native semantics or runtime behavior.
|
recovered native semantics or runtime behavior.
|
||||||
|
|
||||||
An assembly targeting [.NET Standard](https://learn.microsoft.com/en-us/dotnet/standard/net-standard)
|
|
||||||
declares API compatibility across multiple .NET implementations. REA preserves
|
|
||||||
that target in `target_frameworks` and leaves `runtime_family` as `unknown`
|
|
||||||
unless independent markers identify a runtime family, such as a ReadyToRun
|
|
||||||
signature.
|
|
||||||
|
|
||||||
### Resource admission
|
### Resource admission
|
||||||
|
|
||||||
The static provider admits regular input files up to 128 MiB before retaining
|
The static provider admits regular input files up to 128 MiB before retaining
|
||||||
@@ -126,33 +120,6 @@ Member inspection binds build-local tokens, signatures, row offsets, method
|
|||||||
bodies, and decoded relationships to that artifact and MVID. Missing or malformed
|
bodies, and decoded relationships to that artifact and MVID. Missing or malformed
|
||||||
facts remain explicit in coverage and per-member status.
|
facts remain explicit in coverage and per-member status.
|
||||||
|
|
||||||
Metadata table streams may carry the CLR-compatible `ExtraData` extension
|
|
||||||
(`HeapSizes` flag `0x40`), which Microsoft readers honor although it is not
|
|
||||||
specified by ECMA-335. REA skips its fixed four-byte word after the row counts
|
|
||||||
before decoding table rows; the word's value is not a length. An incomplete
|
|
||||||
word is reported as a metadata coverage failure at its file offset, without
|
|
||||||
reading beyond the declared table stream.
|
|
||||||
|
|
||||||
For unoptimized `#-` metadata, nonempty `FieldPtr` and `MethodPtr` tables
|
|
||||||
translate TypeDef list positions to physical member definitions. REA resolves
|
|
||||||
these indirections for member ownership and local attribute-constructor types;
|
|
||||||
field and method tokens still identify the original definition rows.
|
|
||||||
`field_list` and `method_list` retain the metadata's list coordinates, which
|
|
||||||
refer to the pointer table when present rather than necessarily contiguous
|
|
||||||
definition rows. Malformed or ambiguous pointers leave the owner unknown with
|
|
||||||
partial coverage while preserving readable member and attribute facts.
|
|
||||||
The retained inverse indexes are admitted against the existing representation
|
|
||||||
budget before allocation.
|
|
||||||
|
|
||||||
`exported_types` reports ExportedType rows as declared. Facade assemblies such
|
|
||||||
as .NET `System.Runtime.dll` provide their types this way: `forwarder: true`
|
|
||||||
marks a type forwarder, and `implementation_token` names the AssemblyRef, File,
|
|
||||||
or enclosing ExportedType row that implements it. REA does not load the
|
|
||||||
implementing assembly to resolve the forwarded definition, and
|
|
||||||
`compare_managed_members` does not compare exported types. Member Evidence
|
|
||||||
recorded before this field existed reads back with `exported_types: null`,
|
|
||||||
which means the table was not examined.
|
|
||||||
|
|
||||||
CLI `#GUID` heap values retain their exact 16-byte GUID text. REA does not impose
|
CLI `#GUID` heap values retain their exact 16-byte GUID text. REA does not impose
|
||||||
RFC 4122 UUID version or variant bits on MVID, EncId, or EncBaseId because
|
RFC 4122 UUID version or variant bits on MVID, EncId, or EncBaseId because
|
||||||
ECMA-335 metadata does not require those bit patterns. Tokens and RVAs are
|
ECMA-335 metadata does not require those bit patterns. Tokens and RVAs are
|
||||||
|
|||||||
+11
-50
@@ -150,15 +150,13 @@ structured data and matching text projection. Oversized errors are retained
|
|||||||
as Evidence before delivery of a bounded diagnostic with an export reference;
|
as Evidence before delivery of a bounded diagnostic with an export reference;
|
||||||
if retention is unavailable or fails, the diagnostic reports that reason.
|
if retention is unavailable or fails, the diagnostic reports that reason.
|
||||||
|
|
||||||
REA accepts ordinary `tools/call` progress tokens. The numeric `progress` counts
|
REA accepts ordinary `tools/call` progress tokens. Updates are monotonic,
|
||||||
emitted status observations and strictly increases, including when a waiting
|
rate-bounded to at most one intermediate update per 100 ms, and always allow a
|
||||||
phase has completed no additional work. Updates are rate-bounded to at most one
|
terminal update. Unknown totals are omitted; REA does not fabricate percentages.
|
||||||
intermediate update per 100 ms and always allow a terminal update. `total` is
|
|
||||||
omitted because the number of future status observations is unknown. Read
|
|
||||||
`message` for the phase and observed work; REA does not fabricate percentages.
|
|
||||||
`capture_process_scenario` uses that boundary only when the client supplies a
|
`capture_process_scenario` uses that boundary only when the client supplies a
|
||||||
progress token. Notifications put the lifecycle phase, elapsed time, and final
|
progress token. Notifications set `progress` to the count of collected terminal
|
||||||
cleanup status in `message`. A client
|
frames, process samples, and interaction events, omit `total`, and put the
|
||||||
|
lifecycle phase, elapsed time, and final cleanup status in `message`. A client
|
||||||
that does not send a progress token receives no progress notifications. The
|
that does not send a progress token receives no progress notifications. The
|
||||||
tool result is unchanged either way.
|
tool result is unchanged either way.
|
||||||
Provider calls receive the request cancellation signal. Artifact traversal,
|
Provider calls receive the request cancellation signal. Artifact traversal,
|
||||||
@@ -206,7 +204,6 @@ These deadlines have different owners:
|
|||||||
| Deadline | Owner and effect |
|
| Deadline | Owner and effect |
|
||||||
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| MCP initialize | The client bounds transport/REA connection startup, before any target query. |
|
| MCP initialize | The client bounds transport/REA connection startup, before any target query. |
|
||||||
| Hopper startup | REA allows 120,000 ms by default; `REA_HOPPER_STARTUP_TIMEOUT_MS` accepts decimal integers from 1–2,147,483,647 ms. Invalid values fail configuration validation. Startup failure is reported by the first provider query. |
|
|
||||||
| Ghidra startup | REA allows 330,000 ms by default; `REA_GHIDRA_STARTUP_TIMEOUT_MS` accepts decimal integers from 1–2,147,483,647 ms. Invalid supplied values fail configuration validation. Startup failure is reported by the first provider query. |
|
| Ghidra startup | REA allows 330,000 ms by default; `REA_GHIDRA_STARTUP_TIMEOUT_MS` accepts decimal integers from 1–2,147,483,647 ms. Invalid supplied values fail configuration validation. Startup failure is reported by the first provider query. |
|
||||||
| Individual tool call | The client bounds its wait, including cold engine startup. The pinned client SDK 2.3.1 defaults to 60,000 ms and can cancel earlier than REA's startup deadline. |
|
| Individual tool call | The client bounds its wait, including cold engine startup. The pinned client SDK 2.3.1 defaults to 60,000 ms and can cancel earlier than REA's startup deadline. |
|
||||||
|
|
||||||
@@ -232,18 +229,6 @@ engine readiness or a percentage of Ghidra auto-analysis. A longer server
|
|||||||
startup allowance does not extend the client's deadline; progress also does not
|
startup allowance does not extend the client's deadline; progress also does not
|
||||||
extend it unless the client explicitly implements that policy.
|
extend it unless the client explicitly implements that policy.
|
||||||
|
|
||||||
While Ghidra startup is pending, REA sends a waiting notification every ten
|
|
||||||
seconds when the request has a progress token. Its message gives elapsed waiting
|
|
||||||
time; import, auto-analysis and bridge readiness may all still be pending.
|
|
||||||
Waiting notifications stop when startup settles or the caller cancels. They do
|
|
||||||
not measure engine work completed.
|
|
||||||
|
|
||||||
The pinned SDK can reset the request's inactivity timeout on progress with
|
|
||||||
`resetTimeoutOnProgress: true`. Also set `maxTotalTimeout` to bound the complete
|
|
||||||
request; the provider's startup deadline still applies. These options belong in
|
|
||||||
the same second argument of `callTool`. Without that explicit client policy, the
|
|
||||||
default 60-second request deadline still expires despite waiting notifications.
|
|
||||||
|
|
||||||
The 240-second setting is a measured example, not a universal timeout: a
|
The 240-second setting is a measured example, not a universal timeout: a
|
||||||
controlled Linux x64/WSL2 fixture took about 64 seconds for its first overview
|
controlled Linux x64/WSL2 fixture took about 64 seconds for its first overview
|
||||||
with Ghidra 12.1.4 on a mounted NTFS installation, native JDK 21, two CPUs, and a
|
with Ghidra 12.1.4 on a mounted NTFS installation, native JDK 21, two CPUs, and a
|
||||||
@@ -279,10 +264,9 @@ observed process-family member remained after final close. This was a small
|
|||||||
1,024-byte fixture, so the longer request setting remains an example, not a
|
1,024-byte fixture, so the longer request setting remains an example, not a
|
||||||
guarantee for larger targets. No macOS cold-start recovery was exercised.
|
guarantee for larger targets. No macOS cold-start recovery was exercised.
|
||||||
|
|
||||||
With a supplied progress token, that earlier Windows run received an operation-start
|
With a supplied progress token, the Windows run received an operation-start
|
||||||
notification before timeout and start/completion notifications for the
|
notification before timeout and start/completion notifications for the
|
||||||
successful retry, before startup waiting notifications were added. It received
|
successful retry. It received no intermediate import or auto-analysis progress.
|
||||||
no intermediate import or auto-analysis progress.
|
|
||||||
These operation markers do not measure analysis work completed or extend the
|
These operation markers do not measure analysis work completed or extend the
|
||||||
client's deadline. Each new provider session still imports the target into a
|
client's deadline. Each new provider session still imports the target into a
|
||||||
fresh temporary project.
|
fresh temporary project.
|
||||||
@@ -310,13 +294,6 @@ directly to `compare_functions`, and `inspect_artifact` Evidence to
|
|||||||
`compare_artifacts`. Use `get_evidence_bundle` when the task needs broader
|
`compare_artifacts`. Use `get_evidence_bundle` when the task needs broader
|
||||||
retained session history or an explicit bundle for transfer.
|
retained session history or an explicit bundle for transfer.
|
||||||
|
|
||||||
`get_call_graph` keeps provider-limited relationship reads on their node as
|
|
||||||
`limitations`, alongside any observed `calls`. An empty call list with such a
|
|
||||||
limitation is incomplete coverage, not proof that the function has no calls.
|
|
||||||
`trace_call_path` reports each limited expansion in `residual_unknowns` and
|
|
||||||
sets `truncated: true`; any path already supported by observed edges remains
|
|
||||||
visible. Tool errors remain in their existing error or failure fields.
|
|
||||||
|
|
||||||
REA prepares complete MCP results within the pinned stdio client's 10 MiB
|
REA prepares complete MCP results within the pinned stdio client's 10 MiB
|
||||||
receive-buffer budget, including both text and structured representations and
|
receive-buffer budget, including both text and structured representations and
|
||||||
room for the JSON-RPC envelope. Tool errors carry only their text
|
room for the JSON-RPC envelope. Tool errors carry only their text
|
||||||
@@ -328,18 +305,8 @@ session. Its exact reference is reported in
|
|||||||
`details.reported_limits.evidence_reference`; call `inspect_analysis_view` with
|
`details.reported_limits.evidence_reference`; call `inspect_analysis_view` with
|
||||||
that reference for a summary, one section/module, or a stable page, or call
|
that reference for a summary, one section/module, or a stable page, or call
|
||||||
`export_evidence_bundle` with a destination path. Complete
|
`export_evidence_bundle` with a destination path. Complete
|
||||||
bundle exports stream canonical JSON into an atomically published file.
|
bundle exports stream canonical JSON into an atomically published file. A broad
|
||||||
|
follow-up or `get_evidence_bundle` can also exceed the response budget; exporting
|
||||||
For oversized native function Evidence, `details.reported_limits.continuation`
|
|
||||||
contains a ready-to-call `inspect_analysis_view` request for the retained
|
|
||||||
pseudocode's first page. Use its `name` and `arguments` directly, then follow
|
|
||||||
`normalized_result.coverage.next_offset` for subsequent pages. The suggested
|
|
||||||
limit is the view contract's default, not a guarantee that arbitrary source or
|
|
||||||
metadata fits; reduce the limit or export when needed. Continuations are
|
|
||||||
offered for completed `analyze_function` results only after session recording is
|
|
||||||
acknowledged; the complete result and its retention reference remain intact.
|
|
||||||
|
|
||||||
A broad follow-up or `get_evidence_bundle` can also exceed the response budget; exporting
|
|
||||||
preserves the complete session without sending it through a single MCP frame.
|
preserves the complete session without sending it through a single MCP frame.
|
||||||
To discover existing records without their large payloads, call
|
To discover existing records without their large payloads, call
|
||||||
`get_evidence_bundle` with `detail: "summary"`. Its `result.records` contain
|
`get_evidence_bundle` with `detail: "summary"`. Its `result.records` contain
|
||||||
@@ -467,13 +434,7 @@ Tool annotations describe effects and are hints, not authorization controls
|
|||||||
([MCP ToolAnnotations](https://modelcontextprotocol.io/specification/2025-06-18/schema#toolannotations)).
|
([MCP ToolAnnotations](https://modelcontextprotocol.io/specification/2025-06-18/schema#toolannotations)).
|
||||||
`readOnlyHint` includes session state: an analysis call that records additive
|
`readOnlyHint` includes session state: an analysis call that records additive
|
||||||
Evidence is marked non-read-only even when it leaves the target unchanged.
|
Evidence is marked non-read-only even when it leaves the target unchanged.
|
||||||
`destructiveHint` is true when a tool may discard data (overwriting or clearing
|
`destructiveHint` describes possible data loss, not ordinary Evidence recording.
|
||||||
analyst metadata, replacing files, dropping session state), runs or drives code
|
|
||||||
REA does not own (`executesForeignCode`: process, LLDB, Electron, browser, and
|
|
||||||
native UI scenarios), or changes an attached Android device (`mutatesDevice`:
|
|
||||||
push, install, uninstall, start, and stop). Ordinary Evidence recording is not
|
|
||||||
destructive. The effect record in `binary_session` and the generated catalog
|
|
||||||
carries each flag separately.
|
|
||||||
Effect metadata covers possible behavior across supported inputs: DMG inventory
|
Effect metadata covers possible behavior across supported inputs: DMG inventory
|
||||||
can launch `hdiutil` and create an owned temporary mount directory; extraction
|
can launch `hdiutil` and create an owned temporary mount directory; extraction
|
||||||
creates a fresh output directory on every call. Comparing supplied web captures
|
creates a fresh output directory on every call. Comparing supplied web captures
|
||||||
|
|||||||
@@ -195,20 +195,7 @@ outside-memory and undecodable addresses have separate outcomes. Effective
|
|||||||
memory base/index/displacement roles and per-instruction context mode remain
|
memory base/index/displacement roles and per-instruction context mode remain
|
||||||
unavailable; `mode` is the program language variant.
|
unavailable; `mode` is the program language variant.
|
||||||
|
|
||||||
`inspect_native_instruction` also returns `incoming_references` to the exact
|
Compact instruction references and call-target references preserve the source
|
||||||
queried address, including data, interior-instruction and undecodable addresses.
|
|
||||||
Ghidra enumerates its ReferenceManager, excludes synthetic entry-point
|
|
||||||
references, and returns deterministic source-address ordering while retaining
|
|
||||||
distinct operand references from the same source. `[]` means that enumeration
|
|
||||||
found no references; omission or `null` means this facet is unavailable in an
|
|
||||||
older capture or another provider. Empty static references do not prove that
|
|
||||||
the address is unused at runtime. The existing `references` field still holds
|
|
||||||
outgoing instruction references, and `xrefs` still returns bare source addresses.
|
|
||||||
The Ghidra analysis profile versions this incoming-reference coverage. Reopen
|
|
||||||
the target without an older snapshot and save a fresh snapshot to acquire it;
|
|
||||||
the older snapshot's Evidence bundle remains readable with this facet unavailable.
|
|
||||||
|
|
||||||
Compact incoming, outgoing instruction and call-target references preserve the source
|
|
||||||
address, operand index, DATA/READ/WRITE classification, primary status, provider
|
address, operand index, DATA/READ/WRITE classification, primary status, provider
|
||||||
`provenance`, and reference `source` (for Ghidra: `analysis`, `default`, `imported`
|
`provenance`, and reference `source` (for Ghidra: `analysis`, `default`, `imported`
|
||||||
or `user_defined`). Primary status reports the provider's chosen reference; it
|
or `user_defined`). Primary status reports the provider's chosen reference; it
|
||||||
|
|||||||
@@ -1,76 +0,0 @@
|
|||||||
# Headerless raw-binary analysis with Ghidra
|
|
||||||
|
|
||||||
REA admits a headerless executable when the caller supplies the CPU family and
|
|
||||||
the address where file offset 0 should be mapped. That interpretation is not
|
|
||||||
inferred from a `.bin` suffix or from unrecognized bytes.
|
|
||||||
|
|
||||||
## Open and inspect
|
|
||||||
|
|
||||||
```bash
|
|
||||||
rea inspect /absolute/path/to/ecu.bin --target-format raw-binary --architecture arm --entry-point 0x8000000 --provider ghidra --json
|
|
||||||
rea function /absolute/path/to/ecu.bin 0x8000000 --target-format raw-binary --architecture arm --entry-point 0x8000000 --provider ghidra --json
|
|
||||||
rea inspect-native-load-image /absolute/path/to/ecu.bin --target-format raw-binary --architecture arm --entry-point 0x8000000 --provider ghidra --json
|
|
||||||
```
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"name": "open_binary",
|
|
||||||
"arguments": {
|
|
||||||
"path": "/absolute/path/to/ecu.bin",
|
|
||||||
"format": "raw-binary",
|
|
||||||
"architecture": "arm",
|
|
||||||
"entry_point": "0x8000000",
|
|
||||||
"provider_id": "ghidra"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
`architecture` is one of `x86`, `x86_64`, `arm`, or `arm64`. `entry_point` is a
|
|
||||||
hexadecimal address of the form `0x…`. The complete file is mapped starting at
|
|
||||||
that address, and Ghidra seeds an `entry` function there before auto-analysis.
|
|
||||||
ARM and AArch64 entries must be 4-byte aligned; x86 entries may be byte-aligned.
|
|
||||||
`open_binary` and an open `binary_session` return the canonical `entry_point`
|
|
||||||
for raw targets so callers can verify the selected mapping directly.
|
|
||||||
Omitted `format` keeps header-based detection; architecture and entry without
|
|
||||||
`format=raw-binary` are rejected.
|
|
||||||
|
|
||||||
Ghidra imports a private snapshot with `BinaryLoader` and these little-endian
|
|
||||||
generic languages and compiler specifications:
|
|
||||||
|
|
||||||
| architecture | language_id | compiler_spec_id |
|
|
||||||
| ------------ | ------------------- | ---------------- |
|
|
||||||
| x86 | `x86:LE:32:default` | `gcc` |
|
|
||||||
| x86_64 | `x86:LE:64:default` | `gcc` |
|
|
||||||
| arm | `ARM:LE:32:v7` | `default` |
|
|
||||||
| arm64 | `AARCH64:LE:64:v8A` | `default` |
|
|
||||||
|
|
||||||
Compiler specifications select analysis conventions; they do not identify the
|
|
||||||
original compiler or ABI of a headerless target. Ghidra's x86 languages do not
|
|
||||||
provide a compiler specification named `default`.
|
|
||||||
|
|
||||||
Those settings, the caller-supplied entry, and `language_selection:
|
|
||||||
caller-supplied-v1` are committed in the analysis profile. A different entry
|
|
||||||
or architecture is a different profile; snapshots from header-detected targets
|
|
||||||
do not replay.
|
|
||||||
|
|
||||||
The mapped start is independent of Ghidra's program image base, which remains
|
|
||||||
`0x0` for BinaryLoader. Ghidra may report additional language-defined entry
|
|
||||||
points, including unmapped ARM vectors. Load-image verification requires the
|
|
||||||
caller-supplied entry and preserves those other entries as observations.
|
|
||||||
Independent raw verification streams the complete private snapshot digest and
|
|
||||||
extent with bounded memory and supports cancellation during the read.
|
|
||||||
|
|
||||||
Hopper and IDA refuse raw-binary targets. Windows Ghidra P0 continues to admit
|
|
||||||
PE applications only.
|
|
||||||
|
|
||||||
## Limitations
|
|
||||||
|
|
||||||
- Headers are not discovered from file bytes. This increment does not guess
|
|
||||||
load addresses, vector tables, or memory maps.
|
|
||||||
- Big-endian, Thumb-only, Cortex-M, and other Ghidra processor variants are
|
|
||||||
unsupported.
|
|
||||||
- Reset vectors, memory-mapped I/O, and firmware boot sequences are not
|
|
||||||
emulated.
|
|
||||||
- Independent load-image verification covers source identity, mapped file
|
|
||||||
bytes, the bound language, and the caller-supplied entry. Original bytes
|
|
||||||
stay unchanged.
|
|
||||||
+23
-149
@@ -139,11 +139,8 @@ directory, so default OS-home discovery remains unverified. Live model APIs and
|
|||||||
native Windows are also unverified.
|
native Windows are also unverified.
|
||||||
|
|
||||||
`verify:claude-client` requires installed Claude Code (verified with
|
`verify:claude-client` requires installed Claude Code (verified with
|
||||||
`@anthropic-ai/claude-code@2.1.296` on POSIX and native Windows); select it
|
`@anthropic-ai/claude-code@2.1.296`); select it with `REA_VERIFY_CLAUDE_COMMAND`.
|
||||||
with `REA_VERIFY_CLAUDE_COMMAND`. On Windows, select
|
The optional POSIX lane uses native `CLAUDE_CONFIG_DIR` discovery, an independent
|
||||||
`claude.exe`: npm installs put only a `claude.cmd` shim on `PATH`, and the real
|
|
||||||
executable is under `node_modules/@anthropic-ai/claude-code/bin`.
|
|
||||||
The optional lane uses native `CLAUDE_CONFIG_DIR` discovery, an independent
|
|
||||||
Git workspace, user settings and default built-in tools. It preserves caller
|
Git workspace, user settings and default built-in tools. It preserves caller
|
||||||
preferences and backups, checks idempotent setup, waits through the native
|
preferences and backups, checks idempotent setup, waits through the native
|
||||||
`WaitForMcpServers` tool when discovery is pending, and validates the complete
|
`WaitForMcpServers` tool when discovery is pending, and validates the complete
|
||||||
@@ -152,8 +149,8 @@ native `Skill`, checks its full body and verifies named-schema JavaScript Eviden
|
|||||||
for a Unicode path. Use `-- chat` for ordinary chat with REA enabled, or
|
for a Unicode path. Use `-- chat` for ordinary chat with REA enabled, or
|
||||||
`REA_VERIFY_RUNTIME_ROOT` for a production-only installed package. The local
|
`REA_VERIFY_RUNTIME_ROOT` for a production-only installed package. The local
|
||||||
Anthropic Messages/SSE fixture preserves native resource-hint envelopes in its
|
Anthropic Messages/SSE fixture preserves native resource-hint envelopes in its
|
||||||
request artifacts. Usage is synthetic; live Anthropic API and bare-mode
|
request artifacts. Usage is synthetic; live Anthropic API, native Windows and
|
||||||
personal-skill activation remain unverified by this lane.
|
bare-mode personal-skill activation remain unverified by this lane.
|
||||||
|
|
||||||
`verify:copilot-client` requires installed GitHub Copilot CLI (verified with
|
`verify:copilot-client` requires installed GitHub Copilot CLI (verified with
|
||||||
`@github/copilot@1.0.95`); select it with `REA_VERIFY_COPILOT_COMMAND`.
|
`@github/copilot@1.0.95`); select it with `REA_VERIFY_COPILOT_COMMAND`.
|
||||||
@@ -282,12 +279,10 @@ establish live DeepSeek API or native Windows coverage. Receipts include
|
|||||||
request artifacts, result digests and owned-process lineage.
|
request artifacts, result digests and owned-process lineage.
|
||||||
|
|
||||||
Full E2E tests invoke the production command dispatcher and real providers,
|
Full E2E tests invoke the production command dispatcher and real providers,
|
||||||
without fake launchers, runners or responses. `verify:keyed-archive` writes
|
without fake launchers, runners or responses. `verify:keyed-archive` writes an
|
||||||
Foundation binary, XML, and integer archives using one run-owned Swift module
|
actual Foundation binary archive, runs the CLI and a separate stdio MCP
|
||||||
cache. It checks CLI and separate stdio MCP parity, pagination, escaping-path
|
subprocess, checks parity and pagination, rejects an escaping path and checks
|
||||||
rejection, an XML graph golden, and numeric meaning for safe controls, unsafe
|
an XML graph golden. `verify:asset-catalog` compiles source-owned colors with
|
||||||
integers, boxed numbers, and integral-valued reals. `verify:asset-catalog`
|
|
||||||
compiles source-owned colors with
|
|
||||||
`actool`, invokes real `assetutil`, then checks CLI/MCP results, exact catalog
|
`actool`, invokes real `assetutil`, then checks CLI/MCP results, exact catalog
|
||||||
digest, every raw metadata field, pagination and malformed input rejection.
|
digest, every raw metadata field, pagination and malformed input rejection.
|
||||||
Neither artifact workflow requires Hopper or launches it. Both run in macOS CI.
|
Neither artifact workflow requires Hopper or launches it. Both run in macOS CI.
|
||||||
@@ -463,7 +458,7 @@ prove behavior on the verified Ghidra 12.1.4 and JDK 21 build.
|
|||||||
| Ghidra lane | Supported runner/target | Additional local tools |
|
| Ghidra lane | Supported runner/target | Additional local tools |
|
||||||
| ------------------------------------------ | ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
|
| ------------------------------------------ | ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
|
||||||
| `npm run verify:ghidra` | Linux x64/arm64 ELF or macOS x64/arm64 Mach-O | Host C compiler, Ghidra 12.1.4, and full JDK 21 |
|
| `npm run verify:ghidra` | Linux x64/arm64 ELF or macOS x64/arm64 Mach-O | Host C compiler, Ghidra 12.1.4, and full JDK 21 |
|
||||||
| `npm run verify:ghidra:seeds` | POSIX; raw x86 fixture; seed ordering, BSS labels, analyzer readback and unknown-name rejection | Ghidra 12.1.4 and full JDK 21 |
|
| `npm run verify:ghidra:seeds` | POSIX host; source-owned 32-bit x86 raw fixture; function order and BSS labels | Ghidra 12.1.4 and full JDK 21 |
|
||||||
| `npm run verify:ghidra:swift` | macOS x64/arm64 Mach-O | Host Swift compiler, Ghidra 12.1.4, and full JDK 21 |
|
| `npm run verify:ghidra:swift` | macOS x64/arm64 Mach-O | Host Swift compiler, Ghidra 12.1.4, and full JDK 21 |
|
||||||
| `npm run verify:ghidra:switch` | Linux x64 ELF; GCC/Clang optimized and stripped switch fixtures | GCC, Clang, GNU nm/objdump/strip, Ghidra 12.1.4, and full JDK 21 |
|
| `npm run verify:ghidra:switch` | Linux x64 ELF; GCC/Clang optimized and stripped switch fixtures | GCC, Clang, GNU nm/objdump/strip, Ghidra 12.1.4, and full JDK 21 |
|
||||||
| `npm run verify:ghidra:aarch64-jump-table` | Any supported Ghidra host; AArch64 ELF; signed/unsigned byte/halfword tables; host ARM64 Mach-O | Clang with AArch64 target support, Ghidra 12.1.4, and full JDK 21 |
|
| `npm run verify:ghidra:aarch64-jump-table` | Any supported Ghidra host; AArch64 ELF; signed/unsigned byte/halfword tables; host ARM64 Mach-O | Clang with AArch64 target support, Ghidra 12.1.4, and full JDK 21 |
|
||||||
@@ -483,17 +478,8 @@ native decompiler. The namespace verifier reports missing or non-executable
|
|||||||
components before testing the fixture. REA does not build or install them.
|
components before testing the fixture. REA does not build or install them.
|
||||||
|
|
||||||
Windows native conformance runs with `npm run verify:windows-native` and does
|
Windows native conformance runs with `npm run verify:windows-native` and does
|
||||||
not require Ghidra or Java. It includes Job Object commit-limit controls (a
|
not require Ghidra or Java. An optional independently compiled Windows fixture
|
||||||
limited child that reaches the limit, a control that does not, and invalid
|
|
||||||
limit rejection). An optional independently compiled Windows fixture
|
|
||||||
adds in-place reparse, breakaway, environment, and token observations.
|
adds in-place reparse, breakaway, environment, and token observations.
|
||||||
The separate `scripts/verify-windows-native-inspection.mjs` lane uses the
|
|
||||||
`.cache/windows-native-inspection-fixture` artifact built on Linux with
|
|
||||||
`node scripts/build-windows-native.mjs --inspection-fixture`. Its controlled
|
|
||||||
first deletion failure checks retained NTFS ownership, later-query recovery,
|
|
||||||
successful-admission caching, and environment-teardown cleanup. It neither
|
|
||||||
establishes the cause of the intermittent #1701 host failure nor replaces
|
|
||||||
verification with the shipped production artifact.
|
|
||||||
`npm run verify:ghidra:windows:package` additionally packs and installs REA into
|
`npm run verify:ghidra:windows:package` additionally packs and installs REA into
|
||||||
an isolated prefix and runs ordinary-user CLI/MCP operations against their
|
an isolated prefix and runs ordinary-user CLI/MCP operations against their
|
||||||
canonical schemas. Run the controlled fixture generator before that lane, or
|
canonical schemas. Run the controlled fixture generator before that lane, or
|
||||||
@@ -638,18 +624,6 @@ remain GUI-only surfaces in JEB 5.48.0 headless.
|
|||||||
Authenticated IPA and macOS application inventory projection is documented in
|
Authenticated IPA and macOS application inventory projection is documented in
|
||||||
[Apple application analysis](apple-application-analysis.md).
|
[Apple application analysis](apple-application-analysis.md).
|
||||||
|
|
||||||
`npm run verify:harmony` requires no SDK or engine. It projects the pinned
|
|
||||||
harmony-next-pipeline 1.0.1 release HAP from an MIT-licensed source repository,
|
|
||||||
fetched by `npm run fixtures:harmony` into ignored
|
|
||||||
`_reference/harmony-integration/`, set as `REA_HARMONY_TEST_HAP`.
|
|
||||||
The lane exercises `inspect_artifact`, projection determinism, Stage-model
|
|
||||||
path hints, exact component sets, signing-entry limitations, and CLI/MCP parity.
|
|
||||||
The release artifact has no independently established compiler/SDK or
|
|
||||||
reproducible source build; the default lane does not verify an installed package.
|
|
||||||
See [HarmonyOS package inventory](harmony-analysis.md) for those proof boundaries.
|
|
||||||
HarmonyOS `.har` libraries are deliberately not suffix-classified because
|
|
||||||
`.har` also names HTTP Archive JSON.
|
|
||||||
|
|
||||||
Synthetic producer regressions run independently:
|
Synthetic producer regressions run independently:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
@@ -765,15 +739,9 @@ entries, external callees, target switches, cancellation draining, snapshot
|
|||||||
replay exclusion, ownership failures, and incomplete cleanup. They do not
|
replay exclusion, ownership failures, and incomplete cleanup. They do not
|
||||||
establish real IDA operation. The initial real workflows cover legacy upstream
|
establish real IDA operation. The initial real workflows cover legacy upstream
|
||||||
1.4.0 on a Windows GUI and the modern supervisor at upstream commit
|
1.4.0 on a Windows GUI and the modern supervisor at upstream commit
|
||||||
`c133c3853faa111a9b00ee615c013b720d0c4acd` with Windows x64 IDA 9.3, and the
|
`c133c3853faa111a9b00ee615c013b720d0c4acd` with Windows x64 IDA 9.3.
|
||||||
headless profile on macOS arm64 with IDA Professional 9.1 (build 9.1.250226)
|
Linux/macOS headless, modern attached GUI tools, other engine versions and
|
||||||
at the same upstream commit, using `tests/conformance/ida/inventory.c` built
|
architectures remain unverified; see the [provider guide](ida-provider.md).
|
||||||
with `clang -O0 -arch arm64` and the procedure `_rea_fixture_add` (Mach-O C
|
|
||||||
symbols carry a leading underscore). Before the headless session waited out
|
|
||||||
the transient `busy` health a worker can report right after opening, that lane
|
|
||||||
failed intermittently on that host. Linux headless, modern attached GUI tools,
|
|
||||||
other engine versions and architectures remain unverified; see the
|
|
||||||
[provider guide](ida-provider.md).
|
|
||||||
|
|
||||||
## DOS Ghidra analysis
|
## DOS Ghidra analysis
|
||||||
|
|
||||||
@@ -798,16 +766,6 @@ truncation constraint, while leading-zero coordinates still resolve correctly.
|
|||||||
It has the same Ghidra/JDK prerequisites as the MZ lane. Neither lane claims DOS
|
It has the same Ghidra/JDK prerequisites as the MZ lane. Neither lane claims DOS
|
||||||
runtime or PC-98 device execution.
|
runtime or PC-98 device execution.
|
||||||
|
|
||||||
`npm run verify:ghidra:raw` uses a generated ARM little-endian headerless image
|
|
||||||
through the compiled CLI and stdio MCP server. With the same Ghidra/JDK
|
|
||||||
prerequisites, it checks preparation and bridge startup, verified load mappings,
|
|
||||||
instruction and byte readback, canonical-entry session reuse, replacement when
|
|
||||||
the entry changes without `provider_id`, unchanged source bytes, and owned
|
|
||||||
cleanup. Six-byte x86 and x86_64 controls also verify supported compiler
|
|
||||||
specifications, independent mappings, unchanged bytes, and decompilation of a
|
|
||||||
known return value. AArch64 remains covered by deterministic tests rather than
|
|
||||||
this real-provider lane. See [raw binary analysis](raw-binary.md).
|
|
||||||
|
|
||||||
## Apple Interface Builder archives
|
## Apple Interface Builder archives
|
||||||
|
|
||||||
`npm run verify:interface-builder` compiles the source-owned AppKit XIB into a
|
`npm run verify:interface-builder` compiles the source-owned AppKit XIB into a
|
||||||
@@ -877,12 +835,6 @@ target-free analysis, configuration backups/recovery, Evidence and owned
|
|||||||
lifecycle; Inspector checks execute source-owned loopback targets and special
|
lifecycle; Inspector checks execute source-owned loopback targets and special
|
||||||
filename cases.
|
filename cases.
|
||||||
|
|
||||||
POSIX package verification resolves the runner's configured npm cache before
|
|
||||||
creating disposable client homes and passes that location to its child installs.
|
|
||||||
This reuses the download cache restored by `setup-node` while keeping client
|
|
||||||
configuration isolated. Installs retain their existing registry and integrity
|
|
||||||
checks.
|
|
||||||
|
|
||||||
The Apple artifact CLI/MCP lane uses one `macos-15` job to avoid adding demand
|
The Apple artifact CLI/MCP lane uses one `macos-15` job to avoid adding demand
|
||||||
for scarce macOS runner capacity. It runs the artifact-format and metadata
|
for scarce macOS runner capacity. It runs the artifact-format and metadata
|
||||||
verifiers, followed by one consolidated focused invocation containing all
|
verifiers, followed by one consolidated focused invocation containing all
|
||||||
@@ -895,15 +847,6 @@ catalog, and managed-conformance metadata. Each shard still installs the locked
|
|||||||
dependencies and runs its assigned coverage-enabled tests; it no longer
|
dependencies and runs its assigned coverage-enabled tests; it no longer
|
||||||
regenerates the same metadata independently.
|
regenerates the same metadata independently.
|
||||||
|
|
||||||
The build job also retrieves the merged timing report from the last successful
|
|
||||||
default-branch push and includes that same report in each shard's snapshot.
|
|
||||||
CI assigns discovered files by historical duration, with a deterministic
|
|
||||||
fallback weight for new files, rather than dividing only by file count. Every
|
|
||||||
discovered file still belongs to exactly one shard; worker limits, project
|
|
||||||
ordering, coverage instrumentation, and aggregate thresholds remain unchanged.
|
|
||||||
Missing or unusable history falls back to Vitest's default assignment. Only
|
|
||||||
timing data is reused; persistent compile caches remain disabled.
|
|
||||||
|
|
||||||
These native baseline checks complement the Linux source-test shards and the
|
These native baseline checks complement the Linux source-test shards and the
|
||||||
separate Apple-artifact and real-provider lanes. Actual Hopper, Ghidra, IDA,
|
separate Apple-artifact and real-provider lanes. Actual Hopper, Ghidra, IDA,
|
||||||
browser and managed-tool claims require their corresponding verification lanes.
|
browser and managed-tool claims require their corresponding verification lanes.
|
||||||
@@ -949,7 +892,7 @@ behavior, and complete CI evidence before merging.
|
|||||||
| `npm run test:focused -- PATH...` | Exact existing test files; compiled boundaries build first, and unmatched paths fail |
|
| `npm run test:focused -- PATH...` | Exact existing test files; compiled boundaries build first, and unmatched paths fail |
|
||||||
| `npm run test:changed` | Source tests affected since the merge base with `origin/main`, including committed and dirty changes |
|
| `npm run test:changed` | Source tests affected since the merge base with `origin/main`, including committed and dirty changes |
|
||||||
| `npm run test:fast` | All domain, service, adapter, composition, conformance, and evaluation tests without build |
|
| `npm run test:fast` | All domain, service, adapter, composition, conformance, and evaluation tests without build |
|
||||||
| `npm run test:boundary` | Boundary, CLI boundary, MCP boundary, process boundary, and process-global projects |
|
| `npm run test:boundary` | Boundary, MCP boundary, process boundary, and process-global projects |
|
||||||
| `npm run test:mcp` | MCP boundary project |
|
| `npm run test:mcp` | MCP boundary project |
|
||||||
| `npm run test:acceptance` | Complete compiled CLI and MCP acceptance workflows |
|
| `npm run test:acceptance` | Complete compiled CLI and MCP acceptance workflows |
|
||||||
| `npm run test:watch` | Dirty source tests in watch mode, without build |
|
| `npm run test:watch` | Dirty source tests in watch mode, without build |
|
||||||
@@ -979,11 +922,6 @@ it or select another revision.
|
|||||||
|
|
||||||
Source typechecking needs no compiled runtime or generated test metadata.
|
Source typechecking needs no compiled runtime or generated test metadata.
|
||||||
`npm run build:cached` compiles the CLI/MCP runtime and its packaged skill.
|
`npm run build:cached` compiles the CLI/MCP runtime and its packaged skill.
|
||||||
Turbo's strict task environment preserves caller-selected `GOMAXPROCS`,
|
|
||||||
`GOMEMLIMIT`, and `UV_THREADPOOL_SIZE` for resource-constrained builds and
|
|
||||||
checks. These execution controls do not change artifact content, so changing
|
|
||||||
their values retains cache reuse. They control individual runtimes; monitor
|
|
||||||
the complete process family separately when enforcing a total memory budget.
|
|
||||||
`npm run test:prepare` also generates the MCP contract test catalog, product
|
`npm run test:prepare` also generates the MCP contract test catalog, product
|
||||||
catalog, and portable managed evidence used by the complete suite. Focused
|
catalog, and portable managed evidence used by the complete suite. Focused
|
||||||
tests prepare those extra outputs only when their selected files consume them.
|
tests prepare those extra outputs only when their selected files consume them.
|
||||||
@@ -1011,43 +949,18 @@ Vitest projects use up to two workers, bounded by host parallelism.
|
|||||||
`process-boundary` runs later with serial files because process-tree sampling
|
`process-boundary` runs later with serial files because process-tree sampling
|
||||||
shares host resources. Acceptance and process-global cases use isolated forks
|
shares host resources. Acceptance and process-global cases use isolated forks
|
||||||
without serial scheduling. Pure domain/service, composition, conformance,
|
without serial scheduling. Pure domain/service, composition, conformance,
|
||||||
evaluation, CLI boundary, and MCP boundary projects share module graphs. Their
|
evaluation, and MCP boundary projects share module graphs; their tests avoid
|
||||||
tests avoid process-global state and keep resource cleanup test-scoped. Each
|
process-global state and keep resource cleanup test-scoped. Each MCP session
|
||||||
MCP session still owns its resources, and CLI cases retain fresh command
|
still owns its resources. Adapter, non-MCP boundary, acceptance, and
|
||||||
instances or subprocesses. CLI module mocks belong in `tests/process-global/`
|
process-global projects retain per-file isolation. See `vitest.config.ts` for
|
||||||
so they keep per-file isolation. Product catalog verification stays with the
|
current settings.
|
||||||
isolated filesystem boundary tests because it loads both source and compiled
|
|
||||||
module graphs. Adapter, other boundary, acceptance, and process-global projects
|
|
||||||
retain per-file isolation. See `vitest.config.ts` for current settings.
|
|
||||||
|
|
||||||
The reused CLI boundary workers cap V8 old space at 384 MiB, based on their
|
|
||||||
profiled allocation and cleanup behavior. This encourages collection between
|
|
||||||
files; spawned REA processes retain their own heap settings.
|
|
||||||
|
|
||||||
Vitest worker limits do not bound subprocesses launched within a test. Bound
|
|
||||||
those batches separately so repeated CLI validation cannot oversubscribe the
|
|
||||||
runner. Preserve simultaneous launches where concurrency is itself under test.
|
|
||||||
|
|
||||||
Build/documentation writers hold checkout-local output locks. Tests do not
|
Build/documentation writers hold checkout-local output locks. Tests do not
|
||||||
hold a broad command lock; `check:pr` finishes tests before document validation.
|
hold a broad command lock; `check:pr` finishes tests before document validation.
|
||||||
|
|
||||||
Vitest's persistent compile cache remains disabled. The `cliTest` fixture shares
|
Vitest and Node persistent compile caches are deliberately not enabled by
|
||||||
a temporary Node compile cache among its fresh CLI subprocesses. The worker
|
default. To evaluate repeated local runs, opt in for both cold and warm
|
||||||
removes it after test-scoped processes finish. Explicit child environment
|
measurements with an isolated cache:
|
||||||
settings take precedence; children requesting `NODE_V8_COVERAGE` do not receive
|
|
||||||
the fixture cache. These subprocesses are outside aggregate Vitest coverage;
|
|
||||||
subprocess coverage attachment remains disabled. Cold-start import checks launch
|
|
||||||
independently without this fixture cache.
|
|
||||||
|
|
||||||
The Apple artifact verifier step shares a job-temporary bytecode cache among
|
|
||||||
its fresh CLI/MCP children via `REA_ARTIFACT_NODE_COMPILE_CACHE`. The artifact
|
|
||||||
helper maps this setting to child `NODE_COMPILE_CACHE`; npm, Turbo, and nested
|
|
||||||
Vitest runs do not inherit that setting. Explicit `NODE_COMPILE_CACHE` takes
|
|
||||||
precedence, and coverage collection or `NODE_DISABLE_COMPILE_CACHE=1` disables
|
|
||||||
the helper's cache. The cache is discarded with the CI job.
|
|
||||||
|
|
||||||
To evaluate persistent compile caching for repeated local runs, opt in for both
|
|
||||||
cold and warm measurements with an isolated cache:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
NODE_COMPILE_CACHE=.cache/node-compile npm test
|
NODE_COMPILE_CACHE=.cache/node-compile npm test
|
||||||
@@ -1070,19 +983,6 @@ summary. Static checks, documentation, build, package verification, and
|
|||||||
real-system lanes remain separate jobs so one kind of evidence cannot stand in
|
real-system lanes remain separate jobs so one kind of evidence cannot stand in
|
||||||
for another.
|
for another.
|
||||||
|
|
||||||
The build job saves portable Turbo outputs across runs. Eight Linux real-system
|
|
||||||
lanes restore this cache without waiting for the build job. The shared action
|
|
||||||
derives its key from `test:prepare --dry=json` task hashes, runner OS and
|
|
||||||
architecture, and `.npmrc`; test-only changes can reuse compiled outputs. Every
|
|
||||||
build and verification command still runs, so Turbo checks task inputs and
|
|
||||||
rebuilds misses. There is no prefix fallback to accumulate older build outputs.
|
|
||||||
|
|
||||||
Native package jobs reuse the same workflow's Turbo cache for portable compiled
|
|
||||||
JavaScript, skills, and catalogs. They retain the normal build and prepack
|
|
||||||
commands, which restore matching outputs or rebuild on a cache miss. Native
|
|
||||||
artifacts, dependency installs, package archives, and runtime verification remain
|
|
||||||
host-local. Keep platform-dependent outputs out of this shared cache.
|
|
||||||
|
|
||||||
The PR acceptance target is a median `npm run check:pr` wall time below three
|
The PR acceptance target is a median `npm run check:pr` wall time below three
|
||||||
minutes across three warm-build runs on the benchmark host. Keep Vitest caches
|
minutes across three warm-build runs on the benchmark host. Keep Vitest caches
|
||||||
cold unless separately identified. A PR that touches packaging or real-system
|
cold unless separately identified. A PR that touches packaging or real-system
|
||||||
@@ -1157,10 +1057,7 @@ and `REA_JAVASCRIPT_FIXTURE_TOOLS` pointing to an isolated npm prefix containing
|
|||||||
esbuild 0.25.10 and webpack 5.101.3. No global installation is required.
|
esbuild 0.25.10 and webpack 5.101.3. No global installation is required.
|
||||||
The lane compiles source-owned fixtures, exercises CLI and stdio MCP, verifies
|
The lane compiles source-owned fixtures, exercises CLI and stdio MCP, verifies
|
||||||
published bytes and provenance, feeds recovered modules into existing analysis,
|
published bytes and provenance, feeds recovered modules into existing analysis,
|
||||||
and compares a finite set of known fixture results. A webpack fixture with separate
|
and compares a finite set of known fixture results. The provider also accepts
|
||||||
runtime, shared, entry and lazy chunks verifies multi-input recovery through both
|
|
||||||
surfaces, per-file provenance and resolved cross-chunk imports in the downstream
|
|
||||||
application graph. The provider also accepts
|
|
||||||
other ^1.13.0 releases and reports them as unverified; this lane proves the
|
other ^1.13.0 releases and reports them as unverified; this lane proves the
|
||||||
audited release. It does not establish
|
audited release. It does not establish
|
||||||
arbitrary recovered-application equivalence. CI installs these prerequisites only
|
arbitrary recovered-application equivalence. CI installs these prerequisites only
|
||||||
@@ -1377,26 +1274,3 @@ npm run evidence:check
|
|||||||
|
|
||||||
The records preserve unsupported and unverified coverage as explicit unknowns.
|
The records preserve unsupported and unverified coverage as explicit unknowns.
|
||||||
Run the matching real-tool prerequisites described in this guide.
|
Run the matching real-tool prerequisites described in this guide.
|
||||||
|
|
||||||
### Offline WASM artifacts
|
|
||||||
|
|
||||||
`npm run verify:wasm:artifact -- --require-tools` uses an absolute
|
|
||||||
`REA_WABT_BIN_DIRECTORY` containing WABT 1.0.42, including `wat2wasm` for fixture
|
|
||||||
generation. It installs nothing. Without configuration, the default invocation
|
|
||||||
reports a named skip; `--require-tools` makes missing configuration fail.
|
|
||||||
|
|
||||||
The verifier creates and validates real modules with custom sections, multiple
|
|
||||||
import/export kinds, escaped names, an empty module, and a bulk-memory
|
|
||||||
DataCount section. It compares exact WAT,
|
|
||||||
section output and selected/tool digests through the compiled CLI and real MCP
|
|
||||||
SDK, validates advertised schemas, checks identical CLI/MCP Evidence IDs and
|
|
||||||
session bundle readback, retains invalid/truncated module diagnostics, preserves
|
|
||||||
all inputs and checks workspace cleanup. Pass an installed package's
|
|
||||||
`scripts/rea.mjs` as the first argument to run the same lane against the package.
|
|
||||||
`npm run verify:wasm:package` packs and installs REA into an isolated temporary
|
|
||||||
prefix with lifecycle scripts disabled and runs the same required real-tool lane.
|
|
||||||
It requires WABT configuration and makes no host tool installation.
|
|
||||||
|
|
||||||
Source-owned provider tests separately exercise cancellation, deadline propagation,
|
|
||||||
malformed producer output and cleanup uncertainty; shared owned-command tests
|
|
||||||
exercise actual subprocess timeout and cancellation.
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
harm_rank,location,trigger,current_copy,user_risk,proposed_replacement,implementation_status,verification_result
|
harm_rank,location,trigger,current_copy,user_risk,proposed_replacement,implementation_status,verification_result
|
||||||
1,src/domain/errors.ts:AnalysisCapabilityUnavailableError,Requested analysis unavailable,"Provider {providerId} cannot execute {operation}: {reason}",Exposes provider and internal operation/reason,"This analysis is unavailable for the current target. Choose another analysis or target.",implemented,focused assertions passed; full `npm run check` passed
|
1,src/domain/errors.ts:AnalysisCapabilityUnavailableError,Requested analysis unavailable,"Provider {providerId} cannot execute {operation}: {reason}",Exposes provider and internal operation/reason,"This analysis is unavailable for the current target. Choose another analysis or target.",implemented,focused assertions passed; full `npm run check` passed
|
||||||
2,src/domain/errors.ts:ProviderAdapterError,Provider adapter fails,"Provider {providerId} adapter failed during {operation}",Exposes provider and implementation boundary,"Analysis could not complete. Run `rea doctor` and review the reported details; repeating the unchanged request is not expected to succeed.",implemented,focused assertions passed; full `npm run check` passed
|
2,src/domain/errors.ts:ProviderAdapterError,Provider adapter fails,"Provider {providerId} adapter failed during {operation}",Exposes provider and implementation boundary,"Analysis could not complete. Retry once; if it continues, run `rea doctor`.",implemented,focused assertions passed; full `npm run check` passed
|
||||||
3,src/domain/errors.ts:HopperRemoteError,Remote analysis request fails,"Hopper request failed ({code}): {safeMessage}",Exposes provider name code and upstream text,"Analysis could not complete. Run `rea doctor` and review the reported details; repeating the unchanged request is not expected to succeed.",implemented,focused assertions passed; full `npm run check` passed
|
3,src/domain/errors.ts:HopperRemoteError,Remote analysis request fails,"Hopper request failed ({code}): {safeMessage}",Exposes provider name code and upstream text,"Analysis could not complete. Retry once; if it continues, run `rea doctor`.",implemented,focused assertions passed; full `npm run check` passed
|
||||||
4,src/domain/errors.ts:HopperProtocolError,Malformed provider protocol result,Raw constructor message,Can expose provider protocol and implementation details,"Analysis returned an unreadable result. Run `rea doctor` and review the reported details; repeating the unchanged request is not expected to succeed.",implemented,focused assertions passed; full `npm run check` passed
|
4,src/domain/errors.ts:HopperProtocolError,Malformed provider protocol result,Raw constructor message,Can expose provider protocol and implementation details,"Analysis returned an unreadable result. Retry once; if it continues, run `rea doctor`.",implemented,focused assertions passed; full `npm run check` passed
|
||||||
5,src/domain/errors.ts:AnalysisOutputError,Analysis output fails parsing,"Invalid analysis output for {operation}: {reason}",Exposes internal operation and parser reason,"Analysis returned an unreadable result. Run `rea doctor` and review the reported details; repeating the unchanged request is not expected to succeed.",implemented,focused assertions passed; full `npm run check` passed
|
5,src/domain/errors.ts:AnalysisOutputError,Analysis output fails parsing,"Invalid analysis output for {operation}: {reason}",Exposes internal operation and parser reason,"Analysis returned an unreadable result. Retry once; if it continues, run `rea doctor`.",implemented,focused assertions passed; full `npm run check` passed
|
||||||
6,src/domain/errors.ts:AnalysisProtocolError,Application protocol fails,Raw constructor message,Can expose protocol internals,"Analysis returned an unreadable result. Run `rea doctor` and review the reported details; repeating the unchanged request is not expected to succeed.",implemented,focused assertions passed; full `npm run check` passed
|
6,src/domain/errors.ts:AnalysisProtocolError,Application protocol fails,Raw constructor message,Can expose protocol internals,"Analysis returned an unreadable result. Retry once; if it continues, run `rea doctor`.",implemented,focused assertions passed; full `npm run check` passed
|
||||||
7,src/domain/errors.ts:HopperProcessError,Analysis subprocess stops,"Hopper bridge stopped unexpectedly with code {exitCode}",Exposes provider bridge and process code,"Analysis could not start or stopped unexpectedly. Run `rea doctor`, then try again.",implemented,focused assertions passed; full `npm run check` passed
|
7,src/domain/errors.ts:HopperProcessError,Analysis subprocess stops,"Hopper bridge stopped unexpectedly with code {exitCode}",Exposes provider bridge and process code,"Analysis could not start or stopped unexpectedly. Run `rea doctor`, then try again.",implemented,focused assertions passed; full `npm run check` passed
|
||||||
8,src/domain/errors.ts:HopperStartError,Analysis subprocess cannot start,Hopper application bridge could not be started,Exposes provider and bridge implementation,"Analysis could not start or stopped unexpectedly. Run `rea doctor`, then try again.",implemented,focused assertions passed; full `npm run check` passed
|
8,src/domain/errors.ts:HopperStartError,Analysis subprocess cannot start,Hopper application bridge could not be started,Exposes provider and bridge implementation,"Analysis could not start or stopped unexpectedly. Run `rea doctor`, then try again.",implemented,focused assertions passed; full `npm run check` passed
|
||||||
9,src/domain/errors.ts:BinaryTargetError,Target cannot open,"Cannot open artifact: {reason}",May expose raw reason and lacks checks,"Preserve the target admission reason; directories name analyze_javascript_application and rea analyze as available alternatives.",implemented,focused assertions passed; full `npm run check` passed
|
9,src/domain/errors.ts:BinaryTargetError,Target cannot open,"Cannot open artifact: {reason}",May expose raw reason and lacks checks,"Preserve the target admission reason; directories name analyze_javascript_application and rea analyze as available alternatives.",implemented,focused assertions passed; full `npm run check` passed
|
||||||
@@ -21,7 +21,7 @@ harm_rank,location,trigger,current_copy,user_risk,proposed_replacement,implement
|
|||||||
21,src/domain/errors.ts:AnalysisCancelledError,Caller cancels analysis,"Analysis operation was cancelled: {operation}",Exposes operation identifier,"Analysis was cancelled. Start it again when ready.",implemented,focused assertions passed; full `npm run check` passed
|
21,src/domain/errors.ts:AnalysisCancelledError,Caller cancels analysis,"Analysis operation was cancelled: {operation}",Exposes operation identifier,"Analysis was cancelled. Start it again when ready.",implemented,focused assertions passed; full `npm run check` passed
|
||||||
22,src/domain/errors.ts:HopperCancelledError,Caller cancels provider request,Hopper operation was cancelled,Exposes provider name,"Analysis was cancelled. Start it again when ready.",implemented,focused assertions passed; full `npm run check` passed
|
22,src/domain/errors.ts:HopperCancelledError,Caller cancels provider request,Hopper operation was cancelled,Exposes provider name,"Analysis was cancelled. Start it again when ready.",implemented,focused assertions passed; full `npm run check` passed
|
||||||
23,src/domain/errors.ts:NoBinaryOpenError,Analysis requested without target,"No app is open. Ask the user which app to investigate, then call open_binary with its local path.",Low risk; already supplies agent recovery,Keep current copy,implemented,focused assertions passed; full `npm run check` passed
|
23,src/domain/errors.ts:NoBinaryOpenError,Analysis requested without target,"No app is open. Ask the user which app to investigate, then call open_binary with its local path.",Low risk; already supplies agent recovery,Keep current copy,implemented,focused assertions passed; full `npm run check` passed
|
||||||
24,src/server/toolResult.ts:successResult,Successful value violates public output schema,AnalysisOutputError: Analysis output does not match the tool contract,Exposes internal error tag and contract implementation,"Analysis returned an unreadable result. Run `rea doctor` and review the reported details; repeating the unchanged request is not expected to succeed.",implemented,focused assertions passed; full `npm run check` passed
|
24,src/server/toolResult.ts:successResult,Successful value violates public output schema,AnalysisOutputError: Analysis output does not match the tool contract,Exposes internal error tag and contract implementation,"Analysis returned an unreadable result. Retry once; if it continues, run `rea doctor`.",implemented,focused assertions passed; full `npm run check` passed
|
||||||
24.5,src/server/registerOfficialTools.ts:capability unknown,Approved unknown tracking records an unavailable analysis,"TOOL_NAME is unavailable: PROVIDER_REASON",Exposes an internal tool identifier and provider diagnostic in persistent user-visible evidence,"The requested analysis is unavailable for the current target.",implemented,verified by focused MCP integration test
|
24.5,src/server/registerOfficialTools.ts:capability unknown,Approved unknown tracking records an unavailable analysis,"TOOL_NAME is unavailable: PROVIDER_REASON",Exposes an internal tool identifier and provider diagnostic in persistent user-visible evidence,"The requested analysis is unavailable for the current target.",implemented,verified by focused MCP integration test
|
||||||
24.6,src/application/ReferenceSourceImportEntries.ts:failed entry,A partial reference import contains an unreadable entry,Low-level reader diagnostic stored in entry limitations,Can persist filesystem or reader implementation details,"Code- and entry-specific safe guidance with a retry, limit, exclusion, or platform recovery step.",implemented,verified by exhaustive focused projection test
|
24.6,src/application/ReferenceSourceImportEntries.ts:failed entry,A partial reference import contains an unreadable entry,Low-level reader diagnostic stored in entry limitations,Can persist filesystem or reader implementation details,"Code- and entry-specific safe guidance with a retry, limit, exclusion, or platform recovery step.",implemented,verified by exhaustive focused projection test
|
||||||
24.7,src/server/registerSessionTools.ts:process residual,Capture records a residual unknown linked to capture Evidence,SCOPE: RAW_REASON,Persists adapter diagnostic and implementation wording,"Was SCOPE behavior fully observed during capture?",implemented,verified by focused session MCP test
|
24.7,src/server/registerSessionTools.ts:process residual,Capture records a residual unknown linked to capture Evidence,SCOPE: RAW_REASON,Persists adapter diagnostic and implementation wording,"Was SCOPE behavior fully observed during capture?",implemented,verified by focused session MCP test
|
||||||
|
|||||||
|
@@ -1,71 +0,0 @@
|
|||||||
# Offline WebAssembly artifacts
|
|
||||||
|
|
||||||
`inspect_wasm_artifact` / `inspect-wasm-artifact` inspects explicitly selected
|
|
||||||
local WASM bytes using caller-supplied WABT 1.0.42. No active binary target is
|
|
||||||
required. REA does not install tools or fetch artifacts and does not execute WASM.
|
|
||||||
|
|
||||||
Set `REA_WABT_BIN_DIRECTORY` to an absolute directory containing executable
|
|
||||||
`wasm-validate`, `wasm-objdump` and `wasm2wat` (with `.exe` on Windows). Missing
|
|
||||||
executables, unsupported banners and inaccessible tools produce actionable
|
|
||||||
unavailable diagnostics. Capability discovery reports configured availability;
|
|
||||||
execution validates tool files and version banners. Host process-ownership and
|
|
||||||
private-workspace controls must also be available. The real-tool profile has
|
|
||||||
been exercised on macOS arm64; other hosts require their own verification.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
REA_WABT_BIN_DIRECTORY=/absolute/wabt/bin rea inspect-wasm-artifact \
|
|
||||||
/artifacts/module.wasm --glue_paths /artifacts/glue.js \
|
|
||||||
--candidate_paths /artifacts/other/module.wasm --format json
|
|
||||||
```
|
|
||||||
|
|
||||||
Equivalent MCP input:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"name": "inspect_wasm_artifact",
|
|
||||||
"arguments": {
|
|
||||||
"path": "/artifacts/module.wasm",
|
|
||||||
"glue_paths": ["/artifacts/glue.js"],
|
|
||||||
"candidate_paths": ["/artifacts/other/module.wasm"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Each selected regular file is read through the existing stable artifact reader;
|
|
||||||
symlinks, changing files and files over 8 MiB fail closed. WASM bytes are copied
|
|
||||||
into a private workspace as read-only `module.wasm`; its digest is rechecked
|
|
||||||
before and after each tool. WABT validates with `--enable-all`,
|
|
||||||
reports sections through `wasm-objdump -h -x`, and decodes through
|
|
||||||
`wasm2wat --enable-all`. The result retains selected byte SHA-256 and size,
|
|
||||||
section payload ranges, full header/detail output, exact import/export WAT
|
|
||||||
forms, decoded WAT and its UTF-8 SHA-256. Producer format drift and invalid or
|
|
||||||
truncated modules are failures, with validation diagnostics and partial Evidence
|
|
||||||
retaining selected byte identity and tool provenance.
|
|
||||||
|
|
||||||
The tool profile preserves upstream release/source identity, resolved executable
|
|
||||||
paths, executable digests, exact banners and arguments. Executable digests are
|
|
||||||
checked again after each command. Caller-supplied tools are trusted programs;
|
|
||||||
version and digest recording are not publisher authentication or an OS sandbox.
|
|
||||||
Each subprocess has a 30-second deadline and 32 MiB combined output budget;
|
|
||||||
truncation fails. All commands use existing owned-process cancellation and
|
|
||||||
cleanup. Workspace cleanup failures remain explicit errors with resource paths.
|
|
||||||
|
|
||||||
WAT is a decoded representation, not original source or proof of runtime
|
|
||||||
behavior. Custom annotations can preserve payloads, but WAT does not establish original
|
|
||||||
binary layout or round-trip byte identity. Original byte identity and objdump
|
|
||||||
output retain that distinction. Import/export forms retain exact escaped WAT names. Unescaped objdump display
|
|
||||||
names are not parsed as unambiguous identifiers.
|
|
||||||
|
|
||||||
Optional JavaScript glue uses the existing Babel parser and AST traversal. It
|
|
||||||
retains `.wasm` string literals and literal templates with source coordinates,
|
|
||||||
selected glue byte identity and parser status. Relative filesystem matches become
|
|
||||||
local path candidates. URLs, query/fragment variants and unmatched paths retain
|
|
||||||
basename candidates, including multiple matches, or remain unresolved. These are
|
|
||||||
literal associations, not proven data flow, runtime loading or URL-to-file
|
|
||||||
identity. Computed strings, aliases and dynamic imports require further evidence.
|
|
||||||
Candidates are caller-selected files; their identity does not imply validation.
|
|
||||||
|
|
||||||
Both CLI and MCP use the same typed port and application service. MCP publishes
|
|
||||||
SDK-compatible schemas and records Evidence for `get_evidence_bundle` readback.
|
|
||||||
See [WABT provenance](../third_party/wabt/README.md) and
|
|
||||||
[testing](testing.md#offline-wasm-artifacts) for real-tool verification.
|
|
||||||
@@ -125,12 +125,6 @@ both commands have a 30-second wall deadline and independently supervised
|
|||||||
process cleanup. Owned decoder diagnostics retain at most 1 MiB across stdout
|
process cleanup. Owned decoder diagnostics retain at most 1 MiB across stdout
|
||||||
and stderr; the collector drops overflow as it arrives, reports the limit
|
and stderr; the collector drops overflow as it arrives, reports the limit
|
||||||
failure and verifies cleanup. Heap limits alone do not establish aggregate RSS limits.
|
failure and verifies cleanup. Heap limits alone do not establish aggregate RSS limits.
|
||||||
When REA runs on Bun, the HAR decoder runs on Bun, which ignores these V8 heap
|
|
||||||
flags; its limitations and resource failures then omit the heap sizes. On
|
|
||||||
Windows, the decoder's owned Job Object instead limits its committed memory to
|
|
||||||
704 MiB, the 192 MiB budget plus a 512 MiB reserve for Bun itself. The
|
|
||||||
limitations state that limit, and reaching it returns `resource_constraint`
|
|
||||||
with `process_memory_limit_bytes`, whatever exit status Bun reports.
|
|
||||||
|
|
||||||
Observed decoder memory exhaustion returns `resource_constraint`, with the
|
Observed decoder memory exhaustion returns `resource_constraint`, with the
|
||||||
selected capture, applicable limits and retained process diagnostics. HAR's
|
selected capture, applicable limits and retained process diagnostics. HAR's
|
||||||
|
|||||||
@@ -72,18 +72,9 @@ One owned Node subprocess decodes the map. Its private request directory is
|
|||||||
removed before success is returned. Only this child's inherited `NODE_OPTIONS`
|
removed before success is returned. Only this child's inherited `NODE_OPTIONS`
|
||||||
is removed; explicit V8 flags set a 192 MiB old-generation and 8 MiB semi-space
|
is removed; explicit V8 flags set a 192 MiB old-generation and 8 MiB semi-space
|
||||||
budget, one V8 worker and a 20-second deadline. Reported actual V8 heap limits
|
budget, one V8 worker and a 20-second deadline. Reported actual V8 heap limits
|
||||||
are checked. These are heap limits, not an aggregate process RSS limit. When
|
are checked. These are heap limits, not an aggregate process RSS limit. Cleanup
|
||||||
REA runs on Bun, the subprocess is Bun, which ignores these V8 flags: `runtime`
|
may extend the deadline and an unconfirmed cleanup overrides success with
|
||||||
records `id: "bun"`, the Bun version, its Node.js compatibility version and a
|
`cleanup_incomplete` and the owning operation/resources.
|
||||||
null `v8_heap_limit_bytes`. On Windows, the codec's owned Job Object then
|
|
||||||
limits its committed memory to 704 MiB, the 192 MiB budget plus a 512 MiB
|
|
||||||
reserve for Bun itself; `process_memory_limit_bytes` records that limit, the
|
|
||||||
limitations state it, and reaching it returns `resource_constraint` with
|
|
||||||
`codec_process_memory_limit_bytes`. Elsewhere Bun has no enforced codec limit:
|
|
||||||
`process_memory_limit_bytes` is null and the limitations state that no codec
|
|
||||||
heap limit is established. Cleanup may extend the deadline and an unconfirmed
|
|
||||||
cleanup overrides success with `cleanup_incomplete` and the owning
|
|
||||||
operation/resources.
|
|
||||||
|
|
||||||
Complete evidence is bounded by a 4 MiB map, 32 MiB codec reply, 262144 decoded
|
Complete evidence is bounded by a 4 MiB map, 32 MiB codec reply, 262144 decoded
|
||||||
rows/segments and 64 nested section levels. Exceeding a budget returns an explicit
|
rows/segments and 64 nested section levels. Exceeding a budget returns an explicit
|
||||||
|
|||||||
+88
-104
@@ -1,12 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
{
|
|
||||||
# Truncation guard: this brace group opens on line 2 and closes on the last
|
|
||||||
# line, so bash must read the entire file before it runs any command. On the
|
|
||||||
# `curl ... | bash` path, a download cut off anywhere before the final `}` is
|
|
||||||
# an unterminated compound command, which bash reports as a syntax error at
|
|
||||||
# EOF without running anything. Without the guard, a cut right after `set`
|
|
||||||
# would run the bare builtin and print every shell variable, and a cut right
|
|
||||||
# after `main` would run the installer without the caller's flags.
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
PACKAGE="rea-agents"
|
PACKAGE="rea-agents"
|
||||||
@@ -29,112 +21,104 @@ usage() {
|
|||||||
cat <<'EOF'
|
cat <<'EOF'
|
||||||
Usage: install.sh [--version VERSION] [--dry-run] [--no-setup] [--no-prompt] [--verbose]
|
Usage: install.sh [--version VERSION] [--dry-run] [--no-setup] [--no-prompt] [--verbose]
|
||||||
|
|
||||||
Installs the REA CLI, then starts `rea setup` interactively to configure Hopper
|
Installs only the REA CLI. Run `rea setup` separately to configure Hopper and agents.
|
||||||
and agents when a terminal is available. Pass --no-setup (or --no-prompt) to
|
|
||||||
skip setup and run `rea setup` later.
|
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
main() {
|
while (($# > 0)); do
|
||||||
while (($# > 0)); do
|
case "$1" in
|
||||||
case "$1" in
|
--version)
|
||||||
--version)
|
(($# >= 2)) || fail "--version requires a value."
|
||||||
(($# >= 2)) || fail "--version requires a value."
|
version="$2"
|
||||||
version="$2"
|
shift 2
|
||||||
shift 2
|
;;
|
||||||
;;
|
--dry-run)
|
||||||
--dry-run)
|
dry_run=true
|
||||||
dry_run=true
|
shift
|
||||||
shift
|
;;
|
||||||
;;
|
--no-setup|--no-prompt)
|
||||||
--no-setup|--no-prompt)
|
start_setup=false
|
||||||
start_setup=false
|
shift
|
||||||
shift
|
;;
|
||||||
;;
|
--verbose)
|
||||||
--verbose)
|
verbose=true
|
||||||
verbose=true
|
shift
|
||||||
shift
|
;;
|
||||||
;;
|
--help|-h)
|
||||||
--help|-h)
|
usage
|
||||||
usage
|
exit 0
|
||||||
exit 0
|
;;
|
||||||
;;
|
*) fail "unknown option: $1" ;;
|
||||||
*) fail "unknown option: $1" ;;
|
esac
|
||||||
esac
|
done
|
||||||
done
|
|
||||||
|
|
||||||
if [[ "$verbose" == true ]]; then
|
if [[ "$verbose" == true ]]; then
|
||||||
set -x
|
set -x
|
||||||
fi
|
fi
|
||||||
|
|
||||||
platform="$(uname -s)"
|
platform="$(uname -s)"
|
||||||
[[ "$platform" == "Darwin" || "$platform" == "Linux" ]] || fail "REA supports macOS and selected 64-bit Linux distributions."
|
[[ "$platform" == "Darwin" || "$platform" == "Linux" ]] || fail "REA supports macOS and selected 64-bit Linux distributions."
|
||||||
command -v curl >/dev/null 2>&1 || fail "curl is required. Install curl, then rerun this installer."
|
command -v curl >/dev/null 2>&1 || fail "curl is required. Install curl, then rerun this installer."
|
||||||
command -v node >/dev/null 2>&1 || fail "Node.js 22.x (>=22.19), 24.x (>=24.11), or 26+ is required; install it from https://nodejs.org and retry."
|
command -v node >/dev/null 2>&1 || fail "Node.js 22.x (>=22.19), 24.x (>=24.11), or 26+ is required; install it from https://nodejs.org and retry."
|
||||||
command -v npm >/dev/null 2>&1 || fail "npm is required; install it with Node.js and retry."
|
command -v npm >/dev/null 2>&1 || fail "npm is required; install it with Node.js and retry."
|
||||||
|
|
||||||
node_version="$(node -p 'process.versions.node' 2>/dev/null || true)"
|
node_version="$(node -p 'process.versions.node' 2>/dev/null || true)"
|
||||||
IFS=. read -r node_major node_minor _node_patch <<<"$node_version"
|
IFS=. read -r node_major node_minor _node_patch <<<"$node_version"
|
||||||
[[ "$node_major" =~ ^[0-9]+$ && "$node_minor" =~ ^[0-9]+$ ]] || fail "the active Node.js version could not be read. Check that node works and is on PATH, then retry."
|
[[ "$node_major" =~ ^[0-9]+$ && "$node_minor" =~ ^[0-9]+$ ]] || fail "the active Node.js version could not be read. Check that node works and is on PATH, then retry."
|
||||||
if ! [[ "$_node_patch" =~ ^[0-9]+(\+[0-9A-Za-z.-]+)?$ ]] ||
|
if ! [[ "$_node_patch" =~ ^[0-9]+(\+[0-9A-Za-z.-]+)?$ ]] ||
|
||||||
! ((node_major == 22 && node_minor >= 19 || node_major == 24 && node_minor >= 11 || node_major >= 26)); then
|
! ((node_major == 22 && node_minor >= 19 || node_major == 24 && node_minor >= 11 || node_major >= 26)); then
|
||||||
fail "Node.js $node_version is unsupported; use Node.js 22.x (>=22.19), 24.x (>=24.11), or 26+."
|
fail "Node.js $node_version is unsupported; use Node.js 22.x (>=22.19), 24.x (>=24.11), or 26+."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -n "$version" ]]; then
|
if [[ -n "$version" ]]; then
|
||||||
[[ "$version" =~ ^${version_pattern}$ ]] || fail "version must be an exact semantic version."
|
[[ "$version" =~ ^${version_pattern}$ ]] || fail "version must be an exact semantic version."
|
||||||
else
|
else
|
||||||
release_json="$(curl -fsSL --proto '=https' --tlsv1.2 --retry 3 -H 'Accept: application/vnd.github+json' "https://api.github.com/repos/$REPOSITORY/releases/latest")" || fail "the latest REA release could not be resolved. Check network access or pass --version VERSION, then retry."
|
release_json="$(curl -fsSL --proto '=https' --tlsv1.2 --retry 3 -H 'Accept: application/vnd.github+json' "https://api.github.com/repos/$REPOSITORY/releases/latest")" || fail "the latest REA release could not be resolved. Check network access or pass --version VERSION, then retry."
|
||||||
tag="$(printf '%s' "$release_json" | node -e 'let s="";process.stdin.on("data",c=>s+=c).on("end",()=>{const v=JSON.parse(s).tag_name;if(typeof v!=="string")process.exit(1);process.stdout.write(v)})' 2>/dev/null)" || fail "the release response was invalid. Retry later or pass --version VERSION."
|
tag="$(printf '%s' "$release_json" | node -e 'let s="";process.stdin.on("data",c=>s+=c).on("end",()=>{const v=JSON.parse(s).tag_name;if(typeof v!=="string")process.exit(1);process.stdout.write(v)})' 2>/dev/null)" || fail "the release response was invalid. Retry later or pass --version VERSION."
|
||||||
[[ "$tag" =~ ^rea-agents-(${version_pattern})$ ]] || fail "the latest release tag was invalid. Retry later or pass --version VERSION."
|
[[ "$tag" =~ ^rea-agents-(${version_pattern})$ ]] || fail "the latest release tag was invalid. Retry later or pass --version VERSION."
|
||||||
version="${BASH_REMATCH[1]}"
|
version="${BASH_REMATCH[1]}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# npm's exact-version resolver cleans build metadata from the requested version,
|
# npm's exact-version resolver cleans build metadata from the requested version,
|
||||||
# so it may install the base release and make the post-install identity check fail.
|
# so it may install the base release and make the post-install identity check fail.
|
||||||
if [[ "$version" =~ \+ ]]; then
|
if [[ "$version" =~ \+ ]]; then
|
||||||
fail "npm cannot install an exact version with build metadata. Pass a version without build metadata, then retry."
|
fail "npm cannot install an exact version with build metadata. Pass a version without build metadata, then retry."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
install_args=(install --global)
|
install_args=(install --global)
|
||||||
if [[ "$platform" == "Linux" ]]; then
|
if [[ "$platform" == "Linux" ]]; then
|
||||||
install_args+=(--prefix "$HOME/.local")
|
install_args+=(--prefix "$HOME/.local")
|
||||||
install_bin="$HOME/.local/bin/rea"
|
install_bin="$HOME/.local/bin/rea"
|
||||||
else
|
else
|
||||||
npm_prefix="$(npm prefix --global)" || fail "the npm global prefix could not be read. Repair the npm configuration, then retry."
|
npm_prefix="$(npm prefix --global)" || fail "the npm global prefix could not be read. Repair the npm configuration, then retry."
|
||||||
install_bin="$npm_prefix/bin/rea"
|
install_bin="$npm_prefix/bin/rea"
|
||||||
fi
|
fi
|
||||||
install_args+=("$PACKAGE@$version")
|
install_args+=("$PACKAGE@$version")
|
||||||
|
|
||||||
printf 'REA install plan\n'
|
printf 'REA install plan\n'
|
||||||
printf ' Version: %s\n' "$version"
|
printf ' Version: %s\n' "$version"
|
||||||
printf ' Runtime: Node.js %s\n' "$node_version"
|
printf ' Runtime: Node.js %s\n' "$node_version"
|
||||||
printf ' Command:'
|
printf ' Command:'
|
||||||
printf ' %q' npm "${install_args[@]}"
|
printf ' %q' npm "${install_args[@]}"
|
||||||
printf '\n'
|
printf '\n'
|
||||||
printf ' Binary: %s\n' "$install_bin"
|
printf ' Binary: %s\n' "$install_bin"
|
||||||
printf ' Setup: %s\n' "$([[ "$start_setup" == true ]] && printf 'start when a terminal is available' || printf 'skipped')"
|
printf ' Setup: %s\n' "$([[ "$start_setup" == true ]] && printf 'start when a terminal is available' || printf 'skipped')"
|
||||||
|
|
||||||
if [[ "$dry_run" == true ]]; then
|
if [[ "$dry_run" == true ]]; then
|
||||||
printf 'Dry run complete; no changes made.\n'
|
printf 'Dry run complete; no changes made.\n'
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
printf 'Installing %s@%s...\n' "$PACKAGE" "$version"
|
printf 'Installing %s@%s...\n' "$PACKAGE" "$version"
|
||||||
npm "${install_args[@]}" || fail "npm could not install REA. Check registry access and npm permissions, then retry."
|
npm "${install_args[@]}" || fail "npm could not install REA. Check registry access and npm permissions, then retry."
|
||||||
[[ -x "$install_bin" ]] || fail "npm completed without installing the rea command. Check the npm global bin directory and PATH, then retry."
|
[[ -x "$install_bin" ]] || fail "npm completed without installing the rea command. Check the npm global bin directory and PATH, then retry."
|
||||||
installed_version="$("$install_bin" --version 2>/dev/null | tr -d '[:space:]')" || fail "the installed REA version could not be read. Reinstall the requested version, then retry."
|
installed_version="$("$install_bin" --version 2>/dev/null | tr -d '[:space:]')" || fail "the installed REA version could not be read. Reinstall the requested version, then retry."
|
||||||
[[ "$installed_version" == "$version" ]] || fail "installed version $installed_version does not match $version. Reinstall the requested version, then retry."
|
[[ "$installed_version" == "$version" ]] || fail "installed version $installed_version does not match $version. Reinstall the requested version, then retry."
|
||||||
|
|
||||||
printf 'REA %s is installed.\n' "$version"
|
printf 'REA %s is installed.\n' "$version"
|
||||||
if [[ "$start_setup" == true && -r /dev/tty && -w /dev/tty && -t 1 ]]; then
|
if [[ "$start_setup" == true && -r /dev/tty && -w /dev/tty && -t 1 ]]; then
|
||||||
printf 'Starting REA setup...\n'
|
printf 'Starting REA setup...\n'
|
||||||
"$install_bin" setup </dev/tty >/dev/tty
|
"$install_bin" setup </dev/tty >/dev/tty
|
||||||
else
|
else
|
||||||
printf 'Run %s setup to configure Hopper and agents.\n' "$install_bin"
|
printf 'Run %s setup to configure Hopper and agents.\n' "$install_bin"
|
||||||
fi
|
fi
|
||||||
}
|
|
||||||
|
|
||||||
main "$@"
|
|
||||||
exit $?
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -51,23 +51,6 @@ without this lane reports Windows native controls as unavailable.
|
|||||||
unnamed, non-inherited Job Object. Membership and kill-on-close policy are
|
unnamed, non-inherited Job Object. Membership and kill-on-close policy are
|
||||||
checked before resume. Breakaway is disabled, and cleanup waits for all
|
checked before resume. Breakaway is disabled, and cleanup waits for all
|
||||||
job members and captured output, including detached descendants.
|
job members and captured output, including detached descendants.
|
||||||
- A launch may request a Job Object commit limit (`JOB_OBJECT_LIMIT_JOB_MEMORY`)
|
|
||||||
as a positive, page-aligned safe-integer byte count; invalid values fail
|
|
||||||
with `ERROR_INVALID_PARAMETER` before any process is created. Readback must
|
|
||||||
match the requested flags and limit exactly. A private I/O completion port is
|
|
||||||
associated with that job before the child is created; each poll drains it
|
|
||||||
without waiting and records a sticky `memoryLimitReached` when
|
|
||||||
`JOB_OBJECT_MSG_JOB_MEMORY_LIMIT` arrives, alongside the job's
|
|
||||||
`peakJobMemoryBytes`. Notifications are drained before checking for exit
|
|
||||||
and again after exit is observed, so a memory failure between those steps
|
|
||||||
is included in the first exit report. Runtimes report a reached limit
|
|
||||||
differently (Bun 1.4.2 exits 1
|
|
||||||
after a JavaScript out-of-memory exception or 3 after a panic), so callers
|
|
||||||
classify by the notification. `inspect` reports `jobMemoryLimit` only after
|
|
||||||
creating such a job and port. An artifact without that capability refuses a
|
|
||||||
requested limit rather than launching an unlimited process. REA requests
|
|
||||||
limits only for its JavaScript helpers when running on Bun, which ignores
|
|
||||||
their V8 heap flags; Node.js launches are unchanged.
|
|
||||||
- Only the suspended child's default file owner is normalized. Caller token
|
- Only the suspended child's default file owner is normalized. Caller token
|
||||||
privileges and ownership remain unchanged. Caller CPU affinity and process
|
privileges and ownership remain unchanged. Caller CPU affinity and process
|
||||||
priority are preserved in the child. Environment names are sorted and
|
priority are preserved in the child. Environment names are sorted and
|
||||||
@@ -106,41 +89,11 @@ npm run verify:windows-native
|
|||||||
npm run verify:ghidra:windows
|
npm run verify:ghidra:windows
|
||||||
```
|
```
|
||||||
|
|
||||||
The native inspection probe retains its directory owner if deletion fails. A
|
|
||||||
later availability query retries that cleanup before creating another probe;
|
|
||||||
successful admission and static artifact failures remain cached. Environment
|
|
||||||
teardown makes one final cleanup attempt and reports a persistent failure to
|
|
||||||
stderr rather than claiming the directory was removed.
|
|
||||||
|
|
||||||
CI separately builds and verifies a test-only artifact:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
node scripts/build-windows-native.mjs --inspection-fixture
|
|
||||||
```
|
|
||||||
|
|
||||||
On Windows, after compiling the runtime:
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
node scripts/verify-windows-native-inspection.mjs
|
|
||||||
```
|
|
||||||
|
|
||||||
This artifact injects one access-denied disposition result while using a real
|
|
||||||
NTFS directory. The verifier checks retained ownership, recovery on a later
|
|
||||||
query, cached successful admission, and cleanup on environment teardown. It
|
|
||||||
does not reproduce or identify the host-dependent cause reported in #1701.
|
|
||||||
The fixture is stored under `.cache/` and is excluded from the shipped addon.
|
|
||||||
|
|
||||||
The native lane checks DACL readback independently, source write/replacement
|
The native lane checks DACL readback independently, source write/replacement
|
||||||
rejection, unrelated sibling renames, reparse rejection, immutable snapshots,
|
rejection, unrelated sibling renames, reparse rejection, immutable snapshots,
|
||||||
asynchronous cancellation, cleanup containment,
|
asynchronous cancellation, cleanup containment,
|
||||||
descendant termination, unrelated-process preservation, normal exit, owner
|
descendant termination, unrelated-process preservation, normal exit, owner
|
||||||
close, forced owner exit, and Job Object commit limits: invalid limit
|
close, and forced owner exit. An optional independently built
|
||||||
rejection, a 128 MiB-limited child allocating external Buffer memory that the
|
|
||||||
V8 heap flags cannot bound (limit notification, peak commit at the limit, all
|
|
||||||
members settled, with the notification present in the first native exit report
|
|
||||||
and the wrapper's exit event), and a control under the same limit that
|
|
||||||
completes normally.
|
|
||||||
An optional independently built
|
|
||||||
`tests/fixtures/windows/processBoundary.cc` executable adds breakaway and
|
`tests/fixtures/windows/processBoundary.cc` executable adds breakaway and
|
||||||
caller/child token observations and an in-place ancestor reparse attempt:
|
caller/child token observations and an in-place ancestor reparse attempt:
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#include "authority.hpp"
|
#include "authority.hpp"
|
||||||
|
|
||||||
#include <delayimp.h>
|
#include <delayimp.h>
|
||||||
#include <cstdio>
|
|
||||||
|
|
||||||
namespace rea {
|
namespace rea {
|
||||||
|
|
||||||
@@ -90,45 +89,17 @@ napi_value failureValue(napi_env env, const Failure& failure) {
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct InspectionContext { std::unique_ptr<Runtime> probe; };
|
|
||||||
|
|
||||||
static void cleanupInspection(void* data) noexcept {
|
|
||||||
std::unique_ptr<InspectionContext> context(static_cast<InspectionContext*>(data));
|
|
||||||
if (!context->probe) return;
|
|
||||||
try { closeRuntime(*context->probe); }
|
|
||||||
catch (const Failure& failure) {
|
|
||||||
// Environment teardown cannot retain an owner or return an error. Report
|
|
||||||
// terminal cleanup failure instead of claiming the directory was removed.
|
|
||||||
std::fprintf(stderr, "REA Windows probe cleanup failed (Win32 %lu) path=\"",
|
|
||||||
static_cast<unsigned long>(failure.win32));
|
|
||||||
// Emit reversible UTF-16 escapes without allocation or CRT locale conversion.
|
|
||||||
for (wchar_t unit : failure.path) {
|
|
||||||
if (unit == L'"' || unit == L'\\') std::fputc('\\', stderr);
|
|
||||||
if (unit >= 0x20 && unit <= 0x7e) std::fputc(static_cast<int>(unit), stderr);
|
|
||||||
else std::fprintf(stderr, "\\u%04x", static_cast<unsigned>(unit));
|
|
||||||
}
|
|
||||||
std::fprintf(stderr, "\"\n");
|
|
||||||
}
|
|
||||||
catch (const std::exception& failure) {
|
|
||||||
std::fprintf(stderr, "REA Windows probe cleanup failed: %s\n", failure.what());
|
|
||||||
}
|
|
||||||
catch (...) {
|
|
||||||
std::fprintf(stderr, "REA Windows probe cleanup failed: unknown native exception\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static napi_value call(napi_env env, napi_callback_info info) {
|
static napi_value call(napi_env env, napi_callback_info info) {
|
||||||
try {
|
try {
|
||||||
std::array<napi_value, 2> args;
|
std::array<napi_value, 2> args;
|
||||||
size_t count = args.size();
|
size_t count = args.size();
|
||||||
void* data = nullptr;
|
check(napi_get_cb_info(env, info, &count, args.data(), nullptr, nullptr));
|
||||||
check(napi_get_cb_info(env, info, &count, args.data(), nullptr, &data));
|
|
||||||
require(count == 2, "Native call requires operation and arguments", L"", ERROR_INVALID_PARAMETER);
|
require(count == 2, "Native call requires operation and arguments", L"", ERROR_INVALID_PARAMETER);
|
||||||
const auto operation = wide(env, args[0]);
|
const auto operation = wide(env, args[0]);
|
||||||
const auto values = array(env, args[1]);
|
const auto values = array(env, args[1]);
|
||||||
if (operation == L"inspect") {
|
if (operation == L"inspect") {
|
||||||
require(values.empty(), "Inspect takes no arguments", L"", ERROR_INVALID_PARAMETER);
|
require(values.empty(), "Inspect takes no arguments", L"", ERROR_INVALID_PARAMETER);
|
||||||
return inspect(env, static_cast<InspectionContext*>(data)->probe);
|
return inspect(env);
|
||||||
}
|
}
|
||||||
if (operation.rfind(L"process_", 0) == 0) return processCall(env, operation, values);
|
if (operation.rfind(L"process_", 0) == 0) return processCall(env, operation, values);
|
||||||
return filesystemCall(env, operation, values);
|
return filesystemCall(env, operation, values);
|
||||||
@@ -143,13 +114,8 @@ static napi_value call(napi_env env, napi_callback_info info) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static napi_value initialize(napi_env env, napi_value exports) {
|
static napi_value initialize(napi_env env, napi_value exports) {
|
||||||
auto context = std::make_unique<InspectionContext>();
|
|
||||||
if (napi_add_env_cleanup_hook(env, cleanupInspection, context.get()) != napi_ok) return nullptr;
|
|
||||||
// The environment owns callback data before a function can expose it. Failed
|
|
||||||
// initialization still leaves a valid context for the registered cleanup hook.
|
|
||||||
auto* data = context.release();
|
|
||||||
napi_value function;
|
napi_value function;
|
||||||
if (napi_create_function(env, "call", NAPI_AUTO_LENGTH, call, data, &function) != napi_ok) return nullptr;
|
if (napi_create_function(env, "call", NAPI_AUTO_LENGTH, call, nullptr, &function) != napi_ok) return nullptr;
|
||||||
if (napi_set_named_property(env, exports, "call", function) != napi_ok) return nullptr;
|
if (napi_set_named_property(env, exports, "call", function) != napi_ok) return nullptr;
|
||||||
return exports;
|
return exports;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,10 +96,6 @@ struct Runtime : Resource {
|
|||||||
};
|
};
|
||||||
struct Process : Resource {
|
struct Process : Resource {
|
||||||
Handle job, process, stdoutRead, stderrRead, stdinWrite;
|
Handle job, process, stdoutRead, stderrRead, stdinWrite;
|
||||||
// Present only for a job with a commit limit; receives the job's notifications.
|
|
||||||
Handle notifications;
|
|
||||||
ULONGLONG memoryLimit = 0;
|
|
||||||
bool memoryLimitReached = false;
|
|
||||||
bool inputPending = false;
|
bool inputPending = false;
|
||||||
DWORD pid = 0;
|
DWORD pid = 0;
|
||||||
Process() : Resource(Kind::Process) {}
|
Process() : Resource(Kind::Process) {}
|
||||||
@@ -129,9 +125,9 @@ napi_value filesystemCall(napi_env env, const std::wstring& operation,
|
|||||||
const std::vector<napi_value>& args);
|
const std::vector<napi_value>& args);
|
||||||
std::unique_ptr<Process> spawnProcess(const std::wstring& command, const std::wstring& commandLine,
|
std::unique_ptr<Process> spawnProcess(const std::wstring& command, const std::wstring& commandLine,
|
||||||
const std::wstring& cwd, const std::vector<std::wstring>& environment,
|
const std::wstring& cwd, const std::vector<std::wstring>& environment,
|
||||||
bool protocolStdin = false, ULONGLONG memoryLimit = 0);
|
bool protocolStdin = false);
|
||||||
napi_value processCall(napi_env env, const std::wstring& operation,
|
napi_value processCall(napi_env env, const std::wstring& operation,
|
||||||
const std::vector<napi_value>& args);
|
const std::vector<napi_value>& args);
|
||||||
napi_value inspect(napi_env env, std::unique_ptr<Runtime>& probe);
|
napi_value inspect(napi_env env);
|
||||||
|
|
||||||
} // namespace rea
|
} // namespace rea
|
||||||
|
|||||||
@@ -19,55 +19,21 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// A nonzero memory limit is a commit limit for the whole job; zero keeps only
|
static Handle createJob() {
|
||||||
// kill-on-owner-close. The policy read back must match exactly.
|
|
||||||
static Handle createJob(ULONGLONG memoryLimit = 0) {
|
|
||||||
Handle job(CreateJobObjectW(nullptr, nullptr));
|
Handle job(CreateJobObjectW(nullptr, nullptr));
|
||||||
require(job.valid(), "Create owned Job Object failed");
|
require(job.valid(), "Create owned Job Object failed");
|
||||||
const DWORD flags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE | (memoryLimit != 0 ? JOB_OBJECT_LIMIT_JOB_MEMORY : 0);
|
|
||||||
JOBOBJECT_EXTENDED_LIMIT_INFORMATION policy{};
|
JOBOBJECT_EXTENDED_LIMIT_INFORMATION policy{};
|
||||||
policy.BasicLimitInformation.LimitFlags = flags;
|
policy.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
|
||||||
policy.JobMemoryLimit = static_cast<SIZE_T>(memoryLimit);
|
|
||||||
require(SetInformationJobObject(job.get(), JobObjectExtendedLimitInformation, &policy, sizeof(policy)),
|
require(SetInformationJobObject(job.get(), JobObjectExtendedLimitInformation, &policy, sizeof(policy)),
|
||||||
"Apply kill-on-owner-close Job Object policy failed");
|
"Apply kill-on-owner-close Job Object policy failed");
|
||||||
JOBOBJECT_EXTENDED_LIMIT_INFORMATION actual{};
|
JOBOBJECT_EXTENDED_LIMIT_INFORMATION actual{};
|
||||||
require(QueryInformationJobObject(job.get(), JobObjectExtendedLimitInformation, &actual, sizeof(actual), nullptr),
|
require(QueryInformationJobObject(job.get(), JobObjectExtendedLimitInformation, &actual, sizeof(actual), nullptr),
|
||||||
"Read Job Object policy failed");
|
"Read Job Object policy failed");
|
||||||
require(actual.BasicLimitInformation.LimitFlags == flags,
|
require(actual.BasicLimitInformation.LimitFlags == JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE,
|
||||||
"Job Object policy permits unexpected breakaway", L"", ERROR_ACCESS_DENIED);
|
"Job Object policy permits unexpected breakaway", L"", ERROR_ACCESS_DENIED);
|
||||||
require(memoryLimit == 0 || static_cast<ULONGLONG>(actual.JobMemoryLimit) == memoryLimit,
|
|
||||||
"Job Object memory limit was not applied exactly", L"", ERROR_INVALID_PARAMETER);
|
|
||||||
return job;
|
return job;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Associate a private completion port before any process joins the job, so
|
|
||||||
// the job's commit-limit notification cannot be missed.
|
|
||||||
static Handle createNotifications(HANDLE job) {
|
|
||||||
Handle port(CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr, 0, 1));
|
|
||||||
require(port.valid(), "Create owned Job Object notification port failed");
|
|
||||||
JOBOBJECT_ASSOCIATE_COMPLETION_PORT association{};
|
|
||||||
association.CompletionKey = job;
|
|
||||||
association.CompletionPort = port.get();
|
|
||||||
require(SetInformationJobObject(job, JobObjectAssociateCompletionPortInformation, &association, sizeof(association)),
|
|
||||||
"Associate owned Job Object notification port failed");
|
|
||||||
return port;
|
|
||||||
}
|
|
||||||
|
|
||||||
// JavaScript numbers cross the boundary as doubles; accept only an exact
|
|
||||||
// positive safe integer that is a whole number of pages, so read-back is exact.
|
|
||||||
static ULONGLONG jobMemoryLimit(napi_env env, napi_value value) {
|
|
||||||
const double requested = numeric(env, value);
|
|
||||||
require(requested >= 1 && requested <= 9007199254740991.0 &&
|
|
||||||
static_cast<double>(static_cast<ULONGLONG>(requested)) == requested,
|
|
||||||
"Job memory limit must be a positive safe integer", L"", ERROR_INVALID_PARAMETER);
|
|
||||||
SYSTEM_INFO system{};
|
|
||||||
GetSystemInfo(&system);
|
|
||||||
const auto limit = static_cast<ULONGLONG>(requested);
|
|
||||||
require(system.dwPageSize != 0 && limit % system.dwPageSize == 0,
|
|
||||||
"Job memory limit must be a whole number of pages", L"", ERROR_INVALID_PARAMETER);
|
|
||||||
return limit;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void pipe(Handle& read, Handle& write, bool parentReads = true) {
|
static void pipe(Handle& read, Handle& write, bool parentReads = true) {
|
||||||
SECURITY_ATTRIBUTES attributes{sizeof(SECURITY_ATTRIBUTES), nullptr, TRUE};
|
SECURITY_ATTRIBUTES attributes{sizeof(SECURITY_ATTRIBUTES), nullptr, TRUE};
|
||||||
HANDLE rawRead, rawWrite;
|
HANDLE rawRead, rawWrite;
|
||||||
@@ -78,16 +44,12 @@ static void pipe(Handle& read, Handle& write, bool parentReads = true) {
|
|||||||
|
|
||||||
std::unique_ptr<Process> spawnProcess(const std::wstring& command, const std::wstring& commandLine,
|
std::unique_ptr<Process> spawnProcess(const std::wstring& command, const std::wstring& commandLine,
|
||||||
const std::wstring& cwd, const std::vector<std::wstring>& environment,
|
const std::wstring& cwd, const std::vector<std::wstring>& environment,
|
||||||
bool protocolStdin, ULONGLONG memoryLimit) {
|
bool protocolStdin) {
|
||||||
const auto executable = ordinaryDriveSeparators(command);
|
const auto executable = ordinaryDriveSeparators(command);
|
||||||
require(executable.size() >= 3 && executable[1] == L':' && executable[2] == L'\\',
|
require(executable.size() >= 3 && executable[1] == L':' && executable[2] == L'\\',
|
||||||
"Owned Windows process requires an absolute executable path", command, ERROR_INVALID_PARAMETER);
|
"Owned Windows process requires an absolute executable path", command, ERROR_INVALID_PARAMETER);
|
||||||
auto result = std::make_unique<Process>();
|
auto result = std::make_unique<Process>();
|
||||||
result->job = createJob(memoryLimit);
|
result->job = createJob();
|
||||||
if (memoryLimit != 0) {
|
|
||||||
result->notifications = createNotifications(result->job.get());
|
|
||||||
result->memoryLimit = memoryLimit;
|
|
||||||
}
|
|
||||||
Handle stdoutWrite, stderrWrite;
|
Handle stdoutWrite, stderrWrite;
|
||||||
pipe(result->stdoutRead, stdoutWrite); pipe(result->stderrRead, stderrWrite);
|
pipe(result->stdoutRead, stdoutWrite); pipe(result->stderrRead, stderrWrite);
|
||||||
SECURITY_ATTRIBUTES security{sizeof(SECURITY_ATTRIBUTES), nullptr, TRUE};
|
SECURITY_ATTRIBUTES security{sizeof(SECURITY_ATTRIBUTES), nullptr, TRUE};
|
||||||
@@ -208,29 +170,6 @@ static DWORD activeProcesses(Process& process) {
|
|||||||
return state.ActiveProcesses;
|
return state.ActiveProcesses;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Drain queued job notifications without waiting. The commit-limit message is
|
|
||||||
// posted when an allocation fails, before the process can exit. An observed
|
|
||||||
// exit must be followed by another drain before its diagnostics are published.
|
|
||||||
static void observeNotifications(Process& process) {
|
|
||||||
if (!process.notifications.valid()) return;
|
|
||||||
DWORD message = 0;
|
|
||||||
ULONG_PTR key = 0;
|
|
||||||
LPOVERLAPPED detail = nullptr;
|
|
||||||
while (GetQueuedCompletionStatus(process.notifications.get(), &message, &key, &detail, 0)) {
|
|
||||||
if (key == reinterpret_cast<ULONG_PTR>(process.job.get()) && message == JOB_OBJECT_MSG_JOB_MEMORY_LIMIT)
|
|
||||||
process.memoryLimitReached = true;
|
|
||||||
}
|
|
||||||
const auto error = GetLastError();
|
|
||||||
require(detail == nullptr && error == WAIT_TIMEOUT, "Observe owned Job Object notifications failed", L"", error);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ULONGLONG peakJobMemory(Process& process) {
|
|
||||||
JOBOBJECT_EXTENDED_LIMIT_INFORMATION state{};
|
|
||||||
require(QueryInformationJobObject(process.job.get(), JobObjectExtendedLimitInformation, &state, sizeof(state), nullptr),
|
|
||||||
"Observe owned Job Object memory failed");
|
|
||||||
return static_cast<ULONGLONG>(state.PeakJobMemoryUsed);
|
|
||||||
}
|
|
||||||
|
|
||||||
static napi_value callerToken(napi_env env) {
|
static napi_value callerToken(napi_env env) {
|
||||||
HANDLE raw;
|
HANDLE raw;
|
||||||
require(OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_DUPLICATE, &raw), "Read caller token failed");
|
require(OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_DUPLICATE, &raw), "Read caller token failed");
|
||||||
@@ -345,20 +284,16 @@ napi_value processCall(napi_env env, const std::wstring& operation, const std::v
|
|||||||
return callerToken(env);
|
return callerToken(env);
|
||||||
}
|
}
|
||||||
if (operation == L"process_spawn") {
|
if (operation == L"process_spawn") {
|
||||||
require(args.size() >= 4 && args.size() <= 6, "Wrong native process launch argument count", L"", ERROR_INVALID_PARAMETER);
|
require(args.size() == 4 || args.size() == 5, "Wrong native process launch argument count", L"", ERROR_INVALID_PARAMETER);
|
||||||
bool protocolStdin = false;
|
bool protocolStdin = false;
|
||||||
if (args.size() >= 5) check(napi_get_value_bool(env, args[4], &protocolStdin));
|
if (args.size() == 5) check(napi_get_value_bool(env, args[4], &protocolStdin));
|
||||||
const ULONGLONG memoryLimit = args.size() == 6 ? jobMemoryLimit(env, args[5]) : 0;
|
|
||||||
std::vector<std::wstring> environment;
|
std::vector<std::wstring> environment;
|
||||||
for (const auto& entry : array(env, args[3])) environment.push_back(wide(env, entry));
|
for (const auto& entry : array(env, args[3])) environment.push_back(wide(env, entry));
|
||||||
auto process = spawnProcess(wide(env, args[0]), wide(env, args[1]), wide(env, args[2]), environment, protocolStdin,
|
auto process = spawnProcess(wide(env, args[0]), wide(env, args[1]), wide(env, args[2]), environment, protocolStdin);
|
||||||
memoryLimit);
|
|
||||||
auto result = object(env);
|
auto result = object(env);
|
||||||
set(env, result, "pid", number(env, process->pid));
|
set(env, result, "pid", number(env, process->pid));
|
||||||
set(env, result, "jobAssigned", boolean(env, true));
|
set(env, result, "jobAssigned", boolean(env, true));
|
||||||
set(env, result, "killOnOwnerClose", boolean(env, true));
|
set(env, result, "killOnOwnerClose", boolean(env, true));
|
||||||
if (process->memoryLimit != 0)
|
|
||||||
set(env, result, "jobMemoryLimitBytes", number(env, static_cast<double>(process->memoryLimit)));
|
|
||||||
set(env, result, "handle", wrap(env, std::move(process)));
|
set(env, result, "handle", wrap(env, std::move(process)));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -379,21 +314,12 @@ napi_value processCall(napi_env env, const std::wstring& operation, const std::v
|
|||||||
set(env, result, "stderr", readOutput(env, process.stderrRead, stderrEnded));
|
set(env, result, "stderr", readOutput(env, process.stderrRead, stderrEnded));
|
||||||
set(env, result, "stdoutEnded", boolean(env, stdoutEnded));
|
set(env, result, "stdoutEnded", boolean(env, stdoutEnded));
|
||||||
set(env, result, "stderrEnded", boolean(env, stderrEnded));
|
set(env, result, "stderrEnded", boolean(env, stderrEnded));
|
||||||
observeNotifications(process);
|
|
||||||
const auto exited = WaitForSingleObject(process.process.get(), 0);
|
const auto exited = WaitForSingleObject(process.process.get(), 0);
|
||||||
require(exited == WAIT_OBJECT_0 || exited == WAIT_TIMEOUT, "Observe owned process exit failed");
|
require(exited == WAIT_OBJECT_0 || exited == WAIT_TIMEOUT, "Observe owned process exit failed");
|
||||||
DWORD code = 0;
|
DWORD code = 0;
|
||||||
if (exited == WAIT_OBJECT_0) {
|
if (exited == WAIT_OBJECT_0) require(GetExitCodeProcess(process.process.get(), &code), "Read owned process exit code failed");
|
||||||
// The child may have reached its limit and exited after the first drain.
|
|
||||||
observeNotifications(process);
|
|
||||||
require(GetExitCodeProcess(process.process.get(), &code), "Read owned process exit code failed");
|
|
||||||
}
|
|
||||||
set(env, result, "exitCode", exited == WAIT_OBJECT_0 ? number(env, code) : null(env));
|
set(env, result, "exitCode", exited == WAIT_OBJECT_0 ? number(env, code) : null(env));
|
||||||
set(env, result, "activeProcesses", number(env, activeProcesses(process)));
|
set(env, result, "activeProcesses", number(env, activeProcesses(process)));
|
||||||
if (process.memoryLimit != 0) {
|
|
||||||
set(env, result, "memoryLimitReached", boolean(env, process.memoryLimitReached));
|
|
||||||
set(env, result, "peakJobMemoryBytes", number(env, static_cast<double>(peakJobMemory(process))));
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (operation == L"process_alive") return number(env, activeProcesses(process));
|
if (operation == L"process_alive") return number(env, activeProcesses(process));
|
||||||
@@ -405,31 +331,23 @@ napi_value processCall(napi_env env, const std::wstring& operation, const std::v
|
|||||||
if (operation == L"process_close") {
|
if (operation == L"process_close") {
|
||||||
// Closing the job is the crash-safe authority; no PID enumeration is used.
|
// Closing the job is the crash-safe authority; no PID enumeration is used.
|
||||||
process.job.reset(); process.process.reset(); process.stdoutRead.reset(); process.stderrRead.reset(); process.stdinWrite.reset();
|
process.job.reset(); process.process.reset(); process.stdoutRead.reset(); process.stderrRead.reset(); process.stdinWrite.reset();
|
||||||
process.notifications.reset();
|
|
||||||
process.closed = true;
|
process.closed = true;
|
||||||
return null(env);
|
return null(env);
|
||||||
}
|
}
|
||||||
throw Failure("Unknown native process operation", L"", ERROR_INVALID_PARAMETER);
|
throw Failure("Unknown native process operation", L"", ERROR_INVALID_PARAMETER);
|
||||||
}
|
}
|
||||||
|
|
||||||
napi_value inspect(napi_env env, std::unique_ptr<Runtime>& probe) {
|
napi_value inspect(napi_env env) {
|
||||||
// Settle the previous owner before admitting another probe. Failed cleanup
|
|
||||||
// retains its handles, including when identity construction itself failed.
|
|
||||||
if (probe) { closeRuntime(*probe); probe.reset(); }
|
|
||||||
wchar_t temp[32768];
|
wchar_t temp[32768];
|
||||||
const auto length = GetTempPathW(32768, temp);
|
const auto length = GetTempPathW(32768, temp);
|
||||||
require(length > 0 && length < 32768, "Read temporary directory coordinate failed");
|
require(length > 0 && length < 32768, "Read temporary directory coordinate failed");
|
||||||
probe = createRuntime(std::wstring(temp, length), L"rea-native-probe-");
|
auto root = createRuntime(std::wstring(temp, length), L"rea-native-probe-");
|
||||||
auto filesystem = identity(env, probe->directory.get(), probe->path);
|
auto filesystem = identity(env, root->directory.get(), root->path);
|
||||||
closeRuntime(*probe);
|
closeRuntime(*root);
|
||||||
probe.reset();
|
|
||||||
auto job = createJob();
|
auto job = createJob();
|
||||||
Attributes attributes(1);
|
Attributes attributes(1);
|
||||||
HANDLE raw = job.get();
|
HANDLE raw = job.get();
|
||||||
attributes.add(PROC_THREAD_ATTRIBUTE_JOB_LIST, &raw, sizeof(raw));
|
attributes.add(PROC_THREAD_ATTRIBUTE_JOB_LIST, &raw, sizeof(raw));
|
||||||
// Establish the commit-limit policy and its notification port on this host.
|
|
||||||
auto limited = createJob(64ULL * 1024 * 1024);
|
|
||||||
auto notifications = createNotifications(limited.get());
|
|
||||||
auto result = object(env);
|
auto result = object(env);
|
||||||
set(env, result, "abiVersion", number(env, 1));
|
set(env, result, "abiVersion", number(env, 1));
|
||||||
set(env, result, "nodeApiVersion", number(env, 8));
|
set(env, result, "nodeApiVersion", number(env, 8));
|
||||||
@@ -439,7 +357,6 @@ napi_value inspect(napi_env env, std::unique_ptr<Runtime>& probe) {
|
|||||||
set(env, result, "atomicJobAssignment", boolean(env, true));
|
set(env, result, "atomicJobAssignment", boolean(env, true));
|
||||||
set(env, result, "killOnOwnerClose", boolean(env, true));
|
set(env, result, "killOnOwnerClose", boolean(env, true));
|
||||||
set(env, result, "protocolStdin", boolean(env, true));
|
set(env, result, "protocolStdin", boolean(env, true));
|
||||||
set(env, result, "jobMemoryLimit", boolean(env, true));
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Generated
+20
-3
@@ -64,7 +64,6 @@
|
|||||||
"lint-staged": "16.4.0",
|
"lint-staged": "16.4.0",
|
||||||
"oxfmt": "0.72.0",
|
"oxfmt": "0.72.0",
|
||||||
"oxlint": "1.87.0",
|
"oxlint": "1.87.0",
|
||||||
"rolldown": "1.2.12",
|
|
||||||
"turbo": "2.11.7",
|
"turbo": "2.11.7",
|
||||||
"typescript": "7.0.2",
|
"typescript": "7.0.2",
|
||||||
"typescript-termux": "npm:typescript@5.9.3",
|
"typescript-termux": "npm:typescript@5.9.3",
|
||||||
@@ -1129,6 +1128,7 @@
|
|||||||
"integrity": "sha512-oM/5rLBm2tPkg0iBgkH/FOeR3PCDpY19GTgAZjMFM8h9WI9VW7cLgzp6nwtarYKmovavIQZ+Fe/RKX/8C8O/Rw==",
|
"integrity": "sha512-oM/5rLBm2tPkg0iBgkH/FOeR3PCDpY19GTgAZjMFM8h9WI9VW7cLgzp6nwtarYKmovavIQZ+Fe/RKX/8C8O/Rw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/oxc-project"
|
"url": "https://github.com/sponsors/oxc-project"
|
||||||
}
|
}
|
||||||
@@ -2117,6 +2117,7 @@
|
|||||||
"os": [
|
"os": [
|
||||||
"android"
|
"android"
|
||||||
],
|
],
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^20.19.0 || >=22.12.0"
|
"node": "^20.19.0 || >=22.12.0"
|
||||||
}
|
}
|
||||||
@@ -2134,6 +2135,7 @@
|
|||||||
"os": [
|
"os": [
|
||||||
"android"
|
"android"
|
||||||
],
|
],
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^20.19.0 || >=22.12.0"
|
"node": "^20.19.0 || >=22.12.0"
|
||||||
}
|
}
|
||||||
@@ -2151,6 +2153,7 @@
|
|||||||
"os": [
|
"os": [
|
||||||
"darwin"
|
"darwin"
|
||||||
],
|
],
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^20.19.0 || >=22.12.0"
|
"node": "^20.19.0 || >=22.12.0"
|
||||||
}
|
}
|
||||||
@@ -2168,6 +2171,7 @@
|
|||||||
"os": [
|
"os": [
|
||||||
"darwin"
|
"darwin"
|
||||||
],
|
],
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^20.19.0 || >=22.12.0"
|
"node": "^20.19.0 || >=22.12.0"
|
||||||
}
|
}
|
||||||
@@ -2185,6 +2189,7 @@
|
|||||||
"os": [
|
"os": [
|
||||||
"freebsd"
|
"freebsd"
|
||||||
],
|
],
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^20.19.0 || >=22.12.0"
|
"node": "^20.19.0 || >=22.12.0"
|
||||||
}
|
}
|
||||||
@@ -2202,6 +2207,7 @@
|
|||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
],
|
],
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^20.19.0 || >=22.12.0"
|
"node": "^20.19.0 || >=22.12.0"
|
||||||
}
|
}
|
||||||
@@ -2222,6 +2228,7 @@
|
|||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
],
|
],
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^20.19.0 || >=22.12.0"
|
"node": "^20.19.0 || >=22.12.0"
|
||||||
}
|
}
|
||||||
@@ -2242,6 +2249,7 @@
|
|||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
],
|
],
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^20.19.0 || >=22.12.0"
|
"node": "^20.19.0 || >=22.12.0"
|
||||||
}
|
}
|
||||||
@@ -2262,6 +2270,7 @@
|
|||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
],
|
],
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^20.19.0 || >=22.12.0"
|
"node": "^20.19.0 || >=22.12.0"
|
||||||
}
|
}
|
||||||
@@ -2282,6 +2291,7 @@
|
|||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
],
|
],
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^20.19.0 || >=22.12.0"
|
"node": "^20.19.0 || >=22.12.0"
|
||||||
}
|
}
|
||||||
@@ -2302,6 +2312,7 @@
|
|||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
],
|
],
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^20.19.0 || >=22.12.0"
|
"node": "^20.19.0 || >=22.12.0"
|
||||||
}
|
}
|
||||||
@@ -2322,6 +2333,7 @@
|
|||||||
"os": [
|
"os": [
|
||||||
"linux"
|
"linux"
|
||||||
],
|
],
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^20.19.0 || >=22.12.0"
|
"node": "^20.19.0 || >=22.12.0"
|
||||||
}
|
}
|
||||||
@@ -2339,6 +2351,7 @@
|
|||||||
"os": [
|
"os": [
|
||||||
"openharmony"
|
"openharmony"
|
||||||
],
|
],
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^20.19.0 || >=22.12.0"
|
"node": "^20.19.0 || >=22.12.0"
|
||||||
}
|
}
|
||||||
@@ -2356,6 +2369,7 @@
|
|||||||
"os": [
|
"os": [
|
||||||
"win32"
|
"win32"
|
||||||
],
|
],
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^20.19.0 || >=22.12.0"
|
"node": "^20.19.0 || >=22.12.0"
|
||||||
}
|
}
|
||||||
@@ -2373,6 +2387,7 @@
|
|||||||
"os": [
|
"os": [
|
||||||
"win32"
|
"win32"
|
||||||
],
|
],
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^20.19.0 || >=22.12.0"
|
"node": "^20.19.0 || >=22.12.0"
|
||||||
}
|
}
|
||||||
@@ -2382,7 +2397,8 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz",
|
||||||
"integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==",
|
"integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||||
"version": "4.64.1",
|
"version": "4.64.1",
|
||||||
@@ -6707,10 +6723,11 @@
|
|||||||
},
|
},
|
||||||
"node_modules/rolldown": {
|
"node_modules/rolldown": {
|
||||||
"version": "1.2.12",
|
"version": "1.2.12",
|
||||||
"resolved": "https://mirrors.cloud.tencent.com/npm/rolldown/-/rolldown-1.2.12.tgz",
|
"resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.12.tgz",
|
||||||
"integrity": "sha512-8wafseiaG80xmXSfqidUNqZcylTlhmPZZt+za2m+js2sFZ8dTNlhIOV2WcbIPx2hgwPBJpEUGFAMZ9bgBBLTSQ==",
|
"integrity": "sha512-8wafseiaG80xmXSfqidUNqZcylTlhmPZZt+za2m+js2sFZ8dTNlhIOV2WcbIPx2hgwPBJpEUGFAMZ9bgBBLTSQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@oxc-project/types": "=0.152.0",
|
"@oxc-project/types": "=0.152.0",
|
||||||
"@rolldown/pluginutils": "^1.0.0"
|
"@rolldown/pluginutils": "^1.0.0"
|
||||||
|
|||||||
+7
-19
@@ -51,14 +51,10 @@
|
|||||||
"bridge/process/ProcessRunTokenReader.swift",
|
"bridge/process/ProcessRunTokenReader.swift",
|
||||||
"bridge/process/ProcessRunTokenReaderMain.swift",
|
"bridge/process/ProcessRunTokenReaderMain.swift",
|
||||||
"bridge/ghidra/ReaGhidraBridge.java",
|
"bridge/ghidra/ReaGhidraBridge.java",
|
||||||
"bridge/ghidra/ReaGhidraBundleActivator.java",
|
|
||||||
"bridge/ghidra/ReaGhidraExtensions.java",
|
"bridge/ghidra/ReaGhidraExtensions.java",
|
||||||
"bridge/ghidra/ReaGhidraPrepareCom.java",
|
"bridge/ghidra/ReaGhidraPrepareCom.java",
|
||||||
"bridge/ghidra/ReaGhidraApplySeeds.java",
|
"bridge/ghidra/ReaGhidraApplySeeds.java",
|
||||||
"bridge/ghidra/ReaGhidraAnalysisOptions.java",
|
|
||||||
"bridge/ghidra/ReaGhidraNoReturnFix.java",
|
"bridge/ghidra/ReaGhidraNoReturnFix.java",
|
||||||
"bridge/ghidra/ReaGhidraMipsSoftFloat.java",
|
|
||||||
"bridge/ghidra/ReaGhidraPrepareRaw.java",
|
|
||||||
"bridge/android/ReaJadxBridge.java",
|
"bridge/android/ReaJadxBridge.java",
|
||||||
"bridge/mitmproxy/capture.py",
|
"bridge/mitmproxy/capture.py",
|
||||||
"scripts/rea.mjs",
|
"scripts/rea.mjs",
|
||||||
@@ -76,7 +72,6 @@
|
|||||||
"bridge/pwntools/layout.py",
|
"bridge/pwntools/layout.py",
|
||||||
"bridge/pwntools/layout_impl.py",
|
"bridge/pwntools/layout_impl.py",
|
||||||
"third_party/pwntools/README.md",
|
"third_party/pwntools/README.md",
|
||||||
"third_party/wabt/README.md",
|
|
||||||
"third_party/evmole/README.md",
|
"third_party/evmole/README.md",
|
||||||
"third_party/evmole/LICENSE",
|
"third_party/evmole/LICENSE",
|
||||||
"bridge/pwntools/decoder_runtime.py",
|
"bridge/pwntools/decoder_runtime.py",
|
||||||
@@ -128,14 +123,14 @@
|
|||||||
"test:local": "node scripts/run-development-tests.mjs local",
|
"test:local": "node scripts/run-development-tests.mjs local",
|
||||||
"test:fast": "vitest run --project domain --project services --project adapters --project composition --project conformance --project evaluation",
|
"test:fast": "vitest run --project domain --project services --project adapters --project composition --project conformance --project evaluation",
|
||||||
"pretest:boundary": "npm run test:prepare",
|
"pretest:boundary": "npm run test:prepare",
|
||||||
"test:boundary": "vitest run --project boundary --project cli-boundary --project process-boundary --project mcp-boundary --project process-global",
|
"test:boundary": "vitest run --project boundary --project process-boundary --project mcp-boundary --project process-global",
|
||||||
"pretest:mcp": "node scripts/check-dependency-install.mjs && node scripts/run-exclusive.mjs artifacts turbo run artifacts:skills artifacts:mcp-catalog",
|
"pretest:mcp": "node scripts/check-dependency-install.mjs && node scripts/run-exclusive.mjs artifacts turbo run artifacts:skills artifacts:mcp-catalog",
|
||||||
"test:mcp": "vitest run --project mcp-boundary",
|
"test:mcp": "vitest run --project mcp-boundary",
|
||||||
"pretest:acceptance": "npm run build:cached",
|
"pretest:acceptance": "npm run build:cached",
|
||||||
"test:acceptance": "vitest run --project acceptance",
|
"test:acceptance": "vitest run --project acceptance",
|
||||||
"test:changed": "node scripts/run-development-tests.mjs changed",
|
"test:changed": "node scripts/run-development-tests.mjs changed",
|
||||||
"pretest:integration": "npm run test:prepare",
|
"pretest:integration": "npm run test:prepare",
|
||||||
"test:integration": "vitest run --project boundary --project cli-boundary --project process-boundary --project mcp-boundary --project process-global --project acceptance",
|
"test:integration": "vitest run --project boundary --project process-boundary --project mcp-boundary --project process-global --project acceptance",
|
||||||
"pretest:coverage": "npm run test:prepare",
|
"pretest:coverage": "npm run test:prepare",
|
||||||
"test:coverage": "vitest run --coverage.enabled --coverage.provider=v8",
|
"test:coverage": "vitest run --coverage.enabled --coverage.provider=v8",
|
||||||
"test:ci": "npm run test:coverage -- --reporter=default --reporter=junit --outputFile.junit=test-results.xml",
|
"test:ci": "npm run test:coverage -- --reporter=default --reporter=junit --outputFile.junit=test-results.xml",
|
||||||
@@ -165,13 +160,11 @@
|
|||||||
"verify:ghidra": "npm run build:cached && node scripts/verify-real-ghidra.mjs",
|
"verify:ghidra": "npm run build:cached && node scripts/verify-real-ghidra.mjs",
|
||||||
"verify:ghidra:seeds": "npm run build:cached && node scripts/verify/ghidra/seeds.mjs",
|
"verify:ghidra:seeds": "npm run build:cached && node scripts/verify/ghidra/seeds.mjs",
|
||||||
"verify:ghidra:mips": "npm run build:cached && node scripts/verify-real-ghidra-mips.mjs",
|
"verify:ghidra:mips": "npm run build:cached && node scripts/verify-real-ghidra-mips.mjs",
|
||||||
"verify:ghidra:mips-relocatable": "npm run build:cached && node scripts/verify-real-ghidra-mips-relocatable.mjs",
|
|
||||||
"verify:ghidra:swift": "npm run build:cached && node scripts/verify-real-ghidra-swift.mjs",
|
"verify:ghidra:swift": "npm run build:cached && node scripts/verify-real-ghidra-swift.mjs",
|
||||||
"verify:ida": "npm run build:cached && node scripts/verify-real-ida.mjs",
|
"verify:ida": "npm run build:cached && node scripts/verify-real-ida.mjs",
|
||||||
"verify:ghidra:switch": "npm run build:cached && node scripts/verify-real-ghidra-switch.mjs",
|
"verify:ghidra:switch": "npm run build:cached && node scripts/verify-real-ghidra-switch.mjs",
|
||||||
"verify:ghidra:dos": "npm run build:cached && node scripts/verify-real-ghidra-dos.mjs",
|
"verify:ghidra:dos": "npm run build:cached && node scripts/verify-real-ghidra-dos.mjs",
|
||||||
"verify:ghidra:com": "npm run build:cached && node scripts/verify-real-ghidra-com.mjs",
|
"verify:ghidra:com": "npm run build:cached && node scripts/verify-real-ghidra-com.mjs",
|
||||||
"verify:ghidra:raw": "npm run build:cached && node scripts/verify-real-ghidra-raw.mjs",
|
|
||||||
"verify:ghidra:aarch64-jump-table": "npm run build:cached && node scripts/verify-real-ghidra.mjs --aarch64-jump-table",
|
"verify:ghidra:aarch64-jump-table": "npm run build:cached && node scripts/verify-real-ghidra.mjs --aarch64-jump-table",
|
||||||
"verify:interface-builder": "npm run build:cached && node scripts/verify/apple/interface-builder.mjs",
|
"verify:interface-builder": "npm run build:cached && node scripts/verify/apple/interface-builder.mjs",
|
||||||
"verify:ghidra:cross-format": "npm run build:cached && node scripts/verify-real-ghidra.mjs --cross-format",
|
"verify:ghidra:cross-format": "npm run build:cached && node scripts/verify-real-ghidra.mjs --cross-format",
|
||||||
@@ -191,8 +184,6 @@
|
|||||||
"verify:android": "npm run build:cached && node scripts/verify/android/analysis.mjs",
|
"verify:android": "npm run build:cached && node scripts/verify/android/analysis.mjs",
|
||||||
"verify:jeb": "npm run build:cached && node scripts/verify-jeb.mjs",
|
"verify:jeb": "npm run build:cached && node scripts/verify-jeb.mjs",
|
||||||
"fixtures:android": "node scripts/fixtures/android/fetch.mjs",
|
"fixtures:android": "node scripts/fixtures/android/fetch.mjs",
|
||||||
"verify:harmony": "npm run build:cached && node scripts/verify/harmony/analysis.mjs",
|
|
||||||
"fixtures:harmony": "node scripts/fixtures/harmony/fetch.mjs",
|
|
||||||
"verify:agent": "npm run build:cached && node scripts/verify-agent-experience.mjs",
|
"verify:agent": "npm run build:cached && node scripts/verify-agent-experience.mjs",
|
||||||
"verify:hopper:linux": "npm run verify:fixtures && npm run build:cached && node scripts/verify-real-hopper-linux.mjs",
|
"verify:hopper:linux": "npm run verify:fixtures && npm run build:cached && node scripts/verify-real-hopper-linux.mjs",
|
||||||
"verify:setup:linux": "npm run build:cached && node scripts/verify-linux-setup-e2e.mjs",
|
"verify:setup:linux": "npm run build:cached && node scripts/verify-linux-setup-e2e.mjs",
|
||||||
@@ -250,13 +241,11 @@
|
|||||||
"verify:browser:runtime": "npm run build:cached && node scripts/verify-browser-runtime.mjs",
|
"verify:browser:runtime": "npm run build:cached && node scripts/verify-browser-runtime.mjs",
|
||||||
"verify:web:network-captures": "npm run build:cached && node scripts/verify-web-network-captures.mjs",
|
"verify:web:network-captures": "npm run build:cached && node scripts/verify-web-network-captures.mjs",
|
||||||
"verify:binary:layout": "npm run build:cached && node scripts/verify-binary-layout.mjs",
|
"verify:binary:layout": "npm run build:cached && node scripts/verify-binary-layout.mjs",
|
||||||
"verify:wasm:package": "npm run build:cached && node scripts/verify-packaged-wasm-artifact.mjs",
|
|
||||||
"verify:wasm:artifact": "npm run build:cached && node scripts/verify-wasm-artifact.mjs",
|
|
||||||
"verify:evm:interface": "npm run build:cached && node scripts/verify-evm-interface.mjs",
|
"verify:evm:interface": "npm run build:cached && node scripts/verify-evm-interface.mjs",
|
||||||
"verify:recorded:crash": "npm run build:cached && node scripts/verify-recorded-crash.mjs",
|
"verify:recorded:crash": "npm run build:cached && node scripts/verify-recorded-crash.mjs",
|
||||||
"mcp-catalog:check:built": "node scripts/generate-mcp-tool-catalog.mjs --check",
|
"mcp-catalog:check:built": "node scripts/generate-mcp-tool-catalog.mjs --check",
|
||||||
"compile": "node scripts/clean-build-output.mjs && tsc -p tsconfig.build.json && node scripts/bundle-mcp-runtime.mjs",
|
"compile": "node scripts/clean-build-output.mjs && tsc -p tsconfig.build.json",
|
||||||
"compile:termux": "node scripts/clean-build-output.mjs && node --max-old-space-size=3072 node_modules/typescript-termux/lib/tsc.js -p tsconfig.build.json && node scripts/bundle-mcp-runtime.mjs",
|
"compile:termux": "node scripts/clean-build-output.mjs && node --max-old-space-size=3072 node_modules/typescript-termux/lib/tsc.js -p tsconfig.build.json",
|
||||||
"artifacts:mcp-catalog": "node scripts/generate-mcp-tool-catalog.mjs",
|
"artifacts:mcp-catalog": "node scripts/generate-mcp-tool-catalog.mjs",
|
||||||
"artifacts:skills": "node scripts/generate-skill-metadata.mjs",
|
"artifacts:skills": "node scripts/generate-skill-metadata.mjs",
|
||||||
"artifacts:product-catalog": "node scripts/generate-product-catalog.mjs",
|
"artifacts:product-catalog": "node scripts/generate-product-catalog.mjs",
|
||||||
@@ -291,7 +280,6 @@
|
|||||||
"canonicalize": "3.0.0",
|
"canonicalize": "3.0.0",
|
||||||
"cross-spawn": "7.0.6",
|
"cross-spawn": "7.0.6",
|
||||||
"diff": "9.0.0",
|
"diff": "9.0.0",
|
||||||
"evmole": "0.9.3",
|
|
||||||
"har-schema": "2.0.0",
|
"har-schema": "2.0.0",
|
||||||
"ignore": "7.0.6",
|
"ignore": "7.0.6",
|
||||||
"incur": "0.6.1",
|
"incur": "0.6.1",
|
||||||
@@ -308,8 +296,9 @@
|
|||||||
"stream-json": "3.7.0",
|
"stream-json": "3.7.0",
|
||||||
"write-file-atomic": "7.0.0",
|
"write-file-atomic": "7.0.0",
|
||||||
"ws": "8.21.0",
|
"ws": "8.21.0",
|
||||||
"yaml": "2.9.0",
|
"zod": "4.4.3",
|
||||||
"zod": "4.4.3"
|
"evmole": "0.9.3",
|
||||||
|
"yaml": "2.9.0"
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"vitepress": {
|
"vitepress": {
|
||||||
@@ -330,7 +319,6 @@
|
|||||||
"lint-staged": "16.4.0",
|
"lint-staged": "16.4.0",
|
||||||
"oxfmt": "0.72.0",
|
"oxfmt": "0.72.0",
|
||||||
"oxlint": "1.87.0",
|
"oxlint": "1.87.0",
|
||||||
"rolldown": "1.2.12",
|
|
||||||
"turbo": "2.11.7",
|
"turbo": "2.11.7",
|
||||||
"typescript": "7.0.2",
|
"typescript": "7.0.2",
|
||||||
"typescript-termux": "npm:typescript@5.9.3",
|
"typescript-termux": "npm:typescript@5.9.3",
|
||||||
|
|||||||
@@ -11,12 +11,7 @@ const root = join(dirname(fileURLToPath(import.meta.url)), "..");
|
|||||||
const nodeVersion = "22.19.0";
|
const nodeVersion = "22.19.0";
|
||||||
const compiler = "x86_64-w64-mingw32-g++";
|
const compiler = "x86_64-w64-mingw32-g++";
|
||||||
const cache = join(homedir(), ".cache", "rea-windows-native");
|
const cache = join(homedir(), ".cache", "rea-windows-native");
|
||||||
const inspectionFixture = process.argv[2] === "--inspection-fixture";
|
const output = join(root, "native", "windows", "build");
|
||||||
if (process.argv.length > 3 || (process.argv.length > 2 && !inspectionFixture))
|
|
||||||
throw new Error("Unknown Windows native build argument");
|
|
||||||
const output = inspectionFixture
|
|
||||||
? join(root, ".cache", "windows-native-inspection-fixture")
|
|
||||||
: join(root, "native", "windows", "build");
|
|
||||||
const run = (command, args) => {
|
const run = (command, args) => {
|
||||||
const result = spawnSync(command, args, {
|
const result = spawnSync(command, args, {
|
||||||
cwd: root,
|
cwd: root,
|
||||||
@@ -125,9 +120,7 @@ run(compiler, [
|
|||||||
"-Wl,--no-insert-timestamp",
|
"-Wl,--no-insert-timestamp",
|
||||||
`-I${headers}`,
|
`-I${headers}`,
|
||||||
"native/windows/src/addon.cc",
|
"native/windows/src/addon.cc",
|
||||||
inspectionFixture
|
"native/windows/src/filesystem.cc",
|
||||||
? "tests/fixtures/windows-native-inspection-failure.cc"
|
|
||||||
: "native/windows/src/filesystem.cc",
|
|
||||||
"native/windows/src/process.cc",
|
"native/windows/src/process.cc",
|
||||||
library,
|
library,
|
||||||
"-ladvapi32",
|
"-ladvapi32",
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
export const bundleMcpRuntime: (root: string) => Promise<void>;
|
|
||||||
@@ -1,104 +0,0 @@
|
|||||||
import { parse } from "@babel/parser";
|
|
||||||
import { readFile } from "node:fs/promises";
|
|
||||||
import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
||||||
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reduce filesystem resolution during MCP startup. Keep dependencies external,
|
|
||||||
* dynamic imports lazy, and the original compiled files for CLI/worker entrypoints.
|
|
||||||
*/
|
|
||||||
export const bundleMcpRuntime = async (root) => {
|
|
||||||
const compiledRoot = join(root, "dist");
|
|
||||||
const { rolldown, RUNTIME_MODULE_ID } = await import("rolldown");
|
|
||||||
const { imports = {} } = JSON.parse(
|
|
||||||
await readFile(join(root, "package.json"), "utf8"),
|
|
||||||
);
|
|
||||||
const bundle = await rolldown({
|
|
||||||
input: { main: join(compiledRoot, "main.js") },
|
|
||||||
platform: "node",
|
|
||||||
treeshake: false,
|
|
||||||
external: (source) => !source.startsWith(".") && !isAbsolute(source),
|
|
||||||
plugins: [
|
|
||||||
{
|
|
||||||
name: "preserve-compiled-module-locations",
|
|
||||||
transform(code, id) {
|
|
||||||
if (id === RUNTIME_MODULE_ID) return null;
|
|
||||||
if (!code.includes("import.meta")) return null;
|
|
||||||
const sourcePath = relative(compiledRoot, id);
|
|
||||||
if (
|
|
||||||
isAbsolute(sourcePath) ||
|
|
||||||
sourcePath === ".." ||
|
|
||||||
sourcePath.startsWith(`..${sep}`)
|
|
||||||
)
|
|
||||||
throw new Error(`MCP bundle input is outside dist: ${id}`);
|
|
||||||
// All chunks are directly under dist/mcp. Preserve the original
|
|
||||||
// module URL, including URL escaping, for bridges and createRequire.
|
|
||||||
const moduleUrl = `new URL(${JSON.stringify(`../${sourcePath.split(sep).map(encodeURIComponent).join("/")}`)}, import.meta.url).href`;
|
|
||||||
const edits = [];
|
|
||||||
const visit = (node) => {
|
|
||||||
if (node === null || typeof node !== "object") return;
|
|
||||||
const isMeta = (value) =>
|
|
||||||
value?.type === "MetaProperty" &&
|
|
||||||
value.meta.name === "import" &&
|
|
||||||
value.property.name === "meta";
|
|
||||||
if (
|
|
||||||
node.type === "CallExpression" &&
|
|
||||||
node.callee.type === "MemberExpression" &&
|
|
||||||
!node.callee.computed &&
|
|
||||||
isMeta(node.callee.object) &&
|
|
||||||
node.callee.property.name === "resolve" &&
|
|
||||||
node.arguments.length === 1 &&
|
|
||||||
node.arguments[0].type === "StringLiteral" &&
|
|
||||||
Object.hasOwn(imports, node.arguments[0].value)
|
|
||||||
)
|
|
||||||
// Package imports resolve in the same package scope after bundling.
|
|
||||||
return;
|
|
||||||
if (
|
|
||||||
node.type === "MemberExpression" &&
|
|
||||||
!node.computed &&
|
|
||||||
isMeta(node.object) &&
|
|
||||||
node.property.name === "url"
|
|
||||||
) {
|
|
||||||
edits.push({ start: node.start, end: node.end });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (isMeta(node))
|
|
||||||
throw new Error(
|
|
||||||
`Unsupported import.meta use in MCP bundle: ${id}`,
|
|
||||||
);
|
|
||||||
for (const value of Object.values(node)) {
|
|
||||||
if (Array.isArray(value)) value.forEach(visit);
|
|
||||||
else visit(value);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
visit(parse(code, { sourceType: "module" }).program);
|
|
||||||
for (const { start, end } of edits.sort((a, b) => b.start - a.start))
|
|
||||||
code = code.slice(0, start) + moduleUrl + code.slice(end);
|
|
||||||
return { code, map: null };
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
try {
|
|
||||||
await bundle.write({
|
|
||||||
dir: join(compiledRoot, "mcp"),
|
|
||||||
format: "esm",
|
|
||||||
entryFileNames: "[name].js",
|
|
||||||
chunkFileNames: "[name]-[hash].js",
|
|
||||||
codeSplitting: true,
|
|
||||||
strictExecutionOrder: true,
|
|
||||||
minify: false,
|
|
||||||
sourcemap: false,
|
|
||||||
});
|
|
||||||
} finally {
|
|
||||||
await bundle.close();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (
|
|
||||||
process.argv[1] !== undefined &&
|
|
||||||
pathToFileURL(resolve(process.argv[1])).href === import.meta.url
|
|
||||||
)
|
|
||||||
await bundleMcpRuntime(
|
|
||||||
resolve(dirname(fileURLToPath(import.meta.url)), ".."),
|
|
||||||
);
|
|
||||||
@@ -123,7 +123,6 @@ if (
|
|||||||
file.startsWith("docs/")
|
file.startsWith("docs/")
|
||||||
) {
|
) {
|
||||||
selected.docs = true;
|
selected.docs = true;
|
||||||
selected.website ||= matchesAny(file, SCOPES.website);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (/^(src|tests)\/.*\.(?:test|spec)\.[cm]?[jt]sx?$/.test(file)) {
|
if (/^(src|tests)\/.*\.(?:test|spec)\.[cm]?[jt]sx?$/.test(file)) {
|
||||||
|
|||||||
@@ -222,8 +222,7 @@ export const SCOPES = {
|
|||||||
website: [
|
website: [
|
||||||
"website/**",
|
"website/**",
|
||||||
"scripts/*website*.py",
|
"scripts/*website*.py",
|
||||||
"README*.md",
|
"scripts/test-website-scripts.mjs",
|
||||||
".github/workflows/website-check.yml",
|
".github/workflows/website-check.yml",
|
||||||
".github/workflows/website-pages.yml",
|
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,71 +0,0 @@
|
|||||||
import { createHash, randomUUID } from "node:crypto";
|
|
||||||
import { createReadStream } from "node:fs";
|
|
||||||
import { link, mkdir, open, rm } from "node:fs/promises";
|
|
||||||
import { resolve, join } from "node:path";
|
|
||||||
import { fileURLToPath } from "node:url";
|
|
||||||
import fixture from "./pipeline.json" with { type: "json" };
|
|
||||||
|
|
||||||
const args = process.argv.slice(2);
|
|
||||||
if (args.length > 1)
|
|
||||||
throw new Error("Usage: npm run fixtures:harmony -- [DIRECTORY]");
|
|
||||||
const directory = resolve(
|
|
||||||
args[0] ??
|
|
||||||
fileURLToPath(
|
|
||||||
new URL("../../../_reference/harmony-integration/", import.meta.url),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
await mkdir(directory, { recursive: true });
|
|
||||||
const hashFile = async (path) => {
|
|
||||||
const hash = createHash("sha256");
|
|
||||||
for await (const chunk of createReadStream(path)) hash.update(chunk);
|
|
||||||
return hash.digest("hex");
|
|
||||||
};
|
|
||||||
const path = join(directory, fixture.filename);
|
|
||||||
try {
|
|
||||||
const digest = await hashFile(path);
|
|
||||||
if (digest !== fixture.sha256)
|
|
||||||
throw new Error(
|
|
||||||
`Existing ${path} has a different SHA-256; it was not overwritten`,
|
|
||||||
);
|
|
||||||
console.log(`Verified existing ${path}: ${digest}`);
|
|
||||||
} catch (cause) {
|
|
||||||
if (!(cause instanceof Error && "code" in cause && cause.code === "ENOENT"))
|
|
||||||
throw cause;
|
|
||||||
const temporary = `${path}.${randomUUID()}.partial`;
|
|
||||||
try {
|
|
||||||
const response = await fetch(fixture.url, {
|
|
||||||
signal: AbortSignal.timeout(300_000),
|
|
||||||
});
|
|
||||||
if (!response.ok || response.body === null)
|
|
||||||
throw new Error(
|
|
||||||
`Download failed: ${fixture.url}: HTTP ${response.status}`,
|
|
||||||
);
|
|
||||||
const handle = await open(temporary, "wx", 0o600);
|
|
||||||
const hash = createHash("sha256");
|
|
||||||
let bytes = 0;
|
|
||||||
try {
|
|
||||||
for await (const chunk of response.body) {
|
|
||||||
bytes += chunk.length;
|
|
||||||
if (bytes > fixture.bytes)
|
|
||||||
throw new Error(`Download exceeds the pinned ${fixture.bytes} bytes`);
|
|
||||||
hash.update(chunk);
|
|
||||||
await handle.writeFile(chunk);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
await handle.close();
|
|
||||||
}
|
|
||||||
if (bytes !== fixture.bytes)
|
|
||||||
throw new Error(
|
|
||||||
`Download size mismatch: expected ${fixture.bytes}, received ${bytes}`,
|
|
||||||
);
|
|
||||||
const digest = hash.digest("hex");
|
|
||||||
if (digest !== fixture.sha256)
|
|
||||||
throw new Error(
|
|
||||||
`SHA-256 mismatch for ${fixture.filename}: expected ${fixture.sha256}, received ${digest}`,
|
|
||||||
);
|
|
||||||
await link(temporary, path);
|
|
||||||
console.log(`Downloaded and verified ${path}: ${digest}`);
|
|
||||||
} finally {
|
|
||||||
await rm(temporary, { force: true });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "harmony-next-pipeline",
|
|
||||||
"version": "1.0.1",
|
|
||||||
"source": "https://github.com/ohosvscode/harmony-next-pipeline",
|
|
||||||
"source_revision": "196956a1c73e7f800887ef699eeff68b07129e98",
|
|
||||||
"license": "MIT",
|
|
||||||
"license_url": "https://github.com/ohosvscode/harmony-next-pipeline/blob/196956a1c73e7f800887ef699eeff68b07129e98/LICENSE",
|
|
||||||
"license_note": "The source repository is MIT licensed. The downloaded release is used locally, not redistributed; bundled component licenses were not independently audited.",
|
|
||||||
"url": "https://github.com/ohosvscode/harmony-next-pipeline/releases/download/v1.0.1/entry-default-unsigned.hap",
|
|
||||||
"asset_id": 223070058,
|
|
||||||
"filename": "entry-default-unsigned.hap",
|
|
||||||
"bytes": 112885,
|
|
||||||
"sha256": "928a4c6718125328695d2c32297ef5dfba2e06d16fd501d507d4aa32423cbad6",
|
|
||||||
"toolchain": null,
|
|
||||||
"provenance_note": "This is an upstream release artifact. Compiler and SDK versions and a reproducible source-to-artifact build have not been independently established."
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { createRequire } from "node:module";
|
import { createRequire } from "node:module";
|
||||||
import { mkdir, readFile, readdir, writeFile } from "node:fs/promises";
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
||||||
import { join } from "node:path";
|
import { join } from "node:path";
|
||||||
import { fileURLToPath } from "node:url";
|
import { fileURLToPath } from "node:url";
|
||||||
|
|
||||||
@@ -20,56 +20,23 @@ export async function buildRecoveryFixtures(root, prefix) {
|
|||||||
const source = fileURLToPath(new URL("./entry.mjs", import.meta.url));
|
const source = fileURLToPath(new URL("./entry.mjs", import.meta.url));
|
||||||
const webpackOutput = join(root, "webpack");
|
const webpackOutput = join(root, "webpack");
|
||||||
await mkdir(webpackOutput);
|
await mkdir(webpackOutput);
|
||||||
const compileWebpack = async (options) =>
|
await new Promise((resolve, reject) => {
|
||||||
new Promise((resolve, reject) => {
|
const compiler = webpack({
|
||||||
const compiler = webpack(options);
|
mode: "production",
|
||||||
compiler.run((error, stats) => {
|
entry: source,
|
||||||
compiler.close((closeError) => {
|
parallelism: 1,
|
||||||
if (error || closeError) return reject(error ?? closeError);
|
optimization: { concatenateModules: false },
|
||||||
if (!stats || stats.hasErrors())
|
output: { path: webpackOutput, filename: "bundle.js" },
|
||||||
return reject(new Error(stats?.toString() ?? "No webpack stats"));
|
});
|
||||||
resolve();
|
compiler.run((error, stats) => {
|
||||||
});
|
compiler.close((closeError) => {
|
||||||
|
if (error || closeError) return reject(error ?? closeError);
|
||||||
|
if (!stats || stats.hasErrors())
|
||||||
|
return reject(new Error(stats?.toString() ?? "No webpack stats"));
|
||||||
|
resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
await compileWebpack({
|
|
||||||
mode: "production",
|
|
||||||
entry: source,
|
|
||||||
parallelism: 1,
|
|
||||||
optimization: { concatenateModules: false },
|
|
||||||
output: { path: webpackOutput, filename: "bundle.js" },
|
|
||||||
});
|
});
|
||||||
const splitOutput = join(root, "webpack-code-split");
|
|
||||||
await mkdir(splitOutput);
|
|
||||||
const splitSource = fileURLToPath(
|
|
||||||
new URL("./code-split/entry.mjs", import.meta.url),
|
|
||||||
);
|
|
||||||
await compileWebpack({
|
|
||||||
mode: "production",
|
|
||||||
entry: splitSource,
|
|
||||||
parallelism: 1,
|
|
||||||
optimization: {
|
|
||||||
concatenateModules: false,
|
|
||||||
runtimeChunk: "single",
|
|
||||||
splitChunks: {
|
|
||||||
chunks: "all",
|
|
||||||
minSize: 0,
|
|
||||||
cacheGroups: {
|
|
||||||
shared: { test: /shared\.mjs$/u, name: "shared", enforce: true },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
output: {
|
|
||||||
path: splitOutput,
|
|
||||||
filename: "[name].js",
|
|
||||||
chunkFilename: "[id].chunk.js",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const splitFiles = (await readdir(splitOutput))
|
|
||||||
.filter((name) => name !== "main.js")
|
|
||||||
.sort();
|
|
||||||
if (splitFiles.length !== 3)
|
|
||||||
throw new Error("Expected runtime, shared and lazy chunks");
|
|
||||||
const esbuildPath = join(root, "esbuild.js");
|
const esbuildPath = join(root, "esbuild.js");
|
||||||
await esbuild.build({
|
await esbuild.build({
|
||||||
entryPoints: [source],
|
entryPoints: [source],
|
||||||
@@ -128,13 +95,6 @@ export async function buildRecoveryFixtures(root, prefix) {
|
|||||||
options: { extraction_mode: "inspection", rewrite_level: "minimal" },
|
options: { extraction_mode: "inspection", rewrite_level: "minimal" },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
codeSplit: {
|
|
||||||
name: "webpack-code-split",
|
|
||||||
path: join(splitOutput, "main.js"),
|
|
||||||
additional_paths: splitFiles.map((name) => join(splitOutput, name)),
|
|
||||||
expectedFormat: "webpack5",
|
|
||||||
expectedModules: 4,
|
|
||||||
},
|
|
||||||
toolchains: { esbuild: esbuild.version, webpack: webpackVersion },
|
toolchains: { esbuild: esbuild.version, webpack: webpackVersion },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
import { Cart, formatPrice, TAX_RATE } from "./shared.mjs";
|
|
||||||
export function checkout(prices) {
|
|
||||||
const cart = new Cart();
|
|
||||||
prices.forEach((price) => cart.add(price));
|
|
||||||
return formatPrice(cart.total() * (1 + TAX_RATE));
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
import { formatPrice } from "./shared.mjs";
|
|
||||||
console.log(formatPrice(1));
|
|
||||||
import("./checkout.mjs").then(({ checkout }) => console.log(checkout([1, 2])));
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
export class Cart {
|
|
||||||
constructor() {
|
|
||||||
this.items = [];
|
|
||||||
}
|
|
||||||
add(price) {
|
|
||||||
this.items.push(price);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
total() {
|
|
||||||
return this.items.reduce((sum, price) => sum + price, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export const formatPrice = (value) => `$${value.toFixed(2)}`;
|
|
||||||
export const TAX_RATE = 0.08;
|
|
||||||
@@ -5,23 +5,13 @@ import { fileURLToPath } from "node:url";
|
|||||||
import { Client } from "@modelcontextprotocol/client";
|
import { Client } from "@modelcontextprotocol/client";
|
||||||
import { StdioClientTransport } from "@modelcontextprotocol/client/stdio";
|
import { StdioClientTransport } from "@modelcontextprotocol/client/stdio";
|
||||||
|
|
||||||
const environment = () => {
|
const environment = () => ({
|
||||||
const compileCache =
|
PATH: process.env.PATH ?? "/usr/bin:/bin",
|
||||||
process.env.NODE_COMPILE_CACHE ??
|
REA_LOG_LEVEL: "silent",
|
||||||
process.env.REA_ARTIFACT_NODE_COMPILE_CACHE;
|
REA_ANALYSIS_PROVIDER: "auto",
|
||||||
return {
|
// Artifact workflows have no deep-provider prerequisite or GUI authority.
|
||||||
PATH: process.env.PATH ?? "/usr/bin:/bin",
|
HOPPER_LAUNCHER_PATH: "/rea-unconfigured-deep-provider/hopper",
|
||||||
...(compileCache &&
|
});
|
||||||
process.env.NODE_V8_COVERAGE === undefined &&
|
|
||||||
process.env.NODE_DISABLE_COMPILE_CACHE !== "1"
|
|
||||||
? { NODE_COMPILE_CACHE: compileCache }
|
|
||||||
: {}),
|
|
||||||
REA_LOG_LEVEL: "silent",
|
|
||||||
REA_ANALYSIS_PROVIDER: "auto",
|
|
||||||
// Artifact workflows have no deep-provider prerequisite or GUI authority.
|
|
||||||
HOPPER_LAUNCHER_PATH: "/rea-unconfigured-deep-provider/hopper",
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Execute the compiled CLI with production providers and no test adapters. */
|
/** Execute the compiled CLI with production providers and no test adapters. */
|
||||||
export async function artifactCli(
|
export async function artifactCli(
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ export const toolFamilyCatalog = (sources) => {
|
|||||||
contracts: [
|
contracts: [
|
||||||
...sources.artifactContracts.ARTIFACT_TOOL_CONTRACTS,
|
...sources.artifactContracts.ARTIFACT_TOOL_CONTRACTS,
|
||||||
...sources.evmContracts.EVM_TOOL_CONTRACTS,
|
...sources.evmContracts.EVM_TOOL_CONTRACTS,
|
||||||
...sources.wasmContracts.WASM_TOOL_CONTRACTS,
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -180,10 +179,6 @@ export const providerCatalog = (sources) => {
|
|||||||
({ name }) => name === "inspect_pe_resources",
|
({ name }) => name === "inspect_pe_resources",
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
identity: sources.wasmProvider.WABT_PROVIDER_IDENTITY,
|
|
||||||
contracts: sources.wasmContracts.WASM_TOOL_CONTRACTS,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
identity: sources.evmProvider.EVMOLE_PROVIDER_IDENTITY,
|
identity: sources.evmProvider.EVMOLE_PROVIDER_IDENTITY,
|
||||||
contracts: sources.evmContracts.EVM_TOOL_CONTRACTS,
|
contracts: sources.evmContracts.EVM_TOOL_CONTRACTS,
|
||||||
|
|||||||
@@ -45,8 +45,6 @@ const SOURCE_PATHS = {
|
|||||||
"dist/contracts/native/binaryDiagnosticsToolContracts.js",
|
"dist/contracts/native/binaryDiagnosticsToolContracts.js",
|
||||||
pwntoolsProvider: "dist/native/pwntools/PwntoolsRelease.js",
|
pwntoolsProvider: "dist/native/pwntools/PwntoolsRelease.js",
|
||||||
nativeContracts: "dist/contracts/native/nativeToolContracts.js",
|
nativeContracts: "dist/contracts/native/nativeToolContracts.js",
|
||||||
wasmContracts: "dist/contracts/wasm/wasmToolContracts.js",
|
|
||||||
wasmProvider: "dist/wasm/WabtRelease.js",
|
|
||||||
evmContracts: "dist/contracts/evm/evmToolContracts.js",
|
evmContracts: "dist/contracts/evm/evmToolContracts.js",
|
||||||
evmProvider: "dist/evm/EvmoleRelease.js",
|
evmProvider: "dist/evm/EvmoleRelease.js",
|
||||||
artifactContracts: "dist/contracts/artifactToolContracts.js",
|
artifactContracts: "dist/contracts/artifactToolContracts.js",
|
||||||
|
|||||||
@@ -56,9 +56,7 @@ const artifactConsumers = {
|
|||||||
"tests/boundary/mcp/contractPresentation.test.ts",
|
"tests/boundary/mcp/contractPresentation.test.ts",
|
||||||
"tests/boundary/mcp/toolSchemaValidity.test.ts",
|
"tests/boundary/mcp/toolSchemaValidity.test.ts",
|
||||||
],
|
],
|
||||||
"artifacts:product-catalog": [
|
"artifacts:product-catalog": ["tests/boundary/cli/productCatalog.test.ts"],
|
||||||
"tests/boundary/filesystem/productCatalog.test.ts",
|
|
||||||
],
|
|
||||||
"artifacts:managed-evidence": [
|
"artifacts:managed-evidence": [
|
||||||
"tests/boundary/filesystem/setupSkill.test.ts",
|
"tests/boundary/filesystem/setupSkill.test.ts",
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { readFile, readdir, stat } from "node:fs/promises";
|
import { readFile, readdir, stat } from "node:fs/promises";
|
||||||
import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
||||||
|
|
||||||
const readmeLinkTargets = (content, language = "en") =>
|
const readmeLinkTargets = (content) =>
|
||||||
[...content.matchAll(/\]\(([^)\s]+)\)/gu)]
|
[...content.matchAll(/\]\(([^)\s]+)\)/gu)]
|
||||||
.map((match) => match[1] ?? "")
|
.map((match) => match[1] ?? "")
|
||||||
.filter(
|
.filter(
|
||||||
@@ -9,18 +9,6 @@ const readmeLinkTargets = (content, language = "en") =>
|
|||||||
!target.startsWith("#") &&
|
!target.startsWith("#") &&
|
||||||
!/^README(?:_[A-Za-z0-9-]+)?\.md$/u.test(target),
|
!/^README(?:_[A-Za-z0-9-]+)?\.md$/u.test(target),
|
||||||
)
|
)
|
||||||
.map((target) => {
|
|
||||||
if (language === "en" || !URL.canParse(target)) return target;
|
|
||||||
const url = new URL(target);
|
|
||||||
const prefix = `/${language}/`;
|
|
||||||
if (
|
|
||||||
url.origin !== "https://rea.tools" ||
|
|
||||||
!url.pathname.startsWith(prefix)
|
|
||||||
)
|
|
||||||
return target;
|
|
||||||
url.pathname = url.pathname.slice(prefix.length - 1);
|
|
||||||
return url.href;
|
|
||||||
})
|
|
||||||
.sort();
|
.sort();
|
||||||
|
|
||||||
const requireText = (issues, path, content, expected) => {
|
const requireText = (issues, path, content, expected) => {
|
||||||
@@ -95,17 +83,10 @@ export const documentationFactIssues = async (root, catalog) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const canonicalLinks = readmeLinkTargets(readmes.get("README.md") ?? "");
|
const canonicalLinks = readmeLinkTargets(readmes.get("README.md") ?? "");
|
||||||
const languageInventory = JSON.parse(
|
|
||||||
await readFile(join(root, "website/locales/languages.json"), "utf8"),
|
|
||||||
);
|
|
||||||
const readmeLanguages = new Map(
|
|
||||||
languageInventory.map(({ readme, code }) => [readme, code]),
|
|
||||||
);
|
|
||||||
for (const path of readmePaths.filter((path) => path !== "README.md"))
|
for (const path of readmePaths.filter((path) => path !== "README.md"))
|
||||||
if (
|
if (
|
||||||
JSON.stringify(
|
JSON.stringify(readmeLinkTargets(readmes.get(path) ?? "")) !==
|
||||||
readmeLinkTargets(readmes.get(path) ?? "", readmeLanguages.get(path)),
|
JSON.stringify(canonicalLinks)
|
||||||
) !== JSON.stringify(canonicalLinks)
|
|
||||||
)
|
)
|
||||||
issues.push(`${path}: documentation links differ from README.md`);
|
issues.push(`${path}: documentation links differ from README.md`);
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import { fileURLToPath, pathToFileURL } from "node:url";
|
|||||||
const PURE_LAYERS = new Set(["domain", "contracts"]);
|
const PURE_LAYERS = new Set(["domain", "contracts"]);
|
||||||
const MIGRATED_PROVIDER_ROOTS = new Set([
|
const MIGRATED_PROVIDER_ROOTS = new Set([
|
||||||
"evm",
|
"evm",
|
||||||
"wasm",
|
|
||||||
"android",
|
"android",
|
||||||
"firmware",
|
"firmware",
|
||||||
"ghidra",
|
"ghidra",
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ export async function verifyGhidraCompactReferences(call, x86, cli) {
|
|||||||
procedure: address(0x1020),
|
procedure: address(0x1020),
|
||||||
});
|
});
|
||||||
const inspected = {};
|
const inspected = {};
|
||||||
const incomingByTarget = new Map();
|
|
||||||
for (const [kind, offset, target] of cases) {
|
for (const [kind, offset, target] of cases) {
|
||||||
const instruction = await call("inspect_native_instruction", {
|
const instruction = await call("inspect_native_instruction", {
|
||||||
address: address(offset),
|
address: address(offset),
|
||||||
@@ -27,12 +26,6 @@ export async function verifyGhidraCompactReferences(call, x86, cli) {
|
|||||||
assert.equal(reference.data, true);
|
assert.equal(reference.data, true);
|
||||||
assert.equal(reference.read, kind === "read");
|
assert.equal(reference.read, kind === "read");
|
||||||
assert.equal(reference.write, kind === "write");
|
assert.equal(reference.write, kind === "write");
|
||||||
const incoming = await call("inspect_native_instruction", {
|
|
||||||
address: address(target),
|
|
||||||
});
|
|
||||||
assert.notEqual(incoming.status, "decoded");
|
|
||||||
assertIncomingReference(incoming, reference);
|
|
||||||
incomingByTarget.set(incoming.address, incoming);
|
|
||||||
}
|
}
|
||||||
const indexed = await call("inspect_native_instruction", {
|
const indexed = await call("inspect_native_instruction", {
|
||||||
address: address(x86 ? 0x103d : 0x1045),
|
address: address(x86 ? 0x103d : 0x1045),
|
||||||
@@ -46,15 +39,6 @@ export async function verifyGhidraCompactReferences(call, x86, cli) {
|
|||||||
),
|
),
|
||||||
"Indexed fixture lacks a non-primary analyzer reference",
|
"Indexed fixture lacks a non-primary analyzer reference",
|
||||||
);
|
);
|
||||||
for (const reference of indexed.references) {
|
|
||||||
const incoming = await call("inspect_native_instruction", {
|
|
||||||
address: reference.target_address,
|
|
||||||
});
|
|
||||||
assertIncomingReference(incoming, reference);
|
|
||||||
incomingByTarget.set(incoming.address, incoming);
|
|
||||||
}
|
|
||||||
for (const incoming of incomingByTarget.values())
|
|
||||||
await verifyIncomingReferences(call, incoming);
|
|
||||||
|
|
||||||
const { direct, targets } = await verifyDirectCall(
|
const { direct, targets } = await verifyDirectCall(
|
||||||
call,
|
call,
|
||||||
@@ -80,13 +64,7 @@ export async function verifyGhidraCompactReferences(call, x86, cli) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (cli !== undefined) {
|
if (cli !== undefined) {
|
||||||
for (const instruction of [
|
for (const instruction of [inspected.write, indexed, direct, returned])
|
||||||
inspected.write,
|
|
||||||
indexed,
|
|
||||||
direct,
|
|
||||||
returned,
|
|
||||||
...incomingByTarget.values(),
|
|
||||||
])
|
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
await cli("inspect-native-instruction", instruction.address),
|
await cli("inspect-native-instruction", instruction.address),
|
||||||
instruction,
|
instruction,
|
||||||
@@ -104,10 +82,6 @@ export async function verifyGhidraCompactReferences(call, x86, cli) {
|
|||||||
data_read_write: true,
|
data_read_write: true,
|
||||||
source_primary_provenance: true,
|
source_primary_provenance: true,
|
||||||
full_reference_parity: true,
|
full_reference_parity: true,
|
||||||
typed_incoming_reference_parity: true,
|
|
||||||
incoming_reference_ordering: true,
|
|
||||||
incoming_xrefs_parity: true,
|
|
||||||
synthetic_entry_reference_excluded: true,
|
|
||||||
direct_call_reference_parity: true,
|
direct_call_reference_parity: true,
|
||||||
indexed_reference_count: indexed.references.length,
|
indexed_reference_count: indexed.references.length,
|
||||||
indexed_non_primary_count: indexed.references.filter(
|
indexed_non_primary_count: indexed.references.filter(
|
||||||
@@ -141,64 +115,9 @@ async function verifyDirectCall(call, entry, callee) {
|
|||||||
const full = await call("procedure_references", { procedure: entry });
|
const full = await call("procedure_references", { procedure: entry });
|
||||||
for (const reference of direct.references)
|
for (const reference of direct.references)
|
||||||
assertReference(reference, entry, full.references);
|
assertReference(reference, entry, full.references);
|
||||||
const incoming = await call("inspect_native_instruction", {
|
|
||||||
address: callee,
|
|
||||||
});
|
|
||||||
const callReference = direct.references.find(
|
|
||||||
(reference) => reference.target_address === callee && reference.call,
|
|
||||||
);
|
|
||||||
assert.ok(callReference, "Direct fixture call lacks its reference");
|
|
||||||
assertIncomingReference(incoming, callReference);
|
|
||||||
await verifyIncomingReferences(call, incoming);
|
|
||||||
// PE header pointers are real incoming data references; synthetic loader
|
|
||||||
// entry-point references must not be presented as callers.
|
|
||||||
await verifyIncomingReferences(call, direct);
|
|
||||||
for (const reference of direct.incoming_references) {
|
|
||||||
assert.equal(reference.type, "DATA");
|
|
||||||
assert.equal(reference.data, true);
|
|
||||||
assert.equal(reference.source, "default");
|
|
||||||
}
|
|
||||||
return { direct, targets };
|
return { direct, targets };
|
||||||
}
|
}
|
||||||
|
|
||||||
function assertIncomingReference(instruction, reference) {
|
|
||||||
const incoming = instruction.incoming_references.find(
|
|
||||||
(item) =>
|
|
||||||
item.source_address === reference.source_address &&
|
|
||||||
item.target_address === reference.target_address &&
|
|
||||||
item.type === reference.type &&
|
|
||||||
item.operand_index === reference.operand_index &&
|
|
||||||
item.primary === reference.primary,
|
|
||||||
);
|
|
||||||
assert.ok(
|
|
||||||
incoming,
|
|
||||||
"Outgoing reference lacks its typed incoming counterpart",
|
|
||||||
);
|
|
||||||
assert.deepEqual(incoming, reference);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function verifyIncomingReferences(call, instruction) {
|
|
||||||
const repeated = await call("inspect_native_instruction", {
|
|
||||||
address: instruction.address,
|
|
||||||
});
|
|
||||||
assert.deepEqual(
|
|
||||||
repeated.incoming_references,
|
|
||||||
instruction.incoming_references,
|
|
||||||
"Repeated incoming reference queries changed order or provider facts",
|
|
||||||
);
|
|
||||||
assert.deepEqual(
|
|
||||||
[
|
|
||||||
...new Set(
|
|
||||||
instruction.incoming_references.map(
|
|
||||||
(reference) => reference.source_address,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
await call("xrefs", { address: instruction.address }),
|
|
||||||
"Incoming references differ from xrefs source addresses or their order",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function verifyEmptyReferences(call, address) {
|
async function verifyEmptyReferences(call, address) {
|
||||||
const returned = await call("inspect_native_instruction", { address });
|
const returned = await call("inspect_native_instruction", { address });
|
||||||
assert.equal(returned.flow.kind, "return");
|
assert.equal(returned.flow.kind, "return");
|
||||||
@@ -210,7 +129,6 @@ async function verifyEmptyReferences(call, address) {
|
|||||||
const outside = await call("inspect_native_instruction", { address: "0x0" });
|
const outside = await call("inspect_native_instruction", { address: "0x0" });
|
||||||
assert.equal(outside.status, "outside-memory");
|
assert.equal(outside.status, "outside-memory");
|
||||||
assert.deepEqual(outside.references, []);
|
assert.deepEqual(outside.references, []);
|
||||||
assert.deepEqual(outside.incoming_references, []);
|
|
||||||
assert.equal(
|
assert.equal(
|
||||||
(await call("resolve_native_call_targets", { address: "0x0" })).status,
|
(await call("resolve_native_call_targets", { address: "0x0" })).status,
|
||||||
"unavailable",
|
"unavailable",
|
||||||
|
|||||||
@@ -1,180 +0,0 @@
|
|||||||
import assert from "node:assert/strict";
|
|
||||||
import { join } from "node:path";
|
|
||||||
import { pathToFileURL } from "node:url";
|
|
||||||
import { setTimeout as delay } from "node:timers/promises";
|
|
||||||
|
|
||||||
const MIB = 1024 * 1024;
|
|
||||||
const LIMIT = 128 * MIB;
|
|
||||||
// Observed peaks exceed the limit by a few MiB of kernel-charged commit
|
|
||||||
// (e.g. 512 MiB -> 520 MiB, 256 MiB -> 262 MiB under Bun), never by an
|
|
||||||
// allocation the limit refused.
|
|
||||||
const PEAK_OVERSHOOT = 32 * MIB;
|
|
||||||
// External Buffer memory is committed outside the V8 heap, so V8 heap flags
|
|
||||||
// cannot bound it; only the Job Object commit limit can stop this child.
|
|
||||||
const UNBOUNDED = `const kept = [];
|
|
||||||
for (let index = 0; index < 64; index++) kept.push(Buffer.alloc(${String(16 * MIB)}, 1));
|
|
||||||
console.log("unbounded allocation completed");`;
|
|
||||||
const BOUNDED = `const kept = Buffer.alloc(${String(MIB)}, 1);
|
|
||||||
console.log("bounded allocation completed", kept.length);`;
|
|
||||||
|
|
||||||
/** Exercise owned Job Object commit limits through the native boundary and its production wrapper. */
|
|
||||||
export async function verifyWindowsJobMemoryLimit(packageRoot, workspace) {
|
|
||||||
const { WindowsOwnedProcess } = await import(
|
|
||||||
pathToFileURL(join(packageRoot, "dist/windows/WindowsOwnedProcess.js"))
|
|
||||||
);
|
|
||||||
const { requireWindowsNativeAuthority } = await import(
|
|
||||||
pathToFileURL(join(packageRoot, "dist/windows/WindowsNativeLoader.js"))
|
|
||||||
);
|
|
||||||
const native = requireWindowsNativeAuthority();
|
|
||||||
assert.equal(native.inspection.jobMemoryLimit, true);
|
|
||||||
const launch = nativeLauncher(native, workspace);
|
|
||||||
|
|
||||||
for (const invalid of [
|
|
||||||
0,
|
|
||||||
-MIB,
|
|
||||||
1.5,
|
|
||||||
LIMIT + 0.5,
|
|
||||||
2 ** 53,
|
|
||||||
NaN,
|
|
||||||
Infinity,
|
|
||||||
4097,
|
|
||||||
"134217728",
|
|
||||||
null,
|
|
||||||
])
|
|
||||||
assert.throws(() => launch(BOUNDED, false, invalid), {
|
|
||||||
code: "ERR_REA_WINDOWS_NATIVE",
|
|
||||||
win32Code: 87,
|
|
||||||
});
|
|
||||||
|
|
||||||
const unlimited = await settle(native, launch(BOUNDED));
|
|
||||||
assert.equal(unlimited.exitCode, 0);
|
|
||||||
assert.equal("memoryLimitReached" in unlimited, false);
|
|
||||||
assert.equal("peakJobMemoryBytes" in unlimited, false);
|
|
||||||
|
|
||||||
const reachedLaunch = launch(UNBOUNDED, false, LIMIT);
|
|
||||||
assert.equal(reachedLaunch.jobMemoryLimitBytes, LIMIT);
|
|
||||||
const reached = await settle(native, reachedLaunch);
|
|
||||||
assert.notEqual(reached.exitCode, 0);
|
|
||||||
assert.doesNotMatch(reached.output, /unbounded allocation completed/u);
|
|
||||||
assert.equal(reached.activeProcesses, 0);
|
|
||||||
assert.equal(reached.memoryLimitReached, true);
|
|
||||||
assert.equal(reached.memoryLimitReachedAtExit, true);
|
|
||||||
assert.ok(reached.peakJobMemoryBytes <= LIMIT + PEAK_OVERSHOOT);
|
|
||||||
assert.ok(reached.peakJobMemoryBytes > LIMIT - 64 * MIB);
|
|
||||||
|
|
||||||
const control = await settle(native, launch(BOUNDED, false, LIMIT));
|
|
||||||
assert.equal(control.exitCode, 0);
|
|
||||||
assert.match(control.output, /bounded allocation completed/u);
|
|
||||||
assert.equal(control.activeProcesses, 0);
|
|
||||||
assert.equal(control.memoryLimitReached, false);
|
|
||||||
assert.equal(control.memoryLimitReachedAtExit, false);
|
|
||||||
assert.ok(control.peakJobMemoryBytes < LIMIT);
|
|
||||||
|
|
||||||
await verifyWrappedLimit(WindowsOwnedProcess, native, workspace);
|
|
||||||
|
|
||||||
return {
|
|
||||||
limit_bytes: LIMIT,
|
|
||||||
invalid_limits_rejected: true,
|
|
||||||
unlimited_poll_shape_unchanged: true,
|
|
||||||
reached: {
|
|
||||||
exit_code: reached.exitCode,
|
|
||||||
peak_job_memory_bytes: reached.peakJobMemoryBytes,
|
|
||||||
},
|
|
||||||
control: {
|
|
||||||
exit_code: control.exitCode,
|
|
||||||
peak_job_memory_bytes: control.peakJobMemoryBytes,
|
|
||||||
},
|
|
||||||
wrapper_reports_limit_reached: true,
|
|
||||||
first_exit_reports_limit_reached: true,
|
|
||||||
missing_capability_refused: true,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function nativeLauncher(native, workspace) {
|
|
||||||
const environment = Object.entries(process.env)
|
|
||||||
.filter(([, value]) => value !== undefined)
|
|
||||||
.map(([key, value]) => `${key}=${value}`);
|
|
||||||
const quote = (value) =>
|
|
||||||
`"${value.replace(/(\\*)"/gu, '$1$1\\"').replace(/(\\+)$/u, "$1$1")}"`;
|
|
||||||
return (script, ...controls) =>
|
|
||||||
native.call("process_spawn", [
|
|
||||||
process.execPath,
|
|
||||||
[process.execPath, "-e", script].map(quote).join(" "),
|
|
||||||
workspace,
|
|
||||||
environment,
|
|
||||||
...controls,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function verifyWrappedLimit(WindowsOwnedProcess, native, workspace) {
|
|
||||||
const wrapped = new WindowsOwnedProcess(
|
|
||||||
process.execPath,
|
|
||||||
["-e", UNBOUNDED],
|
|
||||||
workspace,
|
|
||||||
process.env,
|
|
||||||
false,
|
|
||||||
{ memoryLimitBytes: LIMIT },
|
|
||||||
);
|
|
||||||
const closed = new Promise((resolve, reject) => {
|
|
||||||
wrapped.once("error", reject);
|
|
||||||
wrapped.once("close", (code) => resolve(code));
|
|
||||||
});
|
|
||||||
let memoryLimitReachedAtExit;
|
|
||||||
wrapped.once("exit", () => {
|
|
||||||
memoryLimitReachedAtExit = wrapped.memoryLimitReached;
|
|
||||||
});
|
|
||||||
wrapped.stdout.resume();
|
|
||||||
wrapped.stderr.resume();
|
|
||||||
assert.notEqual(await closed, 0);
|
|
||||||
assert.equal(memoryLimitReachedAtExit, true);
|
|
||||||
assert.equal(wrapped.memoryLimitReached, true);
|
|
||||||
assert.ok(wrapped.peakJobMemoryBytes <= LIMIT + PEAK_OVERSHOOT);
|
|
||||||
|
|
||||||
assert.throws(
|
|
||||||
() =>
|
|
||||||
new WindowsOwnedProcess(
|
|
||||||
process.execPath,
|
|
||||||
["-e", BOUNDED],
|
|
||||||
workspace,
|
|
||||||
process.env,
|
|
||||||
false,
|
|
||||||
{
|
|
||||||
memoryLimitBytes: LIMIT,
|
|
||||||
authority: {
|
|
||||||
call: native.call,
|
|
||||||
inspection: { ...native.inspection, jobMemoryLimit: undefined },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
),
|
|
||||||
/does not support Job Object memory limits/u,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function settle(native, child) {
|
|
||||||
let output = "";
|
|
||||||
let firstExitState;
|
|
||||||
try {
|
|
||||||
for (let attempt = 0; attempt < 800; attempt++) {
|
|
||||||
const state = native.call("process_poll", [child.handle]);
|
|
||||||
output += state.stdout.toString();
|
|
||||||
if (state.exitCode !== null) firstExitState ??= state;
|
|
||||||
if (
|
|
||||||
state.exitCode !== null &&
|
|
||||||
state.activeProcesses === 0 &&
|
|
||||||
state.stdoutEnded &&
|
|
||||||
state.stderrEnded
|
|
||||||
)
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
output,
|
|
||||||
memoryLimitReachedAtExit: firstExitState.memoryLimitReached,
|
|
||||||
};
|
|
||||||
await delay(25);
|
|
||||||
}
|
|
||||||
throw new Error(
|
|
||||||
"Memory-limited job did not settle within the fixture deadline.",
|
|
||||||
);
|
|
||||||
} finally {
|
|
||||||
native.call("process_close", [child.handle]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -39,7 +39,7 @@ function acquire(Process, workspace, script) {
|
|||||||
workspace,
|
workspace,
|
||||||
process.env,
|
process.env,
|
||||||
false,
|
false,
|
||||||
{ protocolStdin: true },
|
true,
|
||||||
);
|
);
|
||||||
let stdout = "";
|
let stdout = "";
|
||||||
let stderr = "";
|
let stderr = "";
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ if (await pathExists(join(root, "src"))) {
|
|||||||
} else {
|
} else {
|
||||||
for (const path of [
|
for (const path of [
|
||||||
"dist/main.js",
|
"dist/main.js",
|
||||||
"dist/mcp/main.js",
|
|
||||||
"dist/mcpDoctor.js",
|
"dist/mcpDoctor.js",
|
||||||
"dist/cli.js",
|
"dist/cli.js",
|
||||||
"dist/cliOutput.js",
|
"dist/cliOutput.js",
|
||||||
|
|||||||
@@ -76,14 +76,9 @@ def prepare_notes_example(site):
|
|||||||
print(f"Prepared examples/notes-example.zip ({len(EXAMPLE_FILES)} files).")
|
print(f"Prepared examples/notes-example.zip ({len(EXAMPLE_FILES)} files).")
|
||||||
|
|
||||||
|
|
||||||
def prepare_assets(site):
|
if __name__ == "__main__":
|
||||||
"""Finish the shared publish artifact before it replaces the current preview."""
|
root = Path(__file__).resolve().parent.parent
|
||||||
|
site = root / "website/public"
|
||||||
prepare_sharing_image(site)
|
prepare_sharing_image(site)
|
||||||
prepare_sitemap(site)
|
prepare_sitemap(site)
|
||||||
prepare_notes_example(site)
|
prepare_notes_example(site)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
root = Path(__file__).resolve().parent.parent
|
|
||||||
from website_i18n import build_translations
|
|
||||||
build_translations(root, root / "website/_site", finalize=prepare_assets)
|
|
||||||
|
|||||||
+4
-4
@@ -5,7 +5,7 @@ import { dirname, join, resolve } from "node:path";
|
|||||||
import { fileURLToPath } from "node:url";
|
import { fileURLToPath } from "node:url";
|
||||||
|
|
||||||
// Route production MCP before importing Incur. Incur owns registration helpers
|
// Route production MCP before importing Incur. Incur owns registration helpers
|
||||||
// such as `mcp add`, while the MCP runtime serves the stdio tool catalog.
|
// such as `mcp add`, while only dist/main.js may serve the stdio tool catalog.
|
||||||
const args = process.argv.slice(2);
|
const args = process.argv.slice(2);
|
||||||
const { default: packageJson } = await import("../package.json", {
|
const { default: packageJson } = await import("../package.json", {
|
||||||
with: { type: "json" },
|
with: { type: "json" },
|
||||||
@@ -31,9 +31,9 @@ if (
|
|||||||
}
|
}
|
||||||
|
|
||||||
const runtimeFiles = isMcpMode
|
const runtimeFiles = isMcpMode
|
||||||
? ["dist/mcp/main.js"]
|
? ["dist/main.js"]
|
||||||
: isMcpDoctorMode
|
: isMcpDoctorMode
|
||||||
? ["dist/mcp/main.js", "dist/mcpDoctor.js"]
|
? ["dist/main.js", "dist/mcpDoctor.js"]
|
||||||
: ["dist/cli.js", "dist/cliOutput.js", "dist/cli/streamedJsonOutput.js"];
|
: ["dist/cli.js", "dist/cliOutput.js", "dist/cli/streamedJsonOutput.js"];
|
||||||
|
|
||||||
if (!(await compiledRuntimeExists(runtimeFiles))) {
|
if (!(await compiledRuntimeExists(runtimeFiles))) {
|
||||||
@@ -42,7 +42,7 @@ if (!(await compiledRuntimeExists(runtimeFiles))) {
|
|||||||
);
|
);
|
||||||
process.exitCode = 1;
|
process.exitCode = 1;
|
||||||
} else if (isMcpMode) {
|
} else if (isMcpMode) {
|
||||||
const { runEntrypoint } = await import("../dist/mcp/main.js");
|
const { runEntrypoint } = await import("../dist/main.js");
|
||||||
await runEntrypoint();
|
await runEntrypoint();
|
||||||
} else if (isMcpDoctorMode) {
|
} else if (isMcpDoctorMode) {
|
||||||
const { runProductionMcpDoctorCli } = await import("../dist/mcpDoctor.js");
|
const { runProductionMcpDoctorCli } = await import("../dist/mcpDoctor.js");
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
import { globSync, readFileSync } from "node:fs";
|
import { readFileSync } from "node:fs";
|
||||||
|
import { globSync } from "node:fs";
|
||||||
import { relative, resolve } from "node:path";
|
import { relative, resolve } from "node:path";
|
||||||
|
|
||||||
const root = resolve(import.meta.dirname, "..");
|
const root = resolve(import.meta.dirname, "..");
|
||||||
|
|||||||
@@ -0,0 +1,481 @@
|
|||||||
|
// Run the website's browser scripts against a small document model, so missing
|
||||||
|
// page-owned messages are checked without a browser.
|
||||||
|
import assert from "node:assert/strict";
|
||||||
|
import { randomUUID } from "node:crypto";
|
||||||
|
import { test } from "node:test";
|
||||||
|
import { setImmediate as nextTurn } from "node:timers/promises";
|
||||||
|
import { pathToFileURL } from "node:url";
|
||||||
|
|
||||||
|
const ASSETS = new URL("../website/public/assets/", import.meta.url);
|
||||||
|
|
||||||
|
class Element {
|
||||||
|
constructor(tag, attributes = {}, children = [], text = "") {
|
||||||
|
this.tagName = tag.toUpperCase();
|
||||||
|
this.attributes = new Map(Object.entries(attributes));
|
||||||
|
this.children = [];
|
||||||
|
this.parent = null;
|
||||||
|
this.listeners = new Map();
|
||||||
|
this.ownText = text;
|
||||||
|
this.hidden = "hidden" in attributes;
|
||||||
|
this.disabled = "disabled" in attributes;
|
||||||
|
this.checked = "checked" in attributes;
|
||||||
|
this.value = attributes.value ?? "";
|
||||||
|
for (const child of children) this.append(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
append(child) {
|
||||||
|
child.parent = this;
|
||||||
|
this.children.push(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
get textContent() {
|
||||||
|
return (
|
||||||
|
this.ownText + this.children.map((child) => child.textContent).join("")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
set textContent(value) {
|
||||||
|
this.ownText = String(value);
|
||||||
|
this.children = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
get id() {
|
||||||
|
return this.getAttribute("id") ?? "";
|
||||||
|
}
|
||||||
|
|
||||||
|
get lang() {
|
||||||
|
return this.getAttribute("lang") ?? "";
|
||||||
|
}
|
||||||
|
|
||||||
|
get dataset() {
|
||||||
|
const values = {};
|
||||||
|
for (const [name, value] of this.attributes) {
|
||||||
|
if (!name.startsWith("data-")) continue;
|
||||||
|
const key = name
|
||||||
|
.slice(5)
|
||||||
|
.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
|
||||||
|
values[key] = value;
|
||||||
|
}
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
getAttribute(name) {
|
||||||
|
return this.attributes.has(name) ? this.attributes.get(name) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
setAttribute(name, value) {
|
||||||
|
this.attributes.set(name, String(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
removeAttribute(name) {
|
||||||
|
this.attributes.delete(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
addEventListener(type, listener) {
|
||||||
|
this.listeners.set(type, [...(this.listeners.get(type) ?? []), listener]);
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch(type, event = {}) {
|
||||||
|
for (const listener of this.listeners.get(type) ?? []) {
|
||||||
|
listener({ preventDefault() {}, repeat: false, ...event });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
click() {
|
||||||
|
this.dispatch("click");
|
||||||
|
}
|
||||||
|
|
||||||
|
focus() {}
|
||||||
|
|
||||||
|
descendants() {
|
||||||
|
return this.children.flatMap((child) => [child, ...child.descendants()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
matches(selector) {
|
||||||
|
return selector
|
||||||
|
.split(",")
|
||||||
|
.some((part) => matchesComplex(this, part.trim()));
|
||||||
|
}
|
||||||
|
|
||||||
|
closest(selector) {
|
||||||
|
for (let node = this; node !== null; node = node.parent) {
|
||||||
|
if (node.matches(selector)) return node;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
querySelectorAll(selector) {
|
||||||
|
return this.descendants().filter((node) => node.matches(selector));
|
||||||
|
}
|
||||||
|
|
||||||
|
querySelector(selector) {
|
||||||
|
return this.querySelectorAll(selector)[0] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
getContext() {
|
||||||
|
return this.context ?? null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Supports the selector forms the website scripts use: tag, #id, .class and
|
||||||
|
// [attribute], [attribute="value"] or [attribute^="value"], joined by spaces.
|
||||||
|
function matchesCompound(node, compound) {
|
||||||
|
const pattern =
|
||||||
|
/^([a-z0-9]*)((?:#[\w-]+|\.[\w-]+|\[[\w-]+(?:\^?="[^"]*")?\])*)$/i;
|
||||||
|
const parsed = pattern.exec(compound);
|
||||||
|
if (parsed === null) throw new Error(`Unsupported selector: ${compound}`);
|
||||||
|
const [, tag, rest] = parsed;
|
||||||
|
if (tag && node.tagName !== tag.toUpperCase()) return false;
|
||||||
|
for (const [, id, className, name, operator, value] of rest.matchAll(
|
||||||
|
/#([\w-]+)|\.([\w-]+)|\[([\w-]+)(?:(\^?=)"([^"]*)")?\]/g,
|
||||||
|
)) {
|
||||||
|
if (id !== undefined) {
|
||||||
|
if (node.id !== id) return false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (className !== undefined) {
|
||||||
|
const classes = (node.getAttribute("class") ?? "").split(/\s+/);
|
||||||
|
if (!classes.includes(className)) return false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const actual = node.getAttribute(name);
|
||||||
|
if (actual === null) return false;
|
||||||
|
if (operator === "=" && actual !== value) return false;
|
||||||
|
if (operator === "^=" && !actual.startsWith(value)) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function matchesComplex(node, selector) {
|
||||||
|
const parts = selector.split(/\s+/);
|
||||||
|
if (!matchesCompound(node, parts.at(-1))) return false;
|
||||||
|
let ancestor = node.parent;
|
||||||
|
for (const part of parts.slice(0, -1).reverse()) {
|
||||||
|
while (ancestor !== null && !matchesCompound(ancestor, part))
|
||||||
|
ancestor = ancestor.parent;
|
||||||
|
if (ancestor === null) return false;
|
||||||
|
ancestor = ancestor.parent;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const h = (tag, attributes, ...children) => {
|
||||||
|
const text = children.filter((child) => typeof child === "string").join("");
|
||||||
|
return new Element(
|
||||||
|
tag,
|
||||||
|
attributes ?? {},
|
||||||
|
children.filter((child) => child instanceof Element),
|
||||||
|
text,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Install a fresh document and browser globals, then run one script.
|
||||||
|
async function run(
|
||||||
|
script,
|
||||||
|
body,
|
||||||
|
{ lang = "en", clipboard = "resolve", stars = 1234 } = {},
|
||||||
|
) {
|
||||||
|
const root = h("html", { lang }, h("body", {}, ...body));
|
||||||
|
const timers = [];
|
||||||
|
const written = [];
|
||||||
|
const canvasText = [];
|
||||||
|
for (const canvas of root.querySelectorAll("canvas")) {
|
||||||
|
canvas.context = new Proxy(
|
||||||
|
{ fillText: (text) => canvasText.push(text) },
|
||||||
|
{ get: (target, name) => target[name] ?? (() => {}), set: () => true },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const document = {
|
||||||
|
documentElement: root,
|
||||||
|
hidden: false,
|
||||||
|
getElementById: (id) =>
|
||||||
|
root.descendants().find((node) => node.id === id) ?? null,
|
||||||
|
querySelector: (selector) => root.querySelector(selector),
|
||||||
|
querySelectorAll: (selector) => root.querySelectorAll(selector),
|
||||||
|
createRange: () => ({ selectNodeContents() {} }),
|
||||||
|
addEventListener() {},
|
||||||
|
};
|
||||||
|
const window = {
|
||||||
|
scrollY: 0,
|
||||||
|
innerHeight: 900,
|
||||||
|
location: { hash: "" },
|
||||||
|
addEventListener() {},
|
||||||
|
getSelection: () => ({ removeAllRanges() {}, addRange() {} }),
|
||||||
|
matchMedia: () => ({ matches: false, addEventListener() {} }),
|
||||||
|
requestAnimationFrame: () => 1,
|
||||||
|
scrollTo() {},
|
||||||
|
setTimeout: (callback) => timers.push(callback),
|
||||||
|
};
|
||||||
|
Object.assign(globalThis, {
|
||||||
|
document,
|
||||||
|
window,
|
||||||
|
requestAnimationFrame: () => 1,
|
||||||
|
cancelAnimationFrame() {},
|
||||||
|
Path2D: class {},
|
||||||
|
fetch: async () => ({
|
||||||
|
ok: true,
|
||||||
|
json: async () => ({ stargazers_count: stars }),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
Object.defineProperty(globalThis, "navigator", {
|
||||||
|
configurable: true,
|
||||||
|
value: {
|
||||||
|
clipboard: {
|
||||||
|
writeText: async (text) => {
|
||||||
|
if (clipboard === "reject") throw new Error("denied");
|
||||||
|
written.push(text);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
await import(
|
||||||
|
`${pathToFileURL(new URL(script, ASSETS).pathname)}?load=${randomUUID()}`
|
||||||
|
);
|
||||||
|
await nextTurn();
|
||||||
|
return { root, timers, written, canvasText };
|
||||||
|
}
|
||||||
|
|
||||||
|
const copyBlock = () => [
|
||||||
|
h("button", { "data-copy": "command" }, "Copy"),
|
||||||
|
h("pre", {}, h("code", { id: "command" }, "npx rea-agents setup")),
|
||||||
|
];
|
||||||
|
const copyStatus = (messages = {}) =>
|
||||||
|
h("p", {
|
||||||
|
id: "copy-status",
|
||||||
|
...Object.fromEntries(
|
||||||
|
Object.entries(messages).map(([key, value]) => [`data-${key}`, value]),
|
||||||
|
),
|
||||||
|
});
|
||||||
|
const englishCopyMessages = {
|
||||||
|
copied: "Copied",
|
||||||
|
selected: "Selected",
|
||||||
|
"status-copied": "Code copied to clipboard.",
|
||||||
|
"status-selected": "Code selected. Use your keyboard to copy it.",
|
||||||
|
};
|
||||||
|
|
||||||
|
test("copy buttons report and restore localized labels", async () => {
|
||||||
|
const { root, timers, written } = await run("main.js", [
|
||||||
|
...copyBlock(),
|
||||||
|
copyStatus(englishCopyMessages),
|
||||||
|
]);
|
||||||
|
const button = root.querySelector("[data-copy]");
|
||||||
|
button.click();
|
||||||
|
await nextTurn();
|
||||||
|
assert.deepEqual(written, ["npx rea-agents setup"]);
|
||||||
|
assert.equal(button.textContent, "Copied");
|
||||||
|
assert.equal(
|
||||||
|
root.querySelector("#copy-status").textContent,
|
||||||
|
"Code copied to clipboard.",
|
||||||
|
);
|
||||||
|
timers.forEach((callback) => callback());
|
||||||
|
assert.equal(button.textContent, "Copy");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("copy buttons keep their label when messages are missing", async () => {
|
||||||
|
for (const [body, clipboard] of [
|
||||||
|
[[...copyBlock(), copyStatus()], "resolve"],
|
||||||
|
[[...copyBlock(), copyStatus()], "reject"],
|
||||||
|
[
|
||||||
|
[...copyBlock(), copyStatus({ copied: "", "status-copied": "" })],
|
||||||
|
"resolve",
|
||||||
|
],
|
||||||
|
[copyBlock(), "resolve"],
|
||||||
|
]) {
|
||||||
|
const { root, timers, written } = await run("main.js", body, { clipboard });
|
||||||
|
const button = root.querySelector("[data-copy]");
|
||||||
|
button.click();
|
||||||
|
await nextTurn();
|
||||||
|
assert.equal(written.length, clipboard === "resolve" ? 1 : 0);
|
||||||
|
assert.equal(button.textContent, "Copy");
|
||||||
|
assert.equal(root.querySelector("#copy-status")?.textContent ?? "", "");
|
||||||
|
timers.forEach((callback) => callback());
|
||||||
|
assert.equal(button.textContent, "Copy");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const githubLink = (labels = {}) =>
|
||||||
|
h(
|
||||||
|
"a",
|
||||||
|
{
|
||||||
|
class: "nav-github",
|
||||||
|
"aria-label": "REA on GitHub",
|
||||||
|
title: "REA on GitHub",
|
||||||
|
...labels,
|
||||||
|
},
|
||||||
|
h("span", { class: "nav-github-count", hidden: "" }),
|
||||||
|
);
|
||||||
|
|
||||||
|
test("the star label follows the page language and plural rules", async () => {
|
||||||
|
const labels = {
|
||||||
|
"data-label-one": "REA on GitHub ({count} star)",
|
||||||
|
"data-label-other": "REA on GitHub ({count} stars)",
|
||||||
|
};
|
||||||
|
for (const [stars, lang, expected] of [
|
||||||
|
[1, "en", "REA on GitHub (1 star)"],
|
||||||
|
[1234, "en", "REA on GitHub (1,234 stars)"],
|
||||||
|
[1234, "de", "REA on GitHub (1.234 stars)"],
|
||||||
|
]) {
|
||||||
|
const { root } = await run("main.js", [githubLink(labels)], {
|
||||||
|
stars,
|
||||||
|
lang,
|
||||||
|
});
|
||||||
|
await nextTurn();
|
||||||
|
assert.equal(
|
||||||
|
root.querySelector(".nav-github").getAttribute("aria-label"),
|
||||||
|
expected,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// Languages without a "one" category use the "other" label.
|
||||||
|
const { root } = await run(
|
||||||
|
"main.js",
|
||||||
|
[githubLink({ "data-label-other": "{count}" })],
|
||||||
|
{ stars: 1, lang: "ja" },
|
||||||
|
);
|
||||||
|
await nextTurn();
|
||||||
|
assert.equal(
|
||||||
|
root.querySelector(".nav-github").getAttribute("aria-label"),
|
||||||
|
"1",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("the star label stays unchanged without a localized label", async () => {
|
||||||
|
const { root } = await run("main.js", [githubLink()], { stars: 1 });
|
||||||
|
await nextTurn();
|
||||||
|
const link = root.querySelector(".nav-github");
|
||||||
|
assert.equal(link.getAttribute("aria-label"), "REA on GitHub");
|
||||||
|
assert.equal(link.getAttribute("title"), "REA on GitHub");
|
||||||
|
assert.equal(link.querySelector(".nav-github-count").hidden, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
const percentDemo = (messages) =>
|
||||||
|
h(
|
||||||
|
"figure",
|
||||||
|
{ "data-percent-demo": "", ...messages },
|
||||||
|
h(
|
||||||
|
"div",
|
||||||
|
{ class: "percent-operation", hidden: "" },
|
||||||
|
h(
|
||||||
|
"button",
|
||||||
|
{ "data-percent-operation": "add", "aria-pressed": "true" },
|
||||||
|
"200 + 10%",
|
||||||
|
),
|
||||||
|
h(
|
||||||
|
"button",
|
||||||
|
{ "data-percent-operation": "multiply", "aria-pressed": "false" },
|
||||||
|
"200 × 10%",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
h("span", { "data-percent-expression": "" }, "200 +"),
|
||||||
|
h("strong", { "data-percent-display": "" }, "20"),
|
||||||
|
h(
|
||||||
|
"div",
|
||||||
|
{ class: "percent-controls", hidden: "" },
|
||||||
|
h("button", { "data-percent-key": "percent" }, "%"),
|
||||||
|
h("button", { "data-percent-key": "equals", disabled: "" }, "="),
|
||||||
|
h("button", { "data-percent-key": "reset" }, "Reset"),
|
||||||
|
),
|
||||||
|
h(
|
||||||
|
"p",
|
||||||
|
{ "data-percent-status": "" },
|
||||||
|
"10% of 200 = 20. Then 200 + 20 = 220.",
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
test("the percent demo uses page messages and keeps text when one is missing", async () => {
|
||||||
|
const { root } = await run("home.js", [
|
||||||
|
percentDemo({
|
||||||
|
"data-msg-input": "Press % to see what happens to 10.",
|
||||||
|
"data-msg-result": "200 {operator} {percent} = {result}.",
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
const status = root.querySelector("[data-percent-status]");
|
||||||
|
const key = (name) =>
|
||||||
|
root.querySelector(`[data-percent-key="${name}"]`).click();
|
||||||
|
assert.equal(status.textContent, "Press % to see what happens to 10.");
|
||||||
|
key("percent");
|
||||||
|
assert.equal(status.textContent, "Press % to see what happens to 10.");
|
||||||
|
key("equals");
|
||||||
|
assert.equal(status.textContent, "200 + 20 = 220.");
|
||||||
|
|
||||||
|
const bare = await run("home.js", [percentDemo({})]);
|
||||||
|
const bareStatus = bare.root.querySelector("[data-percent-status]");
|
||||||
|
for (const name of ["percent", "equals", "reset"]) {
|
||||||
|
bare.root.querySelector(`[data-percent-key="${name}"]`).click();
|
||||||
|
assert.equal(
|
||||||
|
bareStatus.textContent,
|
||||||
|
"10% of 200 = 20. Then 200 + 20 = 220.",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const dinoDemo = (messages) =>
|
||||||
|
h(
|
||||||
|
"figure",
|
||||||
|
{ "data-dino-demo": "", ...messages },
|
||||||
|
h("svg", { class: "dino-fallback" }),
|
||||||
|
h("canvas", { hidden: "" }),
|
||||||
|
h(
|
||||||
|
"div",
|
||||||
|
{ class: "dino-controls", hidden: "" },
|
||||||
|
h("button", { "data-dino-start": "" }, "Play"),
|
||||||
|
h("button", { "data-dino-jump": "" }, "Jump ↑"),
|
||||||
|
h("button", { "data-dino-reset": "" }, "Restart"),
|
||||||
|
h("output", { "data-dino-speed": "" }, "6.0"),
|
||||||
|
h("input", { "data-dino-slider": "", value: "6" }),
|
||||||
|
h("input", { "data-dino-auto": "", checked: "" }),
|
||||||
|
),
|
||||||
|
h(
|
||||||
|
"p",
|
||||||
|
{ "data-dino-status": "" },
|
||||||
|
"Original rule: start at 6, then increase toward 13.",
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
test("the dinosaur game never shows a missing message", async () => {
|
||||||
|
const { root, canvasText } = await run("dino-demo.js", [
|
||||||
|
dinoDemo({}),
|
||||||
|
h("button", { "data-speed-check": "", hidden: "" }, "Replay"),
|
||||||
|
h("p", { "data-speed-check-status": "" }, "Not replayed yet."),
|
||||||
|
]);
|
||||||
|
const start = root.querySelector("[data-dino-start]");
|
||||||
|
const status = root.querySelector("[data-dino-status]");
|
||||||
|
const slider = root.querySelector("[data-dino-slider]");
|
||||||
|
start.click();
|
||||||
|
start.click();
|
||||||
|
slider.value = "9.5";
|
||||||
|
slider.dispatch("input");
|
||||||
|
root.querySelector("[data-dino-reset]").click();
|
||||||
|
assert.equal(start.textContent, "Play");
|
||||||
|
assert.equal(
|
||||||
|
status.textContent,
|
||||||
|
"Original rule: start at 6, then increase toward 13.",
|
||||||
|
);
|
||||||
|
assert.deepEqual(canvasText, []);
|
||||||
|
root.querySelector("[data-speed-check]").click();
|
||||||
|
assert.equal(
|
||||||
|
root.querySelector("[data-speed-check-status]").textContent,
|
||||||
|
"Not replayed yet.",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("the dinosaur game fills placeholders from page messages", async () => {
|
||||||
|
const { root, canvasText } = await run("dino-demo.js", [
|
||||||
|
dinoDemo({
|
||||||
|
"data-msg-pause": "Pause",
|
||||||
|
"data-msg-fixed-running":
|
||||||
|
"Fixed speed: {speed}. Space or Jump clears a cactus.",
|
||||||
|
"data-msg-distance": "DISTANCE {distance}",
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
const start = root.querySelector("[data-dino-start]");
|
||||||
|
const slider = root.querySelector("[data-dino-slider]");
|
||||||
|
start.click();
|
||||||
|
assert.equal(start.textContent, "Pause");
|
||||||
|
slider.value = "9.5";
|
||||||
|
slider.dispatch("input");
|
||||||
|
assert.equal(
|
||||||
|
root.querySelector("[data-dino-status]").textContent,
|
||||||
|
"Fixed speed: 9.5. Space or Jump clears a cactus.",
|
||||||
|
);
|
||||||
|
assert.ok(canvasText.includes("DISTANCE 0000"));
|
||||||
|
});
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user