Skip to content

Let a patched app use Google sign-in and push through MicroG RE - #125

Closed
kuomartin wants to merge 6 commits into
JingMatrix:masterfrom
kuomartin:master
Closed

kuomartin wants to merge 6 commits into
JingMatrix:masterfrom
kuomartin:master

Conversation

@kuomartin

Copy link
Copy Markdown

Problem

A patched app is signed with LSPatch's key, so Google Play services refuses it wherever it checks the caller's certificate; Google sign-in fails with UNREGISTERED_ON_API_CONSOLE. MicroG RE (ReVanced GmsCore) can stand in for it, but only if the app's traffic reaches it and it knows the app's original certificate.

This supersedes #84, which no longer applies to master and cannot be edited by maintainers. The redirect is ported from NPatch's current version of that work; its authors are credited as co-authors.

Solution

An opt-in MicroG RE support option (--microg-re, also in the manager), recorded in the patch config so a re-patch keeps it.

Patch time — the manifest gets:

  • app.revanced.android.gms.SPOOFED_PACKAGE_SIGNATURE: the original certificate's SHA-1, which MicroG RE reports to Google instead of the caller's.
  • Every com.google.android.c2dm.* string renamed to app.revanced.android.c2dm.*. MicroG RE finds the push receiver by its own RECEIVE action, and the receiver only accepts senders holding com.google.android.c2dm.permission.SEND, a signature permission MicroG RE cannot hold. The manifest editor never descends into intent filters, so the rename is a separate pass over the AXML.

Run time — GmsRedirector rewrites the package, component, action and provider authority of GMS-bound intents and provider calls to MicroG RE, and maps C2DM actions both ways. CHOOSE_ACCOUNT goes to the system account picker; the chimera authority is left to Google Play services.

Differences from #84 and NPatch:

  • An intent the app addresses to itself keeps its action, including through readFromParcel: the sign-in library opens its own SignInHubActivity with GOOGLE_SIGN_IN, and that activity finishes on any other action.
  • No ContentResolver.call retry. It rewrote arguments after the call had returned and swallowed the SecurityException, so callers got null instead of an error.
  • No getPackageInfo hook. It reported the app's own certificate as MicroG's, which matches no check a GMS client makes.

Scope:

  • MicroG RE only. Upstream microG installs as Google Play services, needs no redirect, and would lose pushes to the rename. For it, --fake-signature declares fake-signature with FAKE_PACKAGE_SIGNATURE for a ROM with signature spoofing, as a separate option, also recorded in the patch config.
  • The loader redirects only if it can see MicroG RE, which the app's <queries> don't cover. Local mode already holds QUERY_ALL_PACKAGES; integrated mode needs it added through the added permissions. The option's description and the loader's log say so.

Validation

On a Pixel 10 (Android 17), ReVanced GmsCore installed beside Google Play services, local mode:

  • Google sign-in completes through MicroG RE, which reports the original certificate.
  • Push reaches the app's FCM service, and the app acknowledges it.
  • Rewrite rules (action redirect and restore, self-addressed intents, C2DM mapping) pass a JVM check outside the repo, which has no JUnit setup.
  • The patched manifest for --microg-re, --fake-signature and neither, in both modes, carries exactly the entries above.

Not covered: --fake-signature (no ROM with signature spoofing at hand).

kuomartin and others added 6 commits October 16, 2026 14:52
A patched app is signed with LSPatch's key, so Google Play services refuses it wherever it checks the caller's certificate, Google sign-in among them. The MicroG option redirects the app's GMS intents, provider calls and actions to an installed MicroG, and declares the original certificate in both forms MicroG builds read: fake-signature with FAKE_PACKAGE_SIGNATURE for a ROM with signature spoofing, and app.revanced.android.gms.SPOOFED_PACKAGE_SIGNATURE (the certificate's SHA-1) for ReVanced GmsCore. QUERY_ALL_PACKAGES lets the loader find MicroG, since the app's own queries name only Google Play services.

An intent the app addresses to itself keeps its action, including when it arrives through readFromParcel: the Google sign-in library opens its own SignInHubActivity with com.google.android.gms.auth.GOOGLE_SIGN_IN, and that activity finishes on any other action.

The option is recorded in the patch config, so a re-patch keeps it, and is offered in the manager and as --microg on the command line.

Co-Authored-By: NkBe <HSSkyBoy@outlook.com>
Co-Authored-By: MrZhongzq <108169409+mrzhongzq@users.noreply.github.com>
MicroG looks a patched app's push receiver up by its own RECEIVE action, and the receiver only accepts a sender holding com.google.android.c2dm.permission.SEND, a signature permission of Google Play services that MicroG cannot hold, so every push it delivered was dropped. With MicroG on, every com.google.android.c2dm.* string in the manifest -- intent-filter actions and permissions alike -- is renamed to ReVanced GmsCore's app.revanced.android.c2dm.*, the same rename Morphe applies; the manifest editor never descends into intent filters, so this is a pass of its own.

Two hooks carried over from NPatch are removed. The ContentResolver.call retry rewrote its arguments after the call had already returned and then swallowed the SecurityException, so callers got null instead of an error. The getPackageInfo hook reported the app's own certificate as MicroG's, which matches no check a GMS client makes.
…ts own

Everything the option does is specific to MicroG RE (ReVanced GmsCore): the SPOOFED_PACKAGE_SIGNATURE metadata, the app.revanced C2DM rename and the redirect to app.revanced.android.gms. Upstream microG installs as Google Play services itself, so it needs no redirect, and renaming its standard C2DM actions would stop its pushes. The option is now "MicroG RE support" (--microg-re), and the redirect no longer falls back to org.microg.gms, which the C2DM rename would leave without pushes.

fake-signature with FAKE_PACKAGE_SIGNATURE is the one declaration upstream microG can use, through a ROM with signature spoofing, so it becomes an option of its own (--fake-signature) rather than a side effect of MicroG RE support. Both are recorded in the patch config so a re-patch keeps them.
The loader has to see MicroG RE to start the redirect, and the app's own queries do not name it. Granting every package's visibility for that is broader than the option needs: a manager-mode app already holds QUERY_ALL_PACKAGES, and an integrated one can add it through the added permissions. The option's description and the loader's warning now say so.
Let a patched app use Google sign-in and push through MicroG RE
@JingMatrix

Copy link
Copy Markdown
Owner

Thanks, replaced by #127

@JingMatrix JingMatrix closed this Oct 23, 2026
JingMatrix added a commit that referenced this pull request Oct 23, 2026
A patched app is re-signed, so Google Play services refuses it wherever it
checks the caller's certificate -- most visibly at sign-in, which fails with
UNREGISTERED_ON_API_CONSOLE. A replacement answering the same APIs under its own
package can stand in, but only if the app's calls reach it and it knows which
certificate the app was originally signed with.

Nothing here names a vendor. A replacement is any package of the shape
<vendor>.android.gms, which carries Google's actions, provider authorities and
C2DM names into its own namespace -- so the whole rewrite follows from the one
package name, and the chosen name is what the patch records. The offers in the
manager are discovered on the device rather than listed, and a package that is
not among them can be typed.

Choosing one is three changes, not a flag, which is why the sheet says so before
the patch rather than after: GmsRedirector rewrites the package, component,
authority and action of GMS-bound intents and provider calls at run time; the
manifest's C2DM names are rewritten to that vendor for good, because the app's
push receiver only accepts a sender holding a signature permission of Google
Play services that no other build can hold; and the original certificate is
declared in the metadata the replacement reads.

Declaring that certificate for a ROM with signature spoofing to report is the
alternative, for a replacement that installs as Google Play services itself and
so needs no redirect at all. The two are alternatives rather than additions --
both declare the same certificate and differ only in who reads it -- so at most
one is chosen, and choosing neither changes nothing.

The redirect only arms itself if the app can see the chosen package, which its
own queries do not cover; a local-mode app already holds QUERY_ALL_PACKAGES, and
the manager offers to add it to an integrated one.

Supersedes #115 and #125. The run-time redirect is ported from NPatch, whose
authors are credited below.

Not verified: sign-in and push, for want of a device with a replacement
installed. What is verified on a Pixel 7 (Android 17) is the manager, the
recorded config, and that a patch with no replacement chosen behaves exactly as
before in both local and injected-dex modes.

Co-Authored-By: Martin <kuomartin715@gmail.com>
Co-Authored-By: MrZhongzq <108169409+mrzhongzq@users.noreply.github.com>
Co-Authored-By: NkBe <HSSkyBoy@outlook.com>
JingMatrix added a commit that referenced this pull request Oct 23, 2026
A patched app is re-signed, so Google Play services refuses it wherever it
checks the caller's certificate -- most visibly at sign-in, which fails with
UNREGISTERED_ON_API_CONSOLE. A replacement answering the same APIs under its own
package can stand in, but only if the app's calls reach it and it knows which
certificate the app was originally signed with.

Nothing here names a vendor. A replacement is any package of the shape
<vendor>.android.gms, which carries Google's actions, provider authorities and
C2DM names into its own namespace -- so the whole rewrite follows from the one
package name, and the chosen name is what the patch records. The offers in the
manager are discovered on the device rather than listed, and a package that is
not among them can be typed.

Choosing one is three changes, not a flag, which is why the sheet says so before
the patch rather than after: GmsRedirector rewrites the package, component,
authority and action of GMS-bound intents and provider calls at run time; the
manifest's C2DM names are rewritten to that vendor for good, because the app's
push receiver only accepts a sender holding a signature permission of Google
Play services that no other build can hold; and the original certificate is
declared in the metadata the replacement reads.

Declaring that certificate for a ROM with signature spoofing to report is the
alternative, for a replacement that installs as Google Play services itself and
so needs no redirect at all. The two are alternatives rather than additions --
both declare the same certificate and differ only in who reads it -- so at most
one is chosen, and choosing neither changes nothing.

The redirect only arms itself if the app can see the chosen package, which its
own queries do not cover; a local-mode app already holds QUERY_ALL_PACKAGES, and
the manager offers to add it to an integrated one.

Supersedes #115 and #125. The run-time redirect is ported from NPatch, whose
authors are credited below.

Not verified: sign-in and push, for want of a device with a replacement
installed. What is verified on a Pixel 7 (Android 17) is the manager, the
recorded config, and that a patch with no replacement chosen behaves exactly as
before in both local and injected-dex modes.

Co-Authored-By: Martin <kuomartin715@gmail.com>
Co-Authored-By: MrZhongzq <108169409+mrzhongzq@users.noreply.github.com>
Co-Authored-By: NkBe <HSSkyBoy@outlook.com>
JingMatrix added a commit that referenced this pull request Oct 23, 2026
A patched app is re-signed, so Google Play services refuses it wherever it
checks the caller's certificate -- most visibly at sign-in, which fails with
UNREGISTERED_ON_API_CONSOLE. A replacement answering the same APIs under its own
package can stand in, but only if the app's calls reach it and it knows which
certificate the app was originally signed with.

Nothing here names a vendor. A replacement is any package of the shape
<vendor>.android.gms, which carries Google's actions, provider authorities and
C2DM names into its own namespace -- so the whole rewrite follows from the one
package name, and the chosen name is what the patch records. The offers in the
manager are discovered on the device rather than listed, and a package that is
not among them can be typed.

Choosing one is three changes, not a flag, which is why the sheet says so before
the patch rather than after: GmsRedirector rewrites the package, component,
authority and action of GMS-bound intents and provider calls at run time; the
manifest's C2DM names are rewritten to that vendor for good, because the app's
push receiver only accepts a sender holding a signature permission of Google
Play services that no other build can hold; and the original certificate is
declared in the metadata the replacement reads.

Declaring that certificate for a ROM with signature spoofing to report is the
alternative, for a replacement that installs as Google Play services itself and
so needs no redirect at all. The two are alternatives rather than additions --
both declare the same certificate and differ only in who reads it -- so at most
one is chosen, and choosing neither changes nothing.

The redirect only arms itself if the app can see the chosen package, which its
own queries do not cover; a local-mode app already holds QUERY_ALL_PACKAGES, and
the manager offers to add it to an integrated one.

Supersedes #115 and #125. The run-time redirect is ported from NPatch, whose
authors are credited below.

Not verified: sign-in and push, for want of a device with a replacement
installed. What is verified on a Pixel 7 (Android 17) is the manager, the
recorded config, and that a patch with no replacement chosen behaves exactly as
before in both local and injected-dex modes.

Co-Authored-By: Martin <kuomartin715@gmail.com>
Co-Authored-By: MrZhongzq <108169409+mrzhongzq@users.noreply.github.com>
Co-Authored-By: NkBe <HSSkyBoy@outlook.com>
JingMatrix added a commit that referenced this pull request Oct 23, 2026
A patched app is re-signed, so Google Play services refuses it wherever it
checks the caller's certificate -- most visibly at sign-in, which fails with
UNREGISTERED_ON_API_CONSOLE. A replacement answering the same APIs under its own
package can stand in, but only if the app's calls reach it and it knows which
certificate the app was originally signed with.

Nothing here names a vendor. A replacement is any package of the shape
<vendor>.android.gms, which carries Google's actions, provider authorities and
C2DM names into its own namespace -- so the whole rewrite follows from the one
package name, and the chosen name is what the patch records. The offers in the
manager are discovered on the device rather than listed, and a package that is
not among them can be typed.

Choosing one is three changes, not a flag, which is why the sheet says so before
the patch rather than after: GmsRedirector rewrites the package, component,
authority and action of GMS-bound intents and provider calls at run time; the
manifest's C2DM names are rewritten to that vendor for good, because the app's
push receiver only accepts a sender holding a signature permission of Google
Play services that no other build can hold; and the original certificate is
declared in the metadata the replacement reads.

Declaring that certificate for a ROM with signature spoofing to report is the
alternative, for a replacement that installs as Google Play services itself and
so needs no redirect at all. The two are alternatives rather than additions --
both declare the same certificate and differ only in who reads it -- so at most
one is chosen, and choosing neither changes nothing.

The redirect only arms itself if the app can see the chosen package, which its
own queries do not cover; a local-mode app already holds QUERY_ALL_PACKAGES, and
the manager offers to add it to an integrated one.

Supersedes #115 and #125. The run-time redirect is ported from NPatch, whose
authors are credited below.

Not verified: sign-in and push, for want of a device with a replacement
installed. What is verified on a Pixel 7 (Android 17) is the manager, the
recorded config, and that a patch with no replacement chosen behaves exactly as
before in both local and injected-dex modes.

Co-Authored-By: Martin <kuomartin715@gmail.com>
Co-Authored-By: MrZhongzq <108169409+mrzhongzq@users.noreply.github.com>
Co-Authored-By: NkBe <HSSkyBoy@outlook.com>
JingMatrix added a commit that referenced this pull request Oct 23, 2026
A patched app is re-signed, so Google Play services refuses it wherever it
checks the caller's certificate -- most visibly at sign-in, which fails with
UNREGISTERED_ON_API_CONSOLE. A replacement answering the same APIs under its own
package can stand in, but only if the app's calls reach it and it knows which
certificate the app was originally signed with.

Nothing here names a vendor. A replacement is any package of the shape
<vendor>.android.gms, which carries Google's actions, provider authorities and
C2DM names into its own namespace -- so the whole rewrite follows from the one
package name, and the chosen name is what the patch records. The offers in the
manager are discovered on the device rather than listed, and a package that is
not among them can be typed.

Choosing one is three changes, not a flag, which is why the sheet says so before
the patch rather than after: GmsRedirector rewrites the package, component,
authority and action of GMS-bound intents and provider calls at run time; the
manifest's C2DM names are rewritten to that vendor for good, because the app's
push receiver only accepts a sender holding a signature permission of Google
Play services that no other build can hold; and the original certificate is
declared in the metadata the replacement reads.

Declaring that certificate for a ROM with signature spoofing to report is the
alternative, for a replacement that installs as Google Play services itself and
so needs no redirect at all. The two are alternatives rather than additions --
both declare the same certificate and differ only in who reads it -- so at most
one is chosen, and choosing neither changes nothing.

The redirect only arms itself if the app can see the chosen package, which its
own queries do not cover; a local-mode app already holds QUERY_ALL_PACKAGES, and
the manager offers to add it to an integrated one.

Supersedes #115 and #125. The run-time redirect is ported from NPatch, whose
authors are credited below.

Not verified: sign-in and push, for want of a device with a replacement
installed. What is verified on a Pixel 7 (Android 17) is the manager, the
recorded config, and that a patch with no replacement chosen behaves exactly as
before in both local and injected-dex modes.

Co-Authored-By: Martin <kuomartin715@gmail.com>
Co-Authored-By: MrZhongzq <108169409+mrzhongzq@users.noreply.github.com>
Co-Authored-By: NkBe <HSSkyBoy@outlook.com>
JingMatrix added a commit that referenced this pull request Oct 23, 2026
A patched app is re-signed, so Google Play services refuses it wherever it
checks the caller's certificate -- most visibly at sign-in, which fails with
UNREGISTERED_ON_API_CONSOLE. A replacement answering the same APIs under its own
package can stand in, but only if the app's calls reach it and it knows which
certificate the app was originally signed with.

Nothing here names a vendor. A replacement is any package of the shape
<vendor>.android.gms, which carries Google's actions, provider authorities and
C2DM names into its own namespace -- so the whole rewrite follows from the one
package name, and the chosen name is what the patch records. The offers in the
manager are discovered on the device rather than listed, and a package that is
not among them can be typed.

Choosing one is three changes, not a flag, which is why the sheet says so before
the patch rather than after: GmsRedirector rewrites the package, component,
authority and action of GMS-bound intents and provider calls at run time; the
manifest's C2DM names are rewritten to that vendor for good, because the app's
push receiver only accepts a sender holding a signature permission of Google
Play services that no other build can hold; and the original certificate is
declared in the metadata the replacement reads.

Declaring that certificate for a ROM with signature spoofing to report is the
alternative, for a replacement that installs as Google Play services itself and
so needs no redirect at all. The two are alternatives rather than additions --
both declare the same certificate and differ only in who reads it -- so at most
one is chosen, and choosing neither changes nothing.

The redirect only arms itself if the app can see the chosen package, which its
own queries do not cover; a local-mode app already holds QUERY_ALL_PACKAGES, and
the manager offers to add it to an integrated one.

Supersedes #115 and #125. The run-time redirect is ported from NPatch, whose
authors are credited below.

Not verified: sign-in and push, for want of a device with a replacement
installed. What is verified on a Pixel 7 (Android 17) is the manager, the
recorded config, and that a patch with no replacement chosen behaves exactly as
before in both local and injected-dex modes.

Co-Authored-By: Martin <kuomartin715@gmail.com>
Co-Authored-By: MrZhongzq <108169409+mrzhongzq@users.noreply.github.com>
Co-Authored-By: NkBe <HSSkyBoy@outlook.com>
JingMatrix added a commit that referenced this pull request Oct 23, 2026
A patched app is re-signed, so Google Play services refuses it wherever it
checks the caller's certificate -- most visibly at sign-in, which fails with
UNREGISTERED_ON_API_CONSOLE. A replacement answering the same APIs under its own
package can stand in, but only if the app's calls reach it and it knows which
certificate the app was originally signed with.

Nothing here names a vendor. A replacement is any package of the shape
<vendor>.android.gms, which carries Google's actions, provider authorities and
C2DM names into its own namespace -- so the whole rewrite follows from the one
package name, and the chosen name is what the patch records. The offers in the
manager are discovered on the device rather than listed, and a package that is
not among them can be typed.

Choosing one is three changes, not a flag, which is why the sheet says so before
the patch rather than after: GmsRedirector rewrites the package, component,
authority and action of GMS-bound intents and provider calls at run time; the
manifest's C2DM names are rewritten to that vendor for good, because the app's
push receiver only accepts a sender holding a signature permission of Google
Play services that no other build can hold; and the original certificate is
declared in the metadata the replacement reads.

Declaring that certificate for a ROM with signature spoofing to report is the
alternative, for a replacement that installs as Google Play services itself and
so needs no redirect at all. The two are alternatives rather than additions --
both declare the same certificate and differ only in who reads it -- so at most
one is chosen, and choosing neither changes nothing.

The redirect only arms itself if the app can see the chosen package, which its
own queries do not cover; a local-mode app already holds QUERY_ALL_PACKAGES, and
the manager offers to add it to an integrated one.

Supersedes #115 and #125. The run-time redirect is ported from NPatch, whose
authors are credited below.

Not verified: sign-in and push, for want of a device with a replacement
installed. What is verified on a Pixel 7 (Android 17) is the manager, the
recorded config, and that a patch with no replacement chosen behaves exactly as
before in both local and injected-dex modes.

Co-Authored-By: Martin <kuomartin715@gmail.com>
Co-Authored-By: MrZhongzq <108169409+mrzhongzq@users.noreply.github.com>
Co-Authored-By: NkBe <HSSkyBoy@outlook.com>
JingMatrix added a commit that referenced this pull request Oct 23, 2026
A patched app is re-signed, so Google Play services refuses it wherever it
checks the caller's certificate -- most visibly at sign-in, which fails with
UNREGISTERED_ON_API_CONSOLE. A replacement answering the same APIs under its own
package can stand in, but only if the app's calls reach it and it knows which
certificate the app was originally signed with.

Nothing here names a vendor. A replacement is any package of the shape
<vendor>.android.gms, which carries Google's actions, provider authorities and
C2DM names into its own namespace -- so the whole rewrite follows from the one
package name, and the chosen name is what the patch records. The offers in the
manager are discovered on the device rather than listed, and a package that is
not among them can be typed.

Choosing one is three changes, not a flag, which is why the sheet says so before
the patch rather than after: GmsRedirector rewrites the package, component,
authority and action of GMS-bound intents and provider calls at run time; the
manifest's C2DM names are rewritten to that vendor for good, because the app's
push receiver only accepts a sender holding a signature permission of Google
Play services that no other build can hold; and the original certificate is
declared in the metadata the replacement reads.

Declaring that certificate for a ROM with signature spoofing to report is the
alternative, for a replacement that installs as Google Play services itself and
so needs no redirect at all. The two are alternatives rather than additions --
both declare the same certificate and differ only in who reads it -- so at most
one is chosen, and choosing neither changes nothing.

The redirect only arms itself if the app can see the chosen package, which its
own queries do not cover; a local-mode app already holds QUERY_ALL_PACKAGES, and
the manager offers to add it to an integrated one.

Supersedes #115 and #125. The run-time redirect is ported from NPatch, whose
authors are credited below.

Not verified: sign-in and push, for want of a device with a replacement
installed. What is verified on a Pixel 7 (Android 17) is the manager, the
recorded config, and that a patch with no replacement chosen behaves exactly as
before in both local and injected-dex modes.

Co-Authored-By: Martin <kuomartin715@gmail.com>
Co-Authored-By: MrZhongzq <108169409+mrzhongzq@users.noreply.github.com>
Co-Authored-By: NkBe <HSSkyBoy@outlook.com>
JingMatrix added a commit that referenced this pull request Oct 23, 2026
A patched app is re-signed, so Google Play services refuses it wherever it
checks the caller's certificate -- most visibly at sign-in, which fails with
UNREGISTERED_ON_API_CONSOLE. A replacement answering the same APIs under its own
package can stand in, but only if the app's calls reach it and it knows which
certificate the app was originally signed with.

Nothing here names a vendor. A replacement is any package of the shape
<vendor>.android.gms, which carries Google's actions, provider authorities and
C2DM names into its own namespace -- so the whole rewrite follows from the one
package name, and the chosen name is what the patch records. The offers in the
manager are discovered on the device rather than listed, and a package that is
not among them can be typed.

Choosing one is three changes, not a flag, which is why the sheet says so before
the patch rather than after: GmsRedirector rewrites the package, component,
authority and action of GMS-bound intents and provider calls at run time; the
manifest's C2DM names are rewritten to that vendor for good, because the app's
push receiver only accepts a sender holding a signature permission of Google
Play services that no other build can hold; and the original certificate is
declared in the metadata the replacement reads.

Declaring that certificate for a ROM with signature spoofing to report is the
alternative, for a replacement that installs as Google Play services itself and
so needs no redirect at all. The two are alternatives rather than additions --
both declare the same certificate and differ only in who reads it -- so at most
one is chosen, and choosing neither changes nothing.

The redirect only arms itself if the app can see the chosen package, which its
own queries do not cover; a local-mode app already holds QUERY_ALL_PACKAGES, and
the manager offers to add it to an integrated one.

Supersedes #115 and #125. The run-time redirect is ported from NPatch, whose
authors are credited below.

Not verified: sign-in and push, for want of a device with a replacement
installed. What is verified on a Pixel 7 (Android 17) is the manager, the
recorded config, and that a patch with no replacement chosen behaves exactly as
before in both local and injected-dex modes.

Co-Authored-By: Martin <kuomartin715@gmail.com>
Co-Authored-By: MrZhongzq <108169409+mrzhongzq@users.noreply.github.com>
Co-Authored-By: NkBe <HSSkyBoy@outlook.com>
JingMatrix added a commit that referenced this pull request Oct 23, 2026
A patched app is re-signed, so Google Play services refuses it wherever it
checks the caller's certificate -- most visibly at sign-in, which fails with
UNREGISTERED_ON_API_CONSOLE. A replacement answering the same APIs under its own
package can stand in, but only if the app's calls reach it and it knows which
certificate the app was originally signed with.

Nothing here names a vendor. A replacement is any package of the shape
<vendor>.android.gms, which carries Google's actions, provider authorities and
C2DM names into its own namespace -- so the whole rewrite follows from the one
package name, and the chosen name is what the patch records. The offers in the
manager are discovered on the device rather than listed, and a package that is
not among them can be typed.

Choosing one is three changes, not a flag, which is why the sheet says so before
the patch rather than after: GmsRedirector rewrites the package, component,
authority and action of GMS-bound intents and provider calls at run time; the
manifest's C2DM names are rewritten to that vendor for good, because the app's
push receiver only accepts a sender holding a signature permission of Google
Play services that no other build can hold; and the original certificate is
declared in the metadata the replacement reads.

Declaring that certificate for a ROM with signature spoofing to report is the
alternative, for a replacement that installs as Google Play services itself and
so needs no redirect at all. The two are alternatives rather than additions --
both declare the same certificate and differ only in who reads it -- so at most
one is chosen, and choosing neither changes nothing.

The redirect only arms itself if the app can see the chosen package, which its
own queries do not cover; a local-mode app already holds QUERY_ALL_PACKAGES, and
the manager offers to add it to an integrated one.

Supersedes #115 and #125. The run-time redirect is ported from NPatch, whose
authors are credited below.

Not verified: sign-in and push, for want of a device with a replacement
installed. What is verified on a Pixel 7 (Android 17) is the manager, the
recorded config, and that a patch with no replacement chosen behaves exactly as
before in both local and injected-dex modes.

Co-Authored-By: Martin <kuomartin715@gmail.com>
Co-Authored-By: MrZhongzq <108169409+mrzhongzq@users.noreply.github.com>
Co-Authored-By: NkBe <HSSkyBoy@outlook.com>
JingMatrix added a commit that referenced this pull request Oct 23, 2026
A patched app is re-signed, so Google Play services refuses it wherever it
checks the caller's certificate -- most visibly at sign-in, which fails with
UNREGISTERED_ON_API_CONSOLE. A replacement answering the same APIs under its own
package can stand in, but only if the app's calls reach it and it knows which
certificate the app was originally signed with.

Nothing here names a vendor. A replacement is any package ending in .gms other
than Google's own, and the single question asked of that name is whether it also
ends in .android.gms: such a build renamed Google's namespaces into its own so
it can be installed beside Google Play services, while one that keeps Google's
names is meant to replace it outright and serves them under those names. Only
the first needs its provider authorities and push names rewritten. The offers in
the manager are discovered by asking the device which packages answer the
sign-in service, and a package that is not among them can still be typed.

Choosing one is three changes, not a flag, which is why the sheet says so before
the patch rather than after. GmsRedirector rewrites the package, component and
provider authority of GMS-bound intents and provider calls at run time. Actions
are deliberately left alone: a replacement declares Google's own action names
under its own package, so rewriting the package is what routes a call, and
rewriting the action too would address a name nothing declares. Push is the one
exception, because the app's push receiver only accepts a sender holding a
signature permission of Google Play services that no other build can hold, so
its C2DM names are renamed in the manifest for good and the same prefix rule is
applied to the actions the app sets at run time. The original certificate is
then declared in the metadata the replacement reads.

The client library also asks the package manager -- not an intent -- whether
Google Play services is present, so the redirect never sees that question, and
on a device where it was replaced rather than supplemented the answer is no and
the library stops before sending anything. Once the chosen replacement is found
installed, isGooglePlayServicesAvailable is answered on its behalf, which is
what makes these APIs reachable at all on a device with no Google Play services.
It is logged the first time it changes an answer.

Declaring that certificate for a ROM with signature spoofing to report is the
alternative, for a replacement that installs as Google Play services itself and
so needs no redirect. The two are alternatives rather than additions -- both
declare the same certificate and differ only in who reads it -- so at most one
is chosen, and choosing neither changes nothing.

The redirect only arms itself if the app can see the chosen package, which its
own queries do not cover; a local-mode app already holds QUERY_ALL_PACKAGES, and
the manager offers to add it to an integrated one.

Supersedes #115 and #125. The run-time redirect is ported from NPatch, whose
authors are credited below.

Verified on a Pixel 7 against GmsCore, which renames: sign-in reaches its login
activity, the sign-in, auth and advertising-id services bind to it, the C2DM
names move both in the manifest and on the wire while the app still reads
Google's own, and the renamed receiver resolves only under the new action and
refuses a sender that does not hold the permission GmsCore declares. Verified on
an AOSP emulator with no Google Play services against upstream microG, which
does not rename: the availability check is answered, the same services bind,
sign-in reaches microG's login activity, and no name is rewritten. A patch with
no replacement chosen is unchanged in both modes.

Not verified: a push actually delivered by a replacement, which needs a live FCM
registration. AdvertisingIdClient still refuses where there is no Google Play
services, its check sitting in the client library's obfuscated internals rather
than behind any of the public entry points this answers.

Co-Authored-By: Martin <kuomartin715@gmail.com>
Co-Authored-By: MrZhongzq <108169409+mrzhongzq@users.noreply.github.com>
Co-Authored-By: NkBe <HSSkyBoy@outlook.com>
JingMatrix added a commit that referenced this pull request Oct 23, 2026
A patched app is re-signed, so Google Play services refuses it wherever it
checks the caller's certificate -- most visibly at sign-in, which fails with
UNREGISTERED_ON_API_CONSOLE. A replacement answering the same APIs under its own
package can stand in, but only if the app's calls reach it and it knows which
certificate the app was originally signed with.

Nothing here names a vendor. A replacement is any package ending in .gms other
than Google's own, and the single question asked of that name is whether it also
ends in .android.gms: such a build renamed Google's namespaces into its own so
it can be installed beside Google Play services, while one that keeps Google's
names is meant to replace it outright and serves them under those names. Only
the first needs its provider authorities and push names rewritten. The offers in
the manager are discovered by asking the device which packages answer the
sign-in service, and a package that is not among them can still be typed.

Choosing one is three changes, not a flag, which is why the sheet says so before
the patch rather than after. GmsRedirector rewrites the package, component and
provider authority of GMS-bound intents and provider calls at run time. Actions
are deliberately left alone: a replacement declares Google's own action names
under its own package, so rewriting the package is what routes a call, and
rewriting the action too would address a name nothing declares. Push is the one
exception, because the app's push receiver only accepts a sender holding a
signature permission of Google Play services that no other build can hold, so
its C2DM names are renamed in the manifest for good and the same prefix rule is
applied to the actions the app sets at run time. The original certificate is
then declared in the metadata the replacement reads.

The client library also asks the package manager -- not an intent -- whether
Google Play services is present, so the redirect never sees that question, and
on a device where it was replaced rather than supplemented the answer is no and
the library stops before sending anything. Once the chosen replacement is found
installed, isGooglePlayServicesAvailable is answered on its behalf, which is
what makes these APIs reachable at all on a device with no Google Play services.
It is logged the first time it changes an answer. Only the library's public
entry points are answered; an API that repeats the check inside its own
internals, as the advertising-id client does, still refuses.

Declaring that certificate for a ROM with signature spoofing to report is the
alternative, for a replacement that installs as Google Play services itself and
so needs no redirect. The two are alternatives rather than additions -- both
declare the same certificate and differ only in who reads it -- so at most one
is chosen, and choosing neither changes nothing.

The redirect only arms itself if the app can see the chosen package, which its
own queries do not cover; a local-mode app already holds QUERY_ALL_PACKAGES, and
the manager offers to add it to an integrated one.

Supersedes #115 and #125. The run-time redirect is ported from NPatch, whose
authors are credited below.

Co-Authored-By: Martin <kuomartin715@gmail.com>
Co-Authored-By: MrZhongzq <108169409+mrzhongzq@users.noreply.github.com>
Co-Authored-By: NkBe <HSSkyBoy@outlook.com>
JingMatrix added a commit that referenced this pull request Oct 23, 2026
A patched app is re-signed, so Google Play services refuses it wherever it
checks the caller's certificate -- most visibly at sign-in, which fails with
UNREGISTERED_ON_API_CONSOLE. A replacement answering the same APIs under its own
package can stand in, but only if the app's calls reach it and it knows which
certificate the app was originally signed with.

Nothing here names a vendor. A replacement is any package ending in .gms other
than Google's own, and the single question asked of that name is whether it also
ends in .android.gms: such a build renamed Google's namespaces into its own so
it can be installed beside Google Play services, while one that keeps Google's
names is meant to replace it outright and serves them under those names. Only
the first needs its provider authorities and push names rewritten. The offers in
the manager are discovered by asking the device which packages answer the
sign-in service, and a package that is not among them can still be typed.

Choosing one is three changes, not a flag, which is why the sheet says so before
the patch rather than after. GmsRedirector rewrites the package, component and
provider authority of GMS-bound intents and provider calls at run time. Actions
are deliberately left alone: a replacement declares Google's own action names
under its own package, so rewriting the package is what routes a call, and
rewriting the action too would address a name nothing declares. Push is the one
exception, because the app's push receiver only accepts a sender holding a
signature permission of Google Play services that no other build can hold, so
its C2DM names are renamed in the manifest for good and the same prefix rule is
applied to the actions the app sets at run time. The original certificate is
then declared in the metadata the replacement reads.

The client library also asks the package manager -- not an intent -- whether
Google Play services is present, so the redirect never sees that question, and
on a device where it was replaced rather than supplemented the answer is no and
the library stops before sending anything. Once the chosen replacement is found
installed, isGooglePlayServicesAvailable is answered on its behalf, which is
what makes these APIs reachable at all on a device with no Google Play services.
It is logged the first time it changes an answer. Only the library's public
entry points are answered; an API that repeats the check inside its own
internals, as the advertising-id client does, still refuses.

Declaring that certificate for a ROM with signature spoofing to report is the
alternative, for a replacement that installs as Google Play services itself and
so needs no redirect. The two are alternatives rather than additions -- both
declare the same certificate and differ only in who reads it -- so at most one
is chosen, and choosing neither changes nothing.

The redirect only arms itself if the app can see the chosen package, which its
own queries do not cover; a local-mode app already holds QUERY_ALL_PACKAGES, and
the manager offers to add it to an integrated one.

Supersedes #115 and #125. The run-time redirect is ported from NPatch, where
NkBe introduced it as 7723mod/NPatch e640da4; its authors are credited below.

Co-Authored-By: Martin <kuomartin715@gmail.com>
Co-Authored-By: MrZhongzq <108169409+mrzhongzq@users.noreply.github.com>
Co-Authored-By: NkBe <HSSkyBoy@outlook.com>
JingMatrix added a commit that referenced this pull request Oct 23, 2026
A patched app is re-signed, so Google Play services refuses it wherever it
checks the caller's certificate -- most visibly at sign-in. A replacement
answering the same APIs under its own package can stand in.

No vendor is named: a replacement is any package ending in .gms, and whether it
also ends in .android.gms decides whether its provider authorities and push
names need rewriting. The manager discovers what the device offers by asking
which packages answer the sign-in service.

Redirecting rewrites intents and provider calls at run time, renames the app's
C2DM names in the manifest, and declares the original certificate in the
metadata the replacement reads. Actions are left alone. The availability check
goes through the package manager rather than an intent, so it is answered for
the chosen replacement. Declaring the certificate alone is the alternative, for
a replacement installed as Google Play services itself; at most one is chosen.

Supersedes #115 and #125. The run-time redirect is ported from NPatch, where
NkBe introduced it as 7723mod/NPatch e640da4. Also fixes a sheet's content
sitting under the keyboard.

Co-Authored-By: Martin <kuomartin715@gmail.com>
Co-Authored-By: MrZhongzq <108169409+mrzhongzq@users.noreply.github.com>
Co-Authored-By: NkBe <HSSkyBoy@outlook.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants