chore: lint code

This commit is contained in:
inotia00
2024-06-07 21:44:22 +09:00
parent e374fa306b
commit ecd6fbdf5b
95 changed files with 804 additions and 405 deletions

View File

@ -5,6 +5,6 @@ import app.revanced.util.fingerprint.LiteralValueFingerprint
internal object InterstitialsContainerFingerprint : LiteralValueFingerprint(
returnType = "V",
strings= listOf("overlay_controller_param"),
strings = listOf("overlay_controller_param"),
literalSupplier = { InterstitialsContainer }
)

View File

@ -102,7 +102,9 @@ object AlternativeThumbnailsPatch : BaseBytecodePatch(
block: (MutableMethod) -> Unit
) = alsoResolve(fingerprint).also { block(it.mutableMethod) }
MessageDigestImageUrlFingerprint.resolveAndLetMutableMethod(MessageDigestImageUrlParentFingerprint) {
MessageDigestImageUrlFingerprint.resolveAndLetMutableMethod(
MessageDigestImageUrlParentFingerprint
) {
loadImageUrlMethod = it
addImageUrlHook(ALTERNATIVE_THUMBNAILS_CLASS_DESCRIPTOR, true)
}

View File

@ -6,5 +6,5 @@ import com.android.tools.smali.dexlib2.AccessFlags
internal object MessageDigestImageUrlFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
parameters = listOf("Ljava/lang/String;", "L")
parameters = listOf("Ljava/lang/String;", "L")
)

View File

@ -6,7 +6,7 @@ import com.android.tools.smali.dexlib2.AccessFlags
internal object MessageDigestImageUrlParentFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
returnType = "Ljava/lang/String;",
returnType = "Ljava/lang/String;",
parameters = emptyList(),
strings = listOf("@#&=*+-_.,:!?()/~'%;\$"),
)

View File

@ -7,7 +7,7 @@ import com.android.tools.smali.dexlib2.AccessFlags
internal object OnFailureFingerprint : MethodFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf(
parameters = listOf(
"Lorg/chromium/net/UrlRequest;",
"Lorg/chromium/net/UrlResponseInfo;",
"Lorg/chromium/net/CronetException;"

View File

@ -8,7 +8,7 @@ import com.android.tools.smali.dexlib2.AccessFlags
internal object OnResponseStartedFingerprint : MethodFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("Lorg/chromium/net/UrlRequest;", "Lorg/chromium/net/UrlResponseInfo;"),
parameters = listOf("Lorg/chromium/net/UrlRequest;", "Lorg/chromium/net/UrlResponseInfo;"),
strings = listOf(
"Content-Length",
"Content-Type",

View File

@ -7,7 +7,7 @@ import com.android.tools.smali.dexlib2.AccessFlags
internal object OnSucceededFingerprint : MethodFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("Lorg/chromium/net/UrlRequest;", "Lorg/chromium/net/UrlResponseInfo;"),
parameters = listOf("Lorg/chromium/net/UrlRequest;", "Lorg/chromium/net/UrlResponseInfo;"),
customFingerprint = { methodDef, _ ->
methodDef.name == "onSucceeded"
}

View File

@ -97,7 +97,8 @@ object FeedComponentsPatch : BaseBytecodePatch(
fingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val targetIndex = it.scanResult.patternScanResult!!.endIndex
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
val targetRegister =
getInstruction<OneRegisterInstruction>(targetIndex).registerA
addInstruction(
targetIndex + 1,
@ -131,7 +132,7 @@ object FeedComponentsPatch : BaseBytecodePatch(
addInstruction(
targetIndex + 1,
"invoke-static {v$targetRegister}, $FEED_CLASS_DESCRIPTOR->hideCaptionsButtonContainer(Landroid/view/View;)V"
"invoke-static {v$targetRegister}, $FEED_CLASS_DESCRIPTOR->hideCaptionsButtonContainer(Landroid/view/View;)V"
)
}
@ -253,7 +254,8 @@ object FeedComponentsPatch : BaseBytecodePatch(
ChannelTabRendererFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val iteratorIndex = getTargetIndexWithMethodReferenceName("hasNext")
val iteratorRegister = getInstruction<FiveRegisterInstruction>(iteratorIndex).registerC
val iteratorRegister =
getInstruction<FiveRegisterInstruction>(iteratorIndex).registerC
val targetIndex = indexOfFirstInstruction {
val reference = ((this as? ReferenceInstruction)?.reference as? MethodReference)

View File

@ -32,11 +32,17 @@ object AudioTracksPatch : BaseBytecodePatch(
opcode == Opcode.CHECK_CAST
&& (this as ReferenceInstruction).reference.toString() == "Lcom/google/android/libraries/youtube/innertube/model/media/FormatStreamModel;"
}
val arrayListIndex = getTargetIndexWithReference(formatStreamModelIndex, "Ljava/util/List;->add(Ljava/lang/Object;)Z")
val insertIndex = getTargetIndexWithReference(arrayListIndex, "Ljava/util/List;->isEmpty()Z") + 2
val arrayListIndex = getTargetIndexWithReference(
formatStreamModelIndex,
"Ljava/util/List;->add(Ljava/lang/Object;)Z"
)
val insertIndex =
getTargetIndexWithReference(arrayListIndex, "Ljava/util/List;->isEmpty()Z") + 2
val formatStreamModelRegister = getInstruction<OneRegisterInstruction>(formatStreamModelIndex).registerA
val arrayListRegister = getInstruction<FiveRegisterInstruction>(arrayListIndex).registerC
val formatStreamModelRegister =
getInstruction<OneRegisterInstruction>(formatStreamModelIndex).registerA
val arrayListRegister =
getInstruction<FiveRegisterInstruction>(arrayListIndex).registerC
addInstructions(
insertIndex, """
@ -47,7 +53,7 @@ object AudioTracksPatch : BaseBytecodePatch(
addInstructions(
formatStreamModelIndex + 1,
"invoke-static {v$formatStreamModelRegister}, $GENERAL_CLASS_DESCRIPTOR->setFormatStreamModelArray(Ljava/lang/Object;)V"
"invoke-static {v$formatStreamModelRegister}, $GENERAL_CLASS_DESCRIPTOR->setFormatStreamModelArray(Ljava/lang/Object;)V"
)
}
}

View File

@ -174,8 +174,10 @@ object LayoutComponentsPatch : BaseBytecodePatch(
it.mutableMethod.apply {
val constIndex = getWideLiteralInstructionIndex(AccountSwitcherAccessibility)
val insertIndex = getTargetIndex(constIndex, Opcode.IF_EQZ)
val setVisibilityIndex = getTargetIndexWithMethodReferenceName(insertIndex, "setVisibility")
val visibilityRegister = getInstruction<FiveRegisterInstruction>(setVisibilityIndex).registerD
val setVisibilityIndex =
getTargetIndexWithMethodReferenceName(insertIndex, "setVisibility")
val visibilityRegister =
getInstruction<FiveRegisterInstruction>(setVisibilityIndex).registerD
addInstructions(
insertIndex, """
@ -192,7 +194,8 @@ object LayoutComponentsPatch : BaseBytecodePatch(
SettingsMenuFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val insertIndex = getTargetIndexWithFieldReferenceType("Landroid/support/v7/widget/RecyclerView;")
val insertIndex =
getTargetIndexWithFieldReferenceType("Landroid/support/v7/widget/RecyclerView;")
val insertRegister = getInstruction<TwoRegisterInstruction>(insertIndex).registerA
addInstruction(

View File

@ -29,7 +29,10 @@ object GradientLoadingScreenPatch : BaseBytecodePatch(
GradientLoadingScreenPrimaryFingerprint to 45412406,
GradientLoadingScreenSecondaryFingerprint to 45418917
).forEach { (fingerprint, literal) ->
fingerprint.literalInstructionBooleanHook(literal, "$GENERAL_CLASS_DESCRIPTOR->enableGradientLoadingScreen()Z")
fingerprint.literalInstructionBooleanHook(
literal,
"$GENERAL_CLASS_DESCRIPTOR->enableGradientLoadingScreen()Z"
)
}
/**

View File

@ -8,7 +8,11 @@ import com.android.tools.smali.dexlib2.Opcode
internal object PivotBarSetTextFingerprint : MethodFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
parameters = listOf("Lcom/google/android/libraries/youtube/rendering/ui/pivotbar/PivotBar;", "Landroid/widget/TextView;", "Ljava/lang/CharSequence;"),
parameters = listOf(
"Lcom/google/android/libraries/youtube/rendering/ui/pivotbar/PivotBar;",
"Landroid/widget/TextView;",
"Ljava/lang/CharSequence;"
),
opcodes = listOf(
Opcode.INVOKE_VIRTUAL,
Opcode.RETURN_VOID

View File

@ -32,10 +32,14 @@ object SplashAnimationPatch : BaseBytecodePatch(
) {
override fun execute(context: BytecodeContext) {
StartUpResourceIdFingerprint.resolve(context, StartUpResourceIdParentFingerprint.resultOrThrow().classDef)
StartUpResourceIdFingerprint.resolve(
context,
StartUpResourceIdParentFingerprint.resultOrThrow().classDef
)
val startUpResourceIdMethod = StartUpResourceIdFingerprint.resultOrThrow().mutableMethod
val startUpResourceIdMethodCall = startUpResourceIdMethod.definingClass + "->" + startUpResourceIdMethod.name + "(I)Z"
val startUpResourceIdMethodCall =
startUpResourceIdMethod.definingClass + "->" + startUpResourceIdMethod.name + "(I)Z"
SplashAnimationFingerprint.resultOrThrow().let {
it.mutableMethod.apply {

View File

@ -118,7 +118,8 @@ object TabletMiniPlayerPatch : BaseBytecodePatch(
} else {
MiniPlayerOverrideFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val walkerMethod = getWalkerMethod(context, getStringInstructionIndex("appName") + 2)
val walkerMethod =
getWalkerMethod(context, getStringInstructionIndex("appName") + 2)
walkerMethod.apply {
hook(getTargetIndex(Opcode.RETURN))

View File

@ -45,7 +45,6 @@ import app.revanced.util.getTargetIndexWithReference
import app.revanced.util.getTargetIndexWithReferenceReversed
import app.revanced.util.getWalkerMethod
import app.revanced.util.getWideLiteralInstructionIndex
import app.revanced.util.literalInstructionBooleanHook
import app.revanced.util.literalInstructionHook
import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow
@ -109,7 +108,8 @@ object ToolBarComponentsPatch : BaseBytecodePatch(
// YouTube's headers have the form of AttributeSet, which is decoded from YouTube's built-in classes.
val attributeResolverMethod = AttributeResolverFingerprint.resultOrThrow().mutableMethod
val attributeResolverMethodCall = attributeResolverMethod.definingClass + "->" + attributeResolverMethod.name + "(Landroid/content/Context;I)Landroid/graphics/drawable/Drawable;"
val attributeResolverMethodCall =
attributeResolverMethod.definingClass + "->" + attributeResolverMethod.name + "(Landroid/content/Context;I)Landroid/graphics/drawable/Drawable;"
context.findClass(GENERAL_CLASS_DESCRIPTOR)!!.mutableClass.methods.single { method ->
method.name == "getHeaderDrawable"
@ -139,9 +139,10 @@ object ToolBarComponentsPatch : BaseBytecodePatch(
}
// Override the header in the search bar.
val setActionBarRingoMutableClass = SetActionBarRingoFingerprint.resultOrThrow().mutableClass
setActionBarRingoMutableClass.methods.first {
method -> MethodUtil.isConstructor(method)
val setActionBarRingoMutableClass =
SetActionBarRingoFingerprint.resultOrThrow().mutableClass
setActionBarRingoMutableClass.methods.first { method ->
MethodUtil.isConstructor(method)
}.apply {
val insertIndex = getTargetIndex(Opcode.IPUT_BOOLEAN)
val insertRegister = getInstruction<TwoRegisterInstruction>(insertIndex).registerA
@ -190,7 +191,8 @@ object ToolBarComponentsPatch : BaseBytecodePatch(
.apply {
val staticCalls = implementation!!.instructions.withIndex()
.filter { instruction ->
val methodReference = ((instruction.value as? ReferenceInstruction)?.reference as? MethodReference)
val methodReference =
((instruction.value as? ReferenceInstruction)?.reference as? MethodReference)
methodReference?.parameterTypes?.size == 1 &&
methodReference.returnType == "Z"
}
@ -321,13 +323,18 @@ object ToolBarComponentsPatch : BaseBytecodePatch(
)
)
} else {
SearchBarFingerprint.resolve(context, SearchBarParentFingerprint.resultOrThrow().classDef)
SearchBarFingerprint.resolve(
context,
SearchBarParentFingerprint.resultOrThrow().classDef
)
SearchBarFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val startIndex = it.scanResult.patternScanResult!!.startIndex
val setVisibilityIndex = getTargetIndexWithMethodReferenceName(startIndex, "setVisibility")
val setVisibilityInstruction = getInstruction<FiveRegisterInstruction>(setVisibilityIndex)
val setVisibilityIndex =
getTargetIndexWithMethodReferenceName(startIndex, "setVisibility")
val setVisibilityInstruction =
getInstruction<FiveRegisterInstruction>(setVisibilityIndex)
replaceInstruction(
setVisibilityIndex,
@ -340,8 +347,10 @@ object ToolBarComponentsPatch : BaseBytecodePatch(
SearchResultFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val startIndex = getWideLiteralInstructionIndex(VoiceSearch)
val setOnClickListenerIndex = getTargetIndexWithMethodReferenceName(startIndex, "setOnClickListener")
val viewRegister = getInstruction<FiveRegisterInstruction>(setOnClickListenerIndex).registerC
val setOnClickListenerIndex =
getTargetIndexWithMethodReferenceName(startIndex, "setOnClickListener")
val viewRegister =
getInstruction<FiveRegisterInstruction>(setOnClickListenerIndex).registerC
addInstruction(
setOnClickListenerIndex + 1,

View File

@ -78,7 +78,7 @@ object CustomBrandingIconPatch : BaseResourcePatch(
override fun execute(context: ResourceContext) {
AppIcon?.let { appIcon ->
val appIconValue = appIcon.lowercase().replace(" ","_")
val appIconValue = appIcon.lowercase().replace(" ", "_")
if (!availableIcon.containsValue(appIconValue)) {
mipmapDirectories.map { directory ->
ResourceGroup(

View File

@ -80,7 +80,8 @@ object MinimizedPlaybackPatch : BaseBytecodePatch(
}
PiPControllerFingerprint.resultOrThrow().let {
val targetMethod = it.getWalkerMethod(context, it.scanResult.patternScanResult!!.endIndex)
val targetMethod =
it.getWalkerMethod(context, it.scanResult.patternScanResult!!.endIndex)
targetMethod.apply {
val targetRegister = getInstruction<TwoRegisterInstruction>(0).registerA

View File

@ -33,7 +33,8 @@ object OpenLinksDirectlyPatch : BaseBytecodePatch(
fingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val insertIndex = getTargetIndexWithMethodReferenceName("parse")
val insertRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerC
val insertRegister =
getInstruction<FiveRegisterInstruction>(insertIndex).registerC
replaceInstruction(
insertIndex,

View File

@ -45,13 +45,15 @@ object AmbientModeSwitchPatch : BaseBytecodePatch(
PowerSaveModeSyntheticFingerprint to true
).forEach { (fingerprint, reversed) ->
fingerprint.resultOrThrow().mutableMethod.apply {
val stringIndex = getStringInstructionIndex("android.os.action.POWER_SAVE_MODE_CHANGED")
val stringIndex =
getStringInstructionIndex("android.os.action.POWER_SAVE_MODE_CHANGED")
val targetIndex =
if (reversed)
getTargetIndexReversed(stringIndex, Opcode.INVOKE_DIRECT)
else
getTargetIndex(stringIndex, Opcode.INVOKE_DIRECT)
val targetClass = (getInstruction<ReferenceInstruction>(targetIndex).reference as MethodReference).definingClass
val targetClass =
(getInstruction<ReferenceInstruction>(targetIndex).reference as MethodReference).definingClass
syntheticClassList += targetClass
}

View File

@ -126,16 +126,20 @@ object PlayerButtonsPatch : BaseBytecodePatch(
TitleAnchorFingerprint.resultOrThrow().mutableMethod.apply {
val titleAnchorConstIndex = getWideLiteralInstructionIndex(TitleAnchor)
val titleAnchorIndex = getTargetIndex(titleAnchorConstIndex, Opcode.MOVE_RESULT_OBJECT)
val titleAnchorRegister = getInstruction<OneRegisterInstruction>(titleAnchorIndex).registerA
val titleAnchorRegister =
getInstruction<OneRegisterInstruction>(titleAnchorIndex).registerA
addInstruction(
titleAnchorIndex + 1,
"invoke-static {v$titleAnchorRegister}, $PLAYER_CLASS_DESCRIPTOR->setTitleAnchorStartMargin(Landroid/view/View;)V"
)
val playerCollapseButtonConstIndex = getWideLiteralInstructionIndex(PlayerCollapseButton)
val playerCollapseButtonIndex = getTargetIndex(playerCollapseButtonConstIndex, Opcode.CHECK_CAST)
val playerCollapseButtonRegister = getInstruction<OneRegisterInstruction>(playerCollapseButtonIndex).registerA
val playerCollapseButtonConstIndex =
getWideLiteralInstructionIndex(PlayerCollapseButton)
val playerCollapseButtonIndex =
getTargetIndex(playerCollapseButtonConstIndex, Opcode.CHECK_CAST)
val playerCollapseButtonRegister =
getInstruction<OneRegisterInstruction>(playerCollapseButtonIndex).registerA
addInstruction(
playerCollapseButtonIndex + 1,

View File

@ -37,6 +37,7 @@ object CommentsComponentPatch : BaseBytecodePatch(
) {
private const val FILTER_CLASS_DESCRIPTOR =
"$COMPONENTS_PATH/CommentsFilter;"
override fun execute(context: BytecodeContext) {
// region patch for emoji picker button in shorts
@ -44,7 +45,7 @@ object CommentsComponentPatch : BaseBytecodePatch(
ShortsLiveStreamEmojiPickerOpacityFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val insertIndex = implementation!!.instructions.size - 1
val insertRegister= getInstruction<OneRegisterInstruction>(insertIndex).registerA
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
addInstruction(
insertIndex,
@ -56,12 +57,15 @@ object CommentsComponentPatch : BaseBytecodePatch(
ShortsLiveStreamEmojiPickerOnClickListenerFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val emojiPickerEndpointIndex = getWideLiteralInstructionIndex(126326492)
val emojiPickerOnClickListenerIndex = getTargetIndex(emojiPickerEndpointIndex, Opcode.INVOKE_DIRECT)
val emojiPickerOnClickListenerMethod = getWalkerMethod(context, emojiPickerOnClickListenerIndex)
val emojiPickerOnClickListenerIndex =
getTargetIndex(emojiPickerEndpointIndex, Opcode.INVOKE_DIRECT)
val emojiPickerOnClickListenerMethod =
getWalkerMethod(context, emojiPickerOnClickListenerIndex)
emojiPickerOnClickListenerMethod.apply {
val insertIndex = getTargetIndex(Opcode.IF_EQZ)
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
val insertRegister =
getInstruction<OneRegisterInstruction>(insertIndex).registerA
addInstructions(
insertIndex, """

View File

@ -170,7 +170,7 @@ object PlayerComponentsPatch : BaseBytecodePatch(
LayoutCircleFingerprint,
LayoutIconFingerprint,
LayoutVideoFingerprint
).forEach{ fingerprint ->
).forEach { fingerprint ->
fingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val insertIndex = it.scanResult.patternScanResult!!.endIndex
@ -205,9 +205,10 @@ object PlayerComponentsPatch : BaseBytecodePatch(
val constRegister = getInstruction<OneRegisterInstruction>(constIndex).registerA
val insertIndex = getTargetIndexReversed(constIndex, Opcode.INVOKE_VIRTUAL) + 1
val jumpIndex = implementation!!.instructions.let { instruction ->
insertIndex + instruction.subList(insertIndex, instruction.size - 1).indexOfFirst { instructions ->
instructions.opcode == Opcode.GOTO || instructions.opcode == Opcode.GOTO_16
}
insertIndex + instruction.subList(insertIndex, instruction.size - 1)
.indexOfFirst { instructions ->
instructions.opcode == Opcode.GOTO || instructions.opcode == Opcode.GOTO_16
}
}
val replaceInstruction = getInstruction<TwoRegisterInstruction>(insertIndex)
@ -270,7 +271,8 @@ object PlayerComponentsPatch : BaseBytecodePatch(
val insertIndex = getWideLiteralInstructionIndex(SeekUndoEduOverlayStub)
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
val onClickListenerIndex = getTargetIndexWithMethodReferenceName(insertIndex, "setOnClickListener")
val onClickListenerIndex =
getTargetIndexWithMethodReferenceName(insertIndex, "setOnClickListener")
val constComponent = getConstComponent(insertIndex, onClickListenerIndex - 1)
if (constComponent.isNotEmpty()) {
@ -315,8 +317,10 @@ object PlayerComponentsPatch : BaseBytecodePatch(
it.mutableClass.methods.find { method ->
method.parameters == listOf("Landroid/view/View${'$'}OnClickListener;")
}?.apply {
val setOnClickListenerIndex = getTargetIndexWithMethodReferenceName("setOnClickListener")
val setOnClickListenerRegister = getInstruction<FiveRegisterInstruction>(setOnClickListenerIndex).registerC
val setOnClickListenerIndex =
getTargetIndexWithMethodReferenceName("setOnClickListener")
val setOnClickListenerRegister =
getInstruction<FiveRegisterInstruction>(setOnClickListenerIndex).registerC
addInstruction(
setOnClickListenerIndex + 1,

View File

@ -110,8 +110,10 @@ object DescriptionComponentsPatch : BaseBytecodePatch(
EngagementPanelTitleParentFingerprint.resultOrThrow().classDef
)
EngagementPanelTitleFingerprint.resultOrThrow().mutableMethod.apply {
val contentDescriptionIndex = getTargetIndexWithMethodReferenceName("setContentDescription")
val contentDescriptionRegister = getInstruction<FiveRegisterInstruction>(contentDescriptionIndex).registerD
val contentDescriptionIndex =
getTargetIndexWithMethodReferenceName("setContentDescription")
val contentDescriptionRegister =
getInstruction<FiveRegisterInstruction>(contentDescriptionIndex).registerD
addInstruction(
contentDescriptionIndex,

View File

@ -2,7 +2,7 @@ package app.revanced.patches.youtube.player.flyoutmenu.hide.fingerprints
import app.revanced.util.fingerprint.LiteralValueFingerprint
/**
/**
* This fingerprint is compatible with YouTube v18.39.xx+
*/
internal object PiPModeConfigFingerprint : LiteralValueFingerprint(

View File

@ -46,11 +46,14 @@ object ChangeTogglePatch : BaseBytecodePatch(
) {
override fun execute(context: BytecodeContext) {
val additionalSettingsConfigMethod = AdditionalSettingsConfigFingerprint.resultOrThrow().mutableMethod
val methodToCall = additionalSettingsConfigMethod.definingClass + "->" + additionalSettingsConfigMethod.name + "()Z"
val additionalSettingsConfigMethod =
AdditionalSettingsConfigFingerprint.resultOrThrow().mutableMethod
val methodToCall =
additionalSettingsConfigMethod.definingClass + "->" + additionalSettingsConfigMethod.name + "()Z"
// Resolves fingerprints
val playbackLoopOnClickListenerResult = PlaybackLoopOnClickListenerFingerprint.resultOrThrow()
val playbackLoopOnClickListenerResult =
PlaybackLoopOnClickListenerFingerprint.resultOrThrow()
PlaybackLoopInitFingerprint.resolve(context, playbackLoopOnClickListenerResult.classDef)
var fingerprintArray = arrayOf(
@ -90,7 +93,8 @@ object ChangeTogglePatch : BaseBytecodePatch(
it.mutableMethod.apply {
val referenceIndex = indexOfFirstInstruction {
opcode == Opcode.INVOKE_VIRTUAL
&& (this as ReferenceInstruction).reference.toString().endsWith(methodToCall)
&& (this as ReferenceInstruction).reference.toString()
.endsWith(methodToCall)
}
if (referenceIndex > 0) {
val insertRegister =
@ -117,12 +121,14 @@ object ChangeTogglePatch : BaseBytecodePatch(
val stringReferenceIndex = stableVolumeMethod.indexOfFirstInstruction {
opcode == Opcode.INVOKE_VIRTUAL
&& (this as ReferenceInstruction).reference.toString().endsWith("(Ljava/lang/String;Ljava/lang/String;)V")
&& (this as ReferenceInstruction).reference.toString()
.endsWith("(Ljava/lang/String;Ljava/lang/String;)V")
}
if (stringReferenceIndex < 0)
throw PatchException("Target reference was not found in ${StableVolumeFingerprint.javaClass.simpleName}.")
val stringReference = stableVolumeMethod.getInstruction<ReferenceInstruction>(stringReferenceIndex).reference
val stringReference =
stableVolumeMethod.getInstruction<ReferenceInstruction>(stringReferenceIndex).reference
CinematicLightingFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
@ -135,15 +141,20 @@ object ChangeTogglePatch : BaseBytecodePatch(
val stringIndex = getStringInstructionIndex("menu_item_cinematic_lighting")
val checkCastIndex = getTargetIndexReversed(stringIndex, Opcode.CHECK_CAST)
val iGetObjectPrimaryIndex = getTargetIndexReversed(checkCastIndex, Opcode.IGET_OBJECT)
val iGetObjectPrimaryIndex =
getTargetIndexReversed(checkCastIndex, Opcode.IGET_OBJECT)
val iGetObjectSecondaryIndex = getTargetIndex(checkCastIndex, Opcode.IGET_OBJECT)
val checkCastReference = getInstruction<ReferenceInstruction>(checkCastIndex).reference
val iGetObjectPrimaryReference = getInstruction<ReferenceInstruction>(iGetObjectPrimaryIndex).reference
val iGetObjectSecondaryReference = getInstruction<ReferenceInstruction>(iGetObjectSecondaryIndex).reference
val checkCastReference =
getInstruction<ReferenceInstruction>(checkCastIndex).reference
val iGetObjectPrimaryReference =
getInstruction<ReferenceInstruction>(iGetObjectPrimaryIndex).reference
val iGetObjectSecondaryReference =
getInstruction<ReferenceInstruction>(iGetObjectSecondaryIndex).reference
val invokeVirtualIndex = getTargetIndex(stringIndex, Opcode.INVOKE_VIRTUAL)
val invokeVirtualInstruction = getInstruction<FiveRegisterInstruction>(invokeVirtualIndex)
val invokeVirtualInstruction =
getInstruction<FiveRegisterInstruction>(invokeVirtualIndex)
val freeRegisterC = invokeVirtualInstruction.registerC
val freeRegisterD = invokeVirtualInstruction.registerD
val freeRegisterE = invokeVirtualInstruction.registerE

View File

@ -182,7 +182,8 @@ object FullscreenComponentsPatch : BaseBytecodePatch(
val walkerMethod = getWalkerMethod(context, walkerIndex)
walkerMethod.apply {
val insertIndex = implementation!!.instructions.size - 1
val targetRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
val targetRegister =
getInstruction<OneRegisterInstruction>(insertIndex).registerA
addInstructions(
insertIndex, """
@ -288,7 +289,8 @@ object FullscreenComponentsPatch : BaseBytecodePatch(
LandScapeModeConfigFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val insertIndex = implementation!!.instructions.size - 1
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
val insertRegister =
getInstruction<OneRegisterInstruction>(insertIndex).registerA
addInstructions(
insertIndex, """
@ -300,7 +302,8 @@ object FullscreenComponentsPatch : BaseBytecodePatch(
BroadcastReceiverFingerprint.resultOrThrow().let { result ->
result.mutableMethod.apply {
val stringIndex = getStringInstructionIndex("android.intent.action.SCREEN_ON")
val stringIndex =
getStringInstructionIndex("android.intent.action.SCREEN_ON")
val insertIndex = getTargetIndex(stringIndex, Opcode.IF_EQZ) + 1
addInstruction(

View File

@ -89,22 +89,29 @@ object OverlayButtonsBytecodePatch : BytecodePatch(
&& getReference<FieldReference>()?.definingClass == definingClass
&& (this as TwoRegisterInstruction).registerA == registerResolver
}
val invokerObjectReference = getInstruction<ReferenceInstruction>(invokerObjectIndex).reference
val invokerObjectReference =
getInstruction<ReferenceInstruction>(invokerObjectIndex).reference
val onClickListenerReferenceIndex = getTargetIndexWithReference("<init>(Ljava/lang/Object;I[B)V")
val onClickListenerReference = getInstruction<ReferenceInstruction>(onClickListenerReferenceIndex).reference
val onClickListenerClass = context.findClass((onClickListenerReference as MethodReference).definingClass)!!.mutableClass
val onClickListenerReferenceIndex =
getTargetIndexWithReference("<init>(Ljava/lang/Object;I[B)V")
val onClickListenerReference =
getInstruction<ReferenceInstruction>(onClickListenerReferenceIndex).reference
val onClickListenerClass =
context.findClass((onClickListenerReference as MethodReference).definingClass)!!.mutableClass
var invokeInterfaceReference = ""
onClickListenerClass.methods.find { method -> method.name == "onClick" }
?.apply {
val invokeInterfaceIndex = getTargetIndexWithReference(invokerObjectReference.toString()) + 1
val invokeInterfaceIndex =
getTargetIndexWithReference(invokerObjectReference.toString()) + 1
if (getInstruction(invokeInterfaceIndex).opcode != Opcode.INVOKE_INTERFACE)
throw PatchException("Opcode does not match")
invokeInterfaceReference = getInstruction<ReferenceInstruction>(invokeInterfaceIndex).reference.toString()
invokeInterfaceReference =
getInstruction<ReferenceInstruction>(invokeInterfaceIndex).reference.toString()
} ?: throw PatchException("Could not find onClick method")
val alwaysRepeatMutableClass = context.findClass(INTEGRATIONS_ALWAYS_REPEAT_CLASS_DESCRIPTOR)!!.mutableClass
val alwaysRepeatMutableClass =
context.findClass(INTEGRATIONS_ALWAYS_REPEAT_CLASS_DESCRIPTOR)!!.mutableClass
val smaliInstructions =
"""

View File

@ -129,7 +129,10 @@ object OverlayButtonsPatch : BaseResourcePatch(
val resources = commonResources + specificResources
resources.forEach { resource ->
val folderName = if (resource.endsWith(".xml")) "drawable" else "drawable-xxhdpi"
context.copyResources("youtube/overlaybuttons/$iconValue", ResourceGroup(folderName, resource))
context.copyResources(
"youtube/overlaybuttons/$iconValue",
ResourceGroup(folderName, resource)
)
}
}

View File

@ -11,6 +11,7 @@ internal object OfflineVideoEndpointFingerprint : MethodFingerprint(
"Ljava/util/Map;",
"L",
"Ljava/lang/String", // VideoId
"L"),
"L"
),
strings = listOf("Object is not an offlineable video: ")
)

View File

@ -133,7 +133,8 @@ object SeekbarComponentsPatch : BaseBytecodePatch(
TotalTimeFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val charSequenceIndex = getTargetIndexWithMethodReferenceName("getString") + 1
val charSequenceRegister = getInstruction<OneRegisterInstruction>(charSequenceIndex).registerA
val charSequenceRegister =
getInstruction<OneRegisterInstruction>(charSequenceIndex).registerA
val textViewIndex = getTargetIndexWithMethodReferenceName("getText")
val textViewRegister =
getInstruction<FiveRegisterInstruction>(textViewIndex).registerC
@ -162,7 +163,8 @@ object SeekbarComponentsPatch : BaseBytecodePatch(
}
ControlsOverlayStyleFingerprint.resultOrThrow().let {
val walkerMethod = it.getWalkerMethod(context, it.scanResult.patternScanResult!!.startIndex + 1)
val walkerMethod =
it.getWalkerMethod(context, it.scanResult.patternScanResult!!.startIndex + 1)
walkerMethod.apply {
val colorRegister = getInstruction<TwoRegisterInstruction>(0).registerA
@ -221,18 +223,19 @@ object SeekbarComponentsPatch : BaseBytecodePatch(
// region patch for hide seekbar
SeekbarFingerprint.resultOrThrow().mutableClass.let { mutableClass ->
SeekbarOnDrawFingerprint.also { it.resolve(context, mutableClass) }.resultOrThrow().let {
it.mutableMethod.apply {
addInstructionsWithLabels(
0, """
SeekbarOnDrawFingerprint.also { it.resolve(context, mutableClass) }.resultOrThrow()
.let {
it.mutableMethod.apply {
addInstructionsWithLabels(
0, """
invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->hideSeekbar()Z
move-result v0
if-eqz v0, :show
return-void
""", ExternalLabel("show", getInstruction(0))
)
)
}
}
}
}
// endregion
@ -240,7 +243,8 @@ object SeekbarComponentsPatch : BaseBytecodePatch(
// region patch for hide time stamp
PlayerSeekbarColorFingerprint.resultOrThrow().let { parentResult ->
TimeCounterFingerprint.also { it.resolve(context, parentResult.classDef) }.resultOrThrow().let {
TimeCounterFingerprint.also { it.resolve(context, parentResult.classDef) }
.resultOrThrow().let {
it.mutableMethod.apply {
addInstructionsWithLabels(
0, """
@ -274,7 +278,8 @@ object SeekbarComponentsPatch : BaseBytecodePatch(
"SETTINGS: RESTORE_OLD_SEEKBAR_THUMBNAILS"
)
)
} ?: println("WARNING: Restore old seekbar thumbnails setting is not supported in this version. Use YouTube 19.16.39 or earlier.")
}
?: println("WARNING: Restore old seekbar thumbnails setting is not supported in this version. Use YouTube 19.16.39 or earlier.")
// endregion

View File

@ -49,7 +49,8 @@ object SpeedOverlayPatch : BytecodePatch(
) {
override fun execute(context: BytecodeContext) {
val restoreSlideToSeekBehaviorFingerprintResult = RestoreSlideToSeekBehaviorFingerprint.result
val restoreSlideToSeekBehaviorFingerprintResult =
RestoreSlideToSeekBehaviorFingerprint.result
val speedOverlayFingerprintResult = SpeedOverlayFingerprint.result
val speedOverlayValueFingerprintResult = SpeedOverlayValueFingerprint.result
@ -130,7 +131,8 @@ object SpeedOverlayPatch : BytecodePatch(
val jumpIndex = scanResult.endIndex + 1
val insertIndex = scanResult.endIndex - 1
val insertRegister = getInstruction<TwoRegisterInstruction>(insertIndex).registerA
val insertRegister =
getInstruction<TwoRegisterInstruction>(insertIndex).registerA
hook(insertIndex, insertRegister, jumpIndex)
}
@ -150,7 +152,8 @@ object SpeedOverlayPatch : BytecodePatch(
constructorMethod.apply {
val syntheticIndex = getTargetIndexReversed(Opcode.NEW_INSTANCE)
val syntheticClass = getInstruction<ReferenceInstruction>(syntheticIndex).reference.toString()
val syntheticClass =
getInstruction<ReferenceInstruction>(syntheticIndex).reference.toString()
val syntheticMethod =
context.findClass(syntheticClass)?.mutableClass
@ -170,8 +173,12 @@ object SpeedOverlayPatch : BytecodePatch(
"""
)
insertIndex = getTargetIndexWithMethodReferenceNameReversed(speedOverlayValueIndex, "removeCallbacks") + 1
insertRegister = getInstruction<FiveRegisterInstruction>(insertIndex - 1).registerC
insertIndex = getTargetIndexWithMethodReferenceNameReversed(
speedOverlayValueIndex,
"removeCallbacks"
) + 1
insertRegister =
getInstruction<FiveRegisterInstruction>(insertIndex - 1).registerC
jumpIndex = getTargetIndex(speedOverlayValueIndex, Opcode.RETURN_VOID) + 1
hook(insertIndex, insertRegister, jumpIndex)
}
@ -181,7 +188,8 @@ object SpeedOverlayPatch : BytecodePatch(
SpeedOverlayTextValueFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val targetIndex = it.scanResult.patternScanResult!!.startIndex
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
val targetRegister =
getInstruction<OneRegisterInstruction>(targetIndex).registerA
addInstructions(
targetIndex + 1, """

View File

@ -161,7 +161,10 @@ object ShortsComponentPatch : BaseBytecodePatch(
if (insertIndex == 0)
throw PatchException("insert index not found")
hideButtons(insertIndex, "hideShortsSoundButton(Ljava/lang/Object;)Ljava/lang/Object;")
hideButtons(
insertIndex,
"hideShortsSoundButton(Ljava/lang/Object;)Ljava/lang/Object;"
)
}
}
@ -186,7 +189,8 @@ object ShortsComponentPatch : BaseBytecodePatch(
when (returnType) {
"Landroid/widget/TextView;" -> {
val insertIndex = implementation!!.instructions.size - 1
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
val insertRegister =
getInstruction<OneRegisterInstruction>(insertIndex).registerA
addInstructions(
insertIndex + 1, """
@ -196,6 +200,7 @@ object ShortsComponentPatch : BaseBytecodePatch(
)
removeInstruction(insertIndex)
}
"V" -> {
addInstructionsWithLabels(
0, """
@ -206,6 +211,7 @@ object ShortsComponentPatch : BaseBytecodePatch(
""", ExternalLabel("show", getInstruction(0))
)
}
else -> {
throw PatchException("Unknown returnType: $returnType")
}
@ -260,7 +266,8 @@ object ShortsComponentPatch : BaseBytecodePatch(
TextComponentSpecFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val insertIndex = getTargetIndexWithReference("Landroid/text/SpannableString;->valueOf(Ljava/lang/CharSequence;)Landroid/text/SpannableString;")
val insertIndex =
getTargetIndexWithReference("Landroid/text/SpannableString;->valueOf(Ljava/lang/CharSequence;)Landroid/text/SpannableString;")
val charSequenceRegister =
getInstruction<FiveRegisterInstruction>(insertIndex).registerC

View File

@ -25,7 +25,8 @@ object ShortsNavigationBarPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
InitializeButtonsFingerprint.resultOrThrow().let { parentResult ->
SetPivotBarFingerprint.also { it.resolve(context, parentResult.classDef) }.resultOrThrow().let {
SetPivotBarFingerprint.also { it.resolve(context, parentResult.classDef) }
.resultOrThrow().let {
it.mutableMethod.apply {
val startIndex = it.scanResult.patternScanResult!!.startIndex
val register = getInstruction<OneRegisterInstruction>(startIndex).registerA
@ -39,7 +40,8 @@ object ShortsNavigationBarPatch : BytecodePatch(
}
RenderBottomNavigationBarFingerprint.resultOrThrow().let {
val walkerMethod = it.getWalkerMethod(context, it.scanResult.patternScanResult!!.endIndex)
val walkerMethod =
it.getWalkerMethod(context, it.scanResult.patternScanResult!!.endIndex)
walkerMethod.addInstruction(
0,

View File

@ -42,9 +42,12 @@ object ShortsRepeatPatch : BaseBytecodePatch(
injectEnum(enumName, fieldName)
}
val endScreenStringIndex = getStringInstructionIndex("REEL_LOOP_BEHAVIOR_END_SCREEN")
val endScreenReferenceIndex = getTargetIndex(endScreenStringIndex, Opcode.SPUT_OBJECT)
val endScreenReference = getInstruction<ReferenceInstruction>(endScreenReferenceIndex).reference.toString()
val endScreenStringIndex =
getStringInstructionIndex("REEL_LOOP_BEHAVIOR_END_SCREEN")
val endScreenReferenceIndex =
getTargetIndex(endScreenStringIndex, Opcode.SPUT_OBJECT)
val endScreenReference =
getInstruction<ReferenceInstruction>(endScreenReferenceIndex).reference.toString()
val enumMethodName = ReelEnumStaticFingerprint.resultOrThrow().mutableMethod.name
val enumMethodCall = "$definingClass->$enumMethodName(I)$definingClass"
@ -101,7 +104,8 @@ object ShortsRepeatPatch : BaseBytecodePatch(
if ((instruction as ReferenceInstruction).reference.toString() != enumMethodCall)
continue
val register = getInstruction<OneRegisterInstruction>(index + 1).registerA
val register =
getInstruction<OneRegisterInstruction>(index + 1).registerA
addInstructions(
index + 2, """
@ -109,8 +113,8 @@ object ShortsRepeatPatch : BaseBytecodePatch(
move-result-object v$register
"""
)
}
}
}
}
}
}

View File

@ -38,13 +38,14 @@ object ResumingShortsOnStartupPatch : BaseBytecodePatch(
UserWasInShortsABConfigFingerprint.resultOrThrow().mutableMethod.apply {
val startIndex = indexOfOptionalInstruction(this)
val walkerIndex = implementation!!.instructions.let {
val subListIndex = it.subList(startIndex, startIndex + 20).indexOfFirst { instruction ->
val reference = instruction.getReference<MethodReference>()
instruction.opcode == Opcode.INVOKE_VIRTUAL
&& reference?.returnType == "Z"
&& reference.definingClass != "Lj${'$'}/util/Optional;"
&& reference.parameterTypes.size == 0
}
val subListIndex =
it.subList(startIndex, startIndex + 20).indexOfFirst { instruction ->
val reference = instruction.getReference<MethodReference>()
instruction.opcode == Opcode.INVOKE_VIRTUAL
&& reference?.returnType == "Z"
&& reference.definingClass != "Lj${'$'}/util/Optional;"
&& reference.parameterTypes.size == 0
}
if (subListIndex < 0)
throw PatchException("subListIndex not found")
@ -75,8 +76,10 @@ object ResumingShortsOnStartupPatch : BaseBytecodePatch(
getReference<MethodReference>()?.name == "isDone"
}
if (listenableInstructionIndex < 0) throw PatchException("Could not find instruction index")
val originalInstructionRegister = getInstruction<FiveRegisterInstruction>(listenableInstructionIndex).registerC
val freeRegister = getInstruction<OneRegisterInstruction>(listenableInstructionIndex + 1).registerA
val originalInstructionRegister =
getInstruction<FiveRegisterInstruction>(listenableInstructionIndex).registerC
val freeRegister =
getInstruction<OneRegisterInstruction>(listenableInstructionIndex + 1).registerA
addInstructionsWithLabels(
listenableInstructionIndex + 1,

View File

@ -14,7 +14,7 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
internal object UserWasInShortsABConfigFingerprint : MethodFingerprint(
returnType = "V",
strings = listOf("Failed to get offline response: "),
customFingerprint = { methodDef, _ ->
customFingerprint = { methodDef, _ ->
indexOfOptionalInstruction(methodDef) >= 0
}
) {

View File

@ -62,7 +62,8 @@ object SwipeControlsPatch : BaseBytecodePatch(
// region patch for swipe controls patch
val hostActivityClass = context.findClass(INTEGRATIONS_SWIPE_CONTROLS_HOST_ACTIVITY_CLASS_DESCRIPTOR)!!.mutableClass
val hostActivityClass =
context.findClass(INTEGRATIONS_SWIPE_CONTROLS_HOST_ACTIVITY_CLASS_DESCRIPTOR)!!.mutableClass
val mainActivityClass = mainActivityMutableClass
// inject the wrapper class from integrations into the class hierarchy of MainActivity (WatchWhileActivity)

View File

@ -43,7 +43,8 @@ object CastButtonPatch : BytecodePatch(
MenuItemVisibilityFingerprint.resolve(context, toolbarMenuItemInitializeResult.classDef)
toolbarMenuItemInitializeMethod = toolbarMenuItemInitializeResult.mutableMethod
toolbarMenuItemVisibilityMethod = MenuItemVisibilityFingerprint.resultOrThrow().mutableMethod
toolbarMenuItemVisibilityMethod =
MenuItemVisibilityFingerprint.resultOrThrow().mutableMethod
playerButtonMethod = PlayerButtonFingerprint.resultOrThrow().mutableMethod

View File

@ -32,7 +32,8 @@ object CairoSettingsPatch : BytecodePatch(
*/
CarioFragmentConfigFingerprint.result?.let {
it.mutableMethod.apply {
val targetIndex = getTargetIndex(getWideLiteralInstructionIndex(45532100), Opcode.MOVE_RESULT)
val targetIndex =
getTargetIndex(getWideLiteralInstructionIndex(45532100), Opcode.MOVE_RESULT)
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
addInstruction(

View File

@ -76,10 +76,12 @@ object SpoofClientPatch : BaseBytecodePatch(
BuildInitPlaybackRequestFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val moveUriStringIndex = it.scanResult.patternScanResult!!.startIndex
val targetRegister = getInstruction<OneRegisterInstruction>(moveUriStringIndex).registerA
val targetRegister =
getInstruction<OneRegisterInstruction>(moveUriStringIndex).registerA
addInstructions(
moveUriStringIndex + 1, """
moveUriStringIndex + 1,
"""
invoke-static { v$targetRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->blockInitPlaybackRequest(Ljava/lang/String;)Ljava/lang/String;
move-result-object v$targetRegister
""",
@ -94,10 +96,12 @@ object SpoofClientPatch : BaseBytecodePatch(
BuildPlayerRequestURIFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val invokeToStringIndex = it.scanResult.patternScanResult!!.startIndex
val uriRegister = getInstruction<FiveRegisterInstruction>(invokeToStringIndex).registerC
val uriRegister =
getInstruction<FiveRegisterInstruction>(invokeToStringIndex).registerC
addInstructions(
invokeToStringIndex, """
invokeToStringIndex,
"""
invoke-static { v$uriRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->blockGetWatchRequest(Landroid/net/Uri;)Landroid/net/Uri;
move-result-object v$uriRegister
""",
@ -111,50 +115,59 @@ object SpoofClientPatch : BaseBytecodePatch(
val (clientInfoField, clientInfoClientTypeField, clientInfoClientVersionField) =
SetPlayerRequestClientTypeFingerprint.resultOrThrow().let { result ->
with (result.mutableMethod) {
with(result.mutableMethod) {
// Field in the player request object that holds the client info object.
val clientInfoField = getInstructions().find { instruction ->
// requestMessage.clientInfo = clientInfoBuilder.build();
instruction.opcode == Opcode.IPUT_OBJECT &&
instruction.getReference<FieldReference>()?.type == CLIENT_INFO_CLASS_DESCRIPTOR
}?.getReference<FieldReference>() ?: throw PatchException("Could not find clientInfoField")
}?.getReference<FieldReference>()
?: throw PatchException("Could not find clientInfoField")
// Client info object's client type field.
val clientInfoClientTypeField = getInstruction(result.scanResult.patternScanResult!!.endIndex)
.getReference<FieldReference>() ?: throw PatchException("Could not find clientInfoClientTypeField")
val clientInfoClientTypeField =
getInstruction(result.scanResult.patternScanResult!!.endIndex)
.getReference<FieldReference>()
?: throw PatchException("Could not find clientInfoClientTypeField")
val clientInfoVersionIndex = getStringInstructionIndex("10.29")
val clientInfoVersionRegister = getInstruction<OneRegisterInstruction>(clientInfoVersionIndex).registerA
val clientInfoVersionRegister =
getInstruction<OneRegisterInstruction>(clientInfoVersionIndex).registerA
val clientInfoClientVersionFieldIndex = implementation!!.instructions.let {
clientInfoVersionIndex + it.subList(clientInfoVersionIndex, it.size - 1).indexOfFirst { instruction ->
instruction.opcode == Opcode.IPUT_OBJECT
&& (instruction as TwoRegisterInstruction).registerA == clientInfoVersionRegister
}
clientInfoVersionIndex + it.subList(clientInfoVersionIndex, it.size - 1)
.indexOfFirst { instruction ->
instruction.opcode == Opcode.IPUT_OBJECT
&& (instruction as TwoRegisterInstruction).registerA == clientInfoVersionRegister
}
}
// Client info object's client version field.
val clientInfoClientVersionField = getInstruction(clientInfoClientVersionFieldIndex)
.getReference<FieldReference>() ?: throw PatchException("Could not find clientInfoClientVersionField")
val clientInfoClientVersionField =
getInstruction(clientInfoClientVersionFieldIndex)
.getReference<FieldReference>()
?: throw PatchException("Could not find clientInfoClientVersionField")
Triple(clientInfoField, clientInfoClientTypeField, clientInfoClientVersionField)
}
}
val clientInfoClientModelField = CreatePlayerRequestBodyWithModelFingerprint.resultOrThrow().mutableMethod.let {
val instructions = it.getInstructions()
val getClientModelIndex = indexOfModelInstruction(it)
val clientInfoClientModelField =
CreatePlayerRequestBodyWithModelFingerprint.resultOrThrow().mutableMethod.let {
val instructions = it.getInstructions()
val getClientModelIndex = indexOfModelInstruction(it)
// The next IPUT_OBJECT instruction after getting the client model is setting the client model field.
instructions.subList(
getClientModelIndex,
instructions.size,
).find { instruction ->
val reference = instruction.getReference<FieldReference>()
instruction.opcode == Opcode.IPUT_OBJECT
&& reference?.definingClass == CLIENT_INFO_CLASS_DESCRIPTOR
&& reference.type == "Ljava/lang/String;"
}?.getReference<FieldReference>() ?: throw PatchException("Could not find clientInfoClientModelField")
}
// The next IPUT_OBJECT instruction after getting the client model is setting the client model field.
instructions.subList(
getClientModelIndex,
instructions.size,
).find { instruction ->
val reference = instruction.getReference<FieldReference>()
instruction.opcode == Opcode.IPUT_OBJECT
&& reference?.definingClass == CLIENT_INFO_CLASS_DESCRIPTOR
&& reference.type == "Ljava/lang/String;"
}?.getReference<FieldReference>()
?: throw PatchException("Could not find clientInfoClientModelField")
}
// endregion
@ -167,12 +180,13 @@ object SpoofClientPatch : BaseBytecodePatch(
val checkCastInstruction = getInstruction<OneRegisterInstruction>(checkCastIndex)
val requestMessageInstanceRegister = checkCastInstruction.registerA
val clientInfoContainerClassName = checkCastInstruction.getReference<TypeReference>()!!.type
val clientInfoContainerClassName =
checkCastInstruction.getReference<TypeReference>()!!.type
addInstruction(
checkCastIndex + 1,
"invoke-static { v$requestMessageInstanceRegister }," +
" $definingClass->$setClientInfoMethodName($clientInfoContainerClassName)V",
" $definingClass->$setClientInfoMethodName($clientInfoContainerClassName)V",
)
// Change client info to use the spoofed values.
@ -181,7 +195,13 @@ object SpoofClientPatch : BaseBytecodePatch(
ImmutableMethod(
definingClass,
setClientInfoMethodName,
listOf(ImmutableMethodParameter(clientInfoContainerClassName, annotations, "clientInfoContainer")),
listOf(
ImmutableMethodParameter(
clientInfoContainerClassName,
annotations,
"clientInfoContainer"
)
),
"V",
AccessFlags.PRIVATE or AccessFlags.STATIC,
annotations,
@ -229,7 +249,7 @@ object SpoofClientPatch : BaseBytecodePatch(
PlayerResponseMethodHookPatch += PlayerResponseMethodHookPatch.Hook.PlayerParameter(
"$INTEGRATIONS_CLASS_DESCRIPTOR->setPlayerResponseVideoId(" +
"Ljava/lang/String;Ljava/lang/String;Z)Ljava/lang/String;",
"Ljava/lang/String;Ljava/lang/String;Z)Ljava/lang/String;",
)
// endregion
@ -238,18 +258,19 @@ object SpoofClientPatch : BaseBytecodePatch(
PlayerGestureConfigSyntheticFingerprint.resultOrThrow().let {
arrayOf(3, 9).forEach { offSet ->
it.getWalkerMethod(context, it.scanResult.patternScanResult!!.endIndex - offSet).apply {
val index = implementation!!.instructions.size - 1
val register = getInstruction<OneRegisterInstruction>(index).registerA
it.getWalkerMethod(context, it.scanResult.patternScanResult!!.endIndex - offSet)
.apply {
val index = implementation!!.instructions.size - 1
val register = getInstruction<OneRegisterInstruction>(index).registerA
addInstructions(
index,
"""
addInstructions(
index,
"""
invoke-static {v$register}, $INTEGRATIONS_CLASS_DESCRIPTOR->enablePlayerGesture(Z)Z
move-result v$register
"""
)
}
)
}
}
}

View File

@ -1,8 +1,8 @@
package app.revanced.patches.youtube.utils.fix.client.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patcher.fingerprint.annotation.FuzzyPatternScanMethod
import app.revanced.patches.youtube.utils.fix.client.fingerprints.PlayerGestureConfigSyntheticFingerprint.indexOfDownAndOutAllowedInstruction
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstruction

View File

@ -28,14 +28,18 @@ object DoubleBackToClosePatch : BytecodePatch(
/**
* Hook onBackPressed method inside MainActivity (WatchWhileActivity)
*/
MainActivityResolvePatch.injectOnBackPressedMethodCall(INTEGRATIONS_CLASS_DESCRIPTOR, "closeActivityOnBackPressed")
MainActivityResolvePatch.injectOnBackPressedMethodCall(
INTEGRATIONS_CLASS_DESCRIPTOR,
"closeActivityOnBackPressed"
)
/**
* Inject the methods which start of ScrollView
*/
ScrollPositionFingerprint.resultOrThrow().let {
val walkerMethod = it.getWalkerMethod(context, it.scanResult.patternScanResult!!.startIndex + 1)
val walkerMethod =
it.getWalkerMethod(context, it.scanResult.patternScanResult!!.startIndex + 1)
val insertIndex = walkerMethod.implementation!!.instructions.size - 1 - 1
walkerMethod.injectScrollView(insertIndex, "onStartScrollView")
@ -46,11 +50,12 @@ object DoubleBackToClosePatch : BytecodePatch(
* Inject the methods which stop of ScrollView
*/
ScrollTopParentFingerprint.resultOrThrow().let { parentResult ->
ScrollTopFingerprint.also { it.resolve(context, parentResult.classDef) }.resultOrThrow().let {
val insertIndex = it.scanResult.patternScanResult!!.endIndex
ScrollTopFingerprint.also { it.resolve(context, parentResult.classDef) }.resultOrThrow()
.let {
val insertIndex = it.scanResult.patternScanResult!!.endIndex
it.mutableMethod.injectScrollView(insertIndex, "onStopScrollView")
}
it.mutableMethod.injectScrollView(insertIndex, "onStopScrollView")
}
}
}

View File

@ -33,8 +33,12 @@ object FullscreenButtonViewStubPatch : BytecodePatch(
).forEach { (fingerprint, literalValue) ->
fingerprint.result?.let {
it.mutableMethod.apply {
val targetIndex = getTargetIndex(getWideLiteralInstructionIndex(literalValue.toLong()), Opcode.MOVE_RESULT)
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
val targetIndex = getTargetIndex(
getWideLiteralInstructionIndex(literalValue.toLong()),
Opcode.MOVE_RESULT
)
val targetRegister =
getInstruction<OneRegisterInstruction>(targetIndex).registerA
addInstruction(
targetIndex + 1,

View File

@ -6,8 +6,8 @@ import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
/**
* Resolves to the same method as [StoryboardRendererDecoderRecommendedLevelFingerprint].
*/
* Resolves to the same method as [StoryboardRendererDecoderRecommendedLevelFingerprint].
*/
internal object StoryboardRendererDecoderSpecFingerprint : MethodFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,

View File

@ -27,7 +27,8 @@ object ShortsPlaybackPatch : BytecodePatch(
*/
ShortsPlaybackFingerprint.result?.let {
it.mutableMethod.apply {
val targetIndex = getTargetIndex(getWideLiteralInstructionIndex(45387052), Opcode.MOVE_RESULT)
val targetIndex =
getTargetIndex(getWideLiteralInstructionIndex(45387052), Opcode.MOVE_RESULT)
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
addInstruction(

View File

@ -32,14 +32,18 @@ object SuggestedVideoEndScreenPatch : BytecodePatch(
* Automatically closing the suggested video end screen is not appropriate as it will disable the autoplay behavior.
*/
RemoveOnLayoutChangeListenerFingerprint.resultOrThrow().let {
val walkerIndex = it.getWalkerMethod(context, it.scanResult.patternScanResult!!.endIndex)
val walkerIndex =
it.getWalkerMethod(context, it.scanResult.patternScanResult!!.endIndex)
walkerIndex.apply {
val invokeInterfaceIndex = getTargetIndex(Opcode.INVOKE_INTERFACE)
val iGetObjectIndex = getTargetIndexReversed(invokeInterfaceIndex, Opcode.IGET_OBJECT)
val iGetObjectIndex =
getTargetIndexReversed(invokeInterfaceIndex, Opcode.IGET_OBJECT)
val invokeInterfaceReference = getInstruction<ReferenceInstruction>(invokeInterfaceIndex).reference
val iGetObjectReference = getInstruction<ReferenceInstruction>(iGetObjectIndex).reference
val invokeInterfaceReference =
getInstruction<ReferenceInstruction>(invokeInterfaceIndex).reference
val iGetObjectReference =
getInstruction<ReferenceInstruction>(iGetObjectIndex).reference
addInstructionsWithLabels(
0,

View File

@ -15,7 +15,12 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
fromPackageName = ORIGINAL_PACKAGE_NAME_YOUTUBE,
mainActivityOnCreateFingerprint = MainActivityFingerprint,
integrationsPatchDependency = IntegrationsPatch::class,
dependencies = setOf(SpoofClientPatch::class, SpoofUserAgentPatch::class, PackageNamePatch::class, SettingsPatch::class),
dependencies = setOf(
SpoofClientPatch::class,
SpoofUserAgentPatch::class,
PackageNamePatch::class,
SettingsPatch::class
),
gmsCoreSupportResourcePatch = GmsCoreSupportResourcePatch,
compatiblePackages = COMPATIBLE_PACKAGE
)

View File

@ -20,7 +20,8 @@ object Constants {
const val VIDEO_PATH = "$PATCHES_PATH/video"
const val ADS_CLASS_DESCRIPTOR = "$ADS_PATH/AdsPatch;"
const val ALTERNATIVE_THUMBNAILS_CLASS_DESCRIPTOR = "$ALTERNATIVE_THUMBNAILS_PATH/AlternativeThumbnailsPatch;"
const val ALTERNATIVE_THUMBNAILS_CLASS_DESCRIPTOR =
"$ALTERNATIVE_THUMBNAILS_PATH/AlternativeThumbnailsPatch;"
const val FEED_CLASS_DESCRIPTOR = "$FEED_PATH/FeedPatch;"
const val GENERAL_CLASS_DESCRIPTOR = "$GENERAL_PATH/GeneralPatch;"
const val PLAYER_CLASS_DESCRIPTOR = "$PLAYER_PATH/PlayerPatch;"

View File

@ -72,14 +72,16 @@ object NavigationBarHookPatch : BytecodePatch(
resolve(context, PivotBarConstructorFingerprint.resultOrThrow().classDef)
}.resultOrThrow().mutableMethod.apply {
// Hook the current navigation bar enum value. Note, the 'You' tab does not have an enum value.
val navigationEnumClassName = NavigationEnumFingerprint.resultOrThrow().mutableClass.type
val navigationEnumClassName =
NavigationEnumFingerprint.resultOrThrow().mutableClass.type
addHook(Hook.SET_LAST_APP_NAVIGATION_ENUM) {
opcode == Opcode.INVOKE_STATIC &&
getReference<MethodReference>()?.definingClass == navigationEnumClassName
}
// Hook the creation of navigation tab views.
val drawableTabMethod = PivotBarButtonsCreateDrawableViewFingerprint.resultOrThrow().mutableMethod
val drawableTabMethod =
PivotBarButtonsCreateDrawableViewFingerprint.resultOrThrow().mutableMethod
addHook(Hook.NAVIGATION_TAB_LOADED) predicate@{
MethodUtil.methodSignaturesMatch(
getReference<MethodReference>() ?: return@predicate false,
@ -87,7 +89,8 @@ object NavigationBarHookPatch : BytecodePatch(
)
}
val imageResourceTabMethod = PivotBarButtonsCreateResourceViewFingerprint.resultOrThrow().method
val imageResourceTabMethod =
PivotBarButtonsCreateResourceViewFingerprint.resultOrThrow().method
addHook(Hook.NAVIGATION_IMAGE_RESOURCE_TAB_LOADED) predicate@{
MethodUtil.methodSignaturesMatch(
getReference<MethodReference>() ?: return@predicate false,
@ -111,11 +114,15 @@ object NavigationBarHookPatch : BytecodePatch(
}
}
navigationTabCreatedCallback = context.findClass(INTEGRATIONS_CLASS_DESCRIPTOR)?.mutableClass?.methods?.first { method ->
method.name == "navigationTabCreatedCallback"
} ?: throw PatchException("Could not find navigationTabCreatedCallback method")
navigationTabCreatedCallback =
context.findClass(INTEGRATIONS_CLASS_DESCRIPTOR)?.mutableClass?.methods?.first { method ->
method.name == "navigationTabCreatedCallback"
} ?: throw PatchException("Could not find navigationTabCreatedCallback method")
MainActivityResolvePatch.injectOnBackPressedMethodCall(INTEGRATIONS_CLASS_DESCRIPTOR, "onBackPressed")
MainActivityResolvePatch.injectOnBackPressedMethodCall(
INTEGRATIONS_CLASS_DESCRIPTOR,
"onBackPressed"
)
}
val hookNavigationButtonCreated: (String) -> Unit by lazy {
@ -133,7 +140,10 @@ object NavigationBarHookPatch : BytecodePatch(
private enum class Hook(val methodName: String, val parameters: String) {
SET_LAST_APP_NAVIGATION_ENUM("setLastAppNavigationEnum", "Ljava/lang/Enum;"),
NAVIGATION_TAB_LOADED("navigationTabLoaded", "Landroid/view/View;"),
NAVIGATION_IMAGE_RESOURCE_TAB_LOADED("navigationImageResourceTabLoaded", "Landroid/view/View;"),
NAVIGATION_IMAGE_RESOURCE_TAB_LOADED(
"navigationImageResourceTabLoaded",
"Landroid/view/View;"
),
SEARCH_BAR_RESULTS_VIEW_LOADED("searchBarResultsViewLoaded", "Landroid/view/View;"),
}
}

View File

@ -32,7 +32,8 @@ object PlayerControlsVisibilityHookPatch : BytecodePatch(
it.mutableClass.methods.find { method -> method.name == "<init>" }?.apply {
val targetIndex = getTargetIndex(Opcode.IPUT_OBJECT)
val targetRegister = getInstruction<TwoRegisterInstruction>(targetIndex).registerA
val targetRegister =
getInstruction<TwoRegisterInstruction>(targetIndex).registerA
addInstructions(
targetIndex + 1, """

View File

@ -59,7 +59,8 @@ object PlayerTypeHookPatch : BytecodePatch(
// region patch for set video state
YouTubeControlsOverlayFingerprint.resultOrThrow().let { parentResult ->
VideoStateFingerprint.also { it.resolve(context, parentResult.classDef)
VideoStateFingerprint.also {
it.resolve(context, parentResult.classDef)
}.resultOrThrow().let {
it.mutableMethod.apply {
val endIndex = it.scanResult.patternScanResult!!.endIndex
@ -84,7 +85,8 @@ object PlayerTypeHookPatch : BytecodePatch(
it.mutableMethod.apply {
val targetIndex = getStringInstructionIndex("VL") - 1
val targetReference = getInstruction<ReferenceInstruction>(targetIndex).reference
val targetClass = context.findClass((targetReference as FieldReference).definingClass)!!.mutableClass
val targetClass =
context.findClass((targetReference as FieldReference).definingClass)!!.mutableClass
targetClass.methods.find { method -> method.name == "<init>" }
?.apply {

View File

@ -175,7 +175,8 @@ object SharedResourceIdPatch : ResourcePatch() {
RightComment = getId(DRAWABLE, "ic_right_comment_32c")
ScrimOverlay = getId(ID, "scrim_overlay")
Scrubbing = getId(DIMEN, "vertical_touch_offset_to_enter_fine_scrubbing")
SeekEasyHorizontalTouchOffsetToStartScrubbing = getId(DIMEN, "seek_easy_horizontal_touch_offset_to_start_scrubbing")
SeekEasyHorizontalTouchOffsetToStartScrubbing =
getId(DIMEN, "seek_easy_horizontal_touch_offset_to_start_scrubbing")
SeekUndoEduOverlayStub = getId(ID, "seek_undo_edu_overlay_stub")
SingleLoopEduSnackBarText = getId(STRING, "single_loop_edu_snackbar_text")
SlidingDialogAnimation = getId(STYLE, "SlidingDialogAnimation")
@ -186,9 +187,11 @@ object SharedResourceIdPatch : ResourcePatch() {
TotalTime = getId(STRING, "total_time")
TouchArea = getId(ID, "touch_area")
VideoQualityBottomSheet = getId(LAYOUT, "video_quality_bottom_sheet_list_fragment_title")
VideoQualityUnavailableAnnouncement = getId(STRING, "video_quality_unavailable_announcement")
VideoQualityUnavailableAnnouncement =
getId(STRING, "video_quality_unavailable_announcement")
VoiceSearch = getId(ID, "voice_search")
YouTubeControlsOverlaySubtitleButton = getId(LAYOUT, "youtube_controls_overlay_subtitle_button")
YouTubeControlsOverlaySubtitleButton =
getId(LAYOUT, "youtube_controls_overlay_subtitle_button")
YtOutlinePiPWhite = getId(DRAWABLE, "yt_outline_picture_in_picture_white_24")
YtOutlineVideoCamera = getId(DRAWABLE, "yt_outline_video_camera_black_24")
YtOutlineXWhite = getId(DRAWABLE, "yt_outline_x_white_24")

View File

@ -70,13 +70,17 @@ object ReturnYouTubeDislikePatch : BaseBytecodePatch(
TextComponentContextFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val conversionContextFieldIndex = getTargetIndexWithFieldReferenceType("Ljava/util/Map;") - 1
val conversionContextFieldIndex =
getTargetIndexWithFieldReferenceType("Ljava/util/Map;") - 1
val conversionContextFieldReference =
getInstruction<ReferenceInstruction>(conversionContextFieldIndex).reference
val charSequenceIndex = getTargetIndexWithFieldReferenceType("Ljava/util/BitSet;") - 1
val charSequenceRegister = getInstruction<TwoRegisterInstruction>(charSequenceIndex).registerA
val freeRegister = getInstruction<TwoRegisterInstruction>(charSequenceIndex).registerB
val charSequenceIndex =
getTargetIndexWithFieldReferenceType("Ljava/util/BitSet;") - 1
val charSequenceRegister =
getInstruction<TwoRegisterInstruction>(charSequenceIndex).registerA
val freeRegister =
getInstruction<TwoRegisterInstruction>(charSequenceIndex).registerB
addInstructions(
charSequenceIndex - 1, """

View File

@ -71,7 +71,8 @@ object ReturnYouTubeDislikeShortsPatch : BytecodePatch(
if (SettingsPatch.upward1834) {
TextComponentSpecFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val insertIndex = getTargetIndexWithReference("Landroid/text/SpannableString;->valueOf(Ljava/lang/CharSequence;)Landroid/text/SpannableString;")
val insertIndex =
getTargetIndexWithReference("Landroid/text/SpannableString;->valueOf(Ljava/lang/CharSequence;)Landroid/text/SpannableString;")
val charSequenceRegister =
getInstruction<FiveRegisterInstruction>(insertIndex).registerC

View File

@ -46,11 +46,21 @@ object SettingsBytecodePatch : BytecodePatch(
}
}
MainActivityResolvePatch.injectOnCreateMethodCall(INTEGRATIONS_INITIALIZATION_CLASS_DESCRIPTOR, "setExtendedUtils")
MainActivityResolvePatch.injectOnCreateMethodCall(INTEGRATIONS_INITIALIZATION_CLASS_DESCRIPTOR, "onCreate")
MainActivityResolvePatch.injectConstructorMethodCall(INTEGRATIONS_UTILS_CLASS_DESCRIPTOR, "setActivity")
MainActivityResolvePatch.injectOnCreateMethodCall(
INTEGRATIONS_INITIALIZATION_CLASS_DESCRIPTOR,
"setExtendedUtils"
)
MainActivityResolvePatch.injectOnCreateMethodCall(
INTEGRATIONS_INITIALIZATION_CLASS_DESCRIPTOR,
"onCreate"
)
MainActivityResolvePatch.injectConstructorMethodCall(
INTEGRATIONS_UTILS_CLASS_DESCRIPTOR,
"setActivity"
)
}
private fun MutableMethod.injectCall(index: Int) {
val register = getInstruction<OneRegisterInstruction>(index).registerA

View File

@ -199,9 +199,11 @@ object SettingsPatch : BaseResourcePatch(
// region set ReVanced Integrations Version
val buildConfigMutableClass = SettingsBytecodePatch.contexts.findClass { it.sourceFile == "BuildConfig.java" }!!.mutableClass
val buildConfigMutableClass =
SettingsBytecodePatch.contexts.findClass { it.sourceFile == "BuildConfig.java" }!!.mutableClass
val versionNameField = buildConfigMutableClass.fields.single { it.name == "VERSION_NAME" }
val versionName = versionNameField.initialValue.toString().trim().replace("\"","").replace("&quot;", "")
val versionName =
versionNameField.initialValue.toString().trim().replace("\"", "").replace("&quot;", "")
contexts.updatePatchStatusSettings(
"ReVanced Integrations",

View File

@ -133,7 +133,8 @@ object SponsorBlockBytecodePatch : BytecodePatch(
it.mutableMethod.apply {
val targetIndex = getWideLiteralInstructionIndex(InsetOverlayViewLayout)
val checkCastIndex = getTargetIndex(targetIndex, Opcode.CHECK_CAST)
val targetRegister = getInstruction<OneRegisterInstruction>(checkCastIndex).registerA
val targetRegister =
getInstruction<OneRegisterInstruction>(checkCastIndex).registerA
addInstruction(
checkCastIndex + 1,
@ -146,8 +147,12 @@ object SponsorBlockBytecodePatch : BytecodePatch(
RectangleFieldInvalidatorFingerprint.resultOrThrow().let { result ->
result.mutableMethod.apply {
val invalidateIndex = getTargetIndexWithMethodReferenceNameReversed("invalidate")
val rectangleIndex = getTargetIndexWithFieldReferenceTypeReversed(invalidateIndex + 1, "Landroid/graphics/Rect;")
val rectangleFieldName = (getInstruction<ReferenceInstruction>(rectangleIndex).reference as FieldReference).name
val rectangleIndex = getTargetIndexWithFieldReferenceTypeReversed(
invalidateIndex + 1,
"Landroid/graphics/Rect;"
)
val rectangleFieldName =
(getInstruction<ReferenceInstruction>(rectangleIndex).reference as FieldReference).name
SegmentPlaybackControllerFingerprint.resultOrThrow().let {
it.mutableMethod.apply {

View File

@ -25,9 +25,10 @@ object ViewGroupMarginLayoutParamsHookPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
val method = context.findClass(INTEGRATIONS_CLASS_DESCRIPTOR)?.mutableClass?.methods?.first { method ->
method.name == "hideViewGroupByMarginLayoutParams"
} ?: throw PatchException("Could not find hideViewGroupByMarginLayoutParams method")
val method =
context.findClass(INTEGRATIONS_CLASS_DESCRIPTOR)?.mutableClass?.methods?.first { method ->
method.name == "hideViewGroupByMarginLayoutParams"
} ?: throw PatchException("Could not find hideViewGroupByMarginLayoutParams method")
SetViewGroupMarginFingerprint.resolve(
context,

View File

@ -92,6 +92,7 @@ object VideoInformationPatch : BytecodePatch(
private const val REGISTER_VIDEO_ID = 2
private const val REGISTER_VIDEO_TITLE = 3
private const val REGISTER_VIDEO_LENGTH = 4
@Suppress("unused")
private const val REGISTER_VIDEO_LENGTH_DUMMY = 5
private const val REGISTER_VIDEO_IS_LIVE = 6
@ -118,7 +119,8 @@ object VideoInformationPatch : BytecodePatch(
internal lateinit var videoEndMethod: MutableMethod
override fun execute(context: BytecodeContext) {
val videoInformationMutableClass = context.findClass(INTEGRATIONS_CLASS_DESCRIPTOR)!!.mutableClass
val videoInformationMutableClass =
context.findClass(INTEGRATIONS_CLASS_DESCRIPTOR)!!.mutableClass
VideoEndFingerprint.resultOrThrow().let {
@ -173,7 +175,8 @@ object VideoInformationPatch : BytecodePatch(
true
)
videoEndMethod = getWalkerMethod(context, it.scanResult.patternScanResult!!.startIndex + 1)
videoEndMethod =
getWalkerMethod(context, it.scanResult.patternScanResult!!.startIndex + 1)
}
}
@ -264,11 +267,13 @@ object VideoInformationPatch : BytecodePatch(
*/
VideoIdPatch.hookVideoId("$INTEGRATIONS_CLASS_DESCRIPTOR->setVideoId(Ljava/lang/String;)V")
VideoIdPatch.hookPlayerResponseVideoId(
"$INTEGRATIONS_CLASS_DESCRIPTOR->setPlayerResponseVideoId(Ljava/lang/String;Z)V")
"$INTEGRATIONS_CLASS_DESCRIPTOR->setPlayerResponseVideoId(Ljava/lang/String;Z)V"
)
// Call before any other video id hooks,
// so they can use VideoInformation and check if the video id is for a Short.
PlayerResponseMethodHookPatch += PlayerResponseMethodHookPatch.Hook.PlayerParameterBeforeVideoId(
"$INTEGRATIONS_CLASS_DESCRIPTOR->newPlayerResponseParameter(Ljava/lang/String;Ljava/lang/String;Z)Ljava/lang/String;")
"$INTEGRATIONS_CLASS_DESCRIPTOR->newPlayerResponseParameter(Ljava/lang/String;Ljava/lang/String;Z)Ljava/lang/String;"
)
/**
* Hook current playback speed
@ -278,7 +283,8 @@ object VideoInformationPatch : BytecodePatch(
speedSelectionInsertMethod = this
val speedSelectionValueInstructionIndex = getTargetIndex(Opcode.IGET)
val setPlaybackSpeedContainerClassFieldIndex = getTargetIndexReversed(speedSelectionValueInstructionIndex, Opcode.IGET_OBJECT)
val setPlaybackSpeedContainerClassFieldIndex =
getTargetIndexReversed(speedSelectionValueInstructionIndex, Opcode.IGET_OBJECT)
val setPlaybackSpeedContainerClassFieldReference =
getInstruction<ReferenceInstruction>(setPlaybackSpeedContainerClassFieldIndex).reference.toString()
@ -447,7 +453,7 @@ object VideoInformationPatch : BytecodePatch(
"invoke-static { p1, p2 }, $targetMethodClass->$targetMethodName(J)V"
)
private fun MethodFingerprint.getMethodName(returnType : String) :String {
private fun MethodFingerprint.getMethodName(returnType: String): String {
resultOrThrow().mutableMethod.apply {
val targetIndex = indexOfFirstInstruction {
opcode == Opcode.INVOKE_INTERFACE
@ -465,7 +471,13 @@ object VideoInformationPatch : BytecodePatch(
ImmutableMethod(
definingClass,
"setVideoInformation",
listOf(ImmutableMethodParameter(PLAYER_RESPONSE_MODEL_CLASS_DESCRIPTOR, annotations, null)),
listOf(
ImmutableMethodParameter(
PLAYER_RESPONSE_MODEL_CLASS_DESCRIPTOR,
annotations,
null
)
),
"V",
AccessFlags.PRIVATE or AccessFlags.FINAL,
annotations,

View File

@ -9,5 +9,5 @@ internal object VideoTitleFingerprint : LiteralValueFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = emptyList(),
literalSupplier = { NotificationBigPictureIconWidth }
literalSupplier = { NotificationBigPictureIconWidth }
)

View File

@ -125,7 +125,8 @@ object VideoPlaybackPatch : BaseBytecodePatch(
QualityChangedFromRecyclerViewFingerprint.resultOrThrow().classDef
)
val newMethod = PlaybackSpeedChangedFromRecyclerViewFingerprint.resultOrThrow().mutableMethod
val newMethod =
PlaybackSpeedChangedFromRecyclerViewFingerprint.resultOrThrow().mutableMethod
arrayOf(
newMethod,
@ -293,7 +294,8 @@ object VideoPlaybackPatch : BaseBytecodePatch(
ByteBufferArrayFingerprint.also { it.resolve(context, classDef) }.resultOrThrow().let {
it.mutableMethod.apply {
val insertIndex = it.scanResult.patternScanResult!!.endIndex
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
val insertRegister =
getInstruction<OneRegisterInstruction>(insertIndex).registerA
addInstructions(
insertIndex, """

View File

@ -95,7 +95,8 @@ object PlayerResponseMethodHookPatch :
internal class VideoId(methodDescriptor: String) : Hook(methodDescriptor)
internal class PlayerParameter(methodDescriptor: String) : Hook(methodDescriptor)
internal class PlayerParameterBeforeVideoId(methodDescriptor: String) : Hook(methodDescriptor)
internal class PlayerParameterBeforeVideoId(methodDescriptor: String) :
Hook(methodDescriptor)
override fun toString() = methodDescriptor
}

View File

@ -32,15 +32,17 @@ object VideoIdPatch : BytecodePatch(
*
* @param consumer Consumer that receives the method, insert index and video id register index.
*/
fun MethodFingerprint.setFields(consumer: (MutableMethod, Int, Int) -> Unit) = resultOrThrow().let { result ->
val videoIdRegisterIndex = result.scanResult.patternScanResult!!.endIndex
fun MethodFingerprint.setFields(consumer: (MutableMethod, Int, Int) -> Unit) =
resultOrThrow().let { result ->
val videoIdRegisterIndex = result.scanResult.patternScanResult!!.endIndex
result.mutableMethod.let {
val videoIdRegister = it.getInstruction<OneRegisterInstruction>(videoIdRegisterIndex).registerA
val insertIndex = videoIdRegisterIndex + 1
consumer(it, insertIndex, videoIdRegister)
result.mutableMethod.let {
val videoIdRegister =
it.getInstruction<OneRegisterInstruction>(videoIdRegisterIndex).registerA
val insertIndex = videoIdRegisterIndex + 1
consumer(it, insertIndex, videoIdRegister)
}
}
}
VideoIdFingerprint.resolve(context, VideoIdParentFingerprint.resultOrThrow().classDef)