From ad590962275f888b335252ad5bed0f34e959d3c7 Mon Sep 17 00:00:00 2001 From: benjy3gg Date: Sat, 20 Jul 2024 04:55:08 +0200 Subject: [PATCH] feat(Google News): Add `Enable CustomTabs` and `GmsCore support` patch (#3111) Co-authored-by: benjy3gg Co-authored-by: oSumAtrIX --- api/revanced-patches.api | 22 +++++++++ .../googlenews/customtabs/EnableCustomTabs.kt | 32 +++++++++++++ .../LaunchCustomTabFingerprint.kt | 18 +++++++ .../patches/googlenews/misc/gms/Constants.kt | 6 +++ .../misc/gms/GmsCoreSupportPatch.kt | 26 ++++++++++ .../misc/gms/GmsCoreSupportResourcePatch.kt | 11 +++++ .../MagazinesActivityOnCreateFingerprint.kt | 9 ++++ .../fingerprints/PrimeMethodFingerprint.kt | 7 +++ .../fingerprints/ServiceCheckFingerprint.kt | 12 +++++ .../misc/integrations/IntegrationsPatch.kt | 10 ++++ .../StartActivityInitFingerprint.kt | 41 ++++++++++++++++ .../detection/root/RootDetectionPatch.kt | 8 ++-- .../music/misc/gms/GmsCoreSupportPatch.kt | 6 +-- .../GooglePlayUtilityFingerprint.kt | 18 ------- .../customclients/ads/BaseDisableAdsPatch.kt | 2 +- .../subscription/UnlockSubscriptionPatch.kt | 2 +- .../misc/gms/BaseGmsCoreSupportPatch.kt | 14 ++++-- .../GooglePlayUtilityFingerprint.kt | 6 +-- .../youtube/misc/gms/GmsCoreSupportPatch.kt | 7 +-- .../kotlin/app/revanced/util/BytecodeUtils.kt | 47 ++++++++++++------- 20 files changed, 249 insertions(+), 55 deletions(-) create mode 100644 src/main/kotlin/app/revanced/patches/googlenews/customtabs/EnableCustomTabs.kt create mode 100644 src/main/kotlin/app/revanced/patches/googlenews/customtabs/fingerprints/LaunchCustomTabFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/googlenews/misc/gms/Constants.kt create mode 100644 src/main/kotlin/app/revanced/patches/googlenews/misc/gms/GmsCoreSupportPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/googlenews/misc/gms/GmsCoreSupportResourcePatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/googlenews/misc/gms/fingerprints/MagazinesActivityOnCreateFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/googlenews/misc/gms/fingerprints/PrimeMethodFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/googlenews/misc/gms/fingerprints/ServiceCheckFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/googlenews/misc/integrations/IntegrationsPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/googlenews/misc/integrations/fingerprints/StartActivityInitFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/misc/gms/fingerprints/GooglePlayUtilityFingerprint.kt rename src/main/kotlin/app/revanced/patches/{youtube => shared}/misc/gms/fingerprints/GooglePlayUtilityFingerprint.kt (80%) diff --git a/api/revanced-patches.api b/api/revanced-patches.api index 35e283213..e71ae0017 100644 --- a/api/revanced-patches.api +++ b/api/revanced-patches.api @@ -217,6 +217,24 @@ public final class app/revanced/patches/finanzonline/detection/root/RootDetectio public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V } +public final class app/revanced/patches/googlenews/customtabs/EnableCustomTabs : app/revanced/patcher/patch/BytecodePatch { + public static final field INSTANCE Lapp/revanced/patches/googlenews/customtabs/EnableCustomTabs; + public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V + public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V +} + +public final class app/revanced/patches/googlenews/misc/gms/GmsCoreSupportPatch : app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportPatch { + public static final field INSTANCE Lapp/revanced/patches/googlenews/misc/gms/GmsCoreSupportPatch; +} + +public final class app/revanced/patches/googlenews/misc/gms/GmsCoreSupportResourcePatch : app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportResourcePatch { + public static final field INSTANCE Lapp/revanced/patches/googlenews/misc/gms/GmsCoreSupportResourcePatch; +} + +public final class app/revanced/patches/googlenews/misc/integrations/IntegrationsPatch : app/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch { + public static final field INSTANCE Lapp/revanced/patches/googlenews/misc/integrations/IntegrationsPatch; +} + public final class app/revanced/patches/googlerecorder/restrictions/RemoveDeviceRestrictions : app/revanced/patcher/patch/BytecodePatch { public static final field INSTANCE Lapp/revanced/patches/googlerecorder/restrictions/RemoveDeviceRestrictions; public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V @@ -2033,7 +2051,11 @@ public final class app/revanced/util/BytecodeUtilsKt { public static final fun indexOfIdResourceOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/String;)I public static final fun injectHideViewCall (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;IILjava/lang/String;Ljava/lang/String;)V public static final fun resultOrThrow (Lapp/revanced/patcher/fingerprint/MethodFingerprint;)Lapp/revanced/patcher/fingerprint/MethodFingerprintResult; + public static final fun returnEarly (Lapp/revanced/patcher/fingerprint/MethodFingerprint;Z)V + public static final fun returnEarly (Ljava/lang/Iterable;Z)V public static final fun returnEarly (Ljava/util/List;Z)V + public static synthetic fun returnEarly$default (Lapp/revanced/patcher/fingerprint/MethodFingerprint;ZILjava/lang/Object;)V + public static synthetic fun returnEarly$default (Ljava/lang/Iterable;ZILjava/lang/Object;)V public static synthetic fun returnEarly$default (Ljava/util/List;ZILjava/lang/Object;)V public static final fun transformMethods (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;Lkotlin/jvm/functions/Function1;)V public static final fun traverseClassHierarchy (Lapp/revanced/patcher/data/BytecodeContext;Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;Lkotlin/jvm/functions/Function1;)V diff --git a/src/main/kotlin/app/revanced/patches/googlenews/customtabs/EnableCustomTabs.kt b/src/main/kotlin/app/revanced/patches/googlenews/customtabs/EnableCustomTabs.kt new file mode 100644 index 000000000..9e520c41e --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/googlenews/customtabs/EnableCustomTabs.kt @@ -0,0 +1,32 @@ +package app.revanced.patches.googlenews.customtabs + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patches.googlenews.customtabs.fingerprints.LaunchCustomTabFingerprint +import app.revanced.util.resultOrThrow +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction + +@Patch( + name = "Enable CustomTabs", + description = "Enables CustomTabs to open articles in your default browser.", + compatiblePackages = [CompatiblePackage("com.google.android.apps.magazines")], +) +@Suppress("unused") +object EnableCustomTabs : BytecodePatch( + setOf(LaunchCustomTabFingerprint) +) { + override fun execute(context: BytecodeContext) { + LaunchCustomTabFingerprint.resultOrThrow().let { result -> + result.mutableMethod.apply { + val checkIndex = result.scanResult.patternScanResult!!.endIndex + 1 + val register = getInstruction(checkIndex).registerA + + replaceInstruction(checkIndex, "const/4 v$register, 0x1") + } + } + } +} diff --git a/src/main/kotlin/app/revanced/patches/googlenews/customtabs/fingerprints/LaunchCustomTabFingerprint.kt b/src/main/kotlin/app/revanced/patches/googlenews/customtabs/fingerprints/LaunchCustomTabFingerprint.kt new file mode 100644 index 000000000..fcb39ba1d --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/googlenews/customtabs/fingerprints/LaunchCustomTabFingerprint.kt @@ -0,0 +1,18 @@ +package app.revanced.patches.googlenews.customtabs.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +internal object LaunchCustomTabFingerprint : MethodFingerprint( + accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, + opcodes = listOf( + Opcode.IPUT_OBJECT, + Opcode.CONST_4, + Opcode.IPUT, + Opcode.CONST_4, + Opcode.IPUT_BOOLEAN, + ), + customFingerprint = { _, classDef -> classDef.endsWith("CustomTabsArticleLauncher;") }, +) diff --git a/src/main/kotlin/app/revanced/patches/googlenews/misc/gms/Constants.kt b/src/main/kotlin/app/revanced/patches/googlenews/misc/gms/Constants.kt new file mode 100644 index 000000000..fb5606248 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/googlenews/misc/gms/Constants.kt @@ -0,0 +1,6 @@ +package app.revanced.patches.googlenews.misc.gms + +internal object Constants { + const val MAGAZINES_PACKAGE_NAME = "com.google.android.apps.magazines" + const val REVANCED_MAGAZINES_PACKAGE_NAME = "app.revanced.android.magazines" +} diff --git a/src/main/kotlin/app/revanced/patches/googlenews/misc/gms/GmsCoreSupportPatch.kt b/src/main/kotlin/app/revanced/patches/googlenews/misc/gms/GmsCoreSupportPatch.kt new file mode 100644 index 000000000..e0e239d6a --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/googlenews/misc/gms/GmsCoreSupportPatch.kt @@ -0,0 +1,26 @@ +package app.revanced.patches.googlenews.misc.gms + +import app.revanced.patches.googlenews.misc.gms.Constants.MAGAZINES_PACKAGE_NAME +import app.revanced.patches.googlenews.misc.gms.Constants.REVANCED_MAGAZINES_PACKAGE_NAME +import app.revanced.patches.googlenews.misc.gms.GmsCoreSupportResourcePatch.gmsCoreVendorGroupIdOption +import app.revanced.patches.googlenews.misc.gms.fingerprints.MagazinesActivityOnCreateFingerprint +import app.revanced.patches.googlenews.misc.gms.fingerprints.ServiceCheckFingerprint +import app.revanced.patches.googlenews.misc.integrations.IntegrationsPatch +import app.revanced.patches.shared.misc.gms.BaseGmsCoreSupportPatch + +@Suppress("unused") +object GmsCoreSupportPatch : BaseGmsCoreSupportPatch( + fromPackageName = MAGAZINES_PACKAGE_NAME, + toPackageName = REVANCED_MAGAZINES_PACKAGE_NAME, + primeMethodFingerprint = null, + earlyReturnFingerprints = setOf(ServiceCheckFingerprint), + mainActivityOnCreateFingerprint = MagazinesActivityOnCreateFingerprint, + integrationsPatchDependency = IntegrationsPatch::class, + gmsCoreSupportResourcePatch = GmsCoreSupportResourcePatch, + // Remove version constraint, + // once https://github.com/ReVanced/revanced-patches/pull/3111#issuecomment-2240877277 is resolved. + compatiblePackages = setOf(CompatiblePackage(MAGAZINES_PACKAGE_NAME, setOf("5.108.0.644447823"))), + fingerprints = setOf(ServiceCheckFingerprint), +) { + override val gmsCoreVendorGroupId by gmsCoreVendorGroupIdOption +} diff --git a/src/main/kotlin/app/revanced/patches/googlenews/misc/gms/GmsCoreSupportResourcePatch.kt b/src/main/kotlin/app/revanced/patches/googlenews/misc/gms/GmsCoreSupportResourcePatch.kt new file mode 100644 index 000000000..fd8bc9e03 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/googlenews/misc/gms/GmsCoreSupportResourcePatch.kt @@ -0,0 +1,11 @@ +package app.revanced.patches.googlenews.misc.gms + +import app.revanced.patches.googlenews.misc.gms.Constants.MAGAZINES_PACKAGE_NAME +import app.revanced.patches.googlenews.misc.gms.Constants.REVANCED_MAGAZINES_PACKAGE_NAME +import app.revanced.patches.shared.misc.gms.BaseGmsCoreSupportResourcePatch + +object GmsCoreSupportResourcePatch : BaseGmsCoreSupportResourcePatch( + fromPackageName = MAGAZINES_PACKAGE_NAME, + toPackageName = REVANCED_MAGAZINES_PACKAGE_NAME, + spoofedPackageSignature = "24bb24c05e47e0aefa68a58a766179d9b613a666", +) diff --git a/src/main/kotlin/app/revanced/patches/googlenews/misc/gms/fingerprints/MagazinesActivityOnCreateFingerprint.kt b/src/main/kotlin/app/revanced/patches/googlenews/misc/gms/fingerprints/MagazinesActivityOnCreateFingerprint.kt new file mode 100644 index 000000000..aa7834f86 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/googlenews/misc/gms/fingerprints/MagazinesActivityOnCreateFingerprint.kt @@ -0,0 +1,9 @@ +package app.revanced.patches.googlenews.misc.gms.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint + +internal object MagazinesActivityOnCreateFingerprint : MethodFingerprint( + customFingerprint = { methodDef, classDef -> + methodDef.name == "onCreate" && classDef.endsWith("/StartActivity;") + }, +) diff --git a/src/main/kotlin/app/revanced/patches/googlenews/misc/gms/fingerprints/PrimeMethodFingerprint.kt b/src/main/kotlin/app/revanced/patches/googlenews/misc/gms/fingerprints/PrimeMethodFingerprint.kt new file mode 100644 index 000000000..6ec214bbf --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/googlenews/misc/gms/fingerprints/PrimeMethodFingerprint.kt @@ -0,0 +1,7 @@ +package app.revanced.patches.googlenews.misc.gms.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint + +internal object PrimeMethodFingerprint : MethodFingerprint( + strings = listOf("com.google.android.GoogleCamera", "com.android.vending"), +) diff --git a/src/main/kotlin/app/revanced/patches/googlenews/misc/gms/fingerprints/ServiceCheckFingerprint.kt b/src/main/kotlin/app/revanced/patches/googlenews/misc/gms/fingerprints/ServiceCheckFingerprint.kt new file mode 100644 index 000000000..b8228f7ef --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/googlenews/misc/gms/fingerprints/ServiceCheckFingerprint.kt @@ -0,0 +1,12 @@ +package app.revanced.patches.googlenews.misc.gms.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +internal object ServiceCheckFingerprint : MethodFingerprint( + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC, + parameters = listOf("L", "I"), + strings = listOf("Google Play Services not available", "GooglePlayServices not available due to error "), +) diff --git a/src/main/kotlin/app/revanced/patches/googlenews/misc/integrations/IntegrationsPatch.kt b/src/main/kotlin/app/revanced/patches/googlenews/misc/integrations/IntegrationsPatch.kt new file mode 100644 index 000000000..40e7d880f --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/googlenews/misc/integrations/IntegrationsPatch.kt @@ -0,0 +1,10 @@ +package app.revanced.patches.googlenews.misc.integrations + +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patches.googlenews.misc.integrations.fingerprints.StartActivityInitFingerprint +import app.revanced.patches.shared.misc.integrations.BaseIntegrationsPatch + +@Patch(requiresIntegrations = true) +object IntegrationsPatch : BaseIntegrationsPatch( + setOf(StartActivityInitFingerprint), +) diff --git a/src/main/kotlin/app/revanced/patches/googlenews/misc/integrations/fingerprints/StartActivityInitFingerprint.kt b/src/main/kotlin/app/revanced/patches/googlenews/misc/integrations/fingerprints/StartActivityInitFingerprint.kt new file mode 100644 index 000000000..d69070665 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/googlenews/misc/integrations/fingerprints/StartActivityInitFingerprint.kt @@ -0,0 +1,41 @@ +package app.revanced.patches.googlenews.misc.integrations.fingerprints + +import app.revanced.patches.googlenews.misc.integrations.fingerprints.StartActivityInitFingerprint.getApplicationContextIndex +import app.revanced.patches.shared.misc.integrations.BaseIntegrationsPatch.IntegrationsFingerprint +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstructionOrThrow +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import com.android.tools.smali.dexlib2.iface.reference.MethodReference + +internal object StartActivityInitFingerprint : IntegrationsFingerprint( + opcodes = listOf( + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT, + Opcode.CONST_4, + Opcode.IF_EQZ, + Opcode.CONST, + Opcode.INVOKE_VIRTUAL, + Opcode.IPUT_OBJECT, + Opcode.IPUT_BOOLEAN, + Opcode.INVOKE_VIRTUAL, // Calls startActivity.getApplicationContext(). + Opcode.MOVE_RESULT_OBJECT, + ), + insertIndexResolver = { method -> + getApplicationContextIndex = method.indexOfFirstInstructionOrThrow { + getReference()?.name == "getApplicationContext" + } + + getApplicationContextIndex + 2 // Below the move-result-object instruction + }, + contextRegisterResolver = { method -> + val moveResultInstruction = method.implementation!!.instructions.elementAt(getApplicationContextIndex + 1) + as OneRegisterInstruction + moveResultInstruction.registerA + }, + customFingerprint = { methodDef, classDef -> + methodDef.name == "onCreate" && classDef.endsWith("/StartActivity;") + }, +) { + private var getApplicationContextIndex = -1 +} diff --git a/src/main/kotlin/app/revanced/patches/idaustria/detection/root/RootDetectionPatch.kt b/src/main/kotlin/app/revanced/patches/idaustria/detection/root/RootDetectionPatch.kt index 2b720d3b2..16e5c7e7b 100644 --- a/src/main/kotlin/app/revanced/patches/idaustria/detection/root/RootDetectionPatch.kt +++ b/src/main/kotlin/app/revanced/patches/idaustria/detection/root/RootDetectionPatch.kt @@ -12,15 +12,15 @@ import app.revanced.util.returnEarly @Patch( name = "Remove root detection", description = "Removes the check for root permissions and unlocked bootloader.", - compatiblePackages = [CompatiblePackage("at.gv.oe.app")] + compatiblePackages = [CompatiblePackage("at.gv.oe.app")], ) @Suppress("unused") object RootDetectionPatch : BytecodePatch( - setOf(AttestationSupportedCheckFingerprint, BootloaderCheckFingerprint, RootCheckFingerprint) + setOf(AttestationSupportedCheckFingerprint, BootloaderCheckFingerprint, RootCheckFingerprint), ) { - override fun execute(context: BytecodeContext) = listOf( + override fun execute(context: BytecodeContext) = setOf( AttestationSupportedCheckFingerprint, BootloaderCheckFingerprint, - RootCheckFingerprint + RootCheckFingerprint, ).returnEarly(true) } diff --git a/src/main/kotlin/app/revanced/patches/music/misc/gms/GmsCoreSupportPatch.kt b/src/main/kotlin/app/revanced/patches/music/misc/gms/GmsCoreSupportPatch.kt index 311aeb11f..db41381bb 100644 --- a/src/main/kotlin/app/revanced/patches/music/misc/gms/GmsCoreSupportPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/misc/gms/GmsCoreSupportPatch.kt @@ -15,7 +15,6 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch( primeMethodFingerprint = PrimeMethodFingerprint, earlyReturnFingerprints = setOf( ServiceCheckFingerprint, - GooglePlayUtilityFingerprint, CastDynamiteModuleFingerprint, CastDynamiteModuleV2Fingerprint, CastContextFetchFingerprint, @@ -32,12 +31,11 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch( "7.01.53", "7.02.52", "7.03.52", - ) - ) + ), + ), ), fingerprints = setOf( ServiceCheckFingerprint, - GooglePlayUtilityFingerprint, CastDynamiteModuleFingerprint, CastDynamiteModuleV2Fingerprint, CastContextFetchFingerprint, diff --git a/src/main/kotlin/app/revanced/patches/music/misc/gms/fingerprints/GooglePlayUtilityFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/misc/gms/fingerprints/GooglePlayUtilityFingerprint.kt deleted file mode 100644 index 45b49b345..000000000 --- a/src/main/kotlin/app/revanced/patches/music/misc/gms/fingerprints/GooglePlayUtilityFingerprint.kt +++ /dev/null @@ -1,18 +0,0 @@ -package app.revanced.patches.music.misc.gms.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.AccessFlags - -internal object GooglePlayUtilityFingerprint : MethodFingerprint( - "I", - AccessFlags.PUBLIC or AccessFlags.STATIC, - listOf("L", "I"), - strings = listOf( - "This should never happen.", - "MetadataValueReader", - "GooglePlayServicesUtil", - "com.android.vending", - "android.hardware.type.embedded" - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/ads/BaseDisableAdsPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/ads/BaseDisableAdsPatch.kt index c8697180b..d412f84fc 100644 --- a/src/main/kotlin/app/revanced/patches/reddit/customclients/ads/BaseDisableAdsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/ads/BaseDisableAdsPatch.kt @@ -15,5 +15,5 @@ abstract class BaseDisableAdsPatch( compatiblePackages = compatiblePackages, fingerprints = setOf(IsAdsEnabledFingerprint), ) { - override fun execute(context: BytecodeContext) = listOf(IsAdsEnabledFingerprint).returnEarly() + override fun execute(context: BytecodeContext) = IsAdsEnabledFingerprint.returnEarly() } diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/subscription/UnlockSubscriptionPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/subscription/UnlockSubscriptionPatch.kt index a80adb154..02a274549 100644 --- a/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/subscription/UnlockSubscriptionPatch.kt +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/subscription/UnlockSubscriptionPatch.kt @@ -22,5 +22,5 @@ object UnlockSubscriptionPatch : BytecodePatch( setOf(StartSubscriptionActivityFingerprint, BillingClientOnServiceConnected), ) { override fun execute(context: BytecodeContext) = - listOf(StartSubscriptionActivityFingerprint, BillingClientOnServiceConnected).returnEarly() + setOf(StartSubscriptionActivityFingerprint, BillingClientOnServiceConnected).returnEarly() } diff --git a/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportPatch.kt b/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportPatch.kt index dd3fa0b59..9eb35018a 100644 --- a/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportPatch.kt +++ b/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportPatch.kt @@ -13,6 +13,7 @@ import app.revanced.patches.shared.misc.gms.BaseGmsCoreSupportPatch.Constants.AU import app.revanced.patches.shared.misc.gms.BaseGmsCoreSupportPatch.Constants.PERMISSIONS import app.revanced.patches.shared.misc.gms.fingerprints.GmsCoreSupportFingerprint import app.revanced.patches.shared.misc.gms.fingerprints.GmsCoreSupportFingerprint.GET_GMS_CORE_VENDOR_GROUP_ID_METHOD_NAME +import app.revanced.patches.shared.misc.gms.fingerprints.GooglePlayUtilityFingerprint import app.revanced.util.exception import app.revanced.util.getReference import app.revanced.util.returnEarly @@ -42,7 +43,7 @@ import com.android.tools.smali.dexlib2.util.MethodUtil abstract class BaseGmsCoreSupportPatch( private val fromPackageName: String, private val toPackageName: String, - private val primeMethodFingerprint: MethodFingerprint, + private val primeMethodFingerprint: MethodFingerprint?, private val earlyReturnFingerprints: Set, private val mainActivityOnCreateFingerprint: MethodFingerprint, private val integrationsPatchDependency: PatchClass, @@ -62,6 +63,7 @@ abstract class BaseGmsCoreSupportPatch( compatiblePackages = compatiblePackages, fingerprints = setOf( GmsCoreSupportFingerprint, + GooglePlayUtilityFingerprint, mainActivityOnCreateFingerprint, ) + fingerprints, requiresIntegrations = true, @@ -91,10 +93,13 @@ abstract class BaseGmsCoreSupportPatch( } // Specific method that needs to be patched. - transformPrimeMethod(packageName) + primeMethodFingerprint?.let { transformPrimeMethod(packageName) } // Return these methods early to prevent the app from crashing. - earlyReturnFingerprints.toList().returnEarly() + earlyReturnFingerprints.returnEarly() + if (GooglePlayUtilityFingerprint.result != null) { + GooglePlayUtilityFingerprint.returnEarly() + } // Verify GmsCore is installed and whitelisted for power optimizations and background usage. mainActivityOnCreateFingerprint.result?.mutableMethod?.addInstructions( @@ -192,7 +197,7 @@ abstract class BaseGmsCoreSupportPatch( } private fun transformPrimeMethod(packageName: String) { - primeMethodFingerprint.result?.mutableMethod?.apply { + primeMethodFingerprint!!.result?.mutableMethod?.apply { var register = 2 val index = getInstructions().indexOfFirst { @@ -305,6 +310,7 @@ abstract class BaseGmsCoreSupportPatch( "com.google.android.gms.languageprofile.service.START", "com.google.android.gms.clearcut.service.START", "com.google.android.gms.icing.LIGHTWEIGHT_INDEX_SERVICE", + "com.google.android.gms.accountsettings.action.VIEW_SETTINGS", // potoken "com.google.android.gms.potokens.service.START", diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/gms/fingerprints/GooglePlayUtilityFingerprint.kt b/src/main/kotlin/app/revanced/patches/shared/misc/gms/fingerprints/GooglePlayUtilityFingerprint.kt similarity index 80% rename from src/main/kotlin/app/revanced/patches/youtube/misc/gms/fingerprints/GooglePlayUtilityFingerprint.kt rename to src/main/kotlin/app/revanced/patches/shared/misc/gms/fingerprints/GooglePlayUtilityFingerprint.kt index 219602aa4..be3fc0455 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/gms/fingerprints/GooglePlayUtilityFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/shared/misc/gms/fingerprints/GooglePlayUtilityFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.misc.gms.fingerprints +package app.revanced.patches.shared.misc.gms.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint @@ -8,5 +8,5 @@ internal object GooglePlayUtilityFingerprint : MethodFingerprint( returnType = "I", accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC, parameters = listOf("L", "I"), - strings = listOf("This should never happen.", "MetadataValueReader", "com.google.android.gms") -) \ No newline at end of file + strings = listOf("This should never happen.", "MetadataValueReader", "com.google.android.gms"), +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportPatch.kt index 3ce5a8676..c2255025f 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportPatch.kt @@ -7,7 +7,10 @@ import app.revanced.patches.youtube.misc.fix.playback.SpoofClientPatch import app.revanced.patches.youtube.misc.gms.Constants.REVANCED_YOUTUBE_PACKAGE_NAME import app.revanced.patches.youtube.misc.gms.Constants.YOUTUBE_PACKAGE_NAME import app.revanced.patches.youtube.misc.gms.GmsCoreSupportResourcePatch.gmsCoreVendorGroupIdOption -import app.revanced.patches.youtube.misc.gms.fingerprints.* +import app.revanced.patches.youtube.misc.gms.fingerprints.CastDynamiteModuleFingerprint +import app.revanced.patches.youtube.misc.gms.fingerprints.CastDynamiteModuleV2Fingerprint +import app.revanced.patches.youtube.misc.gms.fingerprints.PrimeMethodFingerprint +import app.revanced.patches.youtube.misc.gms.fingerprints.ServiceCheckFingerprint import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch import app.revanced.patches.youtube.shared.fingerprints.MainActivityOnCreateFingerprint @@ -18,7 +21,6 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch( primeMethodFingerprint = PrimeMethodFingerprint, earlyReturnFingerprints = setOf( ServiceCheckFingerprint, - GooglePlayUtilityFingerprint, CastDynamiteModuleFingerprint, CastDynamiteModuleV2Fingerprint, CastContextFetchFingerprint, @@ -62,7 +64,6 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch( ), fingerprints = setOf( ServiceCheckFingerprint, - GooglePlayUtilityFingerprint, CastDynamiteModuleFingerprint, CastDynamiteModuleV2Fingerprint, CastContextFetchFingerprint, diff --git a/src/main/kotlin/app/revanced/util/BytecodeUtils.kt b/src/main/kotlin/app/revanced/util/BytecodeUtils.kt index 7e5388d3f..f0ac585cc 100644 --- a/src/main/kotlin/app/revanced/util/BytecodeUtils.kt +++ b/src/main/kotlin/app/revanced/util/BytecodeUtils.kt @@ -114,7 +114,7 @@ fun Method.indexOfFirstWideLiteralInstructionValue(literal: Long) = implementati * * @return the first literal instruction with the value, or throws [PatchException] if not found. */ -fun Method.indexOfFirstWideLiteralInstructionValueOrThrow(literal: Long) : Int { +fun Method.indexOfFirstWideLiteralInstructionValueOrThrow(literal: Long): Int { val index = indexOfFirstWideLiteralInstructionValue(literal) if (index < 0) throw PatchException("Could not find literal value: $literal") return index @@ -160,7 +160,7 @@ inline fun Instruction.getReference() = (this as? Refere // TODO: delete this on next major release, the overloaded method with an optional start index serves the same purposes. // Method is deprecated, but annotation is commented out otherwise during compilation usage of the replacement is // incorrectly flagged as deprecated. -//@Deprecated("Use the overloaded method with an optional start index.", ReplaceWith("indexOfFirstInstruction(predicate)")) +// @Deprecated("Use the overloaded method with an optional start index.", ReplaceWith("indexOfFirstInstruction(predicate)")) fun Method.indexOfFirstInstruction(predicate: Instruction.() -> Boolean) = indexOfFirstInstruction(0, predicate) /** @@ -211,28 +211,41 @@ fun Method.findOpcodeIndicesReversed(opcode: Opcode): List { } /** - * Return the resolved methods of [MethodFingerprint]s early. + * Return the resolved method early. */ -fun List.returnEarly(bool: Boolean = false) { +fun MethodFingerprint.returnEarly(bool: Boolean = false) { val const = if (bool) "0x1" else "0x0" - this.forEach { fingerprint -> - fingerprint.result?.let { result -> - val stringInstructions = when (result.method.returnType.first()) { - 'L' -> - """ + result?.let { result -> + val stringInstructions = when (result.method.returnType.first()) { + 'L' -> + """ const/4 v0, $const return-object v0 """ - 'V' -> "return-void" - 'I', 'Z' -> - """ + 'V' -> "return-void" + 'I', 'Z' -> + """ const/4 v0, $const return v0 """ - else -> throw Exception("This case should never happen.") - } + else -> throw Exception("This case should never happen.") + } - result.mutableMethod.addInstructions(0, stringInstructions) - } ?: throw fingerprint.exception - } + result.mutableMethod.addInstructions(0, stringInstructions) + } ?: throw exception +} + +/** + * Return the resolved methods early. + */ +fun Iterable.returnEarly(bool: Boolean = false) = forEach { fingerprint -> + fingerprint.returnEarly(bool) +} + +/** + * Return the resolved methods early. + */ +@Deprecated("Use the Iterable version") +fun List.returnEarly(bool: Boolean = false) = forEach { fingerprint -> + fingerprint.returnEarly(bool) }