mirror of
https://github.com/inotia00/revanced-patches.git
synced 2025-06-12 13:17:46 +02:00
fix(GmsCore support): Spoof package name (#57)
* fix(YouTube - GMSCore Support): Spoof `requestChecksum` package name * Apply code review suggestions * fix(YouTube - GmsCore Support): Add `YouTube` package visibility * feat(GmsCore support): Add the `android.permission.QUERY_ALL_PACKAGES` permission instead of adding the package name to the <queries> element * feat(YouTube/Spoof signature): implemented with settings * Update description Co-authored-by: KobeW50 <84587632+KobeW50@users.noreply.github.com> * Update strings.xml Co-authored-by: KobeW50 <84587632+KobeW50@users.noreply.github.com> * Update strings.xml Co-authored-by: KobeW50 <84587632+KobeW50@users.noreply.github.com> * Update strings.xml Co-authored-by: KobeW50 <84587632+KobeW50@users.noreply.github.com> * fix(YouTube/Spoof signature): Instead of using hardcoded package names, use the Manifest's MetaData * chore: remove unused variable * fix(YouTube/Spoof signature): Removed from settings, integrated into `GmsCore support` patch --------- Co-authored-by: inotia00 <108592928+inotia00@users.noreply.github.com> Co-authored-by: KobeW50 <84587632+KobeW50@users.noreply.github.com>
This commit is contained in:
@ -3,6 +3,7 @@ package app.revanced.patches.shared.gms
|
||||
import app.revanced.patcher.PatchClass
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
@ -13,18 +14,21 @@ import app.revanced.patches.shared.gms.BaseGmsCoreSupportPatch.Constants.PERMISS
|
||||
import app.revanced.patches.shared.gms.fingerprints.CastContextFetchFingerprint
|
||||
import app.revanced.patches.shared.gms.fingerprints.CastDynamiteModuleFingerprint
|
||||
import app.revanced.patches.shared.gms.fingerprints.CastDynamiteModuleV2Fingerprint
|
||||
import app.revanced.patches.shared.gms.fingerprints.CertificateFingerprint
|
||||
import app.revanced.patches.shared.gms.fingerprints.CertificateFingerprint.GET_PACKAGE_NAME_METHOD_REFERENCE
|
||||
import app.revanced.patches.shared.gms.fingerprints.GmsCoreSupportFingerprint
|
||||
import app.revanced.patches.shared.gms.fingerprints.GmsCoreSupportFingerprint.GET_GMS_CORE_VENDOR_GROUP_ID_METHOD_NAME
|
||||
import app.revanced.patches.shared.gms.fingerprints.GooglePlayUtilityFingerprint
|
||||
import app.revanced.patches.shared.gms.fingerprints.PrimeMethodFingerprint
|
||||
import app.revanced.patches.shared.gms.fingerprints.ServiceCheckFingerprint
|
||||
import app.revanced.patches.shared.integrations.Constants.PATCHES_PATH
|
||||
import app.revanced.patches.shared.packagename.PackageNamePatch
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.getTargetIndexWithReference
|
||||
import app.revanced.util.resultOrThrow
|
||||
import app.revanced.util.returnEarly
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction21c
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction21c
|
||||
import com.android.tools.smali.dexlib2.iface.reference.StringReference
|
||||
@ -60,6 +64,7 @@ abstract class BaseGmsCoreSupportPatch(
|
||||
) + dependencies,
|
||||
compatiblePackages = compatiblePackages,
|
||||
fingerprints = setOf(
|
||||
// Google Play Services.
|
||||
CastContextFetchFingerprint,
|
||||
CastDynamiteModuleFingerprint,
|
||||
CastDynamiteModuleV2Fingerprint,
|
||||
@ -67,11 +72,21 @@ abstract class BaseGmsCoreSupportPatch(
|
||||
GooglePlayUtilityFingerprint,
|
||||
PrimeMethodFingerprint,
|
||||
ServiceCheckFingerprint,
|
||||
mainActivityOnCreateFingerprint
|
||||
|
||||
// Signature verification.
|
||||
CertificateFingerprint,
|
||||
|
||||
// MainActivity.
|
||||
mainActivityOnCreateFingerprint,
|
||||
),
|
||||
requiresIntegrations = true,
|
||||
) {
|
||||
private val gmsCoreVendorGroupId = "app.revanced"
|
||||
private companion object {
|
||||
const val GMS_CORE_VENDOR_GROUP_ID = "app.revanced"
|
||||
|
||||
const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
||||
"$PATCHES_PATH/GmsCoreSupport;"
|
||||
}
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
val packageName = PackageNamePatch.getPackageName(fromPackageName)
|
||||
@ -106,14 +121,32 @@ abstract class BaseGmsCoreSupportPatch(
|
||||
// Verify GmsCore is installed and whitelisted for power optimizations and background usage.
|
||||
mainActivityOnCreateFingerprint.resultOrThrow().mutableMethod.addInstructions(
|
||||
1, // Hack to not disturb other patches (such as the YTMusic integrations patch).
|
||||
"invoke-static/range { p0 .. p0 }, $PATCHES_PATH/GmsCoreSupport;->" +
|
||||
"invoke-static/range { p0 .. p0 }, $INTEGRATIONS_CLASS_DESCRIPTOR->" +
|
||||
"checkGmsCore(Landroid/app/Activity;)V",
|
||||
)
|
||||
|
||||
// Change the vendor of GmsCore in ReVanced Integrations.
|
||||
GmsCoreSupportFingerprint.resultOrThrow().mutableClass.methods
|
||||
.single { it.name == GET_GMS_CORE_VENDOR_GROUP_ID_METHOD_NAME }
|
||||
.replaceInstruction(0, "const-string v0, \"$gmsCoreVendorGroupId\"")
|
||||
GmsCoreSupportFingerprint
|
||||
.resultOrThrow()
|
||||
.mutableMethod
|
||||
.replaceInstruction(0, "const-string v0, \"$GMS_CORE_VENDOR_GROUP_ID\"")
|
||||
|
||||
// Spoof signature.
|
||||
CertificateFingerprint.result?.mutableClass?.methods?.forEach { mutableMethod ->
|
||||
mutableMethod.apply {
|
||||
val getPackageNameIndex =
|
||||
getTargetIndexWithReference(GET_PACKAGE_NAME_METHOD_REFERENCE)
|
||||
|
||||
if (getPackageNameIndex > -1) {
|
||||
val targetRegister = (getInstruction(getPackageNameIndex) as FiveRegisterInstruction).registerC
|
||||
|
||||
replaceInstruction(
|
||||
getPackageNameIndex,
|
||||
"invoke-static {v$targetRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->spoofPackageName(Landroid/content/Context;)Ljava/lang/String;",
|
||||
)
|
||||
}
|
||||
}
|
||||
} // Since it has only been confirmed to work on YouTube and YouTube Music, does not raise an exception even if the fingerprint cannot be solved.
|
||||
}
|
||||
|
||||
private fun BytecodeContext.transformStringReferences(transform: (str: String) -> String?) =
|
||||
@ -163,10 +196,10 @@ abstract class BaseGmsCoreSupportPatch(
|
||||
in PERMISSIONS,
|
||||
in ACTIONS,
|
||||
in AUTHORITIES,
|
||||
-> referencedString.replace("com.google", gmsCoreVendorGroupId)
|
||||
-> referencedString.replace("com.google", GMS_CORE_VENDOR_GROUP_ID)
|
||||
|
||||
// No vendor prefix for whatever reason...
|
||||
"subscribedfeeds" -> "$gmsCoreVendorGroupId.subscribedfeeds"
|
||||
"subscribedfeeds" -> "$GMS_CORE_VENDOR_GROUP_ID.subscribedfeeds"
|
||||
else -> null
|
||||
}
|
||||
|
||||
@ -179,7 +212,7 @@ abstract class BaseGmsCoreSupportPatch(
|
||||
if (str.startsWith(uriPrefix)) {
|
||||
return str.replace(
|
||||
uriPrefix,
|
||||
"content://${authority.replace("com.google", gmsCoreVendorGroupId)}",
|
||||
"content://${authority.replace("com.google", GMS_CORE_VENDOR_GROUP_ID)}",
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -189,7 +222,7 @@ abstract class BaseGmsCoreSupportPatch(
|
||||
if (str.startsWith(subFeedsUriPrefix)) {
|
||||
return str.replace(
|
||||
subFeedsUriPrefix,
|
||||
"content://$gmsCoreVendorGroupId.subscribedfeeds"
|
||||
"content://$GMS_CORE_VENDOR_GROUP_ID.subscribedfeeds"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -100,10 +100,17 @@ abstract class BaseGmsCoreSupportResourcePatch(
|
||||
).replace(
|
||||
"com.google.android.c2dm",
|
||||
"$gmsCoreVendorGroupId.android.c2dm",
|
||||
).replace(
|
||||
"</queries>",
|
||||
"<package android:name=\"$gmsCoreVendorGroupId.android.gms\"/></queries>",
|
||||
),
|
||||
)
|
||||
|
||||
// 'QUERY_ALL_PACKAGES' permission is required,
|
||||
// To check whether apps such as GmsCore, YouTube or YouTube Music are installed on the device.
|
||||
xmlEditor["AndroidManifest.xml"].use { editor ->
|
||||
editor.file.getElementsByTagName("manifest").item(0).also {
|
||||
it.appendChild(it.ownerDocument.createElement("uses-permission").also { element ->
|
||||
element.setAttribute("android:name", "android.permission.QUERY_ALL_PACKAGES")
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,20 @@
|
||||
package app.revanced.patches.shared.gms.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patches.shared.gms.fingerprints.CertificateFingerprint.GET_PACKAGE_NAME_METHOD_REFERENCE
|
||||
import app.revanced.util.fingerprint.ReferenceFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
/**
|
||||
* Method which the package name is used to check the app signature.
|
||||
*/
|
||||
internal object CertificateFingerprint : ReferenceFingerprint(
|
||||
returnType = "Ljava/lang/String;",
|
||||
accessFlags = AccessFlags.PROTECTED or AccessFlags.FINAL,
|
||||
parameters = emptyList(),
|
||||
strings = listOf("X.509", "user", "S"),
|
||||
reference = { GET_PACKAGE_NAME_METHOD_REFERENCE }
|
||||
) {
|
||||
const val GET_PACKAGE_NAME_METHOD_REFERENCE =
|
||||
"Landroid/content/Context;->getPackageName()Ljava/lang/String;"
|
||||
}
|
@ -3,9 +3,8 @@ package app.revanced.patches.shared.gms.fingerprints
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
|
||||
internal object GmsCoreSupportFingerprint : MethodFingerprint(
|
||||
customFingerprint = { _, classDef ->
|
||||
classDef.type.endsWith("GmsCoreSupport;")
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.definingClass.endsWith("/GmsCoreSupport;")
|
||||
&& methodDef.name == "getGmsCoreVendorGroupId"
|
||||
},
|
||||
) {
|
||||
const val GET_GMS_CORE_VENDOR_GROUP_ID_METHOD_NAME = "getGmsCoreVendorGroupId"
|
||||
}
|
||||
)
|
||||
|
Reference in New Issue
Block a user