fixes of errors made by AI
This commit is contained in:
parent
7302d29383
commit
b6975fe015
28 changed files with 183 additions and 189 deletions
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
package app.revanced.patches.instagram.hide.navigation
|
package app.revanced.patches.instagram.hide.navigation
|
||||||
|
|
||||||
import app.revanced.patcher.*
|
import app.revanced.patcher.*
|
||||||
|
|
@ -11,6 +10,9 @@ internal val BytecodePatchContext.initializeNavigationButtonsListMethod by getti
|
||||||
returnType("Ljava/util/List;")
|
returnType("Ljava/util/List;")
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val navigationButtonsEnumClassDefMatch = firstMethodComposite(
|
internal val BytecodePatchContext.navigationButtonsEnumMethod by gettingFirstMethodDeclaratively(
|
||||||
"FEED", "fragment_feed", "SEARCH", "fragment_search",
|
"FEED",
|
||||||
|
"fragment_feed",
|
||||||
|
"SEARCH",
|
||||||
|
"fragment_search",
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package app.revanced.patches.instagram.hide.navigation
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.getInstruction
|
import app.revanced.patcher.extensions.getInstruction
|
||||||
import app.revanced.patcher.firstMutableMethodDeclaratively
|
import app.revanced.patcher.firstMutableMethodDeclaratively
|
||||||
|
import app.revanced.patcher.immutableClassDef
|
||||||
import app.revanced.patcher.name
|
import app.revanced.patcher.name
|
||||||
import app.revanced.patcher.patch.booleanOption
|
import app.revanced.patcher.patch.booleanOption
|
||||||
import app.revanced.patcher.patch.creatingBytecodePatch
|
import app.revanced.patcher.patch.creatingBytecodePatch
|
||||||
|
|
@ -73,7 +74,7 @@ val `Hide navigation buttons` by creatingBytecodePatch(
|
||||||
|
|
||||||
// Get the field name which contains the name of the enum for the navigation button
|
// Get the field name which contains the name of the enum for the navigation button
|
||||||
// ("fragment_clips", "fragment_share", ...)
|
// ("fragment_clips", "fragment_share", ...)
|
||||||
val enumNameField = navigationButtonsEnumClassDefMatch.classDef.firstMutableMethodDeclaratively {
|
val enumNameField = navigationButtonsEnumMethod.immutableClassDef.firstMutableMethodDeclaratively {
|
||||||
name("<init>")
|
name("<init>")
|
||||||
}.let { method ->
|
}.let { method ->
|
||||||
method.indexOfFirstInstructionOrThrow {
|
method.indexOfFirstInstructionOrThrow {
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,11 @@
|
||||||
package app.revanced.patches.instagram.misc.devmenu
|
package app.revanced.patches.instagram.misc.devmenu
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.methodReference
|
||||||
import app.revanced.patcher.patch.creatingBytecodePatch
|
import app.revanced.patcher.patch.creatingBytecodePatch
|
||||||
import app.revanced.util.Utils.trimIndentMultiline
|
import app.revanced.util.Utils.trimIndentMultiline
|
||||||
import app.revanced.util.getReference
|
|
||||||
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
||||||
import app.revanced.util.indexOfFirstStringInstruction
|
|
||||||
import app.revanced.util.returnEarly
|
import app.revanced.util.returnEarly
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
|
||||||
|
|
||||||
@Suppress("unused", "ObjectPropertyName")
|
@Suppress("unused", "ObjectPropertyName")
|
||||||
val `Enable developer menu` by creatingBytecodePatch(
|
val `Enable developer menu` by creatingBytecodePatch(
|
||||||
|
|
@ -21,16 +19,17 @@ val `Enable developer menu` by creatingBytecodePatch(
|
||||||
compatibleWith("com.instagram.android")
|
compatibleWith("com.instagram.android")
|
||||||
|
|
||||||
apply {
|
apply {
|
||||||
clearNotificationReceiverMethod.apply {
|
clearNotificationReceiverMethodMatch.let {
|
||||||
val stringIndex = indexOfFirstStringInstruction("NOTIFICATION_DISMISSED")
|
val stringIndex = it.indices.first()
|
||||||
indexOfFirstInstructionReversedOrThrow(stringIndex) {
|
|
||||||
val reference = getReference<MethodReference>()
|
it.method.indexOfFirstInstructionReversedOrThrow(stringIndex) {
|
||||||
|
val reference = methodReference
|
||||||
opcode in listOf(Opcode.INVOKE_STATIC, Opcode.INVOKE_STATIC_RANGE) &&
|
opcode in listOf(Opcode.INVOKE_STATIC, Opcode.INVOKE_STATIC_RANGE) &&
|
||||||
reference?.parameterTypes?.size == 1 &&
|
reference?.parameterTypes?.size == 1 &&
|
||||||
reference.parameterTypes.first() == "Lcom/instagram/common/session/UserSession;" &&
|
reference.parameterTypes.first() == "Lcom/instagram/common/session/UserSession;" &&
|
||||||
reference.returnType == "Z"
|
reference.returnType == "Z"
|
||||||
}.let { index ->
|
}.let { index ->
|
||||||
navigate(this).to(index).stop().returnEarly(true)
|
navigate(it.method).to(index).stop().returnEarly(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,9 @@
|
||||||
package app.revanced.patches.instagram.misc.devmenu
|
package app.revanced.patches.instagram.misc.devmenu
|
||||||
|
|
||||||
import app.revanced.patcher.*
|
import app.revanced.patcher.*
|
||||||
import app.revanced.patcher.patch.BytecodePatchContext
|
|
||||||
|
|
||||||
internal val BytecodePatchContext.clearNotificationReceiverMethod by gettingFirstMutableMethodDeclaratively(
|
internal val clearNotificationReceiverMethodMatch = firstMethodComposite {
|
||||||
"NOTIFICATION_DISMISSED",
|
|
||||||
) {
|
|
||||||
name("onReceive")
|
name("onReceive")
|
||||||
definingClass("Lcom/instagram/notifications/push/ClearNotificationReceiver;")
|
definingClass("Lcom/instagram/notifications/push/ClearNotificationReceiver;")
|
||||||
|
instructions("NOTIFICATION_DISMISSED"())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import app.revanced.patcher.returnType
|
||||||
|
|
||||||
internal const val TARGET_STRING = "Tracking.ARG_CLICK_SOURCE"
|
internal const val TARGET_STRING = "Tracking.ARG_CLICK_SOURCE"
|
||||||
|
|
||||||
internal val inAppBrowserFunctionMethodMatch = firstMethodComposite {
|
internal val inAppBrowserFunctionMethodMatch = firstMethodComposite("TrackingInfo.ARG_MODULE_NAME") {
|
||||||
instructions("TrackingInfo.ARG_MODULE_NAME"(), TARGET_STRING())
|
instructions(TARGET_STRING())
|
||||||
returnType("Z")
|
returnType("Z")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,25 +21,27 @@ val `Open links externally` by creatingBytecodePatch(
|
||||||
compatibleWith("com.instagram.android")
|
compatibleWith("com.instagram.android")
|
||||||
|
|
||||||
apply {
|
apply {
|
||||||
inAppBrowserFunctionMethodMatch.method.apply {
|
inAppBrowserFunctionMethodMatch.let {
|
||||||
val stringMatchIndex = inAppBrowserFunctionMethodMatch.indices.first()
|
val stringMatchIndex = it.indices.first()
|
||||||
|
|
||||||
val urlResultObjIndex = indexOfFirstInstructionOrThrow(
|
it.method.apply {
|
||||||
stringMatchIndex,
|
val urlResultObjIndex = indexOfFirstInstructionOrThrow(
|
||||||
Opcode.MOVE_OBJECT_FROM16,
|
stringMatchIndex,
|
||||||
)
|
Opcode.MOVE_OBJECT_FROM16,
|
||||||
|
)
|
||||||
|
|
||||||
// Register that contains the url after moving from a higher register.
|
// Register that contains the url after moving from a higher register.
|
||||||
val urlRegister = getInstruction<TwoRegisterInstruction>(urlResultObjIndex).registerA
|
val urlRegister = getInstruction<TwoRegisterInstruction>(urlResultObjIndex).registerA
|
||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
urlResultObjIndex + 1,
|
urlResultObjIndex + 1,
|
||||||
"""
|
"""
|
||||||
invoke-static { v$urlRegister }, $EXTENSION_CLASS_DESCRIPTOR->openExternally(Ljava/lang/String;)Z
|
invoke-static { v$urlRegister }, $EXTENSION_CLASS_DESCRIPTOR->openExternally(Ljava/lang/String;)Z
|
||||||
move-result v$urlRegister
|
move-result v$urlRegister
|
||||||
return v$urlRegister
|
return v$urlRegister
|
||||||
""",
|
""",
|
||||||
)
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,24 +3,22 @@ package app.revanced.patches.instagram.misc.share
|
||||||
import app.revanced.patcher.extensions.getInstruction
|
import app.revanced.patcher.extensions.getInstruction
|
||||||
import app.revanced.patcher.patch.BytecodePatchContext
|
import app.revanced.patcher.patch.BytecodePatchContext
|
||||||
import app.revanced.util.indexOfFirstInstruction
|
import app.revanced.util.indexOfFirstInstruction
|
||||||
import app.revanced.util.indexOfFirstStringInstruction
|
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||||
import com.android.tools.smali.dexlib2.mutable.MutableMethod
|
import com.android.tools.smali.dexlib2.mutable.MutableMethod
|
||||||
|
|
||||||
context(_: BytecodePatchContext)
|
internal fun BytecodePatchContext.editShareLinksPatch(block: MutableMethod.(index: Int, register: Int) -> Unit) {
|
||||||
internal fun editShareLinksPatch(block: MutableMethod.(index: Int, register: Int) -> Unit) {
|
|
||||||
val methodsToPatch = arrayOf(
|
val methodsToPatch = arrayOf(
|
||||||
permalinkResponseJsonParserMethod,
|
permalinkResponseJsonParserMethodMatch,
|
||||||
storyUrlResponseJsonParserMethod,
|
storyUrlResponseJsonParserMethodMatch,
|
||||||
profileUrlResponseJsonParserMethod,
|
profileUrlResponseJsonParserMethodMatch,
|
||||||
liveUrlResponseJsonParserMethod,
|
liveUrlResponseJsonParserMethodMatch,
|
||||||
)
|
)
|
||||||
|
|
||||||
for (method in methodsToPatch) {
|
for (match in methodsToPatch) {
|
||||||
method.apply {
|
match.method.apply {
|
||||||
val putSharingUrlIndex = indexOfFirstInstruction(
|
val putSharingUrlIndex = indexOfFirstInstruction(
|
||||||
indexOfFirstStringInstruction("permalink"),
|
match.indices.first(),
|
||||||
Opcode.IPUT_OBJECT,
|
Opcode.IPUT_OBJECT,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
package app.revanced.patches.instagram.misc.share
|
||||||
|
|
||||||
|
import app.revanced.patcher.firstMethodComposite
|
||||||
|
import app.revanced.patcher.instructions
|
||||||
|
import app.revanced.patcher.invoke
|
||||||
|
import app.revanced.patcher.name
|
||||||
|
|
||||||
|
internal val permalinkResponseJsonParserMethodMatch = firstMethodComposite(
|
||||||
|
"PermalinkResponse",
|
||||||
|
) {
|
||||||
|
name("parseFromJson")
|
||||||
|
instructions("permalink"())
|
||||||
|
}
|
||||||
|
|
||||||
|
internal val storyUrlResponseJsonParserMethodMatch = firstMethodComposite(
|
||||||
|
"StoryItemUrlResponse",
|
||||||
|
) {
|
||||||
|
name("parseFromJson")
|
||||||
|
instructions("story_item_to_share_url"())
|
||||||
|
}
|
||||||
|
|
||||||
|
internal val profileUrlResponseJsonParserMethodMatch = firstMethodComposite(
|
||||||
|
"ProfileUrlResponse",
|
||||||
|
) {
|
||||||
|
name("parseFromJson")
|
||||||
|
instructions("profile_to_share_url"())
|
||||||
|
}
|
||||||
|
|
||||||
|
internal val liveUrlResponseJsonParserMethodMatch = firstMethodComposite(
|
||||||
|
"LiveItemLinkUrlResponse",
|
||||||
|
) {
|
||||||
|
name("parseFromJson")
|
||||||
|
instructions("live_to_share_url"())
|
||||||
|
}
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
package app.revanced.patches.instagram.misc.share
|
|
||||||
|
|
||||||
import app.revanced.patcher.*
|
|
||||||
import app.revanced.patcher.patch.BytecodePatchContext
|
|
||||||
|
|
||||||
internal val BytecodePatchContext.permalinkResponseJsonParserMethod by gettingFirstMutableMethodDeclaratively(
|
|
||||||
"permalink", "PermalinkResponse",
|
|
||||||
) {
|
|
||||||
name("parseFromJson")
|
|
||||||
}
|
|
||||||
|
|
||||||
internal val BytecodePatchContext.storyUrlResponseJsonParserMethod by gettingFirstMutableMethodDeclaratively(
|
|
||||||
"story_item_to_share_url", "StoryItemUrlResponse",
|
|
||||||
) {
|
|
||||||
name("parseFromJson")
|
|
||||||
}
|
|
||||||
|
|
||||||
internal val BytecodePatchContext.profileUrlResponseJsonParserMethod by gettingFirstMutableMethodDeclaratively(
|
|
||||||
"profile_to_share_url", "ProfileUrlResponse",
|
|
||||||
) {
|
|
||||||
name("parseFromJson")
|
|
||||||
}
|
|
||||||
|
|
||||||
internal val BytecodePatchContext.liveUrlResponseJsonParserMethod by gettingFirstMutableMethodDeclaratively(
|
|
||||||
"live_to_share_url", "LiveItemLinkUrlResponse",
|
|
||||||
) {
|
|
||||||
name("parseFromJson")
|
|
||||||
}
|
|
||||||
|
|
@ -5,9 +5,9 @@ import app.revanced.patcher.patch.BytecodePatchContext
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
|
||||||
internal val BytecodePatchContext.getCustomShareDomainMethod by gettingFirstMutableMethodDeclaratively {
|
internal val BytecodePatchContext.getCustomShareDomainMethod by gettingFirstMutableMethodDeclaratively {
|
||||||
|
name("getCustomShareDomain")
|
||||||
|
definingClass(EXTENSION_CLASS_DESCRIPTOR)
|
||||||
accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC)
|
accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC)
|
||||||
returnType("Ljava/lang/String;")
|
returnType("Ljava/lang/String;")
|
||||||
parameterTypes()
|
parameterTypes()
|
||||||
name("getCustomShareDomain")
|
|
||||||
definingClass(EXTENSION_CLASS_DESCRIPTOR)
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,20 +2,16 @@ package app.revanced.patches.instagram.misc.signature
|
||||||
|
|
||||||
import app.revanced.patcher.*
|
import app.revanced.patcher.*
|
||||||
import app.revanced.patcher.patch.BytecodePatchContext
|
import app.revanced.patcher.patch.BytecodePatchContext
|
||||||
import app.revanced.util.getReference
|
import com.android.tools.smali.dexlib2.iface.ClassDef
|
||||||
import app.revanced.util.indexOfFirstInstruction
|
|
||||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
|
||||||
|
|
||||||
internal val isValidSignatureClassMethodMatch = firstMethodComposite(
|
context(_: BytecodePatchContext)
|
||||||
"The provider for uri '", "' is not trusted: ",
|
internal fun ClassDef.getIsValidSignatureClassMethod() = firstMutableMethodDeclaratively(
|
||||||
|
"The provider for uri '",
|
||||||
|
"' is not trusted: ",
|
||||||
)
|
)
|
||||||
|
|
||||||
internal val BytecodePatchContext.isValidSignatureMethodMethod by gettingFirstMutableMethodDeclaratively {
|
internal val BytecodePatchContext.isValidSignatureMethodMethod by gettingFirstMutableMethodDeclaratively {
|
||||||
parameterTypes("L", "Z")
|
parameterTypes("L", "Z")
|
||||||
returnType("Z")
|
returnType("Z")
|
||||||
custom {
|
instructions(method("keySet"))
|
||||||
indexOfFirstInstruction {
|
|
||||||
getReference<MethodReference>()?.name == "keySet"
|
|
||||||
} >= 0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package app.revanced.patches.instagram.misc.signature
|
package app.revanced.patches.instagram.misc.signature
|
||||||
|
|
||||||
|
import app.revanced.patcher.immutableClassDef
|
||||||
import app.revanced.patcher.patch.creatingBytecodePatch
|
import app.revanced.patcher.patch.creatingBytecodePatch
|
||||||
import app.revanced.util.returnEarly
|
import app.revanced.util.returnEarly
|
||||||
|
|
||||||
|
|
@ -12,9 +13,6 @@ val `Disable signature check` by creatingBytecodePatch(
|
||||||
compatibleWith("com.instagram.android")
|
compatibleWith("com.instagram.android")
|
||||||
|
|
||||||
apply {
|
apply {
|
||||||
isValidSignatureMethodMethod
|
isValidSignatureMethodMethod.immutableClassDef.getIsValidSignatureClassMethod().returnEarly(true)
|
||||||
.match(isValidSignatureClassMethodMatch.classDef)
|
|
||||||
.method
|
|
||||||
.returnEarly(true)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,8 @@ internal val metaAIKillSwitchCheckMethodMatch = firstMethodComposite("SearchAiag
|
||||||
opcodes(Opcode.CONST_WIDE)
|
opcodes(Opcode.CONST_WIDE)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val extensionMethodMethodMatch = firstMethodComposite("REPLACED_BY_PATCH") {
|
internal val extensionMethodMatch = firstMethodComposite {
|
||||||
name(EXTENSION_METHOD_NAME)
|
name(EXTENSION_METHOD_NAME)
|
||||||
definingClass(EXTENSION_CLASS_DESCRIPTOR)
|
definingClass(EXTENSION_CLASS_DESCRIPTOR)
|
||||||
|
instructions("REPLACED_BY_PATCH"())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,12 +39,10 @@ val `Remove Meta AI` by creatingBytecodePatch(
|
||||||
}.toString().substring(0, 7)
|
}.toString().substring(0, 7)
|
||||||
|
|
||||||
// Replace placeholder in the extension method.
|
// Replace placeholder in the extension method.
|
||||||
extensionMethodMethodMatch.let {
|
extensionMethodMatch.let {
|
||||||
it.method.replaceInstruction(
|
it.method.replaceInstruction(
|
||||||
it.indices.first(),
|
it.indices.first(),
|
||||||
"""
|
"const-string v1, \"$relevantDigits\"",
|
||||||
const-string v1, "$relevantDigits"
|
|
||||||
""",
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,9 +55,9 @@ val `Change start page` by creatingBytecodePatch(
|
||||||
)
|
)
|
||||||
|
|
||||||
// Hook browseId.
|
// Hook browseId.
|
||||||
browseIdMethod.let {
|
browseIdMethodMatch.let {
|
||||||
it.method.apply {
|
it.method.apply {
|
||||||
val browseIdIndex = it.instructionMatches.first().index
|
val browseIdIndex = it.indices.first()
|
||||||
val browseIdRegister = getInstruction<OneRegisterInstruction>(browseIdIndex).registerA
|
val browseIdRegister = getInstruction<OneRegisterInstruction>(browseIdIndex).registerA
|
||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,11 @@ internal val BytecodePatchContext.intentActionMethod by gettingFirstMutableMetho
|
||||||
parameterTypes("Landroid/content/Intent;")
|
parameterTypes("Landroid/content/Intent;")
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val BytecodePatchContext.browseIdMethod by gettingFirstMutableMethodDeclaratively(
|
internal val browseIdMethodMatch = firstMethodComposite {
|
||||||
"FEwhat_to_watch",
|
|
||||||
) {
|
|
||||||
returnType("Lcom/google/android/apps/youtube/app/common/ui/navigation/PaneDescriptor;")
|
returnType("Lcom/google/android/apps/youtube/app/common/ui/navigation/PaneDescriptor;")
|
||||||
// parameterTypes() // 20.30 and earlier is no parameters. 20.31+ parameter is L.
|
// parameterTypes() // 20.30 and earlier is no parameters. 20.31+ parameter is L.
|
||||||
instructions(
|
instructions(
|
||||||
|
"FEwhat_to_watch"(),
|
||||||
512L(),
|
512L(),
|
||||||
allOf(Opcode.IPUT_OBJECT(), field { type == "Ljava/lang/String;" }),
|
allOf(Opcode.IPUT_OBJECT(), field { type == "Ljava/lang/String;" }),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,21 @@
|
||||||
package app.revanced.patches.youtube.layout.theme
|
package app.revanced.patches.youtube.layout.theme
|
||||||
|
|
||||||
import app.revanced.patcher.*
|
import app.revanced.patcher.*
|
||||||
import app.revanced.patcher.patch.BytecodePatchContext
|
|
||||||
import app.revanced.patches.youtube.shared.YOUTUBE_MAIN_ACTIVITY_CLASS_TYPE
|
import app.revanced.patches.youtube.shared.YOUTUBE_MAIN_ACTIVITY_CLASS_TYPE
|
||||||
|
|
||||||
internal val BytecodePatchContext.useGradientLoadingScreenMethod by gettingFirstMutableMethodDeclaratively {
|
internal val useGradientLoadingScreenMethodMatch = firstMethodComposite {
|
||||||
instructions(
|
instructions(45412406L())
|
||||||
45412406L(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val BytecodePatchContext.splashScreenStyleMethod by gettingFirstMutableMethodDeclaratively {
|
internal val splashScreenStyleMethodMatch = firstMethodComposite {
|
||||||
|
definingClass(YOUTUBE_MAIN_ACTIVITY_CLASS_TYPE)
|
||||||
|
name("onCreate")
|
||||||
returnType("V")
|
returnType("V")
|
||||||
parameterTypes("Landroid/os/Bundle;")
|
parameterTypes("Landroid/os/Bundle;")
|
||||||
instructions(
|
instructions(
|
||||||
anyInstruction(
|
anyOf(
|
||||||
1074339245L(), // 20.30+
|
1074339245L(), // 20.30+
|
||||||
269032877L(), // 20.29 and lower.
|
269032877L(), // 20.29 and lower.
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
definingClass(YOUTUBE_MAIN_ACTIVITY_CLASS_TYPE)
|
|
||||||
name("onCreate")
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -200,15 +200,15 @@ val themePatch = baseThemePatch(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
useGradientLoadingScreenMethod.insertLiteralOverride(
|
useGradientLoadingScreenMethodMatch.method.insertLiteralOverride(
|
||||||
45412406L,
|
useGradientLoadingScreenMethodMatch.indices.first(),
|
||||||
"$EXTENSION_CLASS_DESCRIPTOR->gradientLoadingScreenEnabled(Z)Z",
|
"$EXTENSION_CLASS_DESCRIPTOR->gradientLoadingScreenEnabled(Z)Z",
|
||||||
)
|
)
|
||||||
|
|
||||||
if (is_19_47_or_greater) {
|
if (is_19_47_or_greater) {
|
||||||
// Lottie splash screen exists in earlier versions, but it may not be always on.
|
// Lottie splash screen exists in earlier versions, but it may not be always on.
|
||||||
splashScreenStyleMethod.insertLiteralOverride(
|
splashScreenStyleMethodMatch.method.insertLiteralOverride(
|
||||||
1074339245L,
|
splashScreenStyleMethodMatch.indices.first(),
|
||||||
"$EXTENSION_CLASS_DESCRIPTOR->getLoadingScreenType(I)I",
|
"$EXTENSION_CLASS_DESCRIPTOR->getLoadingScreenType(I)I",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,15 @@
|
||||||
package app.revanced.patches.youtube.misc.dimensions.spoof
|
package app.revanced.patches.youtube.misc.dimensions.spoof
|
||||||
|
|
||||||
import app.revanced.patcher.*
|
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
|
||||||
|
import app.revanced.patcher.instructions
|
||||||
|
import app.revanced.patcher.invoke
|
||||||
import app.revanced.patcher.patch.BytecodePatchContext
|
import app.revanced.patcher.patch.BytecodePatchContext
|
||||||
|
import app.revanced.patcher.returnType
|
||||||
|
|
||||||
// Strings are partial matches (format delimiters), so keep in instructions block.
|
internal val BytecodePatchContext.deviceDimensionsModelToStringMethod by gettingFirstMutableMethodDeclaratively {
|
||||||
internal val deviceDimensionsModelToStringMethodMatch = firstMethodComposite {
|
|
||||||
returnType("L")
|
returnType("L")
|
||||||
strings {
|
instructions(
|
||||||
+"minh."
|
"minh."(),
|
||||||
+";maxh."
|
";maxh."(),
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package app.revanced.patches.youtube.misc.dimensions.spoof
|
package app.revanced.patches.youtube.misc.dimensions.spoof
|
||||||
|
|
||||||
|
import app.revanced.patcher.classDef
|
||||||
import app.revanced.patcher.extensions.addInstructions
|
import app.revanced.patcher.extensions.addInstructions
|
||||||
|
import app.revanced.patcher.firstMutableMethod
|
||||||
import app.revanced.patcher.patch.creatingBytecodePatch
|
import app.revanced.patcher.patch.creatingBytecodePatch
|
||||||
import app.revanced.patches.all.misc.resources.addResources
|
import app.revanced.patches.all.misc.resources.addResources
|
||||||
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||||
|
|
@ -38,21 +40,20 @@ val `Spoof device dimensions` by creatingBytecodePatch(
|
||||||
SwitchPreference("revanced_spoof_device_dimensions"),
|
SwitchPreference("revanced_spoof_device_dimensions"),
|
||||||
)
|
)
|
||||||
|
|
||||||
deviceDimensionsModelToStringMethodMatch.classDef.methods.first { method -> method.name == "<init>" }
|
// Override the parameters containing the dimensions.
|
||||||
// Override the parameters containing the dimensions.
|
deviceDimensionsModelToStringMethod.classDef.methods.firstMutableMethod { name == "<init>" }.addInstructions(
|
||||||
.addInstructions(
|
1, // Add after super call.
|
||||||
1, // Add after super call.
|
arrayOf(
|
||||||
arrayOf(
|
1 to "MinHeightOrWidth", // p1 = min height
|
||||||
1 to "MinHeightOrWidth", // p1 = min height
|
2 to "MaxHeightOrWidth", // p2 = max height
|
||||||
2 to "MaxHeightOrWidth", // p2 = max height
|
3 to "MinHeightOrWidth", // p3 = min width
|
||||||
3 to "MinHeightOrWidth", // p3 = min width
|
4 to "MaxHeightOrWidth", // p4 = max width
|
||||||
4 to "MaxHeightOrWidth", // p4 = max width
|
).map { (parameter, method) ->
|
||||||
).map { (parameter, method) ->
|
"""
|
||||||
"""
|
invoke-static { p$parameter }, $EXTENSION_CLASS_DESCRIPTOR->get$method(I)I
|
||||||
invoke-static { p$parameter }, $EXTENSION_CLASS_DESCRIPTOR->get$method(I)I
|
move-result p$parameter
|
||||||
move-result p$parameter
|
"""
|
||||||
"""
|
}.joinToString("\n") { it },
|
||||||
}.joinToString("\n") { it },
|
)
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
package app.revanced.patches.youtube.misc.gms
|
package app.revanced.patches.youtube.misc.gms
|
||||||
|
|
||||||
import app.revanced.patcher.*
|
import app.revanced.patcher.*
|
||||||
import app.revanced.patcher.patch.BytecodePatchContext
|
|
||||||
import app.revanced.patches.shared.misc.mapping.ResourceType
|
import app.revanced.patches.shared.misc.mapping.ResourceType
|
||||||
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
|
||||||
|
|
@ -14,7 +13,7 @@ internal val specificNetworkErrorViewControllerMethodMatch = firstMethodComposit
|
||||||
ResourceType.DRAWABLE("ic_offline_no_content_upside_down"),
|
ResourceType.DRAWABLE("ic_offline_no_content_upside_down"),
|
||||||
ResourceType.STRING("offline_no_content_body_text_not_offline_eligible"),
|
ResourceType.STRING("offline_no_content_body_text_not_offline_eligible"),
|
||||||
method { name == "getString" && returnType == "Ljava/lang/String;" },
|
method { name == "getString" && returnType == "Ljava/lang/String;" },
|
||||||
Opcode.MOVE_RESULT_OBJECT(),
|
after(Opcode.MOVE_RESULT_OBJECT()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -28,6 +27,6 @@ internal val loadingFrameLayoutControllerMethodMatch = firstMethodComposite {
|
||||||
ResourceType.DRAWABLE("ic_offline_no_content_upside_down"),
|
ResourceType.DRAWABLE("ic_offline_no_content_upside_down"),
|
||||||
ResourceType.STRING("offline_no_content_body_text_not_offline_eligible"),
|
ResourceType.STRING("offline_no_content_body_text_not_offline_eligible"),
|
||||||
method { name == "getString" && returnType == "Ljava/lang/String;" },
|
method { name == "getString" && returnType == "Ljava/lang/String;" },
|
||||||
Opcode.MOVE_RESULT_OBJECT(),
|
after(Opcode.MOVE_RESULT_OBJECT()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
package app.revanced.patches.youtube.misc.imageurlhook
|
package app.revanced.patches.youtube.misc.imageurlhook
|
||||||
|
|
||||||
|
import app.revanced.patcher.classDef
|
||||||
import app.revanced.patcher.extensions.addInstruction
|
import app.revanced.patcher.extensions.addInstruction
|
||||||
import app.revanced.patcher.extensions.addInstructions
|
import app.revanced.patcher.extensions.addInstructions
|
||||||
import app.revanced.patcher.extensions.instructions
|
import app.revanced.patcher.extensions.instructions
|
||||||
|
import app.revanced.patcher.immutableClassDef
|
||||||
import app.revanced.patcher.patch.bytecodePatch
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||||
import app.revanced.util.getReference
|
import app.revanced.util.getReference
|
||||||
|
|
@ -30,14 +32,9 @@ val cronetImageUrlHookPatch = bytecodePatch(
|
||||||
dependsOn(sharedExtensionPatch)
|
dependsOn(sharedExtensionPatch)
|
||||||
|
|
||||||
apply {
|
apply {
|
||||||
loadImageUrlMethod = messageDigestImageUrlMethod
|
loadImageUrlMethod = messageDigestImageUrlParentMethod.immutableClassDef.getMessageDigestImageUrlMethod()
|
||||||
.match(messageDigestImageUrlParentMethodMatch.classDef)
|
loadImageSuccessCallbackMethod = onResponseStartedMethod.immutableClassDef.getOnSucceededMethod()
|
||||||
|
loadImageErrorCallbackMethod = onResponseStartedMethod.immutableClassDef.getOnFailureMethod()
|
||||||
loadImageSuccessCallbackMethod = onSucceededMethod
|
|
||||||
.match(onResponseStartedMethodMatch.classDef)
|
|
||||||
|
|
||||||
loadImageErrorCallbackMethod = onFailureMethod
|
|
||||||
.match(onResponseStartedMethodMatch.classDef)
|
|
||||||
|
|
||||||
// The URL is required for the failure callback hook, but the URL field is obfuscated.
|
// The URL is required for the failure callback hook, but the URL field is obfuscated.
|
||||||
// Add a helper get method that returns the URL field.
|
// Add a helper get method that returns the URL field.
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,11 @@ package app.revanced.patches.youtube.misc.imageurlhook
|
||||||
import app.revanced.patcher.*
|
import app.revanced.patcher.*
|
||||||
import app.revanced.patcher.patch.BytecodePatchContext
|
import app.revanced.patcher.patch.BytecodePatchContext
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
import com.android.tools.smali.dexlib2.iface.ClassDef
|
||||||
|
|
||||||
internal val BytecodePatchContext.onFailureMethod by gettingFirstMutableMethodDeclaratively {
|
context(_: BytecodePatchContext)
|
||||||
|
internal fun ClassDef.getOnFailureMethod() = firstMutableMethodDeclaratively {
|
||||||
|
name("onFailed")
|
||||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||||
returnType("V")
|
returnType("V")
|
||||||
parameterTypes(
|
parameterTypes(
|
||||||
|
|
@ -12,49 +15,50 @@ internal val BytecodePatchContext.onFailureMethod by gettingFirstMutableMethodDe
|
||||||
"Lorg/chromium/net/UrlResponseInfo;",
|
"Lorg/chromium/net/UrlResponseInfo;",
|
||||||
"Lorg/chromium/net/CronetException;",
|
"Lorg/chromium/net/CronetException;",
|
||||||
)
|
)
|
||||||
name("onFailed")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Acts as a parent fingerprint.
|
// Acts as a parent fingerprint.
|
||||||
internal val onResponseStartedMethodMatch = firstMethodComposite(
|
internal val BytecodePatchContext.onResponseStartedMethod by gettingFirstMutableMethodDeclaratively(
|
||||||
"Content-Length",
|
"Content-Length",
|
||||||
"Content-Type",
|
"Content-Type",
|
||||||
"identity",
|
"identity",
|
||||||
"application/x-protobuf",
|
"application/x-protobuf",
|
||||||
) {
|
) {
|
||||||
|
name("onResponseStarted")
|
||||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||||
returnType("V")
|
returnType("V")
|
||||||
parameterTypes("Lorg/chromium/net/UrlRequest;", "Lorg/chromium/net/UrlResponseInfo;")
|
parameterTypes("Lorg/chromium/net/UrlRequest;", "Lorg/chromium/net/UrlResponseInfo;")
|
||||||
name("onResponseStarted")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val BytecodePatchContext.onSucceededMethod by gettingFirstMutableMethodDeclaratively {
|
context(_: BytecodePatchContext)
|
||||||
|
internal fun ClassDef.getOnSucceededMethod() = firstMutableMethodDeclaratively {
|
||||||
|
name("onSucceeded")
|
||||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||||
returnType("V")
|
returnType("V")
|
||||||
parameterTypes("Lorg/chromium/net/UrlRequest;", "Lorg/chromium/net/UrlResponseInfo;")
|
parameterTypes("Lorg/chromium/net/UrlRequest;", "Lorg/chromium/net/UrlResponseInfo;")
|
||||||
name("onSucceeded")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal const val CRONET_URL_REQUEST_CLASS_DESCRIPTOR = "Lorg/chromium/net/impl/CronetUrlRequest;"
|
internal const val CRONET_URL_REQUEST_CLASS_DESCRIPTOR = "Lorg/chromium/net/impl/CronetUrlRequest;"
|
||||||
|
|
||||||
internal val BytecodePatchContext.requestMethod by gettingFirstMutableMethodDeclaratively {
|
internal val BytecodePatchContext.requestMethod by gettingFirstMutableMethodDeclaratively {
|
||||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
|
|
||||||
definingClass(CRONET_URL_REQUEST_CLASS_DESCRIPTOR)
|
definingClass(CRONET_URL_REQUEST_CLASS_DESCRIPTOR)
|
||||||
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val BytecodePatchContext.messageDigestImageUrlMethod by gettingFirstMutableMethodDeclaratively {
|
context(_: BytecodePatchContext)
|
||||||
|
internal fun ClassDef.getMessageDigestImageUrlMethod() = firstMutableMethodDeclaratively {
|
||||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
|
||||||
parameterTypes("Ljava/lang/String;", "L")
|
parameterTypes("Ljava/lang/String;", "L")
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val messageDigestImageUrlParentMethodMatch = firstMethodComposite {
|
internal val BytecodePatchContext.messageDigestImageUrlParentMethod by gettingFirstMutableMethodDeclaratively {
|
||||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||||
returnType("Ljava/lang/String;")
|
returnType("Ljava/lang/String;")
|
||||||
parameterTypes()
|
parameterTypes()
|
||||||
strings {
|
instructions(
|
||||||
anyOf(
|
anyOf(
|
||||||
"@#&=*+-_.,:!?()/~'%;\$",
|
"@#&=*+-_.,:!?()/~'%;$"(),
|
||||||
"@#&=*+-_.,:!?()/~'%;\$[]", // 20.38+
|
"@#&=*+-_.,:!?()/~'%;$[]"(), // 20.38+
|
||||||
)
|
),
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,13 +10,10 @@ internal val abUriParserLegacyMethodMatch = firstMethodComposite {
|
||||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||||
returnType("Ljava/lang/Object;")
|
returnType("Ljava/lang/Object;")
|
||||||
parameterTypes("Ljava/lang/Object;")
|
parameterTypes("Ljava/lang/Object;")
|
||||||
strings {
|
|
||||||
// Partial string match - keep in instructions block
|
|
||||||
+"Found entityKey=`"
|
|
||||||
// "that does not contain a PlaylistVideoEntityId" - partial, skipped
|
|
||||||
}
|
|
||||||
instructions(
|
instructions(
|
||||||
method { smali == "Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;" },
|
"Found entityKey=`"(),
|
||||||
|
"that does not contain a PlaylistVideoEntityId"(String::contains),
|
||||||
|
method { toString() == "Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;" },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -30,10 +27,10 @@ internal val abUriParserMethodMatch = firstMethodComposite {
|
||||||
instructions(
|
instructions(
|
||||||
// Method is a switch statement of unrelated code,
|
// Method is a switch statement of unrelated code,
|
||||||
// and there's no strings or anything unique to fingerprint.
|
// and there's no strings or anything unique to fingerprint.
|
||||||
method { smali == "Ljava/lang/Boolean;->valueOf(Z)Ljava/lang/Boolean;" },
|
method { toString() == "Ljava/lang/Boolean;->valueOf(Z)Ljava/lang/Boolean;" },
|
||||||
method { smali == "Ljava/lang/Boolean;->valueOf(Z)Ljava/lang/Boolean;" },
|
method { toString() == "Ljava/lang/Boolean;->valueOf(Z)Ljava/lang/Boolean;" },
|
||||||
method { smali == "Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;" },
|
method { toString() == "Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;" },
|
||||||
method { smali == "Ljava/util/List;->get(I)Ljava/lang/Object;" },
|
method { toString() == "Ljava/util/List;->get(I)Ljava/lang/Object;" },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -42,11 +39,9 @@ internal val httpUriParserMethodMatch = firstMethodComposite {
|
||||||
returnType("Landroid/net/Uri;")
|
returnType("Landroid/net/Uri;")
|
||||||
parameterTypes("Ljava/lang/String;")
|
parameterTypes("Ljava/lang/String;")
|
||||||
instructions(
|
instructions(
|
||||||
method { smali == "Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;" },
|
method { toString() == "Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;" },
|
||||||
|
"https"(),
|
||||||
|
"://"(),
|
||||||
|
"https:"(),
|
||||||
)
|
)
|
||||||
strings {
|
|
||||||
+"https"
|
|
||||||
+"://"
|
|
||||||
+"https:"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import app.revanced.patcher.returnType
|
||||||
import app.revanced.util.literal
|
import app.revanced.util.literal
|
||||||
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.ClassDef
|
||||||
|
|
||||||
internal val BytecodePatchContext.videoQualityItemOnClickParentMethod by gettingFirstMethodDeclaratively(
|
internal val BytecodePatchContext.videoQualityItemOnClickParentMethod by gettingFirstMethodDeclaratively(
|
||||||
"VIDEO_QUALITIES_MENU_BOTTOM_SHEET_FRAGMENT",
|
"VIDEO_QUALITIES_MENU_BOTTOM_SHEET_FRAGMENT",
|
||||||
|
|
@ -20,7 +21,7 @@ internal val BytecodePatchContext.videoQualityItemOnClickParentMethod by getting
|
||||||
}
|
}
|
||||||
|
|
||||||
context(_: BytecodePatchContext)
|
context(_: BytecodePatchContext)
|
||||||
internal fun com.android.tools.smali.dexlib2.iface.ClassDef.getVideoQualityItemOnClickMethod() = firstMutableMethodDeclaratively {
|
internal fun ClassDef.getVideoQualityItemOnClickMethod() = firstMutableMethodDeclaratively {
|
||||||
name("onItemClick")
|
name("onItemClick")
|
||||||
returnType("V")
|
returnType("V")
|
||||||
parameterTypes(
|
parameterTypes(
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,8 @@ internal val customPlaybackSpeedPatch = bytecodePatch(
|
||||||
|
|
||||||
// Get the "showOldPlaybackSpeedMenu" method.
|
// Get the "showOldPlaybackSpeedMenu" method.
|
||||||
// This is later called on the field INSTANCE.
|
// This is later called on the field INSTANCE.
|
||||||
val showOldPlaybackSpeedMenuMethod = getOldPlaybackSpeedsMethod.classDef.getShowOldPlaybackSpeedMenuMethod()
|
val showOldPlaybackSpeedMenuMethod =
|
||||||
|
getOldPlaybackSpeedsMethod.immutableClassDef.getShowOldPlaybackSpeedMenuMethod()
|
||||||
|
|
||||||
// Insert the call to the "showOldPlaybackSpeedMenu" method on the field INSTANCE.
|
// Insert the call to the "showOldPlaybackSpeedMenu" method on the field INSTANCE.
|
||||||
showOldPlaybackSpeedMenuExtensionMethod.apply {
|
showOldPlaybackSpeedMenuExtensionMethod.apply {
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,8 @@ internal fun ClassDef.getVideoIdMethodMatch() = firstMethodComposite {
|
||||||
parameterTypes("L")
|
parameterTypes("L")
|
||||||
instructions(
|
instructions(
|
||||||
method {
|
method {
|
||||||
definingClass == "Lcom/google/android/libraries/youtube/innertube/model/player/PlayerResponseModel;"
|
definingClass == "Lcom/google/android/libraries/youtube/innertube/model/player/PlayerResponseModel;" &&
|
||||||
&& returnType == "Ljava/lang/String;"
|
returnType == "Ljava/lang/String;"
|
||||||
},
|
},
|
||||||
Opcode.MOVE_RESULT_OBJECT(),
|
Opcode.MOVE_RESULT_OBJECT(),
|
||||||
)
|
)
|
||||||
|
|
@ -29,8 +29,8 @@ internal val videoIdBackgroundPlayMethodMatch = firstMethodComposite {
|
||||||
parameterTypes("L")
|
parameterTypes("L")
|
||||||
instructions(
|
instructions(
|
||||||
method {
|
method {
|
||||||
definingClass == "Lcom/google/android/libraries/youtube/innertube/model/player/PlayerResponseModel;"
|
definingClass == "Lcom/google/android/libraries/youtube/innertube/model/player/PlayerResponseModel;" &&
|
||||||
&& returnType == "Ljava/lang/String;"
|
returnType == "Ljava/lang/String;"
|
||||||
},
|
},
|
||||||
Opcode.MOVE_RESULT_OBJECT(),
|
Opcode.MOVE_RESULT_OBJECT(),
|
||||||
Opcode.IPUT_OBJECT(),
|
Opcode.IPUT_OBJECT(),
|
||||||
|
|
@ -40,11 +40,8 @@ internal val videoIdBackgroundPlayMethodMatch = firstMethodComposite {
|
||||||
Opcode.RETURN_VOID(),
|
Opcode.RETURN_VOID(),
|
||||||
)
|
)
|
||||||
custom {
|
custom {
|
||||||
implementation != null &&
|
immutableClassDef.methods.count() == 17 || // 20.39 and lower.
|
||||||
(
|
immutableClassDef.methods.count() == 16 // 20.40+
|
||||||
definingClass.methods.count() == 17 || // 20.39 and lower.
|
|
||||||
definingClass.methods.count() == 16
|
|
||||||
) // 20.40+
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -92,17 +92,19 @@ val videoIdPatch = bytecodePatch(
|
||||||
)
|
)
|
||||||
|
|
||||||
apply {
|
apply {
|
||||||
videoIdParentMethodMatch.classDef.getVideoIdMethodMatch().let {
|
videoIdParentMethodMatch.immutableClassDef.getVideoIdMethodMatch().let {
|
||||||
videoIdMethod = it.method
|
videoIdMethod = it.method
|
||||||
|
|
||||||
val index = it.indices.first()
|
val index = it.indices.first()
|
||||||
videoIdRegister = videoIdMethod.getInstruction<OneRegisterInstruction>(index + 1).registerA
|
videoIdRegister = it.method.getInstruction<OneRegisterInstruction>(index + 1).registerA
|
||||||
videoIdInsertIndex = index + 2
|
videoIdInsertIndex = index + 2
|
||||||
}
|
}
|
||||||
|
|
||||||
videoIdBackgroundPlayMethodMatch.let {
|
videoIdBackgroundPlayMethodMatch.let {
|
||||||
backgroundPlaybackMethod = it.method
|
backgroundPlaybackMethod = it.method
|
||||||
|
|
||||||
val index = it.indices.first()
|
val index = it.indices.first()
|
||||||
backgroundPlaybackVideoIdRegister = backgroundPlaybackMethod.getInstruction<OneRegisterInstruction>(index + 1).registerA
|
backgroundPlaybackVideoIdRegister = it.method.getInstruction<OneRegisterInstruction>(index + 1).registerA
|
||||||
backgroundPlaybackInsertIndex = index + 2
|
backgroundPlaybackInsertIndex = index + 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue