Compare commits

...

7 Commits

21 changed files with 244 additions and 13 deletions

View File

@ -1,3 +1,10 @@
# [4.8.0-dev.16](https://github.com/ReVanced/revanced-patches/compare/v4.8.0-dev.15...v4.8.0-dev.16) (2024-05-12)
### Features
* **WarnWetter - Promo code unlock:** Constrain to last working version ([#3110](https://github.com/ReVanced/revanced-patches/issues/3110)) ([92fc8aa](https://github.com/ReVanced/revanced-patches/commit/92fc8aaad80f8fad35b75e6de032692986211536))
# [4.8.0-dev.15](https://github.com/ReVanced/revanced-patches/compare/v4.8.0-dev.14...v4.8.0-dev.15) (2024-05-11)

View File

@ -259,6 +259,24 @@ public final class app/revanced/patches/lightroom/misc/premium/UnlockPremiumPatc
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
}
public final class app/revanced/patches/magazines/misc/customtabs/UseCustomTabs : app/revanced/patcher/patch/BytecodePatch {
public static final field INSTANCE Lapp/revanced/patches/magazines/misc/customtabs/UseCustomTabs;
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/magazines/misc/gms/GmsCoreSupportPatch : app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportPatch {
public static final field INSTANCE Lapp/revanced/patches/magazines/misc/gms/GmsCoreSupportPatch;
}
public final class app/revanced/patches/magazines/misc/gms/GmsCoreSupportResourcePatch : app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportResourcePatch {
public static final field INSTANCE Lapp/revanced/patches/magazines/misc/gms/GmsCoreSupportResourcePatch;
}
public final class app/revanced/patches/magazines/misc/integrations/IntegrationsPatch : app/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch {
public static final field INSTANCE Lapp/revanced/patches/magazines/misc/integrations/IntegrationsPatch;
}
public final class app/revanced/patches/memegenerator/detection/license/LicenseValidationPatch : app/revanced/patcher/patch/BytecodePatch {
public static final field INSTANCE Lapp/revanced/patches/memegenerator/detection/license/LicenseValidationPatch;
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V

View File

@ -1,4 +1,4 @@
org.gradle.parallel = true
org.gradle.caching = true
kotlin.code.style = official
version = 4.8.0-dev.15
version = 4.8.0-dev.16

View File

@ -0,0 +1,26 @@
package app.revanced.patches.magazines.misc.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.magazines.misc.gms.customtabs.fingerprints.UseCustomTabsFingerprint
import app.revanced.util.exception
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Patch(
name = "Enable CustomTabs",
description = "Enables CustomTabs which allows the Articles to be opened in your set Default Browser instead of Chrome.",
dependencies = [],
compatiblePackages = [CompatiblePackage("com.google.android.apps.magazines")]
)
@Suppress("unused")
object UseCustomTabs : BytecodePatch(setOf(UseCustomTabsFingerprint)) {
override fun execute(context: BytecodeContext) = UseCustomTabsFingerprint.result?.let { result ->
val cmpIndex = result.scanResult.patternScanResult!!.endIndex + 1
val cmpResultRegister = result.mutableMethod.getInstruction<OneRegisterInstruction>(cmpIndex).registerA
result.mutableMethod.replaceInstruction(cmpIndex, "const/4 v${cmpResultRegister}, 0x1")
} ?: throw UseCustomTabsFingerprint.exception
}

View File

@ -0,0 +1,19 @@
package app.revanced.patches.magazines.misc.gms.customtabs.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.Opcode
import app.revanced.patcher.extensions.or
import com.android.tools.smali.dexlib2.AccessFlags
internal object UseCustomTabsFingerprint : MethodFingerprint(
opcodes = listOf(
Opcode.IPUT_OBJECT,
Opcode.CONST_4,
Opcode.IPUT,
Opcode.CONST_4,
Opcode.IPUT_BOOLEAN
),
customFingerprint = { methodDef, _ ->
methodDef.definingClass == "Lcom/google/apps/dots/android/modules/reading/customtabs/CustomTabsArticleLauncher;" && methodDef.accessFlags == AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR
},
)

View File

@ -0,0 +1,6 @@
package app.revanced.patches.magazines.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"
}

View File

@ -0,0 +1,36 @@
package app.revanced.patches.magazines.misc.gms
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patches.shared.misc.gms.BaseGmsCoreSupportPatch
import app.revanced.patches.magazines.misc.gms.Constants.MAGAZINES_PACKAGE_NAME
import app.revanced.patches.magazines.misc.gms.Constants.REVANCED_MAGAZINES_PACKAGE_NAME
import app.revanced.patches.magazines.misc.gms.GmsCoreSupportResourcePatch.gmsCoreVendorGroupIdOption
import app.revanced.patches.magazines.misc.integrations.IntegrationsPatch
import app.revanced.patches.magazines.misc.gms.fingerprints.MagazinesActivityOnCreateFingerprint
import app.revanced.patches.magazines.misc.gms.fingerprints.GooglePlayUtilityFingerprint
import app.revanced.patches.magazines.misc.gms.fingerprints.ServiceCheckFingerprint
@Suppress("unused")
object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
fromPackageName = MAGAZINES_PACKAGE_NAME,
toPackageName = REVANCED_MAGAZINES_PACKAGE_NAME,
primeMethodFingerprint = null,
earlyReturnFingerprints = setOf(
ServiceCheckFingerprint,
GooglePlayUtilityFingerprint,
),
mainActivityOnCreateFingerprint = MagazinesActivityOnCreateFingerprint,
integrationsPatchDependency = IntegrationsPatch::class,
gmsCoreSupportResourcePatch = GmsCoreSupportResourcePatch,
compatiblePackages = setOf(
CompatiblePackage(
MAGAZINES_PACKAGE_NAME,
),
),
fingerprints = setOf(
ServiceCheckFingerprint,
GooglePlayUtilityFingerprint,
),
) {
override val gmsCoreVendorGroupId by gmsCoreVendorGroupIdOption
}

View File

@ -0,0 +1,11 @@
package app.revanced.patches.magazines.misc.gms
import app.revanced.patches.shared.misc.gms.BaseGmsCoreSupportResourcePatch
import app.revanced.patches.magazines.misc.gms.Constants.MAGAZINES_PACKAGE_NAME
import app.revanced.patches.magazines.misc.gms.Constants.REVANCED_MAGAZINES_PACKAGE_NAME
object GmsCoreSupportResourcePatch : BaseGmsCoreSupportResourcePatch(
fromPackageName = MAGAZINES_PACKAGE_NAME,
toPackageName = REVANCED_MAGAZINES_PACKAGE_NAME,
spoofedPackageSignature = "24bb24c05e47e0aefa68a58a766179d9b613a666",
)

View File

@ -0,0 +1,12 @@
package app.revanced.patches.magazines.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(
returnType = "I",
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
parameters = listOf("L", "I"),
strings = listOf("This should never happen.", "MetadataValueReader", "com.google.android.gms")
)

View File

@ -0,0 +1,9 @@
package app.revanced.patches.magazines.misc.gms.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint
internal object MagazinesActivityOnCreateFingerprint : MethodFingerprint(
customFingerprint = { methodDef, classDef ->
classDef.type.endsWith("/StartActivity;") && methodDef.name == "onCreate"
}
)

View File

@ -0,0 +1,8 @@
package app.revanced.patches.magazines.misc.gms.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint
internal object PrimeMethodFingerprint : MethodFingerprint(
strings = listOf("com.google.android.GoogleCamera", "com.android.vending")
)

View File

@ -0,0 +1,12 @@
package app.revanced.patches.magazines.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 ")
)

View File

@ -0,0 +1,12 @@
package app.revanced.patches.magazines.misc.integrations
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.magazines.misc.integrations.fingerprints.StartActivityInitFingerprint
import app.revanced.patches.shared.misc.integrations.BaseIntegrationsPatch
@Patch(requiresIntegrations = true)
object IntegrationsPatch : BaseIntegrationsPatch(
setOf(
StartActivityInitFingerprint
),
)

View File

@ -0,0 +1,44 @@
package app.revanced.patches.magazines.misc.integrations.fingerprints
import app.revanced.patches.shared.misc.integrations.BaseIntegrationsPatch.IntegrationsFingerprint
import app.revanced.util.getReference
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction11x
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
import app.revanced.patcher.extensions.InstructionExtensions.getInstructions
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
import com.android.tools.smali.dexlib2.iface.instruction.Instruction
private var index: Int = -1
private var instructions: List<Instruction> = listOf()
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, // invoke-virtual {p0}, Lcom/google/apps/dots/android/newsstand/activity/StartActivity;->getApplicationContext()Landroid/content/Context;
Opcode.MOVE_RESULT_OBJECT, // move-result-object v2
),
insertIndexResolver = { method ->
instructions = method.toMutable().getInstructions()
index = instructions.indexOfFirst {
return@indexOfFirst it.getReference<MethodReference>()?.name?.contains("getApplicationContext") == true
}
if(index == -1) {
throw PatchException("Error finding the application context.")
}
index + 2 // put this below move-result-object v2
},
contextRegisterResolver = { _ ->
((instructions[index + 1] as BuilderInstruction11x).registerA) // get move-result-object v2 using the provided index
},
customFingerprint = { methodDef, _ -> methodDef.definingClass == "Lcom/google/apps/dots/android/newsstand/activity/StartActivity;" && methodDef.name == "onCreate" },
)

View File

@ -14,7 +14,7 @@ import kotlin.random.Random
name = "Spoof device ID",
description = "Spoofs device ID to mitigate manual bans by developers.",
dependencies = [SignatureDetectionPatch::class],
compatiblePackages = [CompatiblePackage("com.microblink.photomath", ["8.32.0"])]
compatiblePackages = [CompatiblePackage("com.microblink.photomath", ["8.37.0"])]
)
@Suppress("unused")
object SpoofDeviceIdPatch : BytecodePatch(

View File

@ -1,9 +1,21 @@
package app.revanced.patches.photomath.detection.deviceid.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.Opcode
internal object GetDeviceIdFingerprint : MethodFingerprint(
returnType = "Ljava/lang/String;",
strings = listOf("androidId", "android_id"),
opcodes = listOf(
Opcode.SGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IF_NEZ,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_VIRTUAL,
),
parameters = listOf()
)

View File

@ -5,11 +5,9 @@ import com.android.tools.smali.dexlib2.Opcode
internal object CheckSignatureFingerprint : MethodFingerprint(
strings = listOf(
"packageInfo.signatures",
"currentSignature"
"signatures",
),
opcodes = listOf(
Opcode.CONST_STRING,
Opcode.CONST_STRING,
Opcode.INVOKE_STATIC,
Opcode.INVOKE_STATIC,

View File

@ -13,7 +13,7 @@ import app.revanced.util.exception
name = "Hide update popup",
description = "Prevents the update popup from showing up.",
dependencies = [SignatureDetectionPatch::class],
compatiblePackages = [CompatiblePackage("com.microblink.photomath", ["8.32.0"])]
compatiblePackages = [CompatiblePackage("com.microblink.photomath", ["8.37.0"])]
)
@Suppress("unused")
object HideUpdatePopupPatch : BytecodePatch(

View File

@ -13,7 +13,7 @@ import app.revanced.patches.photomath.misc.unlock.plus.fingerprints.IsPlusUnlock
@Patch(
name = "Unlock plus",
dependencies = [SignatureDetectionPatch::class, EnableBookpointPatch::class],
compatiblePackages = [CompatiblePackage("com.microblink.photomath", ["8.32.0"])]
compatiblePackages = [CompatiblePackage("com.microblink.photomath", ["8.37.0"])]
)
@Suppress("unused")
object UnlockPlusPatch : BytecodePatch(

View File

@ -42,7 +42,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<MethodFingerprint>,
private val mainActivityOnCreateFingerprint: MethodFingerprint,
private val integrationsPatchDependency: PatchClass,
@ -91,7 +91,7 @@ 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()
@ -192,7 +192,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 +305,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",

View File

@ -12,7 +12,7 @@ import app.revanced.patches.warnwetter.misc.promocode.fingerprints.PromoCodeUnlo
name = "Promo code unlock",
description = "Disables the validation of promo code. Any code will work to unlock all features.",
dependencies = [FirebaseGetCertPatch::class],
compatiblePackages = [CompatiblePackage("de.dwd.warnapp")]
compatiblePackages = [CompatiblePackage("de.dwd.warnapp", ["4.2.2"])]
)
@Suppress("unused")
object PromoCodeUnlockPatch : BytecodePatch(
@ -28,4 +28,4 @@ object PromoCodeUnlockPatch : BytecodePatch(
"""
)
}
}
}