Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixed signingInfo spoofing on Android 9 to 12 #25

Merged
merged 1 commit into from
Dec 21, 2024

Conversation

gilbsgilbs
Copy link

@gilbsgilbs gilbsgilbs commented Dec 15, 2024

The SigningDetails class used to be embedded in the PackageParser class. This was leading to a ClassNotFoundException on those older versions.

See https://cs.android.com/android/platform/superproject/+/android12L-release:frameworks/base/core/java/android/content/pm/PackageParser.java;l=5897;drc=ed537a2acf627c6820a218c177dfdaa12f50c068


I did not test this PR because I don't own an older Android device. tested on emulated Android 10. Reported by @Fs00 (#23 (comment)). @Fs00, can you check that it works better for you also? app-debug.zip  app-debug.zip (rename to .apk, GitHub doesn't allow uploading .apk files directly).

@MikronT
Copy link

MikronT commented Dec 15, 2024

The 2nd app-debug.zip actually fixed spoofing so all Google apps and services are now running the way they did on my device prior to Google's breaking changes

Environment:

  • Android 12 (AospExtended 9)
  • Magisk 28.1
  • LSPosed 1.9.2
  • microG Services 0.3.5.240913

@gilbsgilbs gilbsgilbs marked this pull request as ready for review December 15, 2024 23:29
@gilbsgilbs
Copy link
Author

Thanks for testing @MikronT .

@gilbsgilbs
Copy link
Author

gilbsgilbs commented Dec 16, 2024

Tested Android 10 in an emulator, works OK. Can't test Android 9 because Magisk doesn't support pre-system-as-root installations in AVD, but I haven't spotted any relevant code change in the classes we reflect, so it should work just as well. RFR.

@MikronT
Copy link

MikronT commented Dec 16, 2024

After further testing some Google apps appeared to be misbehaving even after applying the patch. All apps are up to date. Confirmed fully operational (checked) vs misbehaving (unchecked):

  • Calculator (account not needed, but crashes on startup)
  • Calendar
  • Chrome
  • Contacts (unable to find account)
  • Files (account not needed)
  • Fit
  • Gboard
  • Gmail
  • Google Drive
  • Google Maps
  • Google Play Store (including billing: app licensing and purchasing)
  • Google Photos
  • Keep
  • Messages
  • Phone (account not needed)
  • Recorder
  • Tasks
  • Translate
  • Wallet (account found, unable to load anything)
  • YouTube
  • YouTube Music

Both Google Calculator and Google Contacts throw similar errors into logcat about not being able to find Google Play Store (which is installed, up to date, and operational) and complain about missing APIs.

Google Calculator (crashes on startup):

12-16 01:12:07.369 17876 17903 W GooglePlayServicesUtil: com.google.android.calculator requires the Google Play Store, but it is missing.
12-16 01:12:07.370 17876 17903 W GoogleApiManager: The service for bbt is not available: aru{statusCode=SERVICE_INVALID, resolution=null, message=null}
12-16 01:12:07.371 17876 17903 E CheckboxChecker: fetching usage reporting opt-in failed
12-16 01:12:07.371 17876 17903 E CheckboxChecker: asw: 17: API: UsageReporting.API is not available on this device. Connection failed with: aru{statusCode=SERVICE_INVALID, resolution=null, message=null}
12-16 01:12:07.371 17876 17903 E CheckboxChecker:       at afj.d(PG:13)
12-16 01:12:07.371 17876 17903 E CheckboxChecker:       at atm.d(PG:3)
12-16 01:12:07.371 17876 17903 E CheckboxChecker:       at aue.t(PG:48)
12-16 01:12:07.371 17876 17903 E CheckboxChecker:       at aue.f(PG:10)
12-16 01:12:07.371 17876 17903 E CheckboxChecker:       at aue.j(PG:180)
12-16 01:12:07.371 17876 17903 E CheckboxChecker:       at aue.i(PG:2)
12-16 01:12:07.371 17876 17903 E CheckboxChecker:       at aue.d(PG:173)
12-16 01:12:07.371 17876 17903 E CheckboxChecker:       at aue.e(PG:51)
12-16 01:12:07.371 17876 17903 E CheckboxChecker:       at auh.handleMessage(PG:881)
12-16 01:12:07.371 17876 17903 E CheckboxChecker:       at android.os.Handler.dispatchMessage(Handler.java:102)
12-16 01:12:07.371 17876 17903 E CheckboxChecker:       at android.os.Looper.loopOnce(Looper.java:201)
12-16 01:12:07.371 17876 17903 E CheckboxChecker:       at android.os.Looper.loop(Looper.java:288)
12-16 01:12:07.371 17876 17903 E CheckboxChecker:       at android.os.HandlerThread.run(HandlerThread.java:67)

Google Contacts (unable to find account, sign in prompt only) throws lots of similar errors about not being able to find UsageReporting.API, Phenotype.API, ClearcutLogger.API, and People.API:

12-16 01:07:34.797 16575 16603 W GooglePlayServicesUtil: com.google.android.contacts requires the Google Play Store, but it is missing.
12-16 01:07:34.797 16575 16603 W GoogleApiManager: The service for qlf is not available: ConnectionResult{statusCode=SERVICE_INVALID, resolution=null, message=null}
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: Unable to update local snapshot for com.google.android.contacts#com.google.android.contacts, may result in stale flags.
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: java.util.concurrent.ExecutionException: tbp: 17: 17: API: Phenotype.API is not available on this device. Connection failed with: ConnectionResult{statusCode=SERVICE_INVALID, resolution=null, message=null}
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at wcv.r(PG:21)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at wcv.get(PG:3)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at rq.f(PG:2)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at uvc.aJ(PG:10)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at tcm.b(PG:1)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at spc.run(PG:150)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at java.lang.Thread.run(Thread.java:920)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: Caused by: tbp: 17: 17: API: Phenotype.API is not available on this device. Connection failed with: ConnectionResult{statusCode=SERVICE_INVALID, resolution=null, message=null}
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at rne.a(PG:47)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at wce.e(PG:3)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at wcg.run(PG:130)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at wdx.execute(PG:1)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at wcv.h(PG:1)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at wcv.k(PG:95)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at wcv.o(PG:19)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at ohb.a(PG:76)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at qef.run(PG:555)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at wdx.execute(PG:1)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at qml.b(PG:92)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at zlx.d(PG:36)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at qmx.u(PG:20)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at qef.run(PG:746)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at wdx.execute(PG:1)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at qml.b(PG:106)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at zlx.d(PG:36)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at sul.E(PG:40)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at puj.d(PG:7)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at pvd.t(PG:48)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at pvd.f(PG:10)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at pvd.j(PG:186)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at pvd.i(PG:2)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at pvd.d(PG:176)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at pvd.e(PG:51)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at pvg.handleMessage(PG:856)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at android.os.Handler.dispatchMessage(Handler.java:102)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at qeq.b(PG:1)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at qeq.dispatchMessage(PG:1)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at android.os.Looper.loopOnce(Looper.java:201)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at android.os.Looper.loop(Looper.java:288)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at android.os.HandlerThread.run(HandlerThread.java:67)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: Caused by: ptm: 17: API: Phenotype.API is not available on this device. Connection failed with: ConnectionResult{statusCode=SERVICE_INVALID, resolution=null, message=null}
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at pmt.e(PG:13)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	at puj.d(PG:3)
12-16 01:07:34.802 16575 16611 W MobStoreFlagStore: 	... 13 more

Google Wallet produces lots of stacktraces similar to this one:

12-16 02:06:16.923  8434  8457 I PhenotypeRegistrationTa: Phenotype registration completed
12-16 02:06:16.925  3317  3352 D PhenotypeService: getConfigurationSnapshot2(com.google.android.apps.walletnfcrel#com.google.android.apps.walletnfcrel, , null)
12-16 02:06:16.926  8434  8460 I PhClient: Unable to retrieve flag snapshot for com.google.android.apps.walletnfcrel.onboarding#com.google.android.apps.walletnfcrel, using defaults.
12-16 02:06:16.926  3317  4896 D PhenotypeService: getConfigurationSnapshot2(com.google.android.libraries.notifications.platform#com.google.android.apps.walletnfcrel, , null)
12-16 02:06:16.930  8434  8460 W MobStoreFlagStore: Unable to update local snapshot for com.google.android.libraries.notifications.platform#com.google.android.apps.walletnfcrel, may result in stale flags.
12-16 02:06:16.930  8434  8460 W MobStoreFlagStore: java.util.concurrent.ExecutionException: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Class java.lang.Object.getClass()' on a null object reference
12-16 02:06:16.930  8434  8460 W MobStoreFlagStore: 	at agbg.s(PG:21)
12-16 02:06:16.930  8434  8460 W MobStoreFlagStore: 	at agbg.get(PG:3)
12-16 02:06:16.930  8434  8460 W MobStoreFlagStore: 	at ageu.a(PG:2)
12-16 02:06:16.930  8434  8460 W MobStoreFlagStore: 	at agdf.o(PG:10)
12-16 02:06:16.930  8434  8460 W MobStoreFlagStore: 	at achx.c(PG:1)
12-16 02:06:16.930  8434  8460 W MobStoreFlagStore: 	at achq.run(PG:5)
12-16 02:06:16.930  8434  8460 W MobStoreFlagStore: 	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462)
12-16 02:06:16.930  8434  8460 W MobStoreFlagStore: 	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
12-16 02:06:16.930  8434  8460 W MobStoreFlagStore: 	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
12-16 02:06:16.930  8434  8460 W MobStoreFlagStore: 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
12-16 02:06:16.930  8434  8460 W MobStoreFlagStore: 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
12-16 02:06:16.930  8434  8460 W MobStoreFlagStore: 	at java.lang.Thread.run(Thread.java:920)
12-16 02:06:16.930  8434  8460 W MobStoreFlagStore: Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Class java.lang.Object.getClass()' on a null object reference
12-16 02:06:16.930  8434  8460 W MobStoreFlagStore: 	at acfq.a(PG:32)
12-16 02:06:16.930  8434  8460 W MobStoreFlagStore: 	at xni.run(PG:23)
12-16 02:06:16.930  8434  8460 W MobStoreFlagStore: 	at agcc.execute(PG:1)
12-16 02:06:16.930  8434  8460 W MobStoreFlagStore: 	at xnj.c(PG:8)
12-16 02:06:16.930  8434  8460 W MobStoreFlagStore: 	at xof.b(PG:36)
12-16 02:06:16.930  8434  8460 W MobStoreFlagStore: 	at xol.u(PG:15)
12-16 02:06:16.930  8434  8460 W MobStoreFlagStore: 	at xoh.b(PG:3)
12-16 02:06:16.930  8434  8460 W MobStoreFlagStore: 	at vay.b(PG:7)
12-16 02:06:16.930  8434  8460 W MobStoreFlagStore: 	at xgg.g(PG:3)
12-16 02:06:16.930  8434  8460 W MobStoreFlagStore: 	at xgp.a(PG:261)
12-16 02:06:16.930  8434  8460 W MobStoreFlagStore: 	at lhk.onTransact(PG:21)
12-16 02:06:16.930  8434  8460 W MobStoreFlagStore: 	at android.os.Binder.execTransactInternal(Binder.java:1184)
12-16 02:06:16.930  8434  8460 W MobStoreFlagStore: 	at android.os.Binder.execTransact(Binder.java:1143)

Don't know if these logs are any kind of helpful though

@gilbsgilbs
Copy link
Author

gilbsgilbs commented Dec 16, 2024

I'm unable to reproduce the Calculator and Contacts issues. Is your self-check OK? Are you using a recent version and fresh install of MicroG? Regarding Google Wallet, I don't think it was ever supported but I might be wrong. In any case, these tracebacks don't seem related to FakeGApps directly, and certainly not to this patch or #23.

@MikronT
Copy link

MikronT commented Dec 16, 2024

I'm using the latest versions and I'm on a fresh install of the ROM and microG. Self-check is OK, all permissions are granted, no potentially conflicting Magisk modules installed (yet). These problems do seem unrelated to FakeGapps, so maybe there's something else going on.

Other Google apps and third-party apps that depend on Google services run fine, no crashes, no lags. So thank you for the quick fix!

@porcoddiocanebastardo
Copy link

porcoddiocanebastardo commented Dec 17, 2024

I try app-debug in fresh install:
Android 12 Stock Rom Europe Ulefone 20WT
Magisk 28.1 with Zygisk Next
LSPosed 1.9.2 with your FakeGApps 6 debug version

App updated that begin to function with it:
-Calendar
-Map
-Gmail

App updated that don't function and give some login error or don't start:
-YoutubeMusic and Youtube (not modified versions) -they don't start
-GoogleAssistant -don't start
-GoogleTV -don't start
-Messages -don't start
-Drive -don't login (error of request new login but if log respond you're repeating log)
-Contacts -don't login (same problem of Drive)

App that don't start show for a moment always same error of old version of PlayServices or GoogleTV and Messages say App Interupted at begin.

@Fs00
Copy link

Fs00 commented Dec 18, 2024

Tested this on my Android 11 device with the latest version of Gmail and YouTube and I can confirm it works 👍

Looking at the code, I wonder why a try/catch is used instead of a simple check on the SDK level to determine the class to instantiate. It would make the intent of the code clearer and avoid an exception that is guaranteed to happen every time on Android 9-12.
It might be an unfair comparison, but as it is now it reminds me of code snippets trying to catch NPEs instead of checking for null.

@gilbsgilbs
Copy link
Author

gilbsgilbs commented Dec 18, 2024

@Fs00 Thanks for testing :) .

Looking at the code, I wonder why a try/catch is used instead of a simple check on the SDK level

I did this just to account for the unlikely possibility that some obscure vendor has not ported the class onto a newer Android version, or has backported it into an older Android version. AOSP isn't the ultimate source of truth unfortunately, so I think it's reasonable to make as little assumptions as possible on private APIs implementation in XPosed modules.

Now, to avoid the nested try/catch, one similarly robust way would be to check if the class exists before invoking the constructor, but I fully adhere to the EAFP principle. It can still be flattened by creating a getSigningDetailsClass function if necessary, and also by checking against a list of class names. edit: just refactored to implement that.

Even though I'm fairly happy with my implementation, I’m not opposed to a simpler SDK-level check either if that’s the consensus. It feels like a minor detail, so if everyone feels strongly I’m happy to adjust accordingly.

@Fs00
Copy link

Fs00 commented Dec 18, 2024

but I fully adhere to the EAFP principle

I'd say that this is what I disagree with (didn't know that acronym 😅) as it doesn't seem a good fit for this context to me, but I'll let @whew-inc judge since he's the maintainer here.

the unlikely possibility that some obscure vendor has not ported the class onto a newer Android version, or has backported it into an older Android version

Makes sense. Out of curiosity, have you ever heard/seen situations in which this happened? I imagine that a vendor messing with system services such as the PackageManager could have some trouble passing the CTS.

@gilbsgilbs
Copy link
Author

gilbsgilbs commented Dec 18, 2024

Out of curiosity, have you ever heard/seen situations in which this happened?

No, that was just me being pedantic tbh, this is why I said that I wouldn't mind using a SDK level check instead. Even though I believe the try/catch solution to be more """robust""" by design, the gain in robustness is also probably way too marginal to be observable in the real world.

Maybe one more striking argument would be that the try/catch approach prevents "developer mistakes": I can see myself including or excluding Android 12L by mistake. Maybe there are some other edge-cases I did not see, like beta versions or other transient versions. I'm more confident acknowledging that I'm dumb and safeguarding against it than trying to pretend I'm smart (and be disproved later on 🤪).

@whew-inc
Copy link
Owner

I'd say that this is what I disagree with (didn't know that acronym 😅) as it doesn't seem a good fit for this context to me, but I'll let @whew-inc judge since he's the maintainer here.

I personally agree with you. An SDK check here will probably be fine, as the existing sdk version checks hasn't had any issues with a specific vendor (AFAIK). But I also agree with @gilbsgilbs that the try-catch approach seems more robust, in case that a vendor messes around with this Android code.

Since the proposed approach in this merge request is short and readable, I have no problem with it.

@whew-inc whew-inc merged commit 4fec4f8 into whew-inc:master Dec 21, 2024
@whew-inc
Copy link
Owner

whew-inc commented Dec 21, 2024

Thank you everyone involved! Especially @gilbsgilbs for fixing spoofing yet again ❤️

Edit: A new release should be available tomorrow.

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.

5 participants