[tools] Support current and legacy assembly stores - #12104
Conversation
Teach the assembly store reader to locate CoreCLR stores through the exported _assembly_store symbol while retaining the MonoVM payload-section fallback. Reuse the modern reader from decompress-assemblies without dropping legacy store support. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 55493571-86e2-4326-850e-ea55883aa5d8
There was a problem hiding this comment.
Pull request overview
This PR updates the inspection/decompression tooling to support the current CoreCLR assembly-store layout by locating the store via the exported _assembly_store ELF symbol (with a fallback to the legacy payload section), and wires that into decompress-assemblies so it can correctly extract assemblies from modern APK/AAB layouts under lib/{ABI}/libassembly-store.so. It also factors the v2 reader into a reusable library and ensures decompression failures propagate via the tool exit code.
Changes:
- Add ELF
_assembly_storesymbol lookup (withpayloadsection fallback) to the mk2 assembly-store reader. - Split the mk2 reader into a reusable
AssemblyStorelibrary and consume it from both the mk2 CLI anddecompress-assemblies. - Update
decompress-assembliesto handle both legacyassemblies/assemblies.bloband currentlib/{ABI}/libassembly-store.sostores, and to return non-zero on failures.
Show a summary per file
| File | Description |
|---|---|
| tools/decompress-assemblies/main.cs | Adds support for extracting from current lib/{ABI}/libassembly-store.so stores (plus better failure propagation), while keeping legacy store and individual-entry paths. |
| tools/decompress-assemblies/decompress-assemblies.csproj | Adds a project reference (with alias) to the mk2 AssemblyStore library and the Android SDK tools dependency needed for ABI/arch handling. |
| tools/assembly-store-reader-mk2/Main.cs | Removes redundant file-format/existence checks now handled by AssemblyStoreExplorer.Open. |
| tools/assembly-store-reader-mk2/Directory.Build.targets | Copies the launch script only for executable builds and makes the script path resolution robust via $(MSBuildThisFileDirectory). |
| tools/assembly-store-reader-mk2/AssemblyStore/Utils.cs | Implements _assembly_store dynamic symbol-based payload discovery with fallback to payload section scanning. |
| tools/assembly-store-reader-mk2/AssemblyStore/StoreReader_V2.cs | Uses the new ELF payload discovery API and improves the error message for invalid _assembly_store symbols. |
| tools/assembly-store-reader-mk2/AssemblyStore/ELFPayloadError.cs | Adds an error value for invalid payload symbols. |
| tools/assembly-store-reader-mk2/AssemblyStore/AssemblyStoreItem.cs | Makes AssemblyStoreItem public to support external consumers. |
| tools/assembly-store-reader-mk2/AssemblyStore/AssemblyStoreExplorer.cs | Makes AssemblyStoreExplorer public and updates the “no entries found” error message. |
| tools/assembly-store-reader-mk2/AssemblyStore/AssemblyStore.csproj | Introduces a dedicated reusable library project for the mk2 reader implementation. |
| tools/assembly-store-reader-mk2/assembly-store-reader.csproj | Switches the CLI to consume the new library project instead of compiling the sources directly. |
Copilot's findings
- Files reviewed: 11/11 changed files
- Comments generated: 0
|
/review |
|
✅ Android PR Reviewer completed successfully! |
There was a problem hiding this comment.
⚠️ Needs Changes
Nice, well-structured follow-up that revives decompress-assemblies for symbol-based (libassembly-store.so) stores while preserving the legacy assemblies.blob and individual-entry paths, plus threading failures through the exit code. The ELF _assembly_store symbol resolution with a payload-section fallback is clean, and the 32/64-bit bounds checks are careful.
Issues (see inline comments):
⚠️ 1 error-handling:GetAndroidAbican throwNotSupportedExceptionforNone/Mips/Otherarchs (which pass theHasValueguard), crashing the tool instead of propagating a non-zero exit code — the opposite of one of this PR's goals.- 💡 2 suggestions: arch→ABI mapping duplicates
MonoAndroidHelper; and a diagnostic log for the zero-size symbol fallback.
Verification notes:
- CI is still pending on the head commit — not green yet, so not mergeable until checks pass.
- The retained
FindELFPayloadSectionOffsetAndSizewrapper is correctly kept for its build-task/test caller (ArchiveAssemblyHelper.cs), which now transparently gains symbol-based resolution. - Re: the PR's open question about deleting
decompress-assemblies— that's a reasonable call for maintainers; nothing in this diff blocks either decision.
No blocking correctness issues beyond the unhandled-exception path above.
Generated by Android PR Reviewer for #12104 · 112.5 AIC · ⌖ 18.8 AIC · ⊞ 6.8K
Comment /review to run again
Unify the legacy v1 parser with the modern reader, recognize v2 and v3 store layouts and archive names, and decode both XALZ/LZ4 and XAZS/Zstd assemblies. Add a standalone compatibility matrix and run it in CI. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 55493571-86e2-4326-850e-ea55883aa5d8
Use MonoAndroidHelper as the ABI source of truth, report unsupported store architectures without throwing, and log when zero-sized ELF symbols fall back to the containing section size. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 55493571-86e2-4326-850e-ea55883aa5d8
Keep the file-app project removals while incorporating the shared ELF symbol diagnostic changes from the compatibility branch. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 55493571-86e2-4326-850e-ea55883aa5d8
|
@copilot resolve the merge conflicts in this pull request |
Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
Resolved in |
|
/review |
|
✅ Android PR Reviewer completed successfully! |
There was a problem hiding this comment.
🤖 Code review — ⚠️ minor suggestions
Reviewed the assembly-store tooling changes that add current/legacy store support, _assembly_store ELF-symbol detection, unified LZ4/Zstd decompression (AssemblyCompression), and per-arch v1 store reconstruction.
Assessment
Overall this is a solid, well-structured refactor. Highlights:
ReadEntryImageDatanow guards against short reads (nread == 0→EndOfStreamException) and returns pooled buffers infinally— a real robustness improvement over the previous unbounded loop.- V2 index parsing correctly distinguishes v2 (no
ignorebyte) from v3/v4 entry sizes, avoiding a mis-parse of the trailing byte. - Decompression logic is consolidated into
AssemblyCompressionand reused bytmt,decompress-assemblies, and the mk2 reader, eliminating three near-identical Zstd copies. - Good test coverage: both compression formats, v1 store sets/manifests/APK, and v2/v3 archive names & index layouts.
Comments (all 💡 suggestions, none blocking)
UncompressIfNeededthrowsNotSupportedExceptionfor all uncompress requests on the stable (non-net11) TFM, even for uncompressed entries — consider passing uncompressed data through instead.OpenV1fallback runs while theZipArchivehandle is still open on the same file — possible Windows sharing violation; scope theusingnarrower.uncompressedLengthfrom an untrusted header drives a poolRentup to ~2 GB before validation.
CI
No pipeline checks are reported yet on the head commit (status: pending). Not a blocker for this review — please confirm the Windows compatibility-test leg (added in build-windows-steps.yaml) goes green before merge.
Nice work overall.
Generated by Android PR Reviewer for #12104 · 156.2 AIC · ⌖ 12 AIC · ⊞ 6.8K
Comment /review to run again
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: fe34b69d-7bab-4dd6-904d-dab51648046a
Allow stable-target consumers to request decompression for uncompressed entries, cap decompressed assembly allocations, and release modern archive handles before falling back to the legacy reader. Add stable-target and malformed-header coverage. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: fe34b69d-7bab-4dd6-904d-dab51648046a
## Summary - replace the standalone assembly-store reader and decompressor executable projects with .NET file-based apps owned by repository skills - expand `read-assembly-store` to invoke its bundled app directly - add an `extract-android-assemblies` skill for customer APK/AAB investigation and decompilation preparation - remove the obsolete legacy reader project, launch wrappers, and solution entries while retaining the shared compatibility parser - build both file apps in CI ## Stack This PR is stacked on #12104, which provides the shared v1/v2/v3 and LZ4/Zstd compatibility layer. Review this PR as the single commit on top of that branch. It can be retargeted to `main` after #12104 merges. ## File apps ```text dotnet run --file .github/skills/read-assembly-store/scripts/read-assembly-store.cs -- <input> dotnet run --file .github/skills/extract-android-assemblies/scripts/extract-android-assemblies.cs -- --output <directory> <input> ``` The extractor handles: - APK, AAB, raw store, manifest, store base-name, and DLL inputs - legacy and current assembly stores - raw, ELF `payload`, and `_assembly_store` wrappers - historical and current individually packaged assemblies - LZ4 and Zstd compression - multiple ABIs and satellite assemblies Customer inputs remain local. Extraction rejects path traversal, output-name collisions, and overwrites. ## Validation - both skills pass `skill-creator` validation and package successfully - both file apps build and run through their CI commands - shared parser builds for .NET 10 and .NET 11 - 10 assembly-store compatibility tests pass - byte-for-byte extraction exercised for: - current store APKs - standalone stores - ELF-wrapped individual assemblies - current and historical satellite names - modern loose individual assemblies Co-authored-by: Jonathan Peppers <jonathan.peppers@microsoft.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Summary
_assembly_storeELF symbol while retaining the MonoVMpayloadsection fallbackXALZ/LZ4 andXAZS/Zstd compressed assembliesdecompress-assemblieswithout dropping direct DLL or individual-entry handlingThis follows up on #12033 (comment).
Compatibility
The reader now detects the archive layout, ELF wrapper, store format, and compression format independently:
assemblies/assemblies.blob;libassemblies.{abi}.blob.so;libassembly-store.sopayloadsection; exported_assembly_storesymbolXALZ/LZ4;XAZS/ZstdLegacy common assemblies are included in each ABI-specific view, matching the original store-set behavior.
Follow-up
A separate stacked PR will simplify the standalone tool projects into .NET file-based apps and introduce skills that invoke them for customer APK inspection and extraction. The shared compatibility parser remains in the repository because build/device tests and external projects consume or track it.
Validation
tmt