From 245ffd85866d29c5f5cc0f5c41c24a2194954b7b Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Tue, 15 Apr 2025 10:23:58 +0200 Subject: [PATCH 1/6] fix(Spotify): Fix login by replacing `Spoof signature` patch with new `Spoof package info` patch --- patches/api/patches.api | 4 ++ .../patches/spotify/misc/fix/Fingerprints.kt | 2 +- .../spotify/misc/fix/SpoofPackageInfoPatch.kt | 52 +++++++++++++++++++ .../spotify/misc/fix/SpoofSignaturePatch.kt | 26 ++-------- 4 files changed, 60 insertions(+), 24 deletions(-) create mode 100644 patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofPackageInfoPatch.kt diff --git a/patches/api/patches.api b/patches/api/patches.api index 52dd8348a9..711eccede7 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -842,6 +842,10 @@ public final class app/revanced/patches/spotify/misc/extension/ExtensionPatchKt public static final fun getSharedExtensionPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/spotify/misc/fix/SpoofPackageInfoPatchKt { + public static final fun getSpoofPackageInfoPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/spotify/misc/fix/SpoofSignaturePatchKt { public static final fun getSpoofSignaturePatch ()Lapp/revanced/patcher/patch/BytecodePatch; } diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/Fingerprints.kt index c6e476c56e..1caa844e66 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/Fingerprints.kt @@ -2,4 +2,4 @@ package app.revanced.patches.spotify.misc.fix import app.revanced.patcher.fingerprint -internal val getAppSignatureFingerprint = fingerprint { strings("Failed to get the application signatures") } +internal val getPackageInfoFingerprint = fingerprint { strings("Failed to get the application signatures") } diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofPackageInfoPatch.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofPackageInfoPatch.kt new file mode 100644 index 0000000000..50d1c8bc6f --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofPackageInfoPatch.kt @@ -0,0 +1,52 @@ +package app.revanced.patches.spotify.misc.fix + +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.extensions.InstructionExtensions.instructions +import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.util.addInstructionsAtControlFlowLabel +import app.revanced.util.indexOfFirstInstructionReversedOrThrow +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction + +@Suppress("unused") +val spoofPackageInfoPatch = bytecodePatch( + name = "Spoof package info", + description = "Spoofs the package info of the app to fix various functions of the app.", +) { + compatibleWith("com.spotify.music") + + execute { + getPackageInfoFingerprint.method.apply { + // region Spoof signature. + + val failedToGetSignaturesStringMatch = getPackageInfoFingerprint.stringMatches!!.first() + + val concatSignaturesIndex = indexOfFirstInstructionReversedOrThrow( + failedToGetSignaturesStringMatch.index, + Opcode.MOVE_RESULT_OBJECT, + ) + + val signatureRegister = getInstruction(concatSignaturesIndex).registerA + val expectedSignature = "d6a6dced4a85f24204bf9505ccc1fce114cadb32" + + replaceInstruction(concatSignaturesIndex, "const-string v$signatureRegister, \"$expectedSignature\"") + + // endregion + + // region Spoof installer name. + + val returnInstallerNameIndex = instructions.size - 3 + + val installerNameRegister = getInstruction(returnInstallerNameIndex).registerA + val expectedInstallerName = "com.android.vending" + + addInstructionsAtControlFlowLabel( + returnInstallerNameIndex, + "const-string v$installerNameRegister, \"$expectedInstallerName\"", + ) + + // endregion + } + } +} \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofSignaturePatch.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofSignaturePatch.kt index 6dfd31e450..7ac278ff38 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofSignaturePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofSignaturePatch.kt @@ -1,33 +1,13 @@ package app.revanced.patches.spotify.misc.fix -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.patch.bytecodePatch -import app.revanced.util.indexOfFirstInstructionReversedOrThrow -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +@Deprecated("Superseded by spoofPackageInfoPatch", ReplaceWith("spoofPackageInfoPatch")) @Suppress("unused") val spoofSignaturePatch = bytecodePatch( - name = "Spoof signature", - description = "Spoofs the signature of the app to fix various functions of the app.", + description = "Spoofs the signature of the app fix various functions of the app.", ) { compatibleWith("com.spotify.music") - execute { - getAppSignatureFingerprint.method.apply { - val failedToGetSignaturesStringMatch = getAppSignatureFingerprint.stringMatches!!.first() - - val concatSignaturesIndex = indexOfFirstInstructionReversedOrThrow( - failedToGetSignaturesStringMatch.index, - Opcode.MOVE_RESULT_OBJECT, - ) - - val register = getInstruction(concatSignaturesIndex).registerA - - val expectedSignature = "d6a6dced4a85f24204bf9505ccc1fce114cadb32" - - replaceInstruction(concatSignaturesIndex, "const-string v$register, \"$expectedSignature\"") - } - } + dependsOn(spoofPackageInfoPatch) } From d53118fc97ccd5ee79c735ab3db989df87931f9d Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Tue, 15 Apr 2025 11:42:41 +0200 Subject: [PATCH 2/6] Update patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofPackageInfoPatch.kt Co-authored-by: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> --- .../patches/spotify/misc/fix/SpoofPackageInfoPatch.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofPackageInfoPatch.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofPackageInfoPatch.kt index 50d1c8bc6f..2c829f2ad0 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofPackageInfoPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofPackageInfoPatch.kt @@ -36,7 +36,10 @@ val spoofPackageInfoPatch = bytecodePatch( // region Spoof installer name. - val returnInstallerNameIndex = instructions.size - 3 + val returnInstallerNameIndex = indexOfFirstInstructionReversedOrThrow( + instructions.lastIndex, + Opcode.RETURN_OBJECT + ) val installerNameRegister = getInstruction(returnInstallerNameIndex).registerA val expectedInstallerName = "com.android.vending" From 4f87180870e3522e871e60d028d0e1c7ce5a2a4c Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Tue, 15 Apr 2025 11:51:31 +0200 Subject: [PATCH 3/6] use string for finding index --- .../revanced/patches/spotify/misc/fix/Fingerprints.kt | 7 ++++++- .../patches/spotify/misc/fix/SpoofPackageInfoPatch.kt | 11 +++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/Fingerprints.kt index 1caa844e66..6b57c8e4c0 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/Fingerprints.kt @@ -2,4 +2,9 @@ package app.revanced.patches.spotify.misc.fix import app.revanced.patcher.fingerprint -internal val getPackageInfoFingerprint = fingerprint { strings("Failed to get the application signatures") } +internal val getPackageInfoFingerprint = fingerprint { + strings( + "Failed to get the application signatures", + "Failed to get installer package" + ) +} diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofPackageInfoPatch.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofPackageInfoPatch.kt index 2c829f2ad0..2920ad2bde 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofPackageInfoPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofPackageInfoPatch.kt @@ -5,6 +5,7 @@ import app.revanced.patcher.extensions.InstructionExtensions.instructions import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.patch.bytecodePatch import app.revanced.util.addInstructionsAtControlFlowLabel +import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionReversedOrThrow import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction @@ -20,10 +21,10 @@ val spoofPackageInfoPatch = bytecodePatch( getPackageInfoFingerprint.method.apply { // region Spoof signature. - val failedToGetSignaturesStringMatch = getPackageInfoFingerprint.stringMatches!!.first() + val failedToGetSignaturesStringIndex = getPackageInfoFingerprint.stringMatches!!.first().index val concatSignaturesIndex = indexOfFirstInstructionReversedOrThrow( - failedToGetSignaturesStringMatch.index, + failedToGetSignaturesStringIndex, Opcode.MOVE_RESULT_OBJECT, ) @@ -36,8 +37,10 @@ val spoofPackageInfoPatch = bytecodePatch( // region Spoof installer name. - val returnInstallerNameIndex = indexOfFirstInstructionReversedOrThrow( - instructions.lastIndex, + val failedToGetInstallerPackageStringIndex = getPackageInfoFingerprint.stringMatches!!.last().index + + val returnInstallerNameIndex = indexOfFirstInstructionOrThrow( + failedToGetInstallerPackageStringIndex, Opcode.RETURN_OBJECT ) From 89f4d836db0b6dfa04e7893f816995e0f49ec7f0 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Tue, 15 Apr 2025 12:12:46 +0200 Subject: [PATCH 4/6] fix for old version --- .../revanced/patches/spotify/misc/fix/Fingerprints.kt | 5 +---- .../patches/spotify/misc/fix/SpoofPackageInfoPatch.kt | 9 +++++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/Fingerprints.kt index 6b57c8e4c0..cc2d1f321e 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/Fingerprints.kt @@ -3,8 +3,5 @@ package app.revanced.patches.spotify.misc.fix import app.revanced.patcher.fingerprint internal val getPackageInfoFingerprint = fingerprint { - strings( - "Failed to get the application signatures", - "Failed to get installer package" - ) + strings("Failed to get the application signatures") } diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofPackageInfoPatch.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofPackageInfoPatch.kt index 2920ad2bde..a3b60e5234 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofPackageInfoPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofPackageInfoPatch.kt @@ -3,9 +3,9 @@ package app.revanced.patches.spotify.misc.fix import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.instructions import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction +import app.revanced.patcher.fingerprint import app.revanced.patcher.patch.bytecodePatch import app.revanced.util.addInstructionsAtControlFlowLabel -import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionReversedOrThrow import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction @@ -37,10 +37,11 @@ val spoofPackageInfoPatch = bytecodePatch( // region Spoof installer name. - val failedToGetInstallerPackageStringIndex = getPackageInfoFingerprint.stringMatches!!.last().index + // Old versions of Spotify do not check the installer name. + fingerprint { strings("Failed to get installer package") }.matchOrNull(this) ?: return@execute - val returnInstallerNameIndex = indexOfFirstInstructionOrThrow( - failedToGetInstallerPackageStringIndex, + val returnInstallerNameIndex = indexOfFirstInstructionReversedOrThrow( + instructions.size, Opcode.RETURN_OBJECT ) From 2429d53aa766b10c88d0462942005087610d227e Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Tue, 15 Apr 2025 12:41:03 +0200 Subject: [PATCH 5/6] Use legacy check and two fingerprints --- .../patches/spotify/misc/fix/Fingerprints.kt | 12 ++++++- .../spotify/misc/fix/SpoofPackageInfoPatch.kt | 35 +++++++++++++------ 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/Fingerprints.kt index cc2d1f321e..f8959ae648 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/Fingerprints.kt @@ -3,5 +3,15 @@ package app.revanced.patches.spotify.misc.fix import app.revanced.patcher.fingerprint internal val getPackageInfoFingerprint = fingerprint { - strings("Failed to get the application signatures") + strings( + "Failed to get the application signatures", + "Failed to get installer package" + ) } + +internal val getPackageInfoLegacyFingerprint = fingerprint { + strings( + "Failed to get the application signatures" + ) +} + diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofPackageInfoPatch.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofPackageInfoPatch.kt index a3b60e5234..3dfc44da01 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofPackageInfoPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofPackageInfoPatch.kt @@ -1,11 +1,11 @@ package app.revanced.patches.spotify.misc.fix import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.extensions.InstructionExtensions.instructions import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction -import app.revanced.patcher.fingerprint import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patches.spotify.misc.extension.IS_SPOTIFY_LEGACY_APP_TARGET import app.revanced.util.addInstructionsAtControlFlowLabel +import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionReversedOrThrow import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction @@ -18,10 +18,18 @@ val spoofPackageInfoPatch = bytecodePatch( compatibleWith("com.spotify.music") execute { - getPackageInfoFingerprint.method.apply { + val packageInfoFingerprint = if (IS_SPOTIFY_LEGACY_APP_TARGET) { + getPackageInfoLegacyFingerprint + } else { + getPackageInfoFingerprint + } + + packageInfoFingerprint.method.apply { + val stringMatches = packageInfoFingerprint.stringMatches!! + // region Spoof signature. - val failedToGetSignaturesStringIndex = getPackageInfoFingerprint.stringMatches!!.first().index + val failedToGetSignaturesStringIndex = stringMatches.first().index val concatSignaturesIndex = indexOfFirstInstructionReversedOrThrow( failedToGetSignaturesStringIndex, @@ -37,20 +45,25 @@ val spoofPackageInfoPatch = bytecodePatch( // region Spoof installer name. - // Old versions of Spotify do not check the installer name. - fingerprint { strings("Failed to get installer package") }.matchOrNull(this) ?: return@execute + if (IS_SPOTIFY_LEGACY_APP_TARGET) { + // Package installer name does not appear to be used with the legacy app target. + return@execute + } - val returnInstallerNameIndex = indexOfFirstInstructionReversedOrThrow( - instructions.size, + val expectedInstallerName = "com.android.vending" + + val returnInstallerNameIndex = indexOfFirstInstructionOrThrow( + stringMatches.last().index, Opcode.RETURN_OBJECT ) - val installerNameRegister = getInstruction(returnInstallerNameIndex).registerA - val expectedInstallerName = "com.android.vending" + val installerNameRegister = getInstruction( + returnInstallerNameIndex + ).registerA addInstructionsAtControlFlowLabel( returnInstallerNameIndex, - "const-string v$installerNameRegister, \"$expectedInstallerName\"", + "const-string v$installerNameRegister, \"$expectedInstallerName\"" ) // endregion From 3502093342a12675ff013a00b375999caa998e04 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Tue, 15 Apr 2025 12:45:41 +0200 Subject: [PATCH 6/6] refactor --- .../patches/spotify/misc/fix/SpoofPackageInfoPatch.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofPackageInfoPatch.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofPackageInfoPatch.kt index 3dfc44da01..c06f2a04c2 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofPackageInfoPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/SpoofPackageInfoPatch.kt @@ -18,14 +18,14 @@ val spoofPackageInfoPatch = bytecodePatch( compatibleWith("com.spotify.music") execute { - val packageInfoFingerprint = if (IS_SPOTIFY_LEGACY_APP_TARGET) { + val getPackageInfoFingerprint = if (IS_SPOTIFY_LEGACY_APP_TARGET) { getPackageInfoLegacyFingerprint } else { getPackageInfoFingerprint } - packageInfoFingerprint.method.apply { - val stringMatches = packageInfoFingerprint.stringMatches!! + getPackageInfoFingerprint.method.apply { + val stringMatches = getPackageInfoFingerprint.stringMatches!! // region Spoof signature. @@ -46,7 +46,7 @@ val spoofPackageInfoPatch = bytecodePatch( // region Spoof installer name. if (IS_SPOTIFY_LEGACY_APP_TARGET) { - // Package installer name does not appear to be used with the legacy app target. + // Installer name is not used in the legacy app target. return@execute }