mirror of
https://github.com/inotia00/revanced-patches.git
synced 2025-05-05 09:04:34 +02:00
feat(YouTube): Replace with a fingerprint that supports a wider range of versions (..20.10)
This commit is contained in:
parent
6b1e45f234
commit
1b3ebe1a58
@ -478,6 +478,10 @@ public class GeneralPatch {
|
|||||||
return Settings.HIDE_SEARCH_TERM_THUMBNAIL.get();
|
return Settings.HIDE_SEARCH_TERM_THUMBNAIL.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean hideSearchTermThumbnail(boolean original) {
|
||||||
|
return !hideSearchTermThumbnail() && original;
|
||||||
|
}
|
||||||
|
|
||||||
private static final boolean hideImageSearchButton = Settings.HIDE_IMAGE_SEARCH_BUTTON.get();
|
private static final boolean hideImageSearchButton = Settings.HIDE_IMAGE_SEARCH_BUTTON.get();
|
||||||
private static final boolean hideVoiceSearchButton = Settings.HIDE_VOICE_SEARCH_BUTTON.get();
|
private static final boolean hideVoiceSearchButton = Settings.HIDE_VOICE_SEARCH_BUTTON.get();
|
||||||
|
|
||||||
|
@ -259,13 +259,7 @@ val feedComponentsPatch = bytecodePatch(
|
|||||||
elementParserFingerprint.matchOrThrow(elementParserParentFingerprint).let {
|
elementParserFingerprint.matchOrThrow(elementParserParentFingerprint).let {
|
||||||
it.method.apply {
|
it.method.apply {
|
||||||
val freeRegister = implementation!!.registerCount - parameters.size - 2
|
val freeRegister = implementation!!.registerCount - parameters.size - 2
|
||||||
val insertIndex = indexOfFirstInstructionOrThrow {
|
val insertIndex = indexOfBufferParserInstruction(this)
|
||||||
val reference = getReference<MethodReference>()
|
|
||||||
|
|
||||||
reference?.parameterTypes?.size == 1 &&
|
|
||||||
reference.parameterTypes.first() == "[B" &&
|
|
||||||
reference.returnType.startsWith("L")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_19_46_or_greater) {
|
if (is_19_46_or_greater) {
|
||||||
val objectIndex = indexOfFirstInstructionReversedOrThrow(insertIndex, Opcode.IGET_OBJECT)
|
val objectIndex = indexOfFirstInstructionReversedOrThrow(insertIndex, Opcode.IGET_OBJECT)
|
||||||
|
@ -11,9 +11,13 @@ import app.revanced.patches.youtube.utils.resourceid.filterBarHeight
|
|||||||
import app.revanced.patches.youtube.utils.resourceid.horizontalCardList
|
import app.revanced.patches.youtube.utils.resourceid.horizontalCardList
|
||||||
import app.revanced.patches.youtube.utils.resourceid.relatedChipCloudMargin
|
import app.revanced.patches.youtube.utils.resourceid.relatedChipCloudMargin
|
||||||
import app.revanced.util.fingerprint.legacyFingerprint
|
import app.revanced.util.fingerprint.legacyFingerprint
|
||||||
|
import app.revanced.util.getReference
|
||||||
|
import app.revanced.util.indexOfFirstInstruction
|
||||||
import app.revanced.util.or
|
import app.revanced.util.or
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
import com.android.tools.smali.dexlib2.iface.Method
|
||||||
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
|
|
||||||
internal val breakingNewsFingerprint = legacyFingerprint(
|
internal val breakingNewsFingerprint = legacyFingerprint(
|
||||||
name = "breakingNewsFingerprint",
|
name = "breakingNewsFingerprint",
|
||||||
@ -90,8 +94,18 @@ internal val elementParserFingerprint = legacyFingerprint(
|
|||||||
Opcode.MOVE_RESULT_OBJECT,
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
Opcode.IGET_OBJECT,
|
Opcode.IGET_OBJECT,
|
||||||
Opcode.RETURN_OBJECT
|
Opcode.RETURN_OBJECT
|
||||||
|
),
|
||||||
|
customFingerprint = { method, _ ->
|
||||||
|
indexOfBufferParserInstruction(method) >= 0
|
||||||
|
}
|
||||||
)
|
)
|
||||||
)
|
|
||||||
|
internal fun indexOfBufferParserInstruction(method: Method) =
|
||||||
|
method.indexOfFirstInstruction {
|
||||||
|
val reference = getReference<MethodReference>()
|
||||||
|
reference?.parameterTypes?.firstOrNull() == "[B" &&
|
||||||
|
reference.returnType.startsWith("L")
|
||||||
|
}
|
||||||
|
|
||||||
internal val elementParserParentFingerprint = legacyFingerprint(
|
internal val elementParserParentFingerprint = legacyFingerprint(
|
||||||
name = "elementParserParentFingerprint",
|
name = "elementParserParentFingerprint",
|
||||||
|
@ -91,7 +91,25 @@ internal val createSearchSuggestionsFingerprint = legacyFingerprint(
|
|||||||
returnType = "Landroid/view/View;",
|
returnType = "Landroid/view/View;",
|
||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
parameters = listOf("I", "Landroid/view/View;", "Landroid/view/ViewGroup;"),
|
parameters = listOf("I", "Landroid/view/View;", "Landroid/view/ViewGroup;"),
|
||||||
strings = listOf("ss_rds")
|
strings = listOf("ss_rds"),
|
||||||
|
customFingerprint = { method, _ ->
|
||||||
|
indexOfIteratorInstruction(method) >= 0
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
internal fun indexOfIteratorInstruction(method: Method) =
|
||||||
|
method.indexOfFirstInstructionReversed {
|
||||||
|
opcode == Opcode.INVOKE_INTERFACE &&
|
||||||
|
getReference<MethodReference>()?.toString() == "Ljava/util/Iterator;->next()Ljava/lang/Object;"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flag is present in YouTube 19.16, but was not used until YouTube 19.43.
|
||||||
|
// Related issue: https://github.com/inotia00/ReVanced_Extended/issues/2784
|
||||||
|
internal const val SEARCH_FRAGMENT_FEATURE_FLAG = 45353159L
|
||||||
|
|
||||||
|
internal val searchFragmentFeatureFlagFingerprint = legacyFingerprint(
|
||||||
|
name = "searchFragmentFeatureFlagFingerprint",
|
||||||
|
literals = listOf(SEARCH_FRAGMENT_FEATURE_FLAG),
|
||||||
)
|
)
|
||||||
|
|
||||||
internal val drawerContentViewConstructorFingerprint = legacyFingerprint(
|
internal val drawerContentViewConstructorFingerprint = legacyFingerprint(
|
||||||
|
@ -15,7 +15,7 @@ import app.revanced.patches.youtube.utils.castbutton.hookToolBarCastButton
|
|||||||
import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
||||||
import app.revanced.patches.youtube.utils.extension.Constants.GENERAL_CLASS_DESCRIPTOR
|
import app.revanced.patches.youtube.utils.extension.Constants.GENERAL_CLASS_DESCRIPTOR
|
||||||
import app.revanced.patches.youtube.utils.patch.PatchList.TOOLBAR_COMPONENTS
|
import app.revanced.patches.youtube.utils.patch.PatchList.TOOLBAR_COMPONENTS
|
||||||
import app.revanced.patches.youtube.utils.playservice.is_19_46_or_greater
|
import app.revanced.patches.youtube.utils.playservice.is_19_16_or_greater
|
||||||
import app.revanced.patches.youtube.utils.playservice.versionCheckPatch
|
import app.revanced.patches.youtube.utils.playservice.versionCheckPatch
|
||||||
import app.revanced.patches.youtube.utils.resourceid.actionBarRingoBackground
|
import app.revanced.patches.youtube.utils.resourceid.actionBarRingoBackground
|
||||||
import app.revanced.patches.youtube.utils.resourceid.sharedResourceIdPatch
|
import app.revanced.patches.youtube.utils.resourceid.sharedResourceIdPatch
|
||||||
@ -31,6 +31,7 @@ import app.revanced.util.REGISTER_TEMPLATE_REPLACEMENT
|
|||||||
import app.revanced.util.doRecursively
|
import app.revanced.util.doRecursively
|
||||||
import app.revanced.util.findInstructionIndicesReversedOrThrow
|
import app.revanced.util.findInstructionIndicesReversedOrThrow
|
||||||
import app.revanced.util.findMethodOrThrow
|
import app.revanced.util.findMethodOrThrow
|
||||||
|
import app.revanced.util.fingerprint.injectLiteralInstructionBooleanCall
|
||||||
import app.revanced.util.fingerprint.matchOrThrow
|
import app.revanced.util.fingerprint.matchOrThrow
|
||||||
import app.revanced.util.fingerprint.methodCall
|
import app.revanced.util.fingerprint.methodCall
|
||||||
import app.revanced.util.fingerprint.methodOrThrow
|
import app.revanced.util.fingerprint.methodOrThrow
|
||||||
@ -38,7 +39,6 @@ import app.revanced.util.fingerprint.mutableClassOrThrow
|
|||||||
import app.revanced.util.getReference
|
import app.revanced.util.getReference
|
||||||
import app.revanced.util.getWalkerMethod
|
import app.revanced.util.getWalkerMethod
|
||||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
|
||||||
import app.revanced.util.indexOfFirstLiteralInstructionOrThrow
|
import app.revanced.util.indexOfFirstLiteralInstructionOrThrow
|
||||||
import app.revanced.util.replaceLiteralInstructionCall
|
import app.revanced.util.replaceLiteralInstructionCall
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
@ -46,6 +46,7 @@ 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
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
import com.android.tools.smali.dexlib2.util.MethodUtil
|
import com.android.tools.smali.dexlib2.util.MethodUtil
|
||||||
import org.w3c.dom.Element
|
import org.w3c.dom.Element
|
||||||
@ -266,36 +267,39 @@ val toolBarComponentsPatch = bytecodePatch(
|
|||||||
// region patch for hide search term thumbnail
|
// region patch for hide search term thumbnail
|
||||||
|
|
||||||
createSearchSuggestionsFingerprint.methodOrThrow().apply {
|
createSearchSuggestionsFingerprint.methodOrThrow().apply {
|
||||||
val literal = if (is_19_46_or_greater)
|
val iteratorIndex = indexOfIteratorInstruction(this)
|
||||||
32L
|
val replaceIndex = indexOfFirstInstructionOrThrow(iteratorIndex) {
|
||||||
else
|
opcode == Opcode.IGET_OBJECT &&
|
||||||
40L
|
getReference<FieldReference>()?.type == "Landroid/widget/ImageView;"
|
||||||
val relativeIndex = indexOfFirstLiteralInstructionOrThrow(literal)
|
}
|
||||||
val replaceIndex = indexOfFirstInstructionReversedOrThrow(relativeIndex) {
|
val jumpIndex = indexOfFirstInstructionOrThrow(replaceIndex) {
|
||||||
opcode == Opcode.INVOKE_VIRTUAL &&
|
|
||||||
getReference<MethodReference>()?.toString() == "Landroid/widget/ImageView;->setVisibility(I)V"
|
|
||||||
} - 1
|
|
||||||
|
|
||||||
val jumpIndex = indexOfFirstInstructionOrThrow(relativeIndex) {
|
|
||||||
opcode == Opcode.INVOKE_STATIC &&
|
opcode == Opcode.INVOKE_STATIC &&
|
||||||
getReference<MethodReference>()?.toString() == "Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;"
|
getReference<MethodReference>()?.toString() == "Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;"
|
||||||
} + 4
|
} + 4
|
||||||
|
|
||||||
val replaceIndexInstruction = getInstruction<TwoRegisterInstruction>(replaceIndex)
|
val replaceIndexInstruction = getInstruction<TwoRegisterInstruction>(replaceIndex)
|
||||||
|
val freeRegister = replaceIndexInstruction.registerA
|
||||||
|
val classRegister = replaceIndexInstruction.registerB
|
||||||
val replaceIndexReference =
|
val replaceIndexReference =
|
||||||
getInstruction<ReferenceInstruction>(replaceIndex).reference
|
getInstruction<ReferenceInstruction>(replaceIndex).reference
|
||||||
|
|
||||||
addInstructionsWithLabels(
|
addInstructionsWithLabels(
|
||||||
replaceIndex + 1, """
|
replaceIndex + 1, """
|
||||||
invoke-static { }, $GENERAL_CLASS_DESCRIPTOR->hideSearchTermThumbnail()Z
|
invoke-static { }, $GENERAL_CLASS_DESCRIPTOR->hideSearchTermThumbnail()Z
|
||||||
move-result v${replaceIndexInstruction.registerA}
|
move-result v$freeRegister
|
||||||
if-nez v${replaceIndexInstruction.registerA}, :hidden
|
if-nez v$freeRegister, :hidden
|
||||||
iget-object v${replaceIndexInstruction.registerA}, v${replaceIndexInstruction.registerB}, $replaceIndexReference
|
iget-object v$freeRegister, v$classRegister, $replaceIndexReference
|
||||||
""", ExternalLabel("hidden", getInstruction(jumpIndex))
|
""", ExternalLabel("hidden", getInstruction(jumpIndex))
|
||||||
)
|
)
|
||||||
removeInstruction(replaceIndex)
|
removeInstruction(replaceIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_19_16_or_greater) {
|
||||||
|
searchFragmentFeatureFlagFingerprint.injectLiteralInstructionBooleanCall(
|
||||||
|
SEARCH_FRAGMENT_FEATURE_FLAG,
|
||||||
|
"$GENERAL_CLASS_DESCRIPTOR->hideSearchTermThumbnail(Z)Z"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -234,7 +234,8 @@ internal val youtubeControlsOverlayFingerprint = legacyFingerprint(
|
|||||||
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
|
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
|
||||||
parameters = emptyList(),
|
parameters = emptyList(),
|
||||||
literals = listOf(
|
literals = listOf(
|
||||||
fadeDurationFast,
|
// Removed in YouTube 20.09.40+
|
||||||
|
// fadeDurationFast,
|
||||||
insetOverlayViewLayout,
|
insetOverlayViewLayout,
|
||||||
scrimOverlay,
|
scrimOverlay,
|
||||||
// Removed in YouTube 20.02.38+
|
// Removed in YouTube 20.02.38+
|
||||||
|
@ -146,4 +146,10 @@ internal val onesieEncryptionFeatureFlagFingerprint = legacyFingerprint(
|
|||||||
literals = listOf(ONESIE_ENCRYPTION_FEATURE_FLAG),
|
literals = listOf(ONESIE_ENCRYPTION_FEATURE_FLAG),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// YouTube 20.10 ~
|
||||||
|
internal const val ONESIE_ENCRYPTION_ALTERNATIVE_FEATURE_FLAG = 45683169L
|
||||||
|
|
||||||
|
internal val onesieEncryptionAlternativeFeatureFlagFingerprint = legacyFingerprint(
|
||||||
|
name = "onesieEncryptionAlternativeFeatureFlagFingerprint",
|
||||||
|
literals = listOf(ONESIE_ENCRYPTION_ALTERNATIVE_FEATURE_FLAG),
|
||||||
|
)
|
||||||
|
@ -19,6 +19,7 @@ import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PAC
|
|||||||
import app.revanced.patches.youtube.utils.compatibility.Constants.YOUTUBE_PACKAGE_NAME
|
import app.revanced.patches.youtube.utils.compatibility.Constants.YOUTUBE_PACKAGE_NAME
|
||||||
import app.revanced.patches.youtube.utils.patch.PatchList.SPOOF_STREAMING_DATA
|
import app.revanced.patches.youtube.utils.patch.PatchList.SPOOF_STREAMING_DATA
|
||||||
import app.revanced.patches.youtube.utils.playservice.is_19_34_or_greater
|
import app.revanced.patches.youtube.utils.playservice.is_19_34_or_greater
|
||||||
|
import app.revanced.patches.youtube.utils.playservice.is_20_10_or_greater
|
||||||
import app.revanced.patches.youtube.utils.playservice.versionCheckPatch
|
import app.revanced.patches.youtube.utils.playservice.versionCheckPatch
|
||||||
import app.revanced.patches.youtube.utils.request.buildRequestPatch
|
import app.revanced.patches.youtube.utils.request.buildRequestPatch
|
||||||
import app.revanced.patches.youtube.utils.request.hookBuildRequest
|
import app.revanced.patches.youtube.utils.request.hookBuildRequest
|
||||||
@ -332,6 +333,13 @@ val spoofStreamingDataPatch = bytecodePatch(
|
|||||||
"$EXTENSION_CLASS_DESCRIPTOR->skipResponseEncryption(Z)Z"
|
"$EXTENSION_CLASS_DESCRIPTOR->skipResponseEncryption(Z)Z"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (is_20_10_or_greater) {
|
||||||
|
onesieEncryptionAlternativeFeatureFlagFingerprint.injectLiteralInstructionBooleanCall(
|
||||||
|
ONESIE_ENCRYPTION_ALTERNATIVE_FEATURE_FLAG,
|
||||||
|
"$EXTENSION_CLASS_DESCRIPTOR->skipResponseEncryption(Z)Z"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
settingArray += "SETTINGS: SKIP_RESPONSE_ENCRYPTION"
|
settingArray += "SETTINGS: SKIP_RESPONSE_ENCRYPTION"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,8 @@ var is_19_09_or_greater = false
|
|||||||
private set
|
private set
|
||||||
var is_19_15_or_greater = false
|
var is_19_15_or_greater = false
|
||||||
private set
|
private set
|
||||||
|
var is_19_16_or_greater = false
|
||||||
|
private set
|
||||||
var is_19_17_or_greater = false
|
var is_19_17_or_greater = false
|
||||||
private set
|
private set
|
||||||
var is_19_23_or_greater = false
|
var is_19_23_or_greater = false
|
||||||
@ -59,6 +61,8 @@ var is_20_03_or_greater = false
|
|||||||
private set
|
private set
|
||||||
var is_20_05_or_greater = false
|
var is_20_05_or_greater = false
|
||||||
private set
|
private set
|
||||||
|
var is_20_10_or_greater = false
|
||||||
|
private set
|
||||||
|
|
||||||
val versionCheckPatch = resourcePatch(
|
val versionCheckPatch = resourcePatch(
|
||||||
description = "versionCheckPatch",
|
description = "versionCheckPatch",
|
||||||
@ -83,6 +87,7 @@ val versionCheckPatch = resourcePatch(
|
|||||||
is_19_04_or_greater = 240502000 <= playStoreServicesVersion
|
is_19_04_or_greater = 240502000 <= playStoreServicesVersion
|
||||||
is_19_09_or_greater = 241002000 <= playStoreServicesVersion
|
is_19_09_or_greater = 241002000 <= playStoreServicesVersion
|
||||||
is_19_15_or_greater = 241602000 <= playStoreServicesVersion
|
is_19_15_or_greater = 241602000 <= playStoreServicesVersion
|
||||||
|
is_19_16_or_greater = 241702000 <= playStoreServicesVersion
|
||||||
is_19_17_or_greater = 241802000 <= playStoreServicesVersion
|
is_19_17_or_greater = 241802000 <= playStoreServicesVersion
|
||||||
is_19_23_or_greater = 242402000 <= playStoreServicesVersion
|
is_19_23_or_greater = 242402000 <= playStoreServicesVersion
|
||||||
is_19_25_or_greater = 242599000 <= playStoreServicesVersion
|
is_19_25_or_greater = 242599000 <= playStoreServicesVersion
|
||||||
@ -101,5 +106,6 @@ val versionCheckPatch = resourcePatch(
|
|||||||
is_20_02_or_greater = 250299000 <= playStoreServicesVersion
|
is_20_02_or_greater = 250299000 <= playStoreServicesVersion
|
||||||
is_20_03_or_greater = 250405000 <= playStoreServicesVersion
|
is_20_03_or_greater = 250405000 <= playStoreServicesVersion
|
||||||
is_20_05_or_greater = 250605000 <= playStoreServicesVersion
|
is_20_05_or_greater = 250605000 <= playStoreServicesVersion
|
||||||
|
is_20_10_or_greater = 251105000 <= playStoreServicesVersion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@ private val PLAYER_PARAMETER_STARTS_WITH_PARAMETER_LIST = listOf(
|
|||||||
"[B",
|
"[B",
|
||||||
"Ljava/lang/String;", // Player parameters proto buffer.
|
"Ljava/lang/String;", // Player parameters proto buffer.
|
||||||
"Ljava/lang/String;", // PlaylistId.
|
"Ljava/lang/String;", // PlaylistId.
|
||||||
"I",
|
|
||||||
"I"
|
"I"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -19,7 +18,7 @@ internal val playerParameterBuilderFingerprint = legacyFingerprint(
|
|||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
returnType = "L",
|
returnType = "L",
|
||||||
strings = listOf("psps"),
|
strings = listOf("psps"),
|
||||||
// 19.22 and earlier parameters are:
|
// parameters in 18.29 ~ 19.22 :
|
||||||
// "Ljava/lang/String;", // VideoId.
|
// "Ljava/lang/String;", // VideoId.
|
||||||
// "[B",
|
// "[B",
|
||||||
// "Ljava/lang/String;", // Player parameters proto buffer.
|
// "Ljava/lang/String;", // Player parameters proto buffer.
|
||||||
@ -34,20 +33,39 @@ internal val playerParameterBuilderFingerprint = legacyFingerprint(
|
|||||||
// "Z",
|
// "Z",
|
||||||
// "Z"
|
// "Z"
|
||||||
|
|
||||||
// 19.23+ parameters are:
|
// parameters in 19.23 ~ 20.09 :
|
||||||
// "Ljava/lang/String;", // VideoId.
|
// "Ljava/lang/String;", // VideoId.
|
||||||
// "[B",
|
// "[B",
|
||||||
// "Ljava/lang/String;", // Player parameters proto buffer.
|
// "Ljava/lang/String;", // Player parameters proto buffer.
|
||||||
// "Ljava/lang/String;", // PlaylistId.
|
// "Ljava/lang/String;", // PlaylistId.
|
||||||
// "I",
|
// "I",
|
||||||
// "I",
|
// "I",
|
||||||
// "L",
|
// "L", // New parameters added in 19.25.
|
||||||
// "Ljava/util/Set;",
|
// "Ljava/util/Set;",
|
||||||
// "Ljava/lang/String;",
|
// "Ljava/lang/String;",
|
||||||
// "Ljava/lang/String;",
|
// "Ljava/lang/String;",
|
||||||
// "L",
|
// "L",
|
||||||
// "Z", // Appears to indicate if the video id is being opened or is currently playing.
|
// "Z", // Appears to indicate if the video id is being opened or is currently playing.
|
||||||
// "Z",
|
// "Z",
|
||||||
|
// "Z",
|
||||||
|
// "Z"
|
||||||
|
|
||||||
|
// parameters in 20.10 ~ :
|
||||||
|
// "Ljava/lang/String;", // VideoId.
|
||||||
|
// "[B",
|
||||||
|
// "Ljava/lang/String;", // Player parameters proto buffer.
|
||||||
|
// "Ljava/lang/String;", // PlaylistId.
|
||||||
|
// "I",
|
||||||
|
// "Z", // New parameters added in 20.10.
|
||||||
|
// "I",
|
||||||
|
// "L", // New parameters added in 19.25.
|
||||||
|
// "Ljava/util/Set;",
|
||||||
|
// "Ljava/lang/String;",
|
||||||
|
// "Ljava/lang/String;",
|
||||||
|
// "L",
|
||||||
|
// "Z", // Appears to indicate if the video id is being opened or is currently playing.
|
||||||
|
// "Z",
|
||||||
|
// "Z",
|
||||||
// "Z"
|
// "Z"
|
||||||
customFingerprint = custom@{ method, _ ->
|
customFingerprint = custom@{ method, _ ->
|
||||||
val parameterTypes = method.parameterTypes
|
val parameterTypes = method.parameterTypes
|
||||||
@ -56,7 +74,7 @@ internal val playerParameterBuilderFingerprint = legacyFingerprint(
|
|||||||
return@custom false
|
return@custom false
|
||||||
}
|
}
|
||||||
|
|
||||||
val startsWithMethodParameterList = parameterTypes.slice(0..5)
|
val startsWithMethodParameterList = parameterTypes.slice(0..4)
|
||||||
|
|
||||||
parametersEqual(
|
parametersEqual(
|
||||||
PLAYER_PARAMETER_STARTS_WITH_PARAMETER_LIST,
|
PLAYER_PARAMETER_STARTS_WITH_PARAMETER_LIST,
|
||||||
|
@ -37,11 +37,18 @@ val playerResponseMethodHookPatch = bytecodePatch(
|
|||||||
?: playerParameterBuilderLegacyFingerprint.methodOrThrow()
|
?: playerParameterBuilderLegacyFingerprint.methodOrThrow()
|
||||||
|
|
||||||
playerResponseMethod.apply {
|
playerResponseMethod.apply {
|
||||||
parameterIsShortAndOpeningOrPlaying = parameterTypes.indexOfFirst { it == "Z" } + 1
|
val setIndex = parameterTypes.indexOfFirst { it == "Ljava/util/Set;" }
|
||||||
|
val parameterSize = parameterTypes.size
|
||||||
|
val relativeIndex = parameterTypes.subList(setIndex, parameterSize - 1).indexOfFirst { it == "Z" }
|
||||||
|
|
||||||
|
// YouTube 18.29 ~ 19.22 : p11
|
||||||
|
// YouTube 19.23 ~ 20.09 : p12
|
||||||
|
// YouTube 20.10 ~ : p13
|
||||||
|
parameterIsShortAndOpeningOrPlaying = setIndex + relativeIndex + 1
|
||||||
// On some app targets the method has too many registers pushing the parameters past v15.
|
// On some app targets the method has too many registers pushing the parameters past v15.
|
||||||
// If needed, move the parameters to 4-bit registers so they can be passed to extension.
|
// If needed, move the parameters to 4-bit registers so they can be passed to extension.
|
||||||
playerResponseMethodCopyRegisters = implementation!!.registerCount -
|
playerResponseMethodCopyRegisters = implementation!!.registerCount -
|
||||||
parameterTypes.size + parameterIsShortAndOpeningOrPlaying > 15
|
parameterSize + parameterIsShortAndOpeningOrPlaying > 15
|
||||||
}
|
}
|
||||||
|
|
||||||
if (playerResponseMethodCopyRegisters) {
|
if (playerResponseMethodCopyRegisters) {
|
||||||
|
@ -100,24 +100,24 @@ fun Pair<String, Fingerprint>.injectLiteralInstructionBooleanCall(
|
|||||||
) {
|
) {
|
||||||
methodOrThrow().apply {
|
methodOrThrow().apply {
|
||||||
val literalIndex = indexOfFirstLiteralInstruction(literal)
|
val literalIndex = indexOfFirstLiteralInstruction(literal)
|
||||||
val targetIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.MOVE_RESULT)
|
val index = indexOfFirstInstructionOrThrow(literalIndex, Opcode.MOVE_RESULT)
|
||||||
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
||||||
|
|
||||||
val smaliInstruction =
|
val smaliInstruction =
|
||||||
if (descriptor.startsWith("0x")) """
|
if (descriptor.startsWith("0x")) """
|
||||||
const/16 v$targetRegister, $descriptor
|
const/16 v$register, $descriptor
|
||||||
"""
|
"""
|
||||||
else if (descriptor.endsWith("(Z)Z")) """
|
else if (descriptor.endsWith("(Z)Z")) """
|
||||||
invoke-static {v$targetRegister}, $descriptor
|
invoke-static/range { v$register .. v$register }, $descriptor
|
||||||
move-result v$targetRegister
|
move-result v$register
|
||||||
"""
|
"""
|
||||||
else """
|
else """
|
||||||
invoke-static {}, $descriptor
|
invoke-static {}, $descriptor
|
||||||
move-result v$targetRegister
|
move-result v$register
|
||||||
"""
|
"""
|
||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
targetIndex + 1,
|
index + 1,
|
||||||
smaliInstruction
|
smaliInstruction
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user