[PR #3807] [MERGED] feat(il2cpp): inventory Unity IL2CPP global-metadata images, types and methods #5913

Closed
opened 2026-10-31 01:10:23 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/3807
Author: @8rulerstar
Created: 10/15/2026
Status: ✅ Merged
Merged: 10/19/2026
Merged by: @gensokyo-dev

Base: main ← Head: feat/il2cpp-metadata


📝 Commits (10+)

  • b0c0372 feat(il2cpp): inventory IL2CPP global-metadata images, types and methods
  • 638205e feat(il2cpp): deliver metadata summaries by default over MCP
  • 561b065 fix(il2cpp): reject shifted strings, nesting cycles and method owner drift
  • 657629e feat(il2cpp): decode global-metadata versions 29 and 31
  • 9770165 fix(il2cpp): bound report size before serializing and tighten coverage
  • 9cb8483 fix(il2cpp): refuse oversized metadata before decoding rows
  • a7fd9b0 docs(il2cpp): attach the decoder comment to readIl2cppMetadata
  • dabd1c8 fix(il2cpp): deliver complete rows by default like the other inspection tools
  • ad883b6 test(il2cpp): cover narrow-width -1 sentinels and fix the skill's default
  • b0d7450 docs(il2cpp): request summary explicitly in the summary example

📊 Changes

51 files changed (+4666 additions, -116 deletions)

View changed files

📝 .agents/skills/reverse-engineer-anything/SKILL.md (+9 -0)
📝 .agents/skills/reverse-engineer-anything/references/native-and-artifacts.md (+15 -0)
📝 README.md (+1 -0)
📝 docs/.vitepress/config.ts (+1 -0)
📝 docs/cli.md (+18 -2)
📝 docs/desktop-applications.md (+5 -0)
➕ docs/il2cpp-metadata.md (+211 -0)
📝 docs/managed-code-analysis.md (+5 -3)
📝 package.json (+1 -0)
📝 scripts/lib/catalog-builders.mjs (+5 -0)
📝 scripts/lib/catalog-core.mjs (+2 -0)
📝 scripts/lib/module-boundaries.mjs (+1 -0)
➕ scripts/verify-il2cpp-metadata.mjs (+182 -0)
📝 src/application/CapabilityInventory.ts (+1 -0)
📝 src/application/EvidenceBundleFiles.ts (+2 -2)
📝 src/application/JsonFiles.ts (+8 -3)
➕ src/application/il2cpp/Il2cppMetadataPort.ts (+20 -0)
➕ src/application/il2cpp/Il2cppMetadataService.test.ts (+147 -0)
➕ src/application/il2cpp/Il2cppMetadataService.ts (+124 -0)
📝 src/artifacts/DesktopFileInspection.ts (+6 -22)

...and 31 more files

📄 Description

Outcome

Report the validated header magic/version and decode image, type and method names from a caller-selected Unity IL2CPP global-metadata.dat (versions 29, 31 and 39), without Unity or a native analysis engine. Preserves the original implementation and author history from this PR; follow-up commits add composable queries, bounded delivery and lifecycle fixes. Closes #3784.

  • MCP defaults to compact counts while retaining complete artifact-bound Evidence. Query sections/images/types/methods by stable source index, exact names, batch indices, owners, image or namespace; select fields and page filtered matches. Source indices remain distinct from page offsets, with provenance, coverage and unknowns preserved.
  • CLI defaults to complete Evidence. Compact CLI delivery requires an explicit new Evidence file and never overwrites it. Shared JSON readers/writers preserve filesystem path selection through symlink-parent traversal and directory requirements. Desktop discovery emits a supported-metadata follow-up even without a native library. CLI/MCP share inspection and view semantics.
  • One active inspection per reader; cooperative decoding, owned cancellation and awaited cleanup. Count UTF-8/JSON expansion before serialization and preserve completed source Evidence through descriptor-close failures and cancellation. Retained immutable facts share validation/counts without cloning another cached report.

Validation

Executed locally on Linux with pinned Node 24.18.0: npm run check, npm run docs:check, 100 focused tests across 12 files on 5f65d4adb, and the public CLI/MCP producer verifier. Earlier decoder/view/service/counter coverage passed 115 tests, plus 27 shared JSON-input/cancellation tests after integrating main 7a0c47bfa. Test discovery found every file exactly once. Actual stdio SDK tests validate advertised schemas after conversion and each output.

Real compiled CLI tests cover compact/default and complete delivery, retained reads after source removal, all four collections, filters/batches/fields, exclusive export, and POSIX symlink-parent export/readback with an unrelated decoy preserved. Controlled close faults on real files verify completed source Evidence, original cancellation reasons, retained descriptor ownership and Evidence after cleanup retry; failed reads fabricate no source facts. Codex review was unavailable because the repository review quota is exhausted. Greptile's export-selection and completed-source findings are corrected in this follow-up.

Public producer: Cpp2IL Simple_2022_3_35 at b5ad444, raw metadata v31, 1,892,268 bytes, SHA-256 2441635a7c234a1a34deccc6a9906d6f5abcbdab078a38b2bf488a52a4962c48. An independent raw-byte oracle matched every exposed field across 36 images / 2,468 types / 12,409 methods. Corresponding managed DLLs independently matched names and ownership for 35 images / 2,463 types / 12,406 methods; generated rows have no corresponding DLL and use the byte oracle. No target execution. Versions 29/39 have synthetic coverage here; the original author's five private Unity-build comparisons are historical evidence and were not repeated locally.

Measured task costs

Actual compiled stdio SDK task: find GameObject.SendMessage and Transform.GetChild in CoreModule, then retrieve both facts again after removing the owned input copy. Both paths assert equal facts, SHA and Evidence linkage. Baseline uses explicit summary and the smallest available range queries. Two alternating pairs, baseline original PR integrated at main b4938aed5, follow-up integrated at main 7a0c47bfa; concurrent main changes are included. Fresh processes, 2 CPUs, bounded heaps, compile caches disabled; OS caches and host load uncontrolled.

Cost Baseline 055b8787a Follow-up f8fce575f
Tool calls 7 5
Selected declarations + all calls/replies, tokenx estimate 96,743 22,137
All input declarations + calls/replies, tokenx estimate 314,912 240,306
Entire recorded JSON-RPC exchange, tokenx estimate 1,074,308 1,000,515
Whole task elapsed 4.71–4.84 s 4.60–4.66 s
Whole process-family CPU 5.89–6.06 s 5.77–5.78 s
Sampled peak process-family RSS 719–746 MiB 726–731 MiB

Includes discovery, schemas, protocol envelopes and output validation; build/install excluded. Actual model/host-rendered context tokens are unmeasured. Earlier pairs varied with host load; no consistent speed or memory improvement claimed. First source inspection/first retained view and warm retained queries are recorded separately; the final lookup succeeds without source access. The final header field is included in the measured schemas and replies.

After the boundary fixes and main bf1eeee94 integration, the complete five-call task passed again: 22,210 selected-declaration/call tokens, 240,379 all-input-declaration/call tokens, and 1,000,596 entire-protocol tokens (all tokenx estimates). One final run measured 6.69 s elapsed, 7.67 s process-family CPU and 713 MiB sampled peak RSS. The paired table pins its earlier revisions; this final correctness/cost probe includes the subsequent main changes and is not a speed comparison.

Scope and limitations

Repository-operator authorization covers this static metadata slice and ready-for-review follow-up. No execution, injection, decryption, protected recovery, native address linking or disassembler integration. Fields/signatures/runtime loading and correspondence to GameAssembly remain unknown. Input guard 256 MiB; encoded retained report guard 64 MiB, separate from MCP transport capacity. Optional CLI export writes only the caller-selected Evidence output.

The original author's initial readiness declaration is retained below; later pushes do not require another initial declaration. It is not an assertion of a new human review of these follow-ups.

Author readiness

Human owner: @8rulerstar

  • I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work.
  • I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps.
  • I declare this PR ready for initial maintainer review.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/3807 **Author:** [@8rulerstar](https://github.com/8rulerstar) **Created:** 10/15/2026 **Status:** ✅ Merged **Merged:** 10/19/2026 **Merged by:** [@gensokyo-dev](https://github.com/gensokyo-dev) **Base:** `main` ← **Head:** `feat/il2cpp-metadata` --- ### 📝 Commits (10+) - [`b0c0372`](https://github.com/morluto/rea/commit/b0c0372b57573d0270141550e0ae9b09051166ab) feat(il2cpp): inventory IL2CPP global-metadata images, types and methods - [`638205e`](https://github.com/morluto/rea/commit/638205e600c8bf0a779dd513563160cf0b620b38) feat(il2cpp): deliver metadata summaries by default over MCP - [`561b065`](https://github.com/morluto/rea/commit/561b065cf308604f0ace5fb0df39bc0e13dcc2cb) fix(il2cpp): reject shifted strings, nesting cycles and method owner drift - [`657629e`](https://github.com/morluto/rea/commit/657629eb8e15bb8b81e0cd91a406dcb8dd1f9997) feat(il2cpp): decode global-metadata versions 29 and 31 - [`9770165`](https://github.com/morluto/rea/commit/977016526eef0346c9b0b3f6f79dbd549e7470f1) fix(il2cpp): bound report size before serializing and tighten coverage - [`9cb8483`](https://github.com/morluto/rea/commit/9cb84832b46d95f5beac7d4d6407079b324f7ab8) fix(il2cpp): refuse oversized metadata before decoding rows - [`a7fd9b0`](https://github.com/morluto/rea/commit/a7fd9b0bae08b8835c926f4a185f9530107e8615) docs(il2cpp): attach the decoder comment to readIl2cppMetadata - [`dabd1c8`](https://github.com/morluto/rea/commit/dabd1c81fba715464b111bebaa0702d37d282eff) fix(il2cpp): deliver complete rows by default like the other inspection tools - [`ad883b6`](https://github.com/morluto/rea/commit/ad883b649eb034ba66109744e0f63abde91a4d1a) test(il2cpp): cover narrow-width -1 sentinels and fix the skill's default - [`b0d7450`](https://github.com/morluto/rea/commit/b0d7450c835824cef48e3d9b74534e675eda820a) docs(il2cpp): request summary explicitly in the summary example ### 📊 Changes **51 files changed** (+4666 additions, -116 deletions) <details> <summary>View changed files</summary> 📝 `.agents/skills/reverse-engineer-anything/SKILL.md` (+9 -0) 📝 `.agents/skills/reverse-engineer-anything/references/native-and-artifacts.md` (+15 -0) 📝 `README.md` (+1 -0) 📝 `docs/.vitepress/config.ts` (+1 -0) 📝 `docs/cli.md` (+18 -2) 📝 `docs/desktop-applications.md` (+5 -0) ➕ `docs/il2cpp-metadata.md` (+211 -0) 📝 `docs/managed-code-analysis.md` (+5 -3) 📝 `package.json` (+1 -0) 📝 `scripts/lib/catalog-builders.mjs` (+5 -0) 📝 `scripts/lib/catalog-core.mjs` (+2 -0) 📝 `scripts/lib/module-boundaries.mjs` (+1 -0) ➕ `scripts/verify-il2cpp-metadata.mjs` (+182 -0) 📝 `src/application/CapabilityInventory.ts` (+1 -0) 📝 `src/application/EvidenceBundleFiles.ts` (+2 -2) 📝 `src/application/JsonFiles.ts` (+8 -3) ➕ `src/application/il2cpp/Il2cppMetadataPort.ts` (+20 -0) ➕ `src/application/il2cpp/Il2cppMetadataService.test.ts` (+147 -0) ➕ `src/application/il2cpp/Il2cppMetadataService.ts` (+124 -0) 📝 `src/artifacts/DesktopFileInspection.ts` (+6 -22) _...and 31 more files_ </details> ### 📄 Description ## Outcome Report the validated header magic/version and decode image, type and method names from a caller-selected Unity IL2CPP `global-metadata.dat` (versions 29, 31 and 39), without Unity or a native analysis engine. Preserves the original implementation and author history from this PR; follow-up commits add composable queries, bounded delivery and lifecycle fixes. Closes #3784. - MCP defaults to compact counts while retaining complete artifact-bound Evidence. Query sections/images/types/methods by stable source index, exact names, batch indices, owners, image or namespace; select fields and page filtered matches. Source indices remain distinct from page offsets, with provenance, coverage and unknowns preserved. - CLI defaults to complete Evidence. Compact CLI delivery requires an explicit new Evidence file and never overwrites it. Shared JSON readers/writers preserve filesystem path selection through symlink-parent traversal and directory requirements. Desktop discovery emits a supported-metadata follow-up even without a native library. CLI/MCP share inspection and view semantics. - One active inspection per reader; cooperative decoding, owned cancellation and awaited cleanup. Count UTF-8/JSON expansion before serialization and preserve completed source Evidence through descriptor-close failures and cancellation. Retained immutable facts share validation/counts without cloning another cached report. ## Validation Executed locally on Linux with pinned Node 24.18.0: `npm run check`, `npm run docs:check`, 100 focused tests across 12 files on `5f65d4adb`, and the public CLI/MCP producer verifier. Earlier decoder/view/service/counter coverage passed 115 tests, plus 27 shared JSON-input/cancellation tests after integrating main `7a0c47bfa`. Test discovery found every file exactly once. Actual stdio SDK tests validate advertised schemas after conversion and each output. Real compiled CLI tests cover compact/default and complete delivery, retained reads after source removal, all four collections, filters/batches/fields, exclusive export, and POSIX symlink-parent export/readback with an unrelated decoy preserved. Controlled close faults on real files verify completed source Evidence, original cancellation reasons, retained descriptor ownership and Evidence after cleanup retry; failed reads fabricate no source facts. Codex review was unavailable because the repository review quota is exhausted. Greptile's export-selection and completed-source findings are corrected in this follow-up. Public producer: [Cpp2IL Simple_2022_3_35 at b5ad444](https://github.com/SamboyCoding/Cpp2IL/tree/b5ad444b82267cb1e4b88b8b373c008105bdea52/TestFiles/Simple_2022_3_35), raw metadata v31, 1,892,268 bytes, SHA-256 `2441635a7c234a1a34deccc6a9906d6f5abcbdab078a38b2bf488a52a4962c48`. An independent raw-byte oracle matched every exposed field across 36 images / 2,468 types / 12,409 methods. Corresponding managed DLLs independently matched names and ownership for 35 images / 2,463 types / 12,406 methods; generated rows have no corresponding DLL and use the byte oracle. No target execution. Versions 29/39 have synthetic coverage here; the original author's five private Unity-build comparisons are historical evidence and were not repeated locally. ## Measured task costs Actual compiled stdio SDK task: find `GameObject.SendMessage` and `Transform.GetChild` in CoreModule, then retrieve both facts again after removing the owned input copy. Both paths assert equal facts, SHA and Evidence linkage. Baseline uses explicit summary and the smallest available range queries. Two alternating pairs, baseline original PR integrated at main `b4938aed5`, follow-up integrated at main `7a0c47bfa`; concurrent main changes are included. Fresh processes, 2 CPUs, bounded heaps, compile caches disabled; OS caches and host load uncontrolled. | Cost | Baseline `055b8787a` | Follow-up `f8fce575f` | | --- | ---: | ---: | | Tool calls | 7 | 5 | | Selected declarations + all calls/replies, tokenx estimate | 96,743 | 22,137 | | All input declarations + calls/replies, tokenx estimate | 314,912 | 240,306 | | Entire recorded JSON-RPC exchange, tokenx estimate | 1,074,308 | 1,000,515 | | Whole task elapsed | 4.71–4.84 s | 4.60–4.66 s | | Whole process-family CPU | 5.89–6.06 s | 5.77–5.78 s | | Sampled peak process-family RSS | 719–746 MiB | 726–731 MiB | Includes discovery, schemas, protocol envelopes and output validation; build/install excluded. Actual model/host-rendered context tokens are unmeasured. Earlier pairs varied with host load; no consistent speed or memory improvement claimed. First source inspection/first retained view and warm retained queries are recorded separately; the final lookup succeeds without source access. The final header field is included in the measured schemas and replies. After the boundary fixes and main `bf1eeee94` integration, the complete five-call task passed again: 22,210 selected-declaration/call tokens, 240,379 all-input-declaration/call tokens, and 1,000,596 entire-protocol tokens (all tokenx estimates). One final run measured 6.69 s elapsed, 7.67 s process-family CPU and 713 MiB sampled peak RSS. The paired table pins its earlier revisions; this final correctness/cost probe includes the subsequent main changes and is not a speed comparison. ## Scope and limitations Repository-operator authorization covers this static metadata slice and ready-for-review follow-up. No execution, injection, decryption, protected recovery, native address linking or disassembler integration. Fields/signatures/runtime loading and correspondence to `GameAssembly` remain unknown. Input guard 256 MiB; encoded retained report guard 64 MiB, separate from MCP transport capacity. Optional CLI export writes only the caller-selected Evidence output. The original author's initial readiness declaration is retained below; later pushes do not require another initial declaration. It is not an assertion of a new human review of these follow-ups. ## Author readiness <!-- The human owner completes these declarations before requesting review. The PR author is the owner by default. A different owner must explicitly accept ownership on this PR. AI agents must leave these declarations to a human to dictate to them or there could be catastrophic consequences for many users of REA. Draft PRs may leave them unchecked. These declarations record initial readiness when opening the PR for review; later pushes do not require a new human sign-off. Keep the description and validation evidence current as the work changes. See CONTRIBUTING.md#pull-request-ownership-and-readiness. --> Human owner: @8rulerstar - [x] I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work. - [x] I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps. - [x] I declare this PR ready for initial maintainer review. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-31 01:10:23 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#5913
No description provided.