[r8-obfuscation] Rewrite managed JNI metadata from R8 mappings - #12630
Merged
Conversation
simonrozsival
force-pushed
the
simonrozsival-managed-jni-assembly-rewriting
branch
from
September 1, 2026 15:01
1f696cc to
6dfe6ef
Compare
simonrozsival
force-pushed
the
simonrozsival-managed-jni-assembly-rewriting
branch
from
September 1, 2026 16:11
c8bda30 to
8d1ab29
Compare
simonrozsival
force-pushed
the
simonrozsival-managed-jni-assembly-rewriting
branch
from
September 1, 2026 19:04
8d1ab29 to
f71004c
Compare
simonrozsival
force-pushed
the
simonrozsival-managed-jni-assembly-rewriting
branch
from
September 2, 2026 08:47
f71004c to
fdc7bb8
Compare
simonrozsival
force-pushed
the
simonrozsival-managed-jni-assembly-rewriting
branch
from
September 2, 2026 08:55
fdc7bb8 to
8ce0811
Compare
Member
Author
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
Member
Author
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
simonrozsival
force-pushed
the
simonrozsival-managed-jni-assembly-rewriting
branch
4 times, most recently
from
September 2, 2026 12:11
11dbd9b to
8652697
Compare
simonrozsival
marked this pull request as ready for review
September 2, 2026 14:51
Contributor
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
There are a couple of correctness issues in newly added code paths (custom-attribute prolog validation and Windows-safe in-place path detection) that should be addressed before merge.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review tier: Lite
Findings: 3
New issues introduced by this change (3)
| Severity | Finding |
|---|---|
src/Xamarin.Android.Build.Tasks/Tasks/RewriteJniNamesForR8.cs — ❌ error — The in-place detection compares full paths using Ordinal, which can mis-detect the same… |
|
src/Xamarin.Android.Build.Tasks/Utilities/JniRemapping/CustomAttributeStringRewriter.cs — ❌ error — Custom attribute blobs must start with the ECMA-335 0x0001 prolog; this currently only… |
|
src/Xamarin.Android.Build.Tasks/Utilities/JniRemapping/JniRewritePlanner.cs — |
What changed in this PR
This PR adds the “layer 3” managed-side machinery needed to rewrite JNI-bearing managed metadata/IL strings based on an R8 mapping.txt, enabling opt-in R8 obfuscation while keeping managed ↔ Java/JNI references consistent.
Changes:
- Introduces a PE/metadata scan + rewrite plan (
JniRewritePlanner) and an assembly rewrite façade (JniAssemblyRewriter) to update Register/Jni*Signature attributes and relevantldstrstrings. - Adds an MSBuild task (
RewriteJniNamesForR8) that rewrites/copies assemblies (and adjacent PDBs) and emits a manifest of mapping entries consumed. - Adds XA4325/XA4326 resources + documentation, and extensive end-to-end tests for rewriting behavior and invariants (tokens, resources, debug directory, strong-name flag handling).
| File | Description |
|---|---|
| src/Xamarin.Android.Build.Tasks/Utilities/JniRemapping/JniRewritePlanner.cs | Scans metadata + IL to produce a deterministic rewrite plan and emits XA4326 warnings for unsafe legacy lookup rewrites. |
| src/Xamarin.Android.Build.Tasks/Utilities/JniRemapping/JniAssemblyRewriter.cs | Orchestrates planning + full assembly reconstruction using the existing rebuild substrate. |
| src/Xamarin.Android.Build.Tasks/Utilities/JniRemapping/CustomAttributeStringRewriter.cs | Low-level blob rewriter for fixed string args in custom attribute value blobs. |
| src/Xamarin.Android.Build.Tasks/Tasks/RewriteJniNamesForR8.cs | MSBuild task to apply rewrites across files, copy PDBs, and write a rewrite manifest; introduces XA4325 error surface. |
| src/Xamarin.Android.Build.Tasks/Properties/Resources.resx | Adds XA4325/XA4326 message resources. |
| src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs | Resource designer updates for XA4325/XA4326. |
| src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/JniRemapping/JniAssemblyRewriterTests.cs | End-to-end validation of metadata/IL rewrites and PE invariants. |
| src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/RewriteJniNamesForR8Tests.cs | Task-level tests for copy/rewrite behaviors and error handling. |
| Documentation/docs-mobile/TOC.yml | Adds TOC entries for XA4325/XA4326 docs. |
| Documentation/docs-mobile/messages/xa4325.md | Documents XA4325 error cases and guidance. |
| Documentation/docs-mobile/messages/xa4326.md | Documents XA4326 warning and guidance. |
| Documentation/docs-mobile/messages/index.md | Adds XA4325/XA4326 to the message index. |
Files not reviewed (1)
- src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs: Generated file
simonrozsival
force-pushed
the
simonrozsival-managed-jni-assembly-rewriting
branch
from
September 2, 2026 15:16
8652697 to
40e20ca
Compare
Base automatically changed from
simonrozsival-pe-metadata-rebuild-substrate
to
main
September 3, 2026 05:00
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Replace the ad-hoc RJN0000/RJN0001 error codes and their hard-coded English strings with a single documented, localizable XA4325 product code. The task prefix stays "RJN" so unexpected exceptions keep reporting as XARJN7xxx, consistent with other task-specific prefixes; only the two explicit errors change. The user-visible detail is resource-backed as well: XA4325 is a general wrapper and the two specific failures live in XA4325_SourceDestinationCount and XA4325_AssemblyFailure, so no new English fragments are formatted into the message from code. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Associate legacy JNI member lookups with proven FindClass/Get*ID sequences, remove stale copied PDBs, and keep task outputs empty after rewrite failures. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Preserve managed constructor spellings, resolve cached static JNI class handles through proven FindClass assignments, warn on unsafe renamed lookup sources, and skip identity string rewrites. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Use platform-aware path identity for in-place rewrites, validate custom attribute prologs, and diagnose unsafe member-only mappings without polluting rewrite manifests or reverse scans. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
simonrozsival
force-pushed
the
simonrozsival-managed-jni-assembly-rewriting
branch
from
September 3, 2026 05:00
8704a94 to
7fbf20a
Compare
rolfbjarne
approved these changes
Sep 3, 2026
simonrozsival
deleted the
simonrozsival-managed-jni-assembly-rewriting
branch
September 3, 2026 16:37
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Related to #12535
Depends on #12629
Layer 3 of 6 in the replacement stack for #12575.
This layer rewrites standard managed JNI metadata from R8 mappings. Trimmable typemap and FieldRVA handling follows in layer 4.