Compare commits

..

11 Commits

Author SHA1 Message Date
semantic-release-bot
e386313deb chore(release): 4.3.0-dev.11 [skip ci]
# [4.3.0-dev.11](https://github.com/ReVanced/revanced-patches/compare/v4.3.0-dev.10...v4.3.0-dev.11) (2024-03-02)

### Bug Fixes

* **YouTube - Spoof signature:** Fix tracking such as history or watch time ([f2edae2](f2edae2ac1))
2024-03-02 07:05:33 +00:00
oSumAtrIX
f2edae2ac1 fix(YouTube - Spoof signature): Fix tracking such as history or watch time 2024-03-02 08:03:07 +01:00
semantic-release-bot
c153979981 chore(release): 4.3.0-dev.10 [skip ci]
# [4.3.0-dev.10](https://github.com/ReVanced/revanced-patches/compare/v4.3.0-dev.9...v4.3.0-dev.10) (2024-02-29)

### Bug Fixes

* **YouTube - Spoof app version:** Remove broken versions ([#2776](https://github.com/ReVanced/revanced-patches/issues/2776)) ([2fe9060](2fe9060944))
2024-02-29 00:18:20 +00:00
oSumAtrIX
2fe9060944 fix(YouTube - Spoof app version): Remove broken versions (#2776) 2024-02-29 01:16:06 +01:00
semantic-release-bot
212a94cbb3 chore(release): 4.3.0-dev.9 [skip ci]
# [4.3.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v4.3.0-dev.8...v4.3.0-dev.9) (2024-02-28)

### Bug Fixes

* **Override certificate pinning:** Always overwrite with a generic network security configuration ([16eee2f](16eee2f03f))
2024-02-28 22:04:01 +00:00
oSumAtrIX
16eee2f03f fix(Override certificate pinning): Always overwrite with a generic network security configuration
Previously some conditional checks prevented to patch YouTube for example. The current configuration should work globally for all apps.
2024-02-28 23:01:56 +01:00
semantic-release-bot
4937fa5fbd chore(release): 4.3.0-dev.8 [skip ci]
# [4.3.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v4.3.0-dev.7...v4.3.0-dev.8) (2024-02-28)

### Bug Fixes

* Remove extra space from patch description ([#2780](https://github.com/ReVanced/revanced-patches/issues/2780)) ([a6f5dd9](a6f5dd933f))
2024-02-28 20:35:11 +00:00
KobeW50
a6f5dd933f fix: Remove extra space from patch description (#2780) 2024-02-28 21:32:55 +01:00
semantic-release-bot
97c4682ccc chore(release): 4.3.0-dev.7 [skip ci]
# [4.3.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v4.3.0-dev.6...v4.3.0-dev.7) (2024-02-26)

### Features

* **OpeningHours:** Add `Fix crash` patch ([#2697](https://github.com/ReVanced/revanced-patches/issues/2697)) ([6742cd9](6742cd9232))
2024-02-26 03:52:58 +00:00
Linus
6742cd9232 feat(OpeningHours): Add Fix crash patch (#2697)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2024-02-26 04:50:59 +01:00
oSumAtrIX
5b2cc10adb docs: Fix broken links 2024-02-26 04:37:44 +01:00
13 changed files with 265 additions and 52 deletions

View File

@@ -1,3 +1,38 @@
# [4.3.0-dev.11](https://github.com/ReVanced/revanced-patches/compare/v4.3.0-dev.10...v4.3.0-dev.11) (2024-03-02)
### Bug Fixes
* **YouTube - Spoof signature:** Fix tracking such as history or watch time ([bcd8b48](https://github.com/ReVanced/revanced-patches/commit/bcd8b48e70693dac1bfcc0bf4971d6b526065b59))
# [4.3.0-dev.10](https://github.com/ReVanced/revanced-patches/compare/v4.3.0-dev.9...v4.3.0-dev.10) (2024-02-29)
### Bug Fixes
* **YouTube - Spoof app version:** Remove broken versions ([#2776](https://github.com/ReVanced/revanced-patches/issues/2776)) ([9466d97](https://github.com/ReVanced/revanced-patches/commit/9466d973c6d7a2891e3fa9f283107b64399152ea))
# [4.3.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v4.3.0-dev.8...v4.3.0-dev.9) (2024-02-28)
### Bug Fixes
* **Override certificate pinning:** Always overwrite with a generic network security configuration ([2a842a1](https://github.com/ReVanced/revanced-patches/commit/2a842a1e14e1993eb028ae0bd1a93e227bb929a6))
# [4.3.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v4.3.0-dev.7...v4.3.0-dev.8) (2024-02-28)
### Bug Fixes
* Remove extra space from patch description ([#2780](https://github.com/ReVanced/revanced-patches/issues/2780)) ([96a3f35](https://github.com/ReVanced/revanced-patches/commit/96a3f359266ff8d16ae9ee3c6ce2f16ce67a3b93))
# [4.3.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v4.3.0-dev.6...v4.3.0-dev.7) (2024-02-26)
### Features
* **OpeningHours:** Add `Fix crash` patch ([#2697](https://github.com/ReVanced/revanced-patches/issues/2697)) ([0d011b8](https://github.com/ReVanced/revanced-patches/commit/0d011b876ecf05031a7daa54ab7e6d3506728a47))
# [4.3.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v4.3.0-dev.5...v4.3.0-dev.6) (2024-02-25) # [4.3.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v4.3.0-dev.5...v4.3.0-dev.6) (2024-02-25)

View File

@@ -72,7 +72,7 @@ of ReVanced Patcher and how to use ReVanced Patcher to create patches
## 🙏 Submitting a feature request ## 🙏 Submitting a feature request
Features can be requested by opening an issue using the Features can be requested by opening an issue using the
[Feature request issue template](https://github.com/ReVanced/revanced-patches/issues/new?assignees=&labels=Feature+request&projects=&template=feature-request.yml&title=feat%3A+). [Feature request issue template](https://github.com/ReVanced/revanced-patches/issues/new?assignees=&labels=Feature+request&projects=&template=feature_request.yml&title=feat%3A+).
> **Note** > **Note**
> Requests can be accepted or rejected at the discretion of maintainers of ReVanced Patches. > Requests can be accepted or rejected at the discretion of maintainers of ReVanced Patches.
@@ -81,7 +81,7 @@ Features can be requested by opening an issue using the
## 🐞 Submitting a bug report ## 🐞 Submitting a bug report
If you encounter a bug while using ReVanced Patches, open an issue using the If you encounter a bug while using ReVanced Patches, open an issue using the
[Bug report issue template](https://github.com/ReVanced/revanced-patches/issues/new?assignees=&labels=Bug+report&projects=&template=bug-report.yml&title=bug%3A+). [Bug report issue template](https://github.com/ReVanced/revanced-patches/issues/new?assignees=&labels=Bug+report&projects=&template=bug_report.yml&title=bug%3A+).
## 🧑‍⚖️ Guidelines for requesting or contributing patches ## 🧑‍⚖️ Guidelines for requesting or contributing patches

View File

@@ -410,6 +410,12 @@ public final class app/revanced/patches/nyx/misc/pro/UnlockProPatch : app/revanc
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
} }
public final class app/revanced/patches/openinghours/misc/fix/crash/FixCrashPatch : app/revanced/patcher/patch/BytecodePatch {
public static final field INSTANCE Lapp/revanced/patches/openinghours/misc/fix/crash/FixCrashPatch;
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/photomath/detection/deviceid/SpoofDeviceIdPatch : app/revanced/patcher/patch/BytecodePatch { public final class app/revanced/patches/photomath/detection/deviceid/SpoofDeviceIdPatch : app/revanced/patcher/patch/BytecodePatch {
public static final field INSTANCE Lapp/revanced/patches/photomath/detection/deviceid/SpoofDeviceIdPatch; public static final field INSTANCE Lapp/revanced/patches/photomath/detection/deviceid/SpoofDeviceIdPatch;
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V

View File

@@ -1,4 +1,4 @@
org.gradle.parallel = true org.gradle.parallel = true
org.gradle.caching = true org.gradle.caching = true
kotlin.code.style = official kotlin.code.style = official
version = 4.3.0-dev.6 version = 4.3.0-dev.11

View File

@@ -4,6 +4,7 @@ import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.misc.debugging.EnableAndroidDebuggingPatch import app.revanced.patches.all.misc.debugging.EnableAndroidDebuggingPatch
import app.revanced.util.Utils.trimIndentMultiline
import org.w3c.dom.Element import org.w3c.dom.Element
import java.io.File import java.io.File
@@ -32,8 +33,6 @@ object OverrideCertificatePinningPatch : ResourcePatch() {
// In case the file does not exist create the "network_security_config.xml" file. // In case the file does not exist create the "network_security_config.xml" file.
File(resXmlDirectory, "network_security_config.xml").apply { File(resXmlDirectory, "network_security_config.xml").apply {
if (!exists()) {
createNewFile()
writeText( writeText(
""" """
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
@@ -55,21 +54,8 @@ object OverrideCertificatePinningPatch : ResourcePatch() {
</trust-anchors> </trust-anchors>
</debug-overrides> </debug-overrides>
</network-security-config> </network-security-config>
""", """.trimIndentMultiline(),
) )
} else {
// If the file already exists.
readText().let { text ->
if (!text.contains("<certificates src=\"user\" />")) {
writeText(
text.replace(
"<trust-anchors>",
"<trust-anchors>\n<certificates src=\"user\" overridePins=\"true\" />\n<certificates src=\"system\" />",
),
)
}
}
}
} }
} }
} }

View File

@@ -0,0 +1,115 @@
package app.revanced.patches.openinghours.misc.fix.crash
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.getInstructions
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.extensions.newLabel
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.openinghours.misc.fix.crash.fingerprints.SetPlaceFingerprint
import app.revanced.util.exception
import app.revanced.util.getReference
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction21t
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.Instruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
@Patch(
name = "Fix crash",
compatiblePackages = [CompatiblePackage("de.simon.openinghours", ["1.0"])],
)
@Suppress("unused")
object FixCrashPatch : BytecodePatch(
setOf(SetPlaceFingerprint),
) {
override fun execute(context: BytecodeContext) {
SetPlaceFingerprint.result?.let {
val indexedInstructions = it.mutableMethod.getInstructions().withIndex().toList()
/**
* This function replaces all `checkNotNull` instructions in the integer interval
* from [startIndex] to [endIndex], both inclusive. In place of the `checkNotNull`
* instruction an if-null check is inserted. If the if-null check yields that
* the value is indeed null, we jump to a newly created label at `endIndex + 1`.
*/
fun avoidNullPointerException(startIndex: Int, endIndex: Int) {
val continueLabel = it.mutableMethod.newLabel(endIndex + 1)
for (index in startIndex..endIndex) {
val instruction = indexedInstructions[index].value
if (!instruction.isCheckNotNullInstruction) {
continue
}
val checkNotNullInstruction = instruction as FiveRegisterInstruction
val originalRegister = checkNotNullInstruction.registerC
it.mutableMethod.replaceInstruction(
index,
BuilderInstruction21t(
Opcode.IF_EQZ,
originalRegister,
continueLabel,
),
)
}
}
val getOpeningHoursIndex = getIndicesOfInvoke(
indexedInstructions,
"Lde/simon/openinghours/models/Place;",
"getOpeningHours",
)
val setWeekDayTextIndex = getIndexOfInvoke(
indexedInstructions,
"Lde/simon/openinghours/views/custom/PlaceCard;",
"setWeekDayText",
)
val startCalculateStatusIndex = getIndexOfInvoke(
indexedInstructions,
"Lde/simon/openinghours/views/custom/PlaceCard;",
"startCalculateStatus",
)
// Replace the Intrinsics;->checkNotNull instructions with a null check
// and jump to our newly created label if it returns true.
// This avoids the NullPointerExceptions.
avoidNullPointerException(getOpeningHoursIndex[1], startCalculateStatusIndex)
avoidNullPointerException(getOpeningHoursIndex[0], setWeekDayTextIndex)
} ?: throw SetPlaceFingerprint.exception
}
private fun isInvokeInstruction(instruction: Instruction, className: String, methodName: String): Boolean {
val methodRef = instruction.getReference<MethodReference>() ?: return false
return methodRef.definingClass == className && methodRef.name == methodName
}
private fun getIndicesOfInvoke(
instructions: List<IndexedValue<Instruction>>,
className: String,
methodName: String,
): List<Int> = instructions.mapNotNull { (index, instruction) ->
if (isInvokeInstruction(instruction, className, methodName)) {
index
} else {
null
}
}
private fun getIndexOfInvoke(
instructions: List<IndexedValue<Instruction>>,
className: String,
methodName: String,
): Int = instructions.first { (_, instruction) ->
isInvokeInstruction(instruction, className, methodName)
}.index
private val Instruction.isCheckNotNullInstruction
get() = isInvokeInstruction(this, "Lkotlin/jvm/internal/Intrinsics;", "checkNotNull")
}

View File

@@ -0,0 +1,12 @@
package app.revanced.patches.openinghours.misc.fix.crash.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint
internal object SetPlaceFingerprint : MethodFingerprint(
"V",
parameters = listOf("Lde/simon/openinghours/models/Place;"),
customFingerprint = { methodDef, _ ->
methodDef.definingClass == "Lde/simon/openinghours/views/custom/PlaceCard;" &&
methodDef.name == "setPlace"
},
)

View File

@@ -16,7 +16,8 @@ import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch import app.revanced.patches.youtube.misc.settings.SettingsPatch
import app.revanced.patches.youtube.video.information.VideoInformationPatch import app.revanced.patches.youtube.video.information.VideoInformationPatch
import app.revanced.patches.youtube.video.playerresponse.PlayerResponseMethodHookPatch import app.revanced.patches.youtube.video.playerresponse.PlayerResponseMethodHookPatch
import app.revanced.util.exception import app.revanced.util.*
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.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
@@ -28,8 +29,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
PlayerResponseMethodHookPatch::class, PlayerResponseMethodHookPatch::class,
VideoInformationPatch::class, VideoInformationPatch::class,
SpoofSignatureResourcePatch::class, SpoofSignatureResourcePatch::class,
AddResourcesPatch::class AddResourcesPatch::class,
] ],
) )
object SpoofSignaturePatch : BytecodePatch( object SpoofSignaturePatch : BytecodePatch(
setOf( setOf(
@@ -41,7 +42,9 @@ object SpoofSignaturePatch : BytecodePatch(
StoryboardRendererDecoderRecommendedLevelFingerprint, StoryboardRendererDecoderRecommendedLevelFingerprint,
StoryboardThumbnailParentFingerprint, StoryboardThumbnailParentFingerprint,
ScrubbedPreviewLayoutFingerprint, ScrubbedPreviewLayoutFingerprint,
) StatsQueryParameterFingerprint,
ParamsMapPutFingerprint,
),
) { ) {
private const val INTEGRATIONS_CLASS_DESCRIPTOR = private const val INTEGRATIONS_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/youtube/patches/spoof/SpoofSignaturePatch;" "Lapp/revanced/integrations/youtube/patches/spoof/SpoofSignaturePatch;"
@@ -55,14 +58,14 @@ object SpoofSignaturePatch : BytecodePatch(
preferences = setOf( preferences = setOf(
SwitchPreference("revanced_spoof_signature_verification_enabled"), SwitchPreference("revanced_spoof_signature_verification_enabled"),
SwitchPreference("revanced_spoof_signature_in_feed_enabled"), SwitchPreference("revanced_spoof_signature_in_feed_enabled"),
SwitchPreference("revanced_spoof_storyboard") SwitchPreference("revanced_spoof_storyboard"),
),
), ),
)
) )
// Hook the player parameters. // Hook the player parameters.
PlayerResponseMethodHookPatch += PlayerResponseMethodHookPatch.Hook.ProtoBufferParameter( PlayerResponseMethodHookPatch += PlayerResponseMethodHookPatch.Hook.ProtoBufferParameter(
"$INTEGRATIONS_CLASS_DESCRIPTOR->spoofParameter(Ljava/lang/String;Z)Ljava/lang/String;" "$INTEGRATIONS_CLASS_DESCRIPTOR->spoofParameter(Ljava/lang/String;Z)Ljava/lang/String;",
) )
// Force the seekbar time and chapters to always show up. // Force the seekbar time and chapters to always show up.
@@ -72,7 +75,7 @@ object SpoofSignaturePatch : BytecodePatch(
StoryboardThumbnailFingerprint.also { StoryboardThumbnailFingerprint.also {
it.resolve( it.resolve(
context, context,
classDef classDef,
) )
}.result?.let { }.result?.let {
val endIndex = it.scanResult.patternScanResult!!.endIndex val endIndex = it.scanResult.patternScanResult!!.endIndex
@@ -84,7 +87,7 @@ object SpoofSignaturePatch : BytecodePatch(
endIndex, endIndex,
""" """
invoke-static {}, $INTEGRATIONS_CLASS_DESCRIPTOR->getSeekbarThumbnailOverrideValue()Z invoke-static {}, $INTEGRATIONS_CLASS_DESCRIPTOR->getSeekbarThumbnailOverrideValue()Z
""" """,
) )
// Since this is end of the method must replace one line then add the rest. // Since this is end of the method must replace one line then add the rest.
it.mutableMethod.addInstructions( it.mutableMethod.addInstructions(
@@ -92,7 +95,7 @@ object SpoofSignaturePatch : BytecodePatch(
""" """
move-result v0 move-result v0
return v0 return v0
""" """,
) )
} ?: throw StoryboardThumbnailFingerprint.exception } ?: throw StoryboardThumbnailFingerprint.exception
} }
@@ -107,7 +110,7 @@ object SpoofSignaturePatch : BytecodePatch(
""" """
iget-object v0, p0, $imageViewFieldName # copy imageview field to a register iget-object v0, p0, $imageViewFieldName # copy imageview field to a register
invoke-static {v0}, $INTEGRATIONS_CLASS_DESCRIPTOR->seekbarImageViewCreated(Landroid/widget/ImageView;)V invoke-static {v0}, $INTEGRATIONS_CLASS_DESCRIPTOR->seekbarImageViewCreated(Landroid/widget/ImageView;)V
""" """,
) )
} }
} ?: throw ScrubbedPreviewLayoutFingerprint.exception } ?: throw ScrubbedPreviewLayoutFingerprint.exception
@@ -117,7 +120,7 @@ object SpoofSignaturePatch : BytecodePatch(
*/ */
arrayOf( arrayOf(
PlayerResponseModelImplGeneralFingerprint, PlayerResponseModelImplGeneralFingerprint,
PlayerResponseModelImplLiveStreamFingerprint PlayerResponseModelImplLiveStreamFingerprint,
).forEach { fingerprint -> ).forEach { fingerprint ->
fingerprint.result?.let { fingerprint.result?.let {
it.mutableMethod.apply { it.mutableMethod.apply {
@@ -130,7 +133,7 @@ object SpoofSignaturePatch : BytecodePatch(
""" """
invoke-static { v$getStoryBoardRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getStoryboardRendererSpec(Ljava/lang/String;)Ljava/lang/String; invoke-static { v$getStoryBoardRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getStoryboardRendererSpec(Ljava/lang/String;)Ljava/lang/String;
move-result-object v$getStoryBoardRegister move-result-object v$getStoryBoardRegister
""" """,
) )
} }
} ?: throw fingerprint.exception } ?: throw fingerprint.exception
@@ -143,10 +146,11 @@ object SpoofSignaturePatch : BytecodePatch(
.getInstruction<OneRegisterInstruction>(moveOriginalRecommendedValueIndex).registerA .getInstruction<OneRegisterInstruction>(moveOriginalRecommendedValueIndex).registerA
it.mutableMethod.addInstructions( it.mutableMethod.addInstructions(
moveOriginalRecommendedValueIndex + 1, """ moveOriginalRecommendedValueIndex + 1,
"""
invoke-static { v$originalValueRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getRecommendedLevel(I)I invoke-static { v$originalValueRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getRecommendedLevel(I)I
move-result v$originalValueRegister move-result v$originalValueRegister
""" """,
) )
} ?: throw StoryboardRendererDecoderRecommendedLevelFingerprint.exception } ?: throw StoryboardRendererDecoderRecommendedLevelFingerprint.exception
@@ -158,10 +162,11 @@ object SpoofSignaturePatch : BytecodePatch(
getInstruction<OneRegisterInstruction>(moveOriginalRecommendedValueIndex).registerA getInstruction<OneRegisterInstruction>(moveOriginalRecommendedValueIndex).registerA
addInstructions( addInstructions(
moveOriginalRecommendedValueIndex, """ moveOriginalRecommendedValueIndex,
"""
invoke-static { v$originalValueRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getRecommendedLevel(I)I invoke-static { v$originalValueRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getRecommendedLevel(I)I
move-result v$originalValueRegister move-result v$originalValueRegister
""" """,
) )
} }
} ?: throw PlayerResponseModelImplRecommendedLevelFingerprint.exception } ?: throw PlayerResponseModelImplRecommendedLevelFingerprint.exception
@@ -177,7 +182,7 @@ object SpoofSignaturePatch : BytecodePatch(
invoke-static { p$storyBoardUrlParams }, $INTEGRATIONS_CLASS_DESCRIPTOR->getStoryboardRendererSpec(Ljava/lang/String;)Ljava/lang/String; invoke-static { p$storyBoardUrlParams }, $INTEGRATIONS_CLASS_DESCRIPTOR->getStoryboardRendererSpec(Ljava/lang/String;)Ljava/lang/String;
move-result-object p$storyBoardUrlParams move-result-object p$storyBoardUrlParams
""", """,
ExternalLabel("ignore", getInstruction(0)) ExternalLabel("ignore", getInstruction(0)),
) )
} }
} ?: throw StoryboardRendererSpecFingerprint.exception } ?: throw StoryboardRendererSpecFingerprint.exception
@@ -189,11 +194,43 @@ object SpoofSignaturePatch : BytecodePatch(
it.mutableMethod.getInstruction<OneRegisterInstruction>(storyBoardUrlIndex).registerA it.mutableMethod.getInstruction<OneRegisterInstruction>(storyBoardUrlIndex).registerA
it.mutableMethod.addInstructions( it.mutableMethod.addInstructions(
storyBoardUrlIndex + 1, """ storyBoardUrlIndex + 1,
"""
invoke-static { v$storyboardUrlRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getStoryboardDecoderRendererSpec(Ljava/lang/String;)Ljava/lang/String; invoke-static { v$storyboardUrlRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getStoryboardDecoderRendererSpec(Ljava/lang/String;)Ljava/lang/String;
move-result-object v$storyboardUrlRegister move-result-object v$storyboardUrlRegister
""" """,
) )
} ?: throw StoryboardRendererDecoderSpecFingerprint.exception } ?: throw StoryboardRendererDecoderSpecFingerprint.exception
// Fix stats not being tracked.
// Due to signature spoofing "adformat" is present in query parameters made for /stats requests,
// even though, for regular videos, it should not be.
// This breaks stats tracking.
// Replace the ad parameter with the video parameter in the query parameters.
StatsQueryParameterFingerprint.result?.let {
val putMethod = ParamsMapPutFingerprint.result?.method?.toString()
?: throw ParamsMapPutFingerprint.exception
it.mutableMethod.apply {
val adParamIndex = it.scanResult.stringsScanResult!!.matches.first().index
val videoParamIndex = adParamIndex + 3
// Replace the ad parameter with the video parameter.
replaceInstruction(adParamIndex, getInstruction(videoParamIndex))
// Call paramsMap.put instead of paramsMap.putIfNotExist
// because the key is already present in the map.
val putAdParamIndex = adParamIndex + 1
val putIfKeyNotExistsInstruction = getInstruction<FiveRegisterInstruction>(putAdParamIndex)
replaceInstruction(
putAdParamIndex,
"invoke-virtual { " +
"v${putIfKeyNotExistsInstruction.registerC}, " +
"v${putIfKeyNotExistsInstruction.registerD}, " +
"v${putIfKeyNotExistsInstruction.registerE} }, " +
putMethod,
)
}
} ?: throw StatsQueryParameterFingerprint.exception
} }
} }

View File

@@ -0,0 +1,24 @@
package app.revanced.patches.youtube.misc.fix.playback.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 ParamsMapPutFingerprint : MethodFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf(
"Ljava/lang/String;",
"Ljava/lang/String;",
),
opcodes = listOf(
Opcode.CONST_4,
Opcode.CONST_4,
Opcode.CONST_4,
Opcode.MOVE_OBJECT,
Opcode.MOVE_OBJECT,
Opcode.MOVE_OBJECT,
Opcode.INVOKE_DIRECT_RANGE,
),
)

View File

@@ -0,0 +1,7 @@
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint
internal object StatsQueryParameterFingerprint : MethodFingerprint(
strings = listOf("adunit"),
)

View File

@@ -5,17 +5,11 @@
<item>@string/revanced_spoof_app_version_target_entry_1</item> <item>@string/revanced_spoof_app_version_target_entry_1</item>
<item>@string/revanced_spoof_app_version_target_entry_2</item> <item>@string/revanced_spoof_app_version_target_entry_2</item>
<item>@string/revanced_spoof_app_version_target_entry_3</item> <item>@string/revanced_spoof_app_version_target_entry_3</item>
<item>@string/revanced_spoof_app_version_target_entry_4</item>
<item>@string/revanced_spoof_app_version_target_entry_5</item>
<item>@string/revanced_spoof_app_version_target_entry_6</item>
</string-array> </string-array>
<string-array name="revanced_spoof_app_version_target_entry_values"> <string-array name="revanced_spoof_app_version_target_entry_values">
<item>18.33.40</item> <item>18.33.40</item>
<item>18.20.39</item> <item>18.20.39</item>
<item>18.09.39</item> <item>18.09.39</item>
<item>17.08.35</item>
<item>16.08.35</item>
<item>16.01.35</item>
</string-array> </string-array>
</patch> </patch>
<patch id="layout.startpage.ChangeStartPagePatch"> <patch id="layout.startpage.ChangeStartPagePatch">

View File

@@ -786,9 +786,6 @@
<string name="revanced_spoof_app_version_target_entry_1">18.33.40 - Restore RYD Shorts incognito mode</string> <string name="revanced_spoof_app_version_target_entry_1">18.33.40 - Restore RYD Shorts incognito mode</string>
<string name="revanced_spoof_app_version_target_entry_2">18.20.39 - Restore wide video speed &amp; quality menu</string> <string name="revanced_spoof_app_version_target_entry_2">18.20.39 - Restore wide video speed &amp; quality menu</string>
<string name="revanced_spoof_app_version_target_entry_3">18.09.39 - Restore library tab</string> <string name="revanced_spoof_app_version_target_entry_3">18.09.39 - Restore library tab</string>
<string name="revanced_spoof_app_version_target_entry_4">17.08.35 - Restore old UI layout</string>
<string name="revanced_spoof_app_version_target_entry_5">16.08.35 - Restore explore tab</string>
<string name="revanced_spoof_app_version_target_entry_6">16.01.35 - Restore fewer video player action buttons</string>
</patch> </patch>
<patch id="layout.startpage.ChangeStartPagePatch"> <patch id="layout.startpage.ChangeStartPagePatch">
<string name="revanced_start_page_title">Set start page</string> <string name="revanced_start_page_title">Set start page</string>