mirror of
https://github.com/ReVanced/revanced-patches.git
synced 2026-01-28 13:11:03 +00:00
Compare commits
11 Commits
v4.3.0-dev
...
v4.3.0-dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e386313deb | ||
|
|
f2edae2ac1 | ||
|
|
c153979981 | ||
|
|
2fe9060944 | ||
|
|
212a94cbb3 | ||
|
|
16eee2f03f | ||
|
|
4937fa5fbd | ||
|
|
a6f5dd933f | ||
|
|
97c4682ccc | ||
|
|
6742cd9232 | ||
|
|
5b2cc10adb |
35
CHANGELOG.md
35
CHANGELOG.md
@@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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\" />",
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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")
|
||||||
|
}
|
||||||
@@ -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"
|
||||||
|
},
|
||||||
|
)
|
||||||
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
),
|
||||||
|
)
|
||||||
@@ -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"),
|
||||||
|
)
|
||||||
@@ -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">
|
||||||
|
|||||||
@@ -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 & quality menu</string>
|
<string name="revanced_spoof_app_version_target_entry_2">18.20.39 - Restore wide video speed & 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>
|
||||||
|
|||||||
Reference in New Issue
Block a user