mirror of
https://github.com/revanced/revanced-patches.git
synced 2025-12-24 09:54:07 +01:00
Compare commits
8 Commits
v4.4.0-dev
...
v4.4.0-dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c981f6759 | ||
|
|
2fcd786cc7 | ||
|
|
60ace80cbd | ||
|
|
e6a468cf7a | ||
|
|
38392de4a1 | ||
|
|
bc8bc8c798 | ||
|
|
76805e4f31 | ||
|
|
d18719c59c |
28
CHANGELOG.md
28
CHANGELOG.md
@@ -1,3 +1,31 @@
|
|||||||
|
# [4.4.0-dev.10](https://github.com/ReVanced/revanced-patches/compare/v4.4.0-dev.9...v4.4.0-dev.10) (2024-03-25)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Hide ads:** Prevent app crash if hiding fullscreen ads is not possible ([#2910](https://github.com/ReVanced/revanced-patches/issues/2910)) ([9f50470](https://github.com/ReVanced/revanced-patches/commit/9f50470bf6582fe2f20a903a97bf66c41f296fb2))
|
||||||
|
|
||||||
|
# [4.4.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v4.4.0-dev.8...v4.4.0-dev.9) (2024-03-18)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **TikTok:** Hook application context earlier to prevent crash ([#2893](https://github.com/ReVanced/revanced-patches/issues/2893)) ([395ccda](https://github.com/ReVanced/revanced-patches/commit/395ccda7b9218c522c7ca0f99f75a12036d3e3f3))
|
||||||
|
|
||||||
|
# [4.4.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v4.4.0-dev.7...v4.4.0-dev.8) (2024-03-15)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **YouTube - Downloads:** Use external downloader when selecting 'Download' in home feed flyout menu ([#2881](https://github.com/ReVanced/revanced-patches/issues/2881)) ([10afc8c](https://github.com/ReVanced/revanced-patches/commit/10afc8cc71ff29fea4937fb12fd3d1edf9c581f5))
|
||||||
|
|
||||||
|
# [4.4.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v4.4.0-dev.6...v4.4.0-dev.7) (2024-03-14)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Client spoof:** Spoof all user agents ([44a8a13](https://github.com/ReVanced/revanced-patches/commit/44a8a1399897caaff3ff45db8549ddedb2f01b68))
|
||||||
|
|
||||||
# [4.4.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v4.4.0-dev.5...v4.4.0-dev.6) (2024-03-12)
|
# [4.4.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v4.4.0-dev.5...v4.4.0-dev.6) (2024-03-12)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -628,9 +628,19 @@ public abstract class app/revanced/patches/shared/misc/integrations/BaseIntegrat
|
|||||||
public fun <init> ()V
|
public fun <init> ()V
|
||||||
public fun <init> (Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Iterable;Ljava/lang/Iterable;Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;)V
|
public fun <init> (Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Iterable;Ljava/lang/Iterable;Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;)V
|
||||||
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Iterable;Ljava/lang/Iterable;Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Iterable;Ljava/lang/Iterable;Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
|
public fun <init> (Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Iterable;Ljava/lang/Iterable;Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)V
|
||||||
|
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Iterable;Ljava/lang/Iterable;Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
public final fun invoke (Ljava/lang/String;)V
|
public final fun invoke (Ljava/lang/String;)V
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract interface class app/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch$IntegrationsFingerprint$IHookInsertIndexResolver : kotlin/jvm/functions/Function1 {
|
||||||
|
public abstract fun invoke (Lcom/android/tools/smali/dexlib2/iface/Method;)Ljava/lang/Integer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class app/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch$IntegrationsFingerprint$IHookInsertIndexResolver$DefaultImpls {
|
||||||
|
public static fun invoke (Lapp/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch$IntegrationsFingerprint$IHookInsertIndexResolver;Lcom/android/tools/smali/dexlib2/iface/Method;)Ljava/lang/Integer;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract interface class app/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch$IntegrationsFingerprint$IRegisterResolver : kotlin/jvm/functions/Function1 {
|
public abstract interface class app/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch$IntegrationsFingerprint$IRegisterResolver : kotlin/jvm/functions/Function1 {
|
||||||
public abstract fun invoke (Lcom/android/tools/smali/dexlib2/iface/Method;)Ljava/lang/Integer;
|
public abstract fun invoke (Lcom/android/tools/smali/dexlib2/iface/Method;)Ljava/lang/Integer;
|
||||||
}
|
}
|
||||||
@@ -1514,10 +1524,12 @@ public final class app/revanced/patches/youtube/misc/dimensions/spoof/SpoofDevic
|
|||||||
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/youtube/misc/fix/playback/ClientSpoofPatch : app/revanced/patcher/patch/BytecodePatch {
|
public final class app/revanced/patches/youtube/misc/fix/playback/ClientSpoofPatch : app/revanced/patches/all/misc/transformation/BaseTransformInstructionsPatch {
|
||||||
public static final field INSTANCE Lapp/revanced/patches/youtube/misc/fix/playback/ClientSpoofPatch;
|
public static final field INSTANCE Lapp/revanced/patches/youtube/misc/fix/playback/ClientSpoofPatch;
|
||||||
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
|
public synthetic fun filterMap (Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;I)Ljava/lang/Object;
|
||||||
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
public fun filterMap (Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;I)Lkotlin/Triple;
|
||||||
|
public synthetic fun transform (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;Ljava/lang/Object;)V
|
||||||
|
public fun transform (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;Lkotlin/Triple;)V
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/youtube/misc/fix/playback/SpoofSignaturePatch : app/revanced/patcher/patch/BytecodePatch {
|
public final class app/revanced/patches/youtube/misc/fix/playback/SpoofSignaturePatch : app/revanced/patcher/patch/BytecodePatch {
|
||||||
|
|||||||
@@ -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.4.0-dev.6
|
version = 4.4.0-dev.10
|
||||||
|
|||||||
@@ -49,7 +49,8 @@ abstract class BaseIntegrationsPatch(
|
|||||||
opcodes: Iterable<Opcode?>? = null,
|
opcodes: Iterable<Opcode?>? = null,
|
||||||
strings: Iterable<String>? = null,
|
strings: Iterable<String>? = null,
|
||||||
customFingerprint: ((methodDef: Method, classDef: ClassDef) -> Boolean)? = null,
|
customFingerprint: ((methodDef: Method, classDef: ClassDef) -> Boolean)? = null,
|
||||||
private val contextRegisterResolver: (Method) -> Int = object : IRegisterResolver {},
|
private val insertIndexResolver: ((Method) -> Int) = object : IHookInsertIndexResolver {},
|
||||||
|
private val contextRegisterResolver: (Method) -> Int = object : IRegisterResolver {}
|
||||||
) : MethodFingerprint(
|
) : MethodFingerprint(
|
||||||
returnType,
|
returnType,
|
||||||
accessFlags,
|
accessFlags,
|
||||||
@@ -58,18 +59,45 @@ abstract class BaseIntegrationsPatch(
|
|||||||
strings,
|
strings,
|
||||||
customFingerprint,
|
customFingerprint,
|
||||||
) {
|
) {
|
||||||
|
@Deprecated("Previous constructor that is missing the insert index." +
|
||||||
|
"Here only for binary compatibility, " +
|
||||||
|
"and this can be removed after the next major version update.")
|
||||||
|
constructor(
|
||||||
|
returnType: String? = null,
|
||||||
|
accessFlags: Int? = null,
|
||||||
|
parameters: Iterable<String>? = null,
|
||||||
|
opcodes: Iterable<Opcode?>? = null,
|
||||||
|
strings: Iterable<String>? = null,
|
||||||
|
customFingerprint: ((methodDef: Method, classDef: ClassDef) -> Boolean)? = null,
|
||||||
|
contextRegisterResolver: (Method) -> Int = object : IRegisterResolver {}
|
||||||
|
) : this(
|
||||||
|
returnType,
|
||||||
|
accessFlags,
|
||||||
|
parameters,
|
||||||
|
opcodes,
|
||||||
|
strings,
|
||||||
|
customFingerprint,
|
||||||
|
object : IHookInsertIndexResolver {},
|
||||||
|
contextRegisterResolver
|
||||||
|
)
|
||||||
|
|
||||||
fun invoke(integrationsDescriptor: String) {
|
fun invoke(integrationsDescriptor: String) {
|
||||||
result?.mutableMethod?.let { method ->
|
result?.mutableMethod?.let { method ->
|
||||||
|
val insertIndex = insertIndexResolver(method)
|
||||||
val contextRegister = contextRegisterResolver(method)
|
val contextRegister = contextRegisterResolver(method)
|
||||||
|
|
||||||
method.addInstruction(
|
method.addInstruction(
|
||||||
0,
|
insertIndex,
|
||||||
"invoke-static/range { v$contextRegister .. v$contextRegister }, " +
|
"invoke-static/range { v$contextRegister .. v$contextRegister }, " +
|
||||||
"$integrationsDescriptor->setContext(Landroid/content/Context;)V",
|
"$integrationsDescriptor->setContext(Landroid/content/Context;)V",
|
||||||
)
|
)
|
||||||
} ?: throw PatchException("Could not find hook target fingerprint.")
|
} ?: throw PatchException("Could not find hook target fingerprint.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface IHookInsertIndexResolver : (Method) -> Int {
|
||||||
|
override operator fun invoke(method: Method) = 0
|
||||||
|
}
|
||||||
|
|
||||||
interface IRegisterResolver : (Method) -> Int {
|
interface IRegisterResolver : (Method) -> Int {
|
||||||
override operator fun invoke(method: Method) = method.implementation!!.registerCount - 1
|
override operator fun invoke(method: Method) = method.implementation!!.registerCount - 1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
package app.revanced.patches.tiktok.misc.integrations.fingerprints
|
package app.revanced.patches.tiktok.misc.integrations.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patches.shared.misc.integrations.BaseIntegrationsPatch.IntegrationsFingerprint
|
import app.revanced.patches.shared.misc.integrations.BaseIntegrationsPatch.IntegrationsFingerprint
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
|
||||||
internal object InitFingerprint : IntegrationsFingerprint(
|
internal object InitFingerprint : IntegrationsFingerprint(
|
||||||
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
||||||
customFingerprint = { methodDef, _ ->
|
customFingerprint = { methodDef, _ ->
|
||||||
methodDef.definingClass.endsWith("/AwemeHostApplication;") &&
|
methodDef.definingClass.endsWith("/AwemeHostApplication;") &&
|
||||||
methodDef.name == "onCreate"
|
methodDef.name == "<init>"
|
||||||
}
|
},
|
||||||
|
insertIndexResolver = { 1 } // Insert after call to super class.
|
||||||
)
|
)
|
||||||
@@ -6,9 +6,7 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWith
|
|||||||
import app.revanced.patcher.patch.BytecodePatch
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
import app.revanced.patches.youtube.interaction.downloads.fingerprints.DownloadActionCommandResolverFingerprint
|
import app.revanced.patches.youtube.interaction.downloads.fingerprints.OfflineVideoEndpointFingerprint
|
||||||
import app.revanced.patches.youtube.interaction.downloads.fingerprints.DownloadActionCommandResolverParentFingerprint
|
|
||||||
import app.revanced.patches.youtube.interaction.downloads.fingerprints.LegacyDownloadCommandResolverFingerprint
|
|
||||||
import app.revanced.patches.youtube.misc.playercontrols.PlayerControlsBytecodePatch
|
import app.revanced.patches.youtube.misc.playercontrols.PlayerControlsBytecodePatch
|
||||||
import app.revanced.patches.youtube.shared.fingerprints.MainActivityFingerprint
|
import app.revanced.patches.youtube.shared.fingerprints.MainActivityFingerprint
|
||||||
import app.revanced.patches.youtube.video.information.VideoInformationPatch
|
import app.revanced.patches.youtube.video.information.VideoInformationPatch
|
||||||
@@ -45,8 +43,7 @@ import app.revanced.util.resultOrThrow
|
|||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object DownloadsPatch : BytecodePatch(
|
object DownloadsPatch : BytecodePatch(
|
||||||
setOf(
|
setOf(
|
||||||
DownloadActionCommandResolverParentFingerprint,
|
OfflineVideoEndpointFingerprint,
|
||||||
LegacyDownloadCommandResolverFingerprint,
|
|
||||||
MainActivityFingerprint
|
MainActivityFingerprint
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
@@ -65,36 +62,16 @@ object DownloadsPatch : BytecodePatch(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val commonInstructions = """
|
OfflineVideoEndpointFingerprint.resultOrThrow().mutableMethod.apply {
|
||||||
move-result v0
|
|
||||||
if-eqz v0, :show_native_downloader
|
|
||||||
return-void
|
|
||||||
:show_native_downloader
|
|
||||||
nop
|
|
||||||
"""
|
|
||||||
|
|
||||||
DownloadActionCommandResolverFingerprint.resolve(context,
|
|
||||||
DownloadActionCommandResolverParentFingerprint.resultOrThrow().classDef)
|
|
||||||
DownloadActionCommandResolverFingerprint.resultOrThrow().mutableMethod.apply {
|
|
||||||
addInstructionsWithLabels(
|
addInstructionsWithLabels(
|
||||||
0,
|
0,
|
||||||
"""
|
"""
|
||||||
invoke-static {}, $INTEGRATIONS_CLASS_DESCRIPTOR->inAppDownloadButtonOnClick()Z
|
invoke-static/range {p3 .. p3}, $INTEGRATIONS_CLASS_DESCRIPTOR->inAppDownloadButtonOnClick(Ljava/lang/String;)Z
|
||||||
$commonInstructions
|
move-result v0
|
||||||
"""
|
if-eqz v0, :show_native_downloader
|
||||||
)
|
return-void
|
||||||
}
|
:show_native_downloader
|
||||||
|
nop
|
||||||
// Legacy fingerprint is used for old spoofed versions,
|
|
||||||
// or if download playlist is pressed on any version.
|
|
||||||
// Downloading playlists is not yet supported,
|
|
||||||
// as the code this hooks does not easily expost the playlist id.
|
|
||||||
LegacyDownloadCommandResolverFingerprint.resultOrThrow().mutableMethod.apply {
|
|
||||||
addInstructionsWithLabels(
|
|
||||||
0,
|
|
||||||
"""
|
|
||||||
invoke-static/range {p1 .. p1}, $INTEGRATIONS_CLASS_DESCRIPTOR->inAppDownloadPlaylistLegacyOnClick(Ljava/lang/String;)Z
|
|
||||||
$commonInstructions
|
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
package app.revanced.patches.youtube.interaction.downloads.fingerprints
|
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
|
||||||
import app.revanced.util.patch.LiteralValueFingerprint
|
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
|
||||||
|
|
||||||
internal object DownloadActionCommandResolverParentFingerprint : LiteralValueFingerprint(
|
|
||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
|
||||||
returnType = "V",
|
|
||||||
parameters = listOf("L", "L"),
|
|
||||||
strings = listOf(
|
|
||||||
// Strings are not unique and found in other methods.
|
|
||||||
"com.google.android.libraries.youtube.logging.interaction_logger",
|
|
||||||
"Unknown command"
|
|
||||||
),
|
|
||||||
literalSupplier = { 16 }
|
|
||||||
)
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
package app.revanced.patches.youtube.interaction.downloads.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
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For spoofing to older versions. Also called if download playlist is pressed for any version.
|
|
||||||
*/
|
|
||||||
internal object LegacyDownloadCommandResolverFingerprint : MethodFingerprint(
|
|
||||||
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
|
|
||||||
returnType = "V",
|
|
||||||
parameters = listOf("Ljava/lang/String;", "Ljava/lang/String;", "L", "L"),
|
|
||||||
strings = listOf(""),
|
|
||||||
opcodes = listOf(
|
|
||||||
Opcode.MOVE_OBJECT_FROM16,
|
|
||||||
Opcode.MOVE_OBJECT_FROM16,
|
|
||||||
Opcode.NEW_INSTANCE,
|
|
||||||
Opcode.INVOKE_DIRECT,
|
|
||||||
Opcode.IGET_OBJECT,
|
|
||||||
Opcode.IF_NEZ,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
@@ -4,11 +4,13 @@ import app.revanced.patcher.extensions.or
|
|||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
|
||||||
/**
|
internal object OfflineVideoEndpointFingerprint : MethodFingerprint(
|
||||||
* Resolves to the class found in [DownloadActionCommandResolverParentFingerprint].
|
|
||||||
*/
|
|
||||||
internal object DownloadActionCommandResolverFingerprint : MethodFingerprint(
|
|
||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
returnType = "V",
|
returnType = "V",
|
||||||
parameters = listOf("L", "Ljava/util/Map;")
|
parameters = listOf(
|
||||||
|
"Ljava/util/Map;",
|
||||||
|
"L",
|
||||||
|
"Ljava/lang/String", // VideoId
|
||||||
|
"L"),
|
||||||
|
strings = listOf("Object is not an offlineable video: ")
|
||||||
)
|
)
|
||||||
@@ -1,51 +1,87 @@
|
|||||||
package app.revanced.patches.youtube.misc.fix.playback
|
package app.revanced.patches.youtube.misc.fix.playback
|
||||||
|
|
||||||
import app.revanced.util.exception
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.UserAgentHeaderBuilderFingerprint
|
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
import app.revanced.patches.all.misc.transformation.BaseTransformInstructionsPatch
|
||||||
|
import app.revanced.patches.all.misc.transformation.IMethodCall
|
||||||
|
import app.revanced.patches.all.misc.transformation.Instruction35cInfo
|
||||||
|
import app.revanced.patches.all.misc.transformation.filterMapInstruction35c
|
||||||
|
import app.revanced.util.getReference
|
||||||
|
import com.android.tools.smali.dexlib2.iface.ClassDef
|
||||||
|
import com.android.tools.smali.dexlib2.iface.Method
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.Instruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
|
|
||||||
@Patch(
|
@Patch(
|
||||||
name = "Client spoof",
|
name = "Client spoof",
|
||||||
description = "Adds options to spoof the client to allow video playback.",
|
description = "Adds options to spoof the client to allow video playback.",
|
||||||
dependencies = [SpoofSignaturePatch::class],
|
dependencies = [SpoofSignaturePatch::class],
|
||||||
compatiblePackages = [
|
compatiblePackages = [
|
||||||
CompatiblePackage(
|
CompatiblePackage("com.google.android.youtube"),
|
||||||
"com.google.android.youtube", [
|
],
|
||||||
"18.48.39",
|
|
||||||
"18.49.37",
|
|
||||||
"19.01.34",
|
|
||||||
"19.02.39",
|
|
||||||
"19.03.36",
|
|
||||||
"19.04.38",
|
|
||||||
"19.05.36",
|
|
||||||
"19.06.39",
|
|
||||||
"19.07.40",
|
|
||||||
"19.08.36",
|
|
||||||
"19.09.37"
|
|
||||||
]
|
|
||||||
)
|
|
||||||
]
|
|
||||||
)
|
)
|
||||||
object ClientSpoofPatch : BytecodePatch(
|
object ClientSpoofPatch : BaseTransformInstructionsPatch<Instruction35cInfo>() {
|
||||||
setOf(UserAgentHeaderBuilderFingerprint)
|
|
||||||
) {
|
|
||||||
private const val ORIGINAL_PACKAGE_NAME = "com.google.android.youtube"
|
private const val ORIGINAL_PACKAGE_NAME = "com.google.android.youtube"
|
||||||
|
private const val USER_AGENT_STRING_BUILDER_APPEND_METHOD_REFERENCE =
|
||||||
|
"Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;"
|
||||||
|
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun filterMap(
|
||||||
UserAgentHeaderBuilderFingerprint.result?.let { result ->
|
classDef: ClassDef,
|
||||||
val insertIndex = result.scanResult.patternScanResult!!.endIndex
|
method: Method,
|
||||||
result.mutableMethod.apply {
|
instruction: Instruction,
|
||||||
val packageNameRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerD
|
instructionIndex: Int,
|
||||||
|
) = filterMapInstruction35c<MethodCall>(
|
||||||
|
"Lapp/revanced/integrations",
|
||||||
|
classDef,
|
||||||
|
instruction,
|
||||||
|
instructionIndex,
|
||||||
|
)
|
||||||
|
|
||||||
addInstruction(insertIndex, "const-string v$packageNameRegister, \"$ORIGINAL_PACKAGE_NAME\"")
|
override fun transform(mutableMethod: MutableMethod, entry: Instruction35cInfo) {
|
||||||
}
|
val (_, _, instructionIndex) = entry
|
||||||
|
|
||||||
} ?: throw UserAgentHeaderBuilderFingerprint.exception
|
// Replace the result of context.getPackageName(), if it is used in a user agent string.
|
||||||
|
mutableMethod.apply {
|
||||||
|
// After context.getPackageName() the result is moved to a register.
|
||||||
|
val targetRegister = (
|
||||||
|
getInstruction(instructionIndex + 1)
|
||||||
|
as? OneRegisterInstruction ?: return
|
||||||
|
).registerA
|
||||||
|
|
||||||
|
// IndexOutOfBoundsException is not possible here,
|
||||||
|
// but no such occurrences are present in the app.
|
||||||
|
val referee = getInstruction(instructionIndex + 2).getReference<MethodReference>()?.toString()
|
||||||
|
|
||||||
|
// This can technically also match non-user agent string builder append methods,
|
||||||
|
// but no such occurrences are present in the app.
|
||||||
|
if (referee != USER_AGENT_STRING_BUILDER_APPEND_METHOD_REFERENCE) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overwrite the result of context.getPackageName() with the original package name.
|
||||||
|
replaceInstruction(
|
||||||
|
instructionIndex + 1,
|
||||||
|
"const-string v$targetRegister, \"${ORIGINAL_PACKAGE_NAME}\"",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
private enum class MethodCall(
|
||||||
|
override val definedClassName: String,
|
||||||
|
override val methodName: String,
|
||||||
|
override val methodParams: Array<String>,
|
||||||
|
override val returnType: String,
|
||||||
|
) : IMethodCall {
|
||||||
|
GetPackageName(
|
||||||
|
"Landroid/content/Context;",
|
||||||
|
"getPackageName",
|
||||||
|
emptyArray(),
|
||||||
|
"Ljava/lang/String;",
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
|
|
||||||
|
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
|
||||||
|
|
||||||
internal object UserAgentHeaderBuilderFingerprint : MethodFingerprint(
|
|
||||||
parameters = listOf("L", "L", "L"),
|
|
||||||
opcodes = listOf(Opcode.MOVE_RESULT_OBJECT, Opcode.INVOKE_VIRTUAL),
|
|
||||||
strings = listOf("(Linux; U; Android "),
|
|
||||||
)
|
|
||||||
@@ -199,6 +199,7 @@
|
|||||||
<string name="revanced_hide_merchandise_banners_title">Hide merchandise banners</string>
|
<string name="revanced_hide_merchandise_banners_title">Hide merchandise banners</string>
|
||||||
<string name="revanced_hide_merchandise_banners_summary_on">Merchandise banners are hidden</string>
|
<string name="revanced_hide_merchandise_banners_summary_on">Merchandise banners are hidden</string>
|
||||||
<string name="revanced_hide_merchandise_banners_summary_off">Merchandise banners are shown</string>
|
<string name="revanced_hide_merchandise_banners_summary_off">Merchandise banners are shown</string>
|
||||||
|
<string name="revanced_hide_fullscreen_ads_feature_not_available_toast">Failed to hide full-screen ad. Disabling to prevent issues</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="ad.getpremium.HideGetPremiumPatch">
|
<patch id="ad.getpremium.HideGetPremiumPatch">
|
||||||
<string name="revanced_hide_get_premium_title">Hide YouTube Premium promotions</string>
|
<string name="revanced_hide_get_premium_title">Hide YouTube Premium promotions</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user