mirror of
https://github.com/inotia00/revanced-patches.git
synced 2025-05-03 08:04:36 +02:00
chore: lint code
This commit is contained in:
parent
e374fa306b
commit
ecd6fbdf5b
@ -8,5 +8,8 @@ internal fun main() = PatchBundleLoader.Jar(
|
|||||||
).also { loader ->
|
).also { loader ->
|
||||||
if (loader.isEmpty()) throw IllegalStateException("No patches found")
|
if (loader.isEmpty()) throw IllegalStateException("No patches found")
|
||||||
}.let { bundle ->
|
}.let { bundle ->
|
||||||
arrayOf(JsonPatchesFileGenerator(), ReadMeFileGenerator()).forEach { generator -> generator.generate(bundle) }
|
arrayOf(
|
||||||
|
JsonPatchesFileGenerator(),
|
||||||
|
ReadMeFileGenerator()
|
||||||
|
).forEach { generator -> generator.generate(bundle) }
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,8 @@ internal class ReadMeFileGenerator : PatchesFileGenerator {
|
|||||||
val output = StringBuilder()
|
val output = StringBuilder()
|
||||||
|
|
||||||
// create a temp file
|
// create a temp file
|
||||||
val readMeTemplateTempFile = File.createTempFile("README", ".md", File(Paths.get("").toAbsolutePath().toString()))
|
val readMeTemplateTempFile =
|
||||||
|
File.createTempFile("README", ".md", File(Paths.get("").toAbsolutePath().toString()))
|
||||||
|
|
||||||
// copy the contents of 'README-template.md' to the temp file
|
// copy the contents of 'README-template.md' to the temp file
|
||||||
StringBuilder(readMeTemplateFile.readText())
|
StringBuilder(readMeTemplateFile.readText())
|
||||||
@ -37,19 +38,24 @@ internal class ReadMeFileGenerator : PatchesFileGenerator {
|
|||||||
app.revanced.patches.reddit.utils.compatibility.Constants.COMPATIBLE_PACKAGE to "\"COMPATIBLE_PACKAGE_REDDIT\"",
|
app.revanced.patches.reddit.utils.compatibility.Constants.COMPATIBLE_PACKAGE to "\"COMPATIBLE_PACKAGE_REDDIT\"",
|
||||||
app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE to "\"COMPATIBLE_PACKAGE_YOUTUBE\""
|
app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE to "\"COMPATIBLE_PACKAGE_YOUTUBE\""
|
||||||
).forEach { (compatiblePackage, replaceString) ->
|
).forEach { (compatiblePackage, replaceString) ->
|
||||||
compatiblePackage.map { CompatiblePackage(it.name, it.versions?.toSet()?.ifEmpty { null }) }
|
compatiblePackage.map {
|
||||||
|
CompatiblePackage(
|
||||||
|
it.name,
|
||||||
|
it.versions?.toSet()?.ifEmpty { null })
|
||||||
|
}
|
||||||
.forEach { compatiblePackages ->
|
.forEach { compatiblePackages ->
|
||||||
val pkgName = compatiblePackages.name
|
val pkgName = compatiblePackages.name
|
||||||
val supportedVersion = if (compatiblePackages.versions == null && exception.containsKey(pkgName)) {
|
val supportedVersion =
|
||||||
exception[pkgName] + "+"
|
if (compatiblePackages.versions == null && exception.containsKey(pkgName)) {
|
||||||
} else {
|
exception[pkgName] + "+"
|
||||||
compatiblePackages.versions
|
} else {
|
||||||
?.toString()
|
compatiblePackages.versions
|
||||||
?.replace("[", "[\n \"")
|
?.toString()
|
||||||
?.replace("]", "\"\n ]")
|
?.replace("[", "[\n \"")
|
||||||
?.replace(", ", "\",\n \"")
|
?.replace("]", "\"\n ]")
|
||||||
?: "\"ALL\""
|
?.replace(", ", "\",\n \"")
|
||||||
}
|
?: "\"ALL\""
|
||||||
|
}
|
||||||
|
|
||||||
StringBuilder(readMeTemplateTempFile.readText())
|
StringBuilder(readMeTemplateTempFile.readText())
|
||||||
.replace(Regex(replaceString), supportedVersion)
|
.replace(Regex(replaceString), supportedVersion)
|
||||||
|
@ -65,8 +65,10 @@ object AccountComponentsPatch : BaseBytecodePatch(
|
|||||||
result.mutableMethod.apply {
|
result.mutableMethod.apply {
|
||||||
|
|
||||||
val textColorIndex = getTargetIndexWithMethodReferenceName("setTextColor")
|
val textColorIndex = getTargetIndexWithMethodReferenceName("setTextColor")
|
||||||
val setVisibilityIndex = getTargetIndexWithMethodReferenceName(textColorIndex, "setVisibility")
|
val setVisibilityIndex =
|
||||||
val textViewInstruction = getInstruction<FiveRegisterInstruction>(setVisibilityIndex)
|
getTargetIndexWithMethodReferenceName(textColorIndex, "setVisibility")
|
||||||
|
val textViewInstruction =
|
||||||
|
getInstruction<FiveRegisterInstruction>(setVisibilityIndex)
|
||||||
|
|
||||||
replaceInstruction(
|
replaceInstruction(
|
||||||
setVisibilityIndex,
|
setVisibilityIndex,
|
||||||
@ -96,7 +98,8 @@ object AccountComponentsPatch : BaseBytecodePatch(
|
|||||||
|
|
||||||
TermsOfServiceFingerprint.resultOrThrow().let {
|
TermsOfServiceFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val insertIndex = getTargetIndexWithReference("/PrivacyTosFooter;->setVisibility(I)V")
|
val insertIndex =
|
||||||
|
getTargetIndexWithReference("/PrivacyTosFooter;->setVisibility(I)V")
|
||||||
val visibilityRegister =
|
val visibilityRegister =
|
||||||
getInstruction<FiveRegisterInstruction>(insertIndex).registerD
|
getInstruction<FiveRegisterInstruction>(insertIndex).registerD
|
||||||
|
|
||||||
|
@ -49,7 +49,8 @@ object ActionBarComponentsPatch : BaseBytecodePatch(
|
|||||||
|
|
||||||
// hook download button
|
// hook download button
|
||||||
val addViewIndex = getTargetIndexWithMethodReferenceName("addView")
|
val addViewIndex = getTargetIndexWithMethodReferenceName("addView")
|
||||||
val addViewRegister = getInstruction<FiveRegisterInstruction>(addViewIndex).registerD
|
val addViewRegister =
|
||||||
|
getInstruction<FiveRegisterInstruction>(addViewIndex).registerD
|
||||||
|
|
||||||
addInstruction(
|
addInstruction(
|
||||||
addViewIndex + 1,
|
addViewIndex + 1,
|
||||||
@ -86,7 +87,8 @@ object ActionBarComponentsPatch : BaseBytecodePatch(
|
|||||||
val freeRegister = min(implementation!!.registerCount - parameters.size - 2, 15)
|
val freeRegister = min(implementation!!.registerCount - parameters.size - 2, 15)
|
||||||
|
|
||||||
val spannedIndex = getTargetIndexWithReference(")Landroid/text/Spanned;")
|
val spannedIndex = getTargetIndexWithReference(")Landroid/text/Spanned;")
|
||||||
val spannedRegister = getInstruction<FiveRegisterInstruction>(spannedIndex).registerC
|
val spannedRegister =
|
||||||
|
getInstruction<FiveRegisterInstruction>(spannedIndex).registerC
|
||||||
val spannedReference = getInstruction<ReferenceInstruction>(spannedIndex).reference
|
val spannedReference = getInstruction<ReferenceInstruction>(spannedIndex).reference
|
||||||
|
|
||||||
addInstructionsWithLabels(
|
addInstructionsWithLabels(
|
||||||
@ -101,10 +103,12 @@ object ActionBarComponentsPatch : BaseBytecodePatch(
|
|||||||
|
|
||||||
// set action button identifier
|
// set action button identifier
|
||||||
val buttonTypeDownloadIndex = it.scanResult.patternScanResult!!.startIndex + 1
|
val buttonTypeDownloadIndex = it.scanResult.patternScanResult!!.startIndex + 1
|
||||||
val buttonTypeDownloadRegister = getInstruction<OneRegisterInstruction>(buttonTypeDownloadIndex).registerA
|
val buttonTypeDownloadRegister =
|
||||||
|
getInstruction<OneRegisterInstruction>(buttonTypeDownloadIndex).registerA
|
||||||
|
|
||||||
val buttonTypeIndex = it.scanResult.patternScanResult!!.endIndex - 1
|
val buttonTypeIndex = it.scanResult.patternScanResult!!.endIndex - 1
|
||||||
val buttonTypeRegister = getInstruction<OneRegisterInstruction>(buttonTypeIndex).registerA
|
val buttonTypeRegister =
|
||||||
|
getInstruction<OneRegisterInstruction>(buttonTypeIndex).registerA
|
||||||
|
|
||||||
addInstruction(
|
addInstruction(
|
||||||
buttonTypeIndex + 2,
|
buttonTypeIndex + 2,
|
||||||
|
@ -191,16 +191,19 @@ object AdsPatch : BaseBytecodePatch(
|
|||||||
// get premium button at the bottom of the account switching menu
|
// get premium button at the bottom of the account switching menu
|
||||||
AccountMenuFooterFingerprint.resultOrThrow().let {
|
AccountMenuFooterFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val constIndex = getWideLiteralInstructionIndex(SharedResourceIdPatch.PrivacyTosFooter)
|
val constIndex =
|
||||||
|
getWideLiteralInstructionIndex(SharedResourceIdPatch.PrivacyTosFooter)
|
||||||
val walkerIndex = getTargetIndex(constIndex + 2, Opcode.INVOKE_VIRTUAL)
|
val walkerIndex = getTargetIndex(constIndex + 2, Opcode.INVOKE_VIRTUAL)
|
||||||
val viewIndex = getTargetIndex(constIndex, Opcode.IGET_OBJECT)
|
val viewIndex = getTargetIndex(constIndex, Opcode.IGET_OBJECT)
|
||||||
val viewReference = getInstruction<ReferenceInstruction>(viewIndex).reference.toString()
|
val viewReference =
|
||||||
|
getInstruction<ReferenceInstruction>(viewIndex).reference.toString()
|
||||||
|
|
||||||
val walkerMethod = getWalkerMethod(context, walkerIndex)
|
val walkerMethod = getWalkerMethod(context, walkerIndex)
|
||||||
walkerMethod.apply {
|
walkerMethod.apply {
|
||||||
val insertIndex = getTargetIndexWithReference(viewReference)
|
val insertIndex = getTargetIndexWithReference(viewReference)
|
||||||
val nullCheckIndex = getTargetIndex(insertIndex - 1, Opcode.IF_NEZ)
|
val nullCheckIndex = getTargetIndex(insertIndex - 1, Opcode.IF_NEZ)
|
||||||
val nullCheckRegister = getInstruction<OneRegisterInstruction>(nullCheckIndex).registerA
|
val nullCheckRegister =
|
||||||
|
getInstruction<OneRegisterInstruction>(nullCheckIndex).registerA
|
||||||
|
|
||||||
addInstruction(
|
addInstruction(
|
||||||
nullCheckIndex,
|
nullCheckIndex,
|
||||||
|
@ -5,6 +5,6 @@ import app.revanced.util.fingerprint.LiteralValueFingerprint
|
|||||||
|
|
||||||
internal object InterstitialsContainerFingerprint : LiteralValueFingerprint(
|
internal object InterstitialsContainerFingerprint : LiteralValueFingerprint(
|
||||||
returnType = "V",
|
returnType = "V",
|
||||||
strings= listOf("overlay_controller_param"),
|
strings = listOf("overlay_controller_param"),
|
||||||
literalSupplier = { InterstitialsContainer }
|
literalSupplier = { InterstitialsContainer }
|
||||||
)
|
)
|
@ -73,7 +73,8 @@ object FlyoutMenuComponentsPatch : BaseBytecodePatch(
|
|||||||
// region patch for enable compact dialog
|
// region patch for enable compact dialog
|
||||||
|
|
||||||
DialogSolidFingerprint.resultOrThrow().let {
|
DialogSolidFingerprint.resultOrThrow().let {
|
||||||
val walkerMethod = it.getWalkerMethod(context, it.scanResult.patternScanResult!!.endIndex)
|
val walkerMethod =
|
||||||
|
it.getWalkerMethod(context, it.scanResult.patternScanResult!!.endIndex)
|
||||||
walkerMethod.addInstructions(
|
walkerMethod.addInstructions(
|
||||||
2, """
|
2, """
|
||||||
invoke-static {p0}, $FLYOUT_CLASS_DESCRIPTOR->enableCompactDialog(I)I
|
invoke-static {p0}, $FLYOUT_CLASS_DESCRIPTOR->enableCompactDialog(I)I
|
||||||
@ -94,17 +95,22 @@ object FlyoutMenuComponentsPatch : BaseBytecodePatch(
|
|||||||
|
|
||||||
TrimSilenceSwitchFingerprint.resultOrThrow().let {
|
TrimSilenceSwitchFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val constIndex = getWideLiteralInstructionIndex(SharedResourceIdPatch.TrimSilenceSwitch)
|
val constIndex =
|
||||||
val onCheckedChangedListenerIndex = getTargetIndex(constIndex, Opcode.INVOKE_DIRECT)
|
getWideLiteralInstructionIndex(SharedResourceIdPatch.TrimSilenceSwitch)
|
||||||
val onCheckedChangedListenerReference = getInstruction<ReferenceInstruction>(onCheckedChangedListenerIndex).reference
|
val onCheckedChangedListenerIndex =
|
||||||
val onCheckedChangedListenerDefiningClass = (onCheckedChangedListenerReference as MethodReference).definingClass
|
getTargetIndex(constIndex, Opcode.INVOKE_DIRECT)
|
||||||
|
val onCheckedChangedListenerReference =
|
||||||
|
getInstruction<ReferenceInstruction>(onCheckedChangedListenerIndex).reference
|
||||||
|
val onCheckedChangedListenerDefiningClass =
|
||||||
|
(onCheckedChangedListenerReference as MethodReference).definingClass
|
||||||
val onCheckedChangedListenerClass =
|
val onCheckedChangedListenerClass =
|
||||||
context.findClass(onCheckedChangedListenerDefiningClass)!!.mutableClass
|
context.findClass(onCheckedChangedListenerDefiningClass)!!.mutableClass
|
||||||
|
|
||||||
onCheckedChangedListenerClass.methods.find { method -> method.name == "onCheckedChanged" }
|
onCheckedChangedListenerClass.methods.find { method -> method.name == "onCheckedChanged" }
|
||||||
?.apply {
|
?.apply {
|
||||||
val walkerIndex = indexOfFirstInstruction {
|
val walkerIndex = indexOfFirstInstruction {
|
||||||
val reference = ((this as? ReferenceInstruction)?.reference as? MethodReference)
|
val reference =
|
||||||
|
((this as? ReferenceInstruction)?.reference as? MethodReference)
|
||||||
|
|
||||||
opcode == Opcode.INVOKE_VIRTUAL
|
opcode == Opcode.INVOKE_VIRTUAL
|
||||||
&& reference?.returnType == "V"
|
&& reference?.returnType == "V"
|
||||||
@ -113,7 +119,8 @@ object FlyoutMenuComponentsPatch : BaseBytecodePatch(
|
|||||||
}
|
}
|
||||||
getWalkerMethod(context, walkerIndex).apply {
|
getWalkerMethod(context, walkerIndex).apply {
|
||||||
val insertIndex = getTargetIndex(Opcode.MOVE_RESULT)
|
val insertIndex = getTargetIndex(Opcode.MOVE_RESULT)
|
||||||
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
val insertRegister =
|
||||||
|
getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
insertIndex + 1, """
|
insertIndex + 1, """
|
||||||
@ -148,25 +155,30 @@ object FlyoutMenuComponentsPatch : BaseBytecodePatch(
|
|||||||
|
|
||||||
val enumIndex = indexOfFirstInstruction {
|
val enumIndex = indexOfFirstInstruction {
|
||||||
opcode == Opcode.INVOKE_STATIC
|
opcode == Opcode.INVOKE_STATIC
|
||||||
&& (this as? ReferenceInstruction)?.reference.toString().contains("(I)L")
|
&& (this as? ReferenceInstruction)?.reference.toString()
|
||||||
|
.contains("(I)L")
|
||||||
} + 1
|
} + 1
|
||||||
val enumRegister = getInstruction<OneRegisterInstruction>(enumIndex).registerA
|
val enumRegister = getInstruction<OneRegisterInstruction>(enumIndex).registerA
|
||||||
|
|
||||||
addInstructionsWithLabels(
|
addInstructionsWithLabels(
|
||||||
enumIndex + 1, """
|
enumIndex + 1,
|
||||||
|
"""
|
||||||
invoke-static {v$enumRegister, v$textViewRegister, v$imageViewRegister}, $FLYOUT_CLASS_DESCRIPTOR->replaceComponents(Ljava/lang/Enum;Landroid/widget/TextView;Landroid/widget/ImageView;)V
|
invoke-static {v$enumRegister, v$textViewRegister, v$imageViewRegister}, $FLYOUT_CLASS_DESCRIPTOR->replaceComponents(Ljava/lang/Enum;Landroid/widget/TextView;Landroid/widget/ImageView;)V
|
||||||
invoke-static {v$enumRegister}, $FLYOUT_CLASS_DESCRIPTOR->hideComponents(Ljava/lang/Enum;)Z
|
invoke-static {v$enumRegister}, $FLYOUT_CLASS_DESCRIPTOR->hideComponents(Ljava/lang/Enum;)Z
|
||||||
move-result v$freeRegister
|
move-result v$freeRegister
|
||||||
if-nez v$freeRegister, :hide
|
if-nez v$freeRegister, :hide
|
||||||
""", ExternalLabel("hide", getInstruction(implementation!!.instructions.size - 1))
|
""",
|
||||||
|
ExternalLabel("hide", getInstruction(implementation!!.instructions.size - 1))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TouchOutsideFingerprint.resultOrThrow().let {
|
TouchOutsideFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val setOnClickListenerIndex = getTargetIndexWithMethodReferenceName("setOnClickListener")
|
val setOnClickListenerIndex =
|
||||||
val setOnClickListenerRegister = getInstruction<FiveRegisterInstruction>(setOnClickListenerIndex).registerC
|
getTargetIndexWithMethodReferenceName("setOnClickListener")
|
||||||
|
val setOnClickListenerRegister =
|
||||||
|
getInstruction<FiveRegisterInstruction>(setOnClickListenerIndex).registerC
|
||||||
|
|
||||||
addInstruction(
|
addInstruction(
|
||||||
setOnClickListenerIndex + 1,
|
setOnClickListenerIndex + 1,
|
||||||
|
@ -106,7 +106,8 @@ object LayoutComponentsPatch : BaseBytecodePatch(
|
|||||||
// hide floating cast banner
|
// hide floating cast banner
|
||||||
PlayerOverlayChipFingerprint.resultOrThrow().let {
|
PlayerOverlayChipFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val targetIndex = getWideLiteralInstructionIndex(SharedResourceIdPatch.PlayerOverlayChip) + 2
|
val targetIndex =
|
||||||
|
getWideLiteralInstructionIndex(SharedResourceIdPatch.PlayerOverlayChip) + 2
|
||||||
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||||
|
|
||||||
addInstruction(
|
addInstruction(
|
||||||
@ -164,7 +165,8 @@ object LayoutComponentsPatch : BaseBytecodePatch(
|
|||||||
fingerprint.resultOrThrow().let {
|
fingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val insertIndex = it.scanResult.patternScanResult!!.startIndex
|
val insertIndex = it.scanResult.patternScanResult!!.startIndex
|
||||||
val insertRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerD
|
val insertRegister =
|
||||||
|
getInstruction<FiveRegisterInstruction>(insertIndex).registerD
|
||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
insertIndex, """
|
insertIndex, """
|
||||||
@ -232,7 +234,8 @@ object LayoutComponentsPatch : BaseBytecodePatch(
|
|||||||
TasteBuilderSyntheticFingerprint.resolve(context, parentResult.classDef)
|
TasteBuilderSyntheticFingerprint.resolve(context, parentResult.classDef)
|
||||||
|
|
||||||
parentResult.mutableMethod.apply {
|
parentResult.mutableMethod.apply {
|
||||||
val constIndex = getWideLiteralInstructionIndex(SharedResourceIdPatch.MusicTasteBuilderShelf)
|
val constIndex =
|
||||||
|
getWideLiteralInstructionIndex(SharedResourceIdPatch.MusicTasteBuilderShelf)
|
||||||
val targetIndex = getTargetIndex(constIndex, Opcode.MOVE_RESULT_OBJECT)
|
val targetIndex = getTargetIndex(constIndex, Opcode.MOVE_RESULT_OBJECT)
|
||||||
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||||
|
|
||||||
@ -281,7 +284,8 @@ object LayoutComponentsPatch : BaseBytecodePatch(
|
|||||||
SearchBarFingerprint.resultOrThrow().let {
|
SearchBarFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val setVisibilityIndex = getTargetIndexWithMethodReferenceName("setVisibility")
|
val setVisibilityIndex = getTargetIndexWithMethodReferenceName("setVisibility")
|
||||||
val setVisibilityInstruction = getInstruction<FiveRegisterInstruction>(setVisibilityIndex)
|
val setVisibilityInstruction =
|
||||||
|
getInstruction<FiveRegisterInstruction>(setVisibilityIndex)
|
||||||
|
|
||||||
replaceInstruction(
|
replaceInstruction(
|
||||||
setVisibilityIndex,
|
setVisibilityIndex,
|
||||||
|
@ -3,4 +3,5 @@ package app.revanced.patches.music.general.dialog
|
|||||||
import app.revanced.patches.music.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
|
import app.revanced.patches.music.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
|
||||||
import app.revanced.patches.shared.dialog.BaseViewerDiscretionDialogPatch
|
import app.revanced.patches.shared.dialog.BaseViewerDiscretionDialogPatch
|
||||||
|
|
||||||
object ViewerDiscretionDialogBytecodePatch : BaseViewerDiscretionDialogPatch(GENERAL_CLASS_DESCRIPTOR)
|
object ViewerDiscretionDialogBytecodePatch :
|
||||||
|
BaseViewerDiscretionDialogPatch(GENERAL_CLASS_DESCRIPTOR)
|
||||||
|
@ -51,13 +51,15 @@ object DislikeRedirectionPatch : BaseBytecodePatch(
|
|||||||
|
|
||||||
onClickMethod.apply {
|
onClickMethod.apply {
|
||||||
val onClickIndex = indexOfFirstInstruction {
|
val onClickIndex = indexOfFirstInstruction {
|
||||||
val reference = ((this as? ReferenceInstruction)?.reference as? MethodReference)
|
val reference =
|
||||||
|
((this as? ReferenceInstruction)?.reference as? MethodReference)
|
||||||
|
|
||||||
opcode == Opcode.INVOKE_INTERFACE
|
opcode == Opcode.INVOKE_INTERFACE
|
||||||
&& reference?.returnType == "V"
|
&& reference?.returnType == "V"
|
||||||
&& reference.parameterTypes.size == 1
|
&& reference.parameterTypes.size == 1
|
||||||
}
|
}
|
||||||
onClickReference = getInstruction<ReferenceInstruction>(onClickIndex).reference
|
onClickReference =
|
||||||
|
getInstruction<ReferenceInstruction>(onClickIndex).reference
|
||||||
|
|
||||||
injectCall(onClickIndex)
|
injectCall(onClickIndex)
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ object CustomBrandingIconPatch : BaseResourcePatch(
|
|||||||
|
|
||||||
override fun execute(context: ResourceContext) {
|
override fun execute(context: ResourceContext) {
|
||||||
AppIcon?.let { appIcon ->
|
AppIcon?.let { appIcon ->
|
||||||
val appIconValue = appIcon.lowercase().replace(" ","_")
|
val appIconValue = appIcon.lowercase().replace(" ", "_")
|
||||||
if (!availableIcon.containsValue(appIconValue)) {
|
if (!availableIcon.containsValue(appIconValue)) {
|
||||||
mipmapDirectories.map { directory ->
|
mipmapDirectories.map { directory ->
|
||||||
ResourceGroup(
|
ResourceGroup(
|
||||||
|
@ -136,8 +136,10 @@ object PlayerComponentsPatch : BaseBytecodePatch(
|
|||||||
val invokeVirtualIndex = getTargetIndex(relativeIndex, Opcode.INVOKE_VIRTUAL)
|
val invokeVirtualIndex = getTargetIndex(relativeIndex, Opcode.INVOKE_VIRTUAL)
|
||||||
val iGetIndex = getTargetIndex(relativeIndex, Opcode.IGET)
|
val iGetIndex = getTargetIndex(relativeIndex, Opcode.IGET)
|
||||||
|
|
||||||
colorMathPlayerInvokeVirtualReference = getInstruction<ReferenceInstruction>(invokeVirtualIndex).reference
|
colorMathPlayerInvokeVirtualReference =
|
||||||
colorMathPlayerIGetReference = getInstruction<ReferenceInstruction>(iGetIndex).reference
|
getInstruction<ReferenceInstruction>(invokeVirtualIndex).reference
|
||||||
|
colorMathPlayerIGetReference =
|
||||||
|
getInstruction<ReferenceInstruction>(iGetIndex).reference
|
||||||
|
|
||||||
// black player background
|
// black player background
|
||||||
val invokeDirectIndex = getTargetIndex(Opcode.INVOKE_DIRECT)
|
val invokeDirectIndex = getTargetIndex(Opcode.INVOKE_DIRECT)
|
||||||
@ -161,7 +163,8 @@ object PlayerComponentsPatch : BaseBytecodePatch(
|
|||||||
val colorGreyIndex = getWideLiteralInstructionIndex(ColorGrey)
|
val colorGreyIndex = getWideLiteralInstructionIndex(ColorGrey)
|
||||||
val iPutIndex = getTargetIndex(colorGreyIndex, Opcode.IPUT)
|
val iPutIndex = getTargetIndex(colorGreyIndex, Opcode.IPUT)
|
||||||
|
|
||||||
colorMathPlayerIPutReference = getInstruction<ReferenceInstruction>(iPutIndex).reference
|
colorMathPlayerIPutReference =
|
||||||
|
getInstruction<ReferenceInstruction>(iPutIndex).reference
|
||||||
}
|
}
|
||||||
|
|
||||||
parentResult.mutableClass.methods.filter { method ->
|
parentResult.mutableClass.methods.filter { method ->
|
||||||
@ -172,8 +175,12 @@ object PlayerComponentsPatch : BaseBytecodePatch(
|
|||||||
mutableMethod.apply {
|
mutableMethod.apply {
|
||||||
val freeRegister = implementation!!.registerCount - parameters.size - 3
|
val freeRegister = implementation!!.registerCount - parameters.size - 3
|
||||||
|
|
||||||
val invokeDirectIndex = getTargetIndexReversed(implementation!!.instructions.size - 1, Opcode.INVOKE_DIRECT)
|
val invokeDirectIndex = getTargetIndexReversed(
|
||||||
val invokeDirectReference = getInstruction<ReferenceInstruction>(invokeDirectIndex).reference
|
implementation!!.instructions.size - 1,
|
||||||
|
Opcode.INVOKE_DIRECT
|
||||||
|
)
|
||||||
|
val invokeDirectReference =
|
||||||
|
getInstruction<ReferenceInstruction>(invokeDirectIndex).reference
|
||||||
|
|
||||||
addInstructionsWithLabels(
|
addInstructionsWithLabels(
|
||||||
invokeDirectIndex + 1, """
|
invokeDirectIndex + 1, """
|
||||||
@ -275,14 +282,30 @@ object PlayerComponentsPatch : BaseBytecodePatch(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
miniPlayerConstructorMutableMethod.setInstanceFieldValue(NEXT_BUTTON_METHOD_NAME, TopStart)
|
miniPlayerConstructorMutableMethod.setInstanceFieldValue(
|
||||||
|
NEXT_BUTTON_METHOD_NAME,
|
||||||
|
TopStart
|
||||||
|
)
|
||||||
mppWatchWhileLayoutMutableMethod.setStaticFieldValue(NEXT_BUTTON_FIELD_NAME, TopStart)
|
mppWatchWhileLayoutMutableMethod.setStaticFieldValue(NEXT_BUTTON_FIELD_NAME, TopStart)
|
||||||
pendingIntentReceiverMutableMethod.setOnClickListener(context, NEXT_BUTTON_INTENT_STRING, NEXT_BUTTON_ONCLICK_METHOD_NAME, NEXT_BUTTON_CLASS_FIELD_NAME)
|
pendingIntentReceiverMutableMethod.setOnClickListener(
|
||||||
|
context,
|
||||||
|
NEXT_BUTTON_INTENT_STRING,
|
||||||
|
NEXT_BUTTON_ONCLICK_METHOD_NAME,
|
||||||
|
NEXT_BUTTON_CLASS_FIELD_NAME
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
miniPlayerConstructorMutableMethod.setInstanceFieldValue(PREVIOUS_BUTTON_METHOD_NAME, TopEnd)
|
miniPlayerConstructorMutableMethod.setInstanceFieldValue(
|
||||||
|
PREVIOUS_BUTTON_METHOD_NAME,
|
||||||
|
TopEnd
|
||||||
|
)
|
||||||
mppWatchWhileLayoutMutableMethod.setStaticFieldValue(PREVIOUS_BUTTON_FIELD_NAME, TopEnd)
|
mppWatchWhileLayoutMutableMethod.setStaticFieldValue(PREVIOUS_BUTTON_FIELD_NAME, TopEnd)
|
||||||
pendingIntentReceiverMutableMethod.setOnClickListener(context, PREVIOUS_BUTTON_INTENT_STRING, PREVIOUS_BUTTON_ONCLICK_METHOD_NAME, PREVIOUS_BUTTON_CLASS_FIELD_NAME)
|
pendingIntentReceiverMutableMethod.setOnClickListener(
|
||||||
|
context,
|
||||||
|
PREVIOUS_BUTTON_INTENT_STRING,
|
||||||
|
PREVIOUS_BUTTON_ONCLICK_METHOD_NAME,
|
||||||
|
PREVIOUS_BUTTON_CLASS_FIELD_NAME
|
||||||
|
)
|
||||||
|
|
||||||
mppWatchWhileLayoutMutableMethod.setViewArray()
|
mppWatchWhileLayoutMutableMethod.setViewArray()
|
||||||
|
|
||||||
@ -327,7 +350,8 @@ object PlayerComponentsPatch : BaseBytecodePatch(
|
|||||||
SwipeToCloseFingerprint.resultOrThrow().let {
|
SwipeToCloseFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val insertIndex = implementation!!.instructions.size - 1
|
val insertIndex = implementation!!.instructions.size - 1
|
||||||
val targetRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
val targetRegister =
|
||||||
|
getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
insertIndex, """
|
insertIndex, """
|
||||||
@ -343,10 +367,12 @@ object PlayerComponentsPatch : BaseBytecodePatch(
|
|||||||
|
|
||||||
InteractionLoggingEnumFingerprint.resultOrThrow().let {
|
InteractionLoggingEnumFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val stringIndex = getStringInstructionIndex("INTERACTION_LOGGING_GESTURE_TYPE_SWIPE")
|
val stringIndex =
|
||||||
|
getStringInstructionIndex("INTERACTION_LOGGING_GESTURE_TYPE_SWIPE")
|
||||||
val sPutObjectIndex = getTargetIndex(stringIndex, Opcode.SPUT_OBJECT)
|
val sPutObjectIndex = getTargetIndex(stringIndex, Opcode.SPUT_OBJECT)
|
||||||
|
|
||||||
swipeToDismissSGetObjectReference = getInstruction<ReferenceInstruction>(sPutObjectIndex).reference
|
swipeToDismissSGetObjectReference =
|
||||||
|
getInstruction<ReferenceInstruction>(sPutObjectIndex).reference
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -354,13 +380,20 @@ object PlayerComponentsPatch : BaseBytecodePatch(
|
|||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
swipeToDismissWidgetIndex = getWideLiteralInstructionIndex(79500)
|
swipeToDismissWidgetIndex = getWideLiteralInstructionIndex(79500)
|
||||||
|
|
||||||
swipeToDismissIGetObjectReference = getSwipeToDismissReference(Opcode.IGET_OBJECT, true)
|
swipeToDismissIGetObjectReference =
|
||||||
swipeToDismissInvokeInterfacePrimaryReference = getSwipeToDismissReference(Opcode.INVOKE_INTERFACE, true)
|
getSwipeToDismissReference(Opcode.IGET_OBJECT, true)
|
||||||
swipeToDismissCheckCastReference = getSwipeToDismissReference(Opcode.CHECK_CAST, true)
|
swipeToDismissInvokeInterfacePrimaryReference =
|
||||||
swipeToDismissNewInstanceReference = getSwipeToDismissReference(Opcode.NEW_INSTANCE, true)
|
getSwipeToDismissReference(Opcode.INVOKE_INTERFACE, true)
|
||||||
swipeToDismissInvokeStaticReference = getSwipeToDismissReference(Opcode.INVOKE_STATIC, false)
|
swipeToDismissCheckCastReference =
|
||||||
swipeToDismissInvokeDirectReference = getSwipeToDismissReference(Opcode.INVOKE_DIRECT, false)
|
getSwipeToDismissReference(Opcode.CHECK_CAST, true)
|
||||||
swipeToDismissInvokeInterfaceSecondaryReference = getSwipeToDismissReference(Opcode.INVOKE_INTERFACE, false)
|
swipeToDismissNewInstanceReference =
|
||||||
|
getSwipeToDismissReference(Opcode.NEW_INSTANCE, true)
|
||||||
|
swipeToDismissInvokeStaticReference =
|
||||||
|
getSwipeToDismissReference(Opcode.INVOKE_STATIC, false)
|
||||||
|
swipeToDismissInvokeDirectReference =
|
||||||
|
getSwipeToDismissReference(Opcode.INVOKE_DIRECT, false)
|
||||||
|
swipeToDismissInvokeInterfaceSecondaryReference =
|
||||||
|
getSwipeToDismissReference(Opcode.INVOKE_INTERFACE, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -369,11 +402,14 @@ object PlayerComponentsPatch : BaseBytecodePatch(
|
|||||||
HandleSignInEventFingerprint.resolve(context, parentResult.classDef)
|
HandleSignInEventFingerprint.resolve(context, parentResult.classDef)
|
||||||
|
|
||||||
HandleSignInEventFingerprint.resultOrThrow().let {
|
HandleSignInEventFingerprint.resultOrThrow().let {
|
||||||
val dismissBehaviorMethod = it.getWalkerMethod(context, it.scanResult.patternScanResult!!.startIndex)
|
val dismissBehaviorMethod =
|
||||||
|
it.getWalkerMethod(context, it.scanResult.patternScanResult!!.startIndex)
|
||||||
|
|
||||||
dismissBehaviorMethod.apply {
|
dismissBehaviorMethod.apply {
|
||||||
val insertIndex = getTargetIndexWithFieldReferenceType("Ljava/util/concurrent/atomic/AtomicBoolean;")
|
val insertIndex =
|
||||||
val primaryRegister = getInstruction<TwoRegisterInstruction>(insertIndex).registerB
|
getTargetIndexWithFieldReferenceType("Ljava/util/concurrent/atomic/AtomicBoolean;")
|
||||||
|
val primaryRegister =
|
||||||
|
getInstruction<TwoRegisterInstruction>(insertIndex).registerB
|
||||||
val secondaryRegister = primaryRegister + 1
|
val secondaryRegister = primaryRegister + 1
|
||||||
val tertiaryRegister = secondaryRegister + 1
|
val tertiaryRegister = secondaryRegister + 1
|
||||||
|
|
||||||
@ -410,7 +446,8 @@ object PlayerComponentsPatch : BaseBytecodePatch(
|
|||||||
MiniPlayerDefaultTextFingerprint.resultOrThrow().let {
|
MiniPlayerDefaultTextFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val insertIndex = it.scanResult.patternScanResult!!.endIndex
|
val insertIndex = it.scanResult.patternScanResult!!.endIndex
|
||||||
val insertRegister = getInstruction<TwoRegisterInstruction>(insertIndex).registerB
|
val insertRegister =
|
||||||
|
getInstruction<TwoRegisterInstruction>(insertIndex).registerB
|
||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
insertIndex, """
|
insertIndex, """
|
||||||
@ -429,22 +466,26 @@ object PlayerComponentsPatch : BaseBytecodePatch(
|
|||||||
it.mutableClass.methods.find { method ->
|
it.mutableClass.methods.find { method ->
|
||||||
method.parameters == listOf("Landroid/view/View;", "I")
|
method.parameters == listOf("Landroid/view/View;", "I")
|
||||||
}?.apply {
|
}?.apply {
|
||||||
val bottomSheetBehaviorIndex = implementation!!.instructions.indexOfFirst { instruction ->
|
val bottomSheetBehaviorIndex =
|
||||||
instruction.opcode == Opcode.INVOKE_VIRTUAL
|
implementation!!.instructions.indexOfFirst { instruction ->
|
||||||
&& instruction.getReference<MethodReference>()?.definingClass == "Lcom/google/android/material/bottomsheet/BottomSheetBehavior;"
|
instruction.opcode == Opcode.INVOKE_VIRTUAL
|
||||||
&& instruction.getReference<MethodReference>()?.parameterTypes?.first() == "Z"
|
&& instruction.getReference<MethodReference>()?.definingClass == "Lcom/google/android/material/bottomsheet/BottomSheetBehavior;"
|
||||||
}
|
&& instruction.getReference<MethodReference>()?.parameterTypes?.first() == "Z"
|
||||||
|
}
|
||||||
if (bottomSheetBehaviorIndex < 0)
|
if (bottomSheetBehaviorIndex < 0)
|
||||||
throw PatchException("Could not find bottomSheetBehaviorIndex")
|
throw PatchException("Could not find bottomSheetBehaviorIndex")
|
||||||
|
|
||||||
val freeRegister = getInstruction<FiveRegisterInstruction>(bottomSheetBehaviorIndex).registerD
|
val freeRegister =
|
||||||
|
getInstruction<FiveRegisterInstruction>(bottomSheetBehaviorIndex).registerD
|
||||||
|
|
||||||
addInstructionsWithLabels(
|
addInstructionsWithLabels(
|
||||||
bottomSheetBehaviorIndex - 2, """
|
bottomSheetBehaviorIndex - 2,
|
||||||
|
"""
|
||||||
invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->enableSwipeToDismissMiniPlayer()Z
|
invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->enableSwipeToDismissMiniPlayer()Z
|
||||||
move-result v$freeRegister
|
move-result v$freeRegister
|
||||||
if-nez v$freeRegister, :dismiss
|
if-nez v$freeRegister, :dismiss
|
||||||
""", ExternalLabel("dismiss", getInstruction(bottomSheetBehaviorIndex + 1))
|
""",
|
||||||
|
ExternalLabel("dismiss", getInstruction(bottomSheetBehaviorIndex + 1))
|
||||||
)
|
)
|
||||||
} ?: throw PatchException("Could not find targetMethod")
|
} ?: throw PatchException("Could not find targetMethod")
|
||||||
|
|
||||||
@ -473,7 +514,8 @@ object PlayerComponentsPatch : BaseBytecodePatch(
|
|||||||
ZenModeFingerprint.result?.let {
|
ZenModeFingerprint.result?.let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val startIndex = it.scanResult.patternScanResult!!.startIndex
|
val startIndex = it.scanResult.patternScanResult!!.startIndex
|
||||||
val targetRegister = getInstruction<OneRegisterInstruction>(startIndex).registerA
|
val targetRegister =
|
||||||
|
getInstruction<OneRegisterInstruction>(startIndex).registerA
|
||||||
|
|
||||||
val insertIndex = it.scanResult.patternScanResult!!.endIndex + 1
|
val insertIndex = it.scanResult.patternScanResult!!.endIndex + 1
|
||||||
|
|
||||||
@ -616,13 +658,16 @@ object PlayerComponentsPatch : BaseBytecodePatch(
|
|||||||
|
|
||||||
val startIndex = it.scanResult.patternScanResult!!.startIndex
|
val startIndex = it.scanResult.patternScanResult!!.startIndex
|
||||||
val endIndex = it.scanResult.patternScanResult!!.endIndex
|
val endIndex = it.scanResult.patternScanResult!!.endIndex
|
||||||
val imageViewIndex = getTargetIndexWithFieldReferenceType("Landroid/widget/ImageView;")
|
val imageViewIndex =
|
||||||
|
getTargetIndexWithFieldReferenceType("Landroid/widget/ImageView;")
|
||||||
|
|
||||||
val shuffleReference1 = getInstruction<ReferenceInstruction>(startIndex).reference
|
val shuffleReference1 = getInstruction<ReferenceInstruction>(startIndex).reference
|
||||||
val shuffleReference2 = getInstruction<ReferenceInstruction>(startIndex + 1).reference
|
val shuffleReference2 =
|
||||||
|
getInstruction<ReferenceInstruction>(startIndex + 1).reference
|
||||||
val shuffleReference3 = getInstruction<ReferenceInstruction>(endIndex).reference
|
val shuffleReference3 = getInstruction<ReferenceInstruction>(endIndex).reference
|
||||||
val shuffleFieldReference = shuffleReference3 as FieldReference
|
val shuffleFieldReference = shuffleReference3 as FieldReference
|
||||||
rememberShuffleStateImageViewReference = getInstruction<ReferenceInstruction>(imageViewIndex).reference
|
rememberShuffleStateImageViewReference =
|
||||||
|
getInstruction<ReferenceInstruction>(imageViewIndex).reference
|
||||||
|
|
||||||
rememberShuffleStateShuffleStateLabel = """
|
rememberShuffleStateShuffleStateLabel = """
|
||||||
iget-object v1, v0, $shuffleReference1
|
iget-object v1, v0, $shuffleReference1
|
||||||
@ -783,10 +828,14 @@ object PlayerComponentsPatch : BaseBytecodePatch(
|
|||||||
methodName: String,
|
methodName: String,
|
||||||
viewId: Long
|
viewId: Long
|
||||||
) {
|
) {
|
||||||
val miniPlayerPlayPauseReplayButtonIndex = getWideLiteralInstructionIndex(MiniPlayerPlayPauseReplayButton)
|
val miniPlayerPlayPauseReplayButtonIndex =
|
||||||
val miniPlayerPlayPauseReplayButtonRegister = getInstruction<OneRegisterInstruction>(miniPlayerPlayPauseReplayButtonIndex).registerA
|
getWideLiteralInstructionIndex(MiniPlayerPlayPauseReplayButton)
|
||||||
val findViewByIdIndex = getTargetIndex(miniPlayerPlayPauseReplayButtonIndex, Opcode.INVOKE_VIRTUAL)
|
val miniPlayerPlayPauseReplayButtonRegister =
|
||||||
val parentViewRegister = getInstruction<FiveRegisterInstruction>(findViewByIdIndex).registerC
|
getInstruction<OneRegisterInstruction>(miniPlayerPlayPauseReplayButtonIndex).registerA
|
||||||
|
val findViewByIdIndex =
|
||||||
|
getTargetIndex(miniPlayerPlayPauseReplayButtonIndex, Opcode.INVOKE_VIRTUAL)
|
||||||
|
val parentViewRegister =
|
||||||
|
getInstruction<FiveRegisterInstruction>(findViewByIdIndex).registerC
|
||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
miniPlayerPlayPauseReplayButtonIndex, """
|
miniPlayerPlayPauseReplayButtonIndex, """
|
||||||
@ -802,10 +851,14 @@ object PlayerComponentsPatch : BaseBytecodePatch(
|
|||||||
fieldName: String,
|
fieldName: String,
|
||||||
viewId: Long
|
viewId: Long
|
||||||
) {
|
) {
|
||||||
val miniPlayerPlayPauseReplayButtonIndex = getWideLiteralInstructionIndex(MiniPlayerPlayPauseReplayButton)
|
val miniPlayerPlayPauseReplayButtonIndex =
|
||||||
val constRegister = getInstruction<OneRegisterInstruction>(miniPlayerPlayPauseReplayButtonIndex).registerA
|
getWideLiteralInstructionIndex(MiniPlayerPlayPauseReplayButton)
|
||||||
val findViewByIdIndex = getTargetIndex(miniPlayerPlayPauseReplayButtonIndex, Opcode.INVOKE_VIRTUAL)
|
val constRegister =
|
||||||
val findViewByIdRegister = getInstruction<FiveRegisterInstruction>(findViewByIdIndex).registerC
|
getInstruction<OneRegisterInstruction>(miniPlayerPlayPauseReplayButtonIndex).registerA
|
||||||
|
val findViewByIdIndex =
|
||||||
|
getTargetIndex(miniPlayerPlayPauseReplayButtonIndex, Opcode.INVOKE_VIRTUAL)
|
||||||
|
val findViewByIdRegister =
|
||||||
|
getInstruction<FiveRegisterInstruction>(findViewByIdIndex).registerC
|
||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
miniPlayerPlayPauseReplayButtonIndex, """
|
miniPlayerPlayPauseReplayButtonIndex, """
|
||||||
@ -818,8 +871,10 @@ object PlayerComponentsPatch : BaseBytecodePatch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun MutableMethod.setViewArray() {
|
private fun MutableMethod.setViewArray() {
|
||||||
val miniPlayerPlayPauseReplayButtonIndex = getWideLiteralInstructionIndex(MiniPlayerPlayPauseReplayButton)
|
val miniPlayerPlayPauseReplayButtonIndex =
|
||||||
val invokeStaticIndex = getTargetIndex(miniPlayerPlayPauseReplayButtonIndex, Opcode.INVOKE_STATIC)
|
getWideLiteralInstructionIndex(MiniPlayerPlayPauseReplayButton)
|
||||||
|
val invokeStaticIndex =
|
||||||
|
getTargetIndex(miniPlayerPlayPauseReplayButtonIndex, Opcode.INVOKE_STATIC)
|
||||||
val viewArrayRegister = getInstruction<FiveRegisterInstruction>(invokeStaticIndex).registerC
|
val viewArrayRegister = getInstruction<FiveRegisterInstruction>(invokeStaticIndex).registerC
|
||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
|
@ -22,17 +22,20 @@ object AccessibilityNodeInfoPatch : BytecodePatch(
|
|||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
// Target instruction is invoke-static, but can also be invoke-virtual.
|
// Target instruction is invoke-static, but can also be invoke-virtual.
|
||||||
// Therefore, the opcode is not checked.
|
// Therefore, the opcode is not checked.
|
||||||
val touchExplorationHoverEventMethodIndex = implementation!!.instructions.indexOfFirst { instruction ->
|
val touchExplorationHoverEventMethodIndex =
|
||||||
val reference = ((instruction as? ReferenceInstruction)?.reference as? MethodReference)
|
implementation!!.instructions.indexOfFirst { instruction ->
|
||||||
((instruction as? ReferenceInstruction)?.reference as? MethodReference)?.definingClass == definingClass
|
val reference =
|
||||||
&& reference?.returnType == "Z"
|
((instruction as? ReferenceInstruction)?.reference as? MethodReference)
|
||||||
}
|
((instruction as? ReferenceInstruction)?.reference as? MethodReference)?.definingClass == definingClass
|
||||||
|
&& reference?.returnType == "Z"
|
||||||
|
}
|
||||||
|
|
||||||
// Doesn't raise an exception, even if the target instruction is not found in this method
|
// Doesn't raise an exception, even if the target instruction is not found in this method
|
||||||
val touchExplorationHoverEventMethodName = if (touchExplorationHoverEventMethodIndex > -1)
|
val touchExplorationHoverEventMethodName =
|
||||||
(getInstruction<ReferenceInstruction>(touchExplorationHoverEventMethodIndex).reference as MethodReference).name
|
if (touchExplorationHoverEventMethodIndex > -1)
|
||||||
else
|
(getInstruction<ReferenceInstruction>(touchExplorationHoverEventMethodIndex).reference as MethodReference).name
|
||||||
"UNDEFINED"
|
else
|
||||||
|
"UNDEFINED"
|
||||||
|
|
||||||
val methods = it.mutableClass.methods
|
val methods = it.mutableClass.methods
|
||||||
|
|
||||||
|
@ -14,7 +14,11 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
|
|||||||
fromPackageName = ORIGINAL_PACKAGE_NAME_YOUTUBE,
|
fromPackageName = ORIGINAL_PACKAGE_NAME_YOUTUBE,
|
||||||
mainActivityOnCreateFingerprint = MainActivityFingerprint,
|
mainActivityOnCreateFingerprint = MainActivityFingerprint,
|
||||||
integrationsPatchDependency = IntegrationsPatch::class,
|
integrationsPatchDependency = IntegrationsPatch::class,
|
||||||
dependencies = setOf(SpoofUserAgentPatch::class, PackageNamePatch::class, FileProviderPatch::class),
|
dependencies = setOf(
|
||||||
|
SpoofUserAgentPatch::class,
|
||||||
|
PackageNamePatch::class,
|
||||||
|
FileProviderPatch::class
|
||||||
|
),
|
||||||
gmsCoreSupportResourcePatch = GmsCoreSupportResourcePatch,
|
gmsCoreSupportResourcePatch = GmsCoreSupportResourcePatch,
|
||||||
compatiblePackages = COMPATIBLE_PACKAGE
|
compatiblePackages = COMPATIBLE_PACKAGE
|
||||||
)
|
)
|
||||||
|
@ -13,6 +13,7 @@ object PlayerTypeHookPatch : BytecodePatch(
|
|||||||
) {
|
) {
|
||||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
||||||
"$UTILS_PATH/PlayerTypeHookPatch;"
|
"$UTILS_PATH/PlayerTypeHookPatch;"
|
||||||
|
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
|
|
||||||
PlayerTypeFingerprint.resultOrThrow().let {
|
PlayerTypeFingerprint.resultOrThrow().let {
|
||||||
|
@ -55,9 +55,11 @@ object ReturnYouTubeDislikeBytecodePatch : BytecodePatch(
|
|||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val insertIndex = indexOfFirstInstruction {
|
val insertIndex = indexOfFirstInstruction {
|
||||||
opcode == Opcode.INVOKE_STATIC
|
opcode == Opcode.INVOKE_STATIC
|
||||||
&& (this as ReferenceInstruction).reference.toString().endsWith("Ljava/lang/CharSequence;")
|
&& (this as ReferenceInstruction).reference.toString()
|
||||||
|
.endsWith("Ljava/lang/CharSequence;")
|
||||||
} + 2
|
} + 2
|
||||||
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex - 1).registerA
|
val insertRegister =
|
||||||
|
getInstruction<OneRegisterInstruction>(insertIndex - 1).registerA
|
||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
insertIndex, """
|
insertIndex, """
|
||||||
|
@ -39,7 +39,10 @@ object ResourceUtils {
|
|||||||
private fun ResourceContext.replacePackageName() {
|
private fun ResourceContext.replacePackageName() {
|
||||||
this[SETTINGS_HEADER_PATH].writeText(
|
this[SETTINGS_HEADER_PATH].writeText(
|
||||||
this[SETTINGS_HEADER_PATH].readText()
|
this[SETTINGS_HEADER_PATH].readText()
|
||||||
.replace("\"com.google.android.apps.youtube.music\"", "\"" + musicPackageName + "\"")
|
.replace(
|
||||||
|
"\"com.google.android.apps.youtube.music\"",
|
||||||
|
"\"" + musicPackageName + "\""
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,7 +68,10 @@ object ResourceUtils {
|
|||||||
.forEach {
|
.forEach {
|
||||||
if (!isIncludedCategory(category)) {
|
if (!isIncludedCategory(category)) {
|
||||||
it.adoptChild(PREFERENCE_SCREEN_TAG_NAME) {
|
it.adoptChild(PREFERENCE_SCREEN_TAG_NAME) {
|
||||||
setAttribute("android:title", "@string/revanced_preference_screen_$category" + "_title")
|
setAttribute(
|
||||||
|
"android:title",
|
||||||
|
"@string/revanced_preference_screen_$category" + "_title"
|
||||||
|
)
|
||||||
setAttribute("android:key", "revanced_preference_screen_$category")
|
setAttribute("android:key", "revanced_preference_screen_$category")
|
||||||
}
|
}
|
||||||
setPreferenceCategory(category)
|
setPreferenceCategory(category)
|
||||||
@ -117,7 +123,9 @@ object ResourceUtils {
|
|||||||
this.xmlEditor[SETTINGS_HEADER_PATH].use { editor ->
|
this.xmlEditor[SETTINGS_HEADER_PATH].use { editor ->
|
||||||
val tags = editor.file.getElementsByTagName(PREFERENCE_SCREEN_TAG_NAME)
|
val tags = editor.file.getElementsByTagName(PREFERENCE_SCREEN_TAG_NAME)
|
||||||
List(tags.length) { tags.item(it) as Element }
|
List(tags.length) { tags.item(it) as Element }
|
||||||
.filter { it.getAttribute("android:key").contains("revanced_preference_screen_$category") }
|
.filter {
|
||||||
|
it.getAttribute("android:key").contains("revanced_preference_screen_$category")
|
||||||
|
}
|
||||||
.forEach {
|
.forEach {
|
||||||
it.adoptChild("Preference") {
|
it.adoptChild("Preference") {
|
||||||
setAttribute("android:title", "@string/$key" + "_title")
|
setAttribute("android:title", "@string/$key" + "_title")
|
||||||
@ -145,7 +153,9 @@ object ResourceUtils {
|
|||||||
this.xmlEditor[SETTINGS_HEADER_PATH].use { editor ->
|
this.xmlEditor[SETTINGS_HEADER_PATH].use { editor ->
|
||||||
val tags = editor.file.getElementsByTagName(PREFERENCE_SCREEN_TAG_NAME)
|
val tags = editor.file.getElementsByTagName(PREFERENCE_SCREEN_TAG_NAME)
|
||||||
List(tags.length) { tags.item(it) as Element }
|
List(tags.length) { tags.item(it) as Element }
|
||||||
.filter { it.getAttribute("android:key").contains("revanced_preference_screen_$category") }
|
.filter {
|
||||||
|
it.getAttribute("android:key").contains("revanced_preference_screen_$category")
|
||||||
|
}
|
||||||
.forEach {
|
.forEach {
|
||||||
it.adoptChild(SWITCH_PREFERENCE_TAG_NAME) {
|
it.adoptChild(SWITCH_PREFERENCE_TAG_NAME) {
|
||||||
setAttribute("android:title", "@string/$key" + "_title")
|
setAttribute("android:title", "@string/$key" + "_title")
|
||||||
@ -170,7 +180,9 @@ object ResourceUtils {
|
|||||||
this.xmlEditor[SETTINGS_HEADER_PATH].use { editor ->
|
this.xmlEditor[SETTINGS_HEADER_PATH].use { editor ->
|
||||||
val tags = editor.file.getElementsByTagName(PREFERENCE_SCREEN_TAG_NAME)
|
val tags = editor.file.getElementsByTagName(PREFERENCE_SCREEN_TAG_NAME)
|
||||||
List(tags.length) { tags.item(it) as Element }
|
List(tags.length) { tags.item(it) as Element }
|
||||||
.filter { it.getAttribute("android:key").contains("revanced_preference_screen_$category") }
|
.filter {
|
||||||
|
it.getAttribute("android:key").contains("revanced_preference_screen_$category")
|
||||||
|
}
|
||||||
.forEach {
|
.forEach {
|
||||||
it.adoptChild("Preference") {
|
it.adoptChild("Preference") {
|
||||||
setAttribute("android:title", "@string/$key" + "_title")
|
setAttribute("android:title", "@string/$key" + "_title")
|
||||||
|
@ -15,8 +15,8 @@ import app.revanced.patches.music.utils.mainactivity.MainActivityResolvePatch
|
|||||||
import app.revanced.patches.music.utils.settings.fingerprints.GoogleApiActivityFingerprint
|
import app.revanced.patches.music.utils.settings.fingerprints.GoogleApiActivityFingerprint
|
||||||
import app.revanced.patches.music.utils.settings.fingerprints.PreferenceFingerprint
|
import app.revanced.patches.music.utils.settings.fingerprints.PreferenceFingerprint
|
||||||
import app.revanced.patches.music.utils.settings.fingerprints.SettingsHeadersFragmentFingerprint
|
import app.revanced.patches.music.utils.settings.fingerprints.SettingsHeadersFragmentFingerprint
|
||||||
import app.revanced.patches.shared.integrations.Constants.INTEGRATIONS_UTILS_CLASS_DESCRIPTOR
|
|
||||||
import app.revanced.patches.shared.fingerprints.SharedSettingFingerprint
|
import app.revanced.patches.shared.fingerprints.SharedSettingFingerprint
|
||||||
|
import app.revanced.patches.shared.integrations.Constants.INTEGRATIONS_UTILS_CLASS_DESCRIPTOR
|
||||||
import app.revanced.util.getTargetIndex
|
import app.revanced.util.getTargetIndex
|
||||||
import app.revanced.util.resultOrThrow
|
import app.revanced.util.resultOrThrow
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
@ -109,9 +109,18 @@ object SettingsBytecodePatch : BytecodePatch(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MainActivityResolvePatch.injectOnCreateMethodCall(INTEGRATIONS_INITIALIZATION_CLASS_DESCRIPTOR, "setDeviceInformation")
|
MainActivityResolvePatch.injectOnCreateMethodCall(
|
||||||
MainActivityResolvePatch.injectOnCreateMethodCall(INTEGRATIONS_INITIALIZATION_CLASS_DESCRIPTOR, "onCreate")
|
INTEGRATIONS_INITIALIZATION_CLASS_DESCRIPTOR,
|
||||||
MainActivityResolvePatch.injectConstructorMethodCall(INTEGRATIONS_UTILS_CLASS_DESCRIPTOR, "setActivity")
|
"setDeviceInformation"
|
||||||
|
)
|
||||||
|
MainActivityResolvePatch.injectOnCreateMethodCall(
|
||||||
|
INTEGRATIONS_INITIALIZATION_CLASS_DESCRIPTOR,
|
||||||
|
"onCreate"
|
||||||
|
)
|
||||||
|
MainActivityResolvePatch.injectConstructorMethodCall(
|
||||||
|
INTEGRATIONS_UTILS_CLASS_DESCRIPTOR,
|
||||||
|
"setActivity"
|
||||||
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,7 +143,9 @@ object SponsorBlockPatch : BaseResourcePatch(
|
|||||||
context.xmlEditor[SETTINGS_HEADER_PATH].use { editor ->
|
context.xmlEditor[SETTINGS_HEADER_PATH].use { editor ->
|
||||||
val tags = editor.file.getElementsByTagName(PREFERENCE_SCREEN_TAG_NAME)
|
val tags = editor.file.getElementsByTagName(PREFERENCE_SCREEN_TAG_NAME)
|
||||||
List(tags.length) { tags.item(it) as Element }
|
List(tags.length) { tags.item(it) as Element }
|
||||||
.filter { it.getAttribute("android:key").contains("revanced_preference_screen_$category") }
|
.filter {
|
||||||
|
it.getAttribute("android:key").contains("revanced_preference_screen_$category")
|
||||||
|
}
|
||||||
.forEach {
|
.forEach {
|
||||||
it.adoptChild(SWITCH_PREFERENCE_TAG_NAME) {
|
it.adoptChild(SWITCH_PREFERENCE_TAG_NAME) {
|
||||||
setAttribute("android:title", "@string/revanced_$key")
|
setAttribute("android:title", "@string/revanced_$key")
|
||||||
@ -166,7 +168,9 @@ object SponsorBlockPatch : BaseResourcePatch(
|
|||||||
context.xmlEditor[SETTINGS_HEADER_PATH].use { editor ->
|
context.xmlEditor[SETTINGS_HEADER_PATH].use { editor ->
|
||||||
val tags = editor.file.getElementsByTagName(PREFERENCE_SCREEN_TAG_NAME)
|
val tags = editor.file.getElementsByTagName(PREFERENCE_SCREEN_TAG_NAME)
|
||||||
List(tags.length) { tags.item(it) as Element }
|
List(tags.length) { tags.item(it) as Element }
|
||||||
.filter { it.getAttribute("android:key").contains("revanced_preference_screen_$category") }
|
.filter {
|
||||||
|
it.getAttribute("android:key").contains("revanced_preference_screen_$category")
|
||||||
|
}
|
||||||
.forEach {
|
.forEach {
|
||||||
it.adoptChild("Preference") {
|
it.adoptChild("Preference") {
|
||||||
setAttribute("android:title", "@string/revanced_$key")
|
setAttribute("android:title", "@string/revanced_$key")
|
||||||
|
@ -65,7 +65,8 @@ object VideoInformationPatch : BytecodePatch(
|
|||||||
internal lateinit var playbackSpeedResult: MethodFingerprintResult
|
internal lateinit var playbackSpeedResult: MethodFingerprintResult
|
||||||
|
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
val videoInformationMutableClass = context.findClass(INTEGRATIONS_CLASS_DESCRIPTOR)!!.mutableClass
|
val videoInformationMutableClass =
|
||||||
|
context.findClass(INTEGRATIONS_CLASS_DESCRIPTOR)!!.mutableClass
|
||||||
|
|
||||||
VideoEndFingerprint.resultOrThrow().let {
|
VideoEndFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
@ -119,7 +120,8 @@ object VideoInformationPatch : BytecodePatch(
|
|||||||
* Set the video time method
|
* Set the video time method
|
||||||
*/
|
*/
|
||||||
PlayerControllerSetTimeReferenceFingerprint.resultOrThrow().let {
|
PlayerControllerSetTimeReferenceFingerprint.resultOrThrow().let {
|
||||||
videoTimeConstructorMethod = it.getWalkerMethod(context, it.scanResult.patternScanResult!!.startIndex)
|
videoTimeConstructorMethod =
|
||||||
|
it.getWalkerMethod(context, it.scanResult.patternScanResult!!.startIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -137,8 +139,12 @@ object VideoInformationPatch : BytecodePatch(
|
|||||||
VideoLengthFingerprint.resultOrThrow().let {
|
VideoLengthFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val invalidateIndex = getTargetIndexWithMethodReferenceNameReversed("invalidate")
|
val invalidateIndex = getTargetIndexWithMethodReferenceNameReversed("invalidate")
|
||||||
val rectangleIndex = getTargetIndexWithFieldReferenceTypeReversed(invalidateIndex + 1, "Landroid/graphics/Rect;")
|
val rectangleIndex = getTargetIndexWithFieldReferenceTypeReversed(
|
||||||
rectangleFieldName = (getInstruction<ReferenceInstruction>(rectangleIndex).reference as FieldReference).name
|
invalidateIndex + 1,
|
||||||
|
"Landroid/graphics/Rect;"
|
||||||
|
)
|
||||||
|
rectangleFieldName =
|
||||||
|
(getInstruction<ReferenceInstruction>(rectangleIndex).reference as FieldReference).name
|
||||||
|
|
||||||
val videoLengthRegisterIndex = it.scanResult.patternScanResult!!.startIndex + 1
|
val videoLengthRegisterIndex = it.scanResult.patternScanResult!!.startIndex + 1
|
||||||
val videoLengthRegister =
|
val videoLengthRegister =
|
||||||
|
@ -22,7 +22,8 @@ object VideoIdPatch : BytecodePatch(
|
|||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
videoIdMethod = this
|
videoIdMethod = this
|
||||||
videoIdInsertIndex = it.scanResult.patternScanResult!!.startIndex + 2
|
videoIdInsertIndex = it.scanResult.patternScanResult!!.startIndex + 2
|
||||||
videoIdRegister = getInstruction<OneRegisterInstruction>(videoIdInsertIndex - 1).registerA
|
videoIdRegister =
|
||||||
|
getInstruction<OneRegisterInstruction>(videoIdInsertIndex - 1).registerA
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,8 @@ abstract class BaseAutoCaptionsPatch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
SubtitleTrackFingerprint.resultOrThrow().let {
|
SubtitleTrackFingerprint.resultOrThrow().let {
|
||||||
val targetMethod = it.getWalkerMethod(context, it.scanResult.patternScanResult!!.startIndex + 1)
|
val targetMethod =
|
||||||
|
it.getWalkerMethod(context, it.scanResult.patternScanResult!!.startIndex + 1)
|
||||||
|
|
||||||
targetMethod.apply {
|
targetMethod.apply {
|
||||||
val targetIndex = indexOfFirstInstruction {
|
val targetIndex = indexOfFirstInstruction {
|
||||||
|
@ -52,7 +52,7 @@ abstract class BaseGmsCoreSupportPatch(
|
|||||||
) : BytecodePatch(
|
) : BytecodePatch(
|
||||||
name = "GmsCore support",
|
name = "GmsCore support",
|
||||||
description = "Allows patched Google apps to run without root and under a different package name " +
|
description = "Allows patched Google apps to run without root and under a different package name " +
|
||||||
"by using GmsCore instead of Google Play Services.",
|
"by using GmsCore instead of Google Play Services.",
|
||||||
dependencies = setOf(
|
dependencies = setOf(
|
||||||
PackageNamePatch::class,
|
PackageNamePatch::class,
|
||||||
gmsCoreSupportResourcePatch::class,
|
gmsCoreSupportResourcePatch::class,
|
||||||
@ -116,36 +116,43 @@ abstract class BaseGmsCoreSupportPatch(
|
|||||||
.replaceInstruction(0, "const-string v0, \"$gmsCoreVendorGroupId\"")
|
.replaceInstruction(0, "const-string v0, \"$gmsCoreVendorGroupId\"")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun BytecodeContext.transformStringReferences(transform: (str: String) -> String?) = classes.forEach {
|
private fun BytecodeContext.transformStringReferences(transform: (str: String) -> String?) =
|
||||||
val mutableClass by lazy {
|
classes.forEach {
|
||||||
proxy(it).mutableClass
|
val mutableClass by lazy {
|
||||||
}
|
proxy(it).mutableClass
|
||||||
|
|
||||||
it.methods.forEach classLoop@{ methodDef ->
|
|
||||||
val implementation = methodDef.implementation ?: return@classLoop
|
|
||||||
|
|
||||||
val mutableMethod by lazy {
|
|
||||||
mutableClass.methods.first { method -> MethodUtil.methodSignaturesMatch(method, methodDef) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
implementation.instructions.forEachIndexed insnLoop@{ index, instruction ->
|
it.methods.forEach classLoop@{ methodDef ->
|
||||||
val string = ((instruction as? Instruction21c)?.reference as? StringReference)?.string
|
val implementation = methodDef.implementation ?: return@classLoop
|
||||||
?: return@insnLoop
|
|
||||||
|
|
||||||
// Apply transformation.
|
val mutableMethod by lazy {
|
||||||
val transformedString = transform(string) ?: return@insnLoop
|
mutableClass.methods.first { method ->
|
||||||
|
MethodUtil.methodSignaturesMatch(
|
||||||
|
method,
|
||||||
|
methodDef
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mutableMethod.replaceInstruction(
|
implementation.instructions.forEachIndexed insnLoop@{ index, instruction ->
|
||||||
index,
|
val string =
|
||||||
BuilderInstruction21c(
|
((instruction as? Instruction21c)?.reference as? StringReference)?.string
|
||||||
Opcode.CONST_STRING,
|
?: return@insnLoop
|
||||||
instruction.registerA,
|
|
||||||
ImmutableStringReference(transformedString),
|
// Apply transformation.
|
||||||
),
|
val transformedString = transform(string) ?: return@insnLoop
|
||||||
)
|
|
||||||
|
mutableMethod.replaceInstruction(
|
||||||
|
index,
|
||||||
|
BuilderInstruction21c(
|
||||||
|
Opcode.CONST_STRING,
|
||||||
|
instruction.registerA,
|
||||||
|
ImmutableStringReference(transformedString),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// region Collection of transformations that are applied to all strings.
|
// region Collection of transformations that are applied to all strings.
|
||||||
|
|
||||||
@ -180,14 +187,20 @@ abstract class BaseGmsCoreSupportPatch(
|
|||||||
// gms also has a 'subscribedfeeds' authority, check for that one too
|
// gms also has a 'subscribedfeeds' authority, check for that one too
|
||||||
val subFeedsUriPrefix = "content://subscribedfeeds"
|
val subFeedsUriPrefix = "content://subscribedfeeds"
|
||||||
if (str.startsWith(subFeedsUriPrefix)) {
|
if (str.startsWith(subFeedsUriPrefix)) {
|
||||||
return str.replace(subFeedsUriPrefix, "content://$gmsCoreVendorGroupId.subscribedfeeds")
|
return str.replace(
|
||||||
|
subFeedsUriPrefix,
|
||||||
|
"content://$gmsCoreVendorGroupId.subscribedfeeds"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun packageNameTransform(fromPackageName: String, toPackageName: String): (String) -> String? = { string ->
|
private fun packageNameTransform(
|
||||||
|
fromPackageName: String,
|
||||||
|
toPackageName: String
|
||||||
|
): (String) -> String? = { string ->
|
||||||
when (string) {
|
when (string) {
|
||||||
"$fromPackageName.SuggestionsProvider",
|
"$fromPackageName.SuggestionsProvider",
|
||||||
"$fromPackageName.fileprovider",
|
"$fromPackageName.fileprovider",
|
||||||
|
@ -53,12 +53,18 @@ abstract class BaseGmsCoreSupportResourcePatch(
|
|||||||
|
|
||||||
// Spoof package name and signature.
|
// Spoof package name and signature.
|
||||||
applicationNode.adoptChild("meta-data") {
|
applicationNode.adoptChild("meta-data") {
|
||||||
setAttribute("android:name", "$gmsCoreVendorGroupId.android.gms.SPOOFED_PACKAGE_NAME")
|
setAttribute(
|
||||||
|
"android:name",
|
||||||
|
"$gmsCoreVendorGroupId.android.gms.SPOOFED_PACKAGE_NAME"
|
||||||
|
)
|
||||||
setAttribute("android:value", fromPackageName)
|
setAttribute("android:value", fromPackageName)
|
||||||
}
|
}
|
||||||
|
|
||||||
applicationNode.adoptChild("meta-data") {
|
applicationNode.adoptChild("meta-data") {
|
||||||
setAttribute("android:name", "$gmsCoreVendorGroupId.android.gms.SPOOFED_PACKAGE_SIGNATURE")
|
setAttribute(
|
||||||
|
"android:name",
|
||||||
|
"$gmsCoreVendorGroupId.android.gms.SPOOFED_PACKAGE_SIGNATURE"
|
||||||
|
)
|
||||||
setAttribute("android:value", spoofedPackageSignature)
|
setAttribute("android:value", spoofedPackageSignature)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +113,8 @@ object LithoFilterPatch : BytecodePatch(
|
|||||||
if ((instruction as? ReferenceInstruction)?.reference.toString() != pathBuilderMethodCall)
|
if ((instruction as? ReferenceInstruction)?.reference.toString() != pathBuilderMethodCall)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
val insertRegister = getInstruction<OneRegisterInstruction>(index + 1).registerA
|
val insertRegister =
|
||||||
|
getInstruction<OneRegisterInstruction>(index + 1).registerA
|
||||||
val insertIndex = index + 2
|
val insertIndex = index + 2
|
||||||
|
|
||||||
addInstructionsWithLabels(
|
addInstructionsWithLabels(
|
||||||
@ -134,13 +135,16 @@ object LithoFilterPatch : BytecodePatch(
|
|||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
|
|
||||||
val stringBuilderIndex = getTargetIndexWithFieldReferenceType("Ljava/lang/StringBuilder;")
|
val stringBuilderIndex =
|
||||||
val stringBuilderRegister = getInstruction<TwoRegisterInstruction>(stringBuilderIndex).registerA
|
getTargetIndexWithFieldReferenceType("Ljava/lang/StringBuilder;")
|
||||||
|
val stringBuilderRegister =
|
||||||
|
getInstruction<TwoRegisterInstruction>(stringBuilderIndex).registerA
|
||||||
|
|
||||||
val emptyStringIndex = getEmptyStringInstructionIndex()
|
val emptyStringIndex = getEmptyStringInstructionIndex()
|
||||||
|
|
||||||
val identifierIndex = getTargetIndexReversed(emptyStringIndex, Opcode.IPUT_OBJECT)
|
val identifierIndex = getTargetIndexReversed(emptyStringIndex, Opcode.IPUT_OBJECT)
|
||||||
val identifierRegister = getInstruction<TwoRegisterInstruction>(identifierIndex).registerA
|
val identifierRegister =
|
||||||
|
getInstruction<TwoRegisterInstruction>(identifierIndex).registerA
|
||||||
|
|
||||||
val objectIndex = getTargetIndex(emptyStringIndex, Opcode.INVOKE_VIRTUAL)
|
val objectIndex = getTargetIndex(emptyStringIndex, Opcode.INVOKE_VIRTUAL)
|
||||||
val objectRegister = getInstruction<BuilderInstruction35c>(objectIndex).registerC
|
val objectRegister = getInstruction<BuilderInstruction35c>(objectIndex).registerC
|
||||||
|
@ -14,7 +14,7 @@ import kotlin.properties.Delegates
|
|||||||
|
|
||||||
abstract class BaseMainActivityResolvePatch(
|
abstract class BaseMainActivityResolvePatch(
|
||||||
private val mainActivityOnCreateFingerprint: MethodFingerprint
|
private val mainActivityOnCreateFingerprint: MethodFingerprint
|
||||||
): BytecodePatch(
|
) : BytecodePatch(
|
||||||
setOf(mainActivityOnCreateFingerprint)
|
setOf(mainActivityOnCreateFingerprint)
|
||||||
) {
|
) {
|
||||||
lateinit var mainActivityMutableClass: MutableClass
|
lateinit var mainActivityMutableClass: MutableClass
|
||||||
@ -41,10 +41,18 @@ abstract class BaseMainActivityResolvePatch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun injectConstructorMethodCall(classDescriptor: String, methodDescriptor: String) =
|
fun injectConstructorMethodCall(classDescriptor: String, methodDescriptor: String) =
|
||||||
constructorMethod.injectMethodCall(classDescriptor, methodDescriptor, constructorMethodIndex)
|
constructorMethod.injectMethodCall(
|
||||||
|
classDescriptor,
|
||||||
|
methodDescriptor,
|
||||||
|
constructorMethodIndex
|
||||||
|
)
|
||||||
|
|
||||||
fun injectOnBackPressedMethodCall(classDescriptor: String, methodDescriptor: String) =
|
fun injectOnBackPressedMethodCall(classDescriptor: String, methodDescriptor: String) =
|
||||||
onBackPressedMethod.injectMethodCall(classDescriptor, methodDescriptor, onBackPressedMethodIndex)
|
onBackPressedMethod.injectMethodCall(
|
||||||
|
classDescriptor,
|
||||||
|
methodDescriptor,
|
||||||
|
onBackPressedMethodIndex
|
||||||
|
)
|
||||||
|
|
||||||
fun injectOnCreateMethodCall(classDescriptor: String, methodDescriptor: String) =
|
fun injectOnCreateMethodCall(classDescriptor: String, methodDescriptor: String) =
|
||||||
onCreateMethod.injectMethodCall(classDescriptor, methodDescriptor)
|
onCreateMethod.injectMethodCall(classDescriptor, methodDescriptor)
|
||||||
|
@ -13,8 +13,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
|||||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.reference.Reference
|
import com.android.tools.smali.dexlib2.iface.reference.Reference
|
||||||
|
|
||||||
@Deprecated("This patch is generally not required for the latest versions of YouTube and YouTube Music." +
|
@Deprecated(
|
||||||
"For YouTube Music, if user spoofs the app version to v4.27.53, mp4a codec is still used, this is the patch for some of these users.")
|
"This patch is generally not required for the latest versions of YouTube and YouTube Music." +
|
||||||
|
"For YouTube Music, if user spoofs the app version to v4.27.53, mp4a codec is still used, this is the patch for some of these users."
|
||||||
|
)
|
||||||
abstract class BaseOpusCodecsPatch(
|
abstract class BaseOpusCodecsPatch(
|
||||||
private val descriptor: String
|
private val descriptor: String
|
||||||
) : BytecodePatch(
|
) : BytecodePatch(
|
||||||
|
@ -20,10 +20,14 @@ object OverlayBackgroundUtils {
|
|||||||
arrayOf("height", "width").forEach replacement@{ replacement ->
|
arrayOf("height", "width").forEach replacement@{ replacement ->
|
||||||
if (it !is Element) return@replacement
|
if (it !is Element) return@replacement
|
||||||
|
|
||||||
if (it.attributes.getNamedItem("android:id")?.nodeValue?.endsWith(identifier) == true) {
|
if (it.attributes.getNamedItem("android:id")?.nodeValue?.endsWith(
|
||||||
it.getAttributeNode("android:layout_$replacement")?.let { attribute ->
|
identifier
|
||||||
attribute.textContent = "0.0dip"
|
) == true
|
||||||
}
|
) {
|
||||||
|
it.getAttributeNode("android:layout_$replacement")
|
||||||
|
?.let { attribute ->
|
||||||
|
attribute.textContent = "0.0dip"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,8 @@ abstract class BaseSpoofUserAgentPatch(
|
|||||||
|
|
||||||
// IndexOutOfBoundsException is not possible here,
|
// IndexOutOfBoundsException is not possible here,
|
||||||
// but no such occurrences are present in the app.
|
// but no such occurrences are present in the app.
|
||||||
val referee = getInstruction(instructionIndex + 2).getReference<MethodReference>()?.toString()
|
val referee =
|
||||||
|
getInstruction(instructionIndex + 2).getReference<MethodReference>()?.toString()
|
||||||
|
|
||||||
// This can technically also match non-user agent string builder append methods,
|
// This can technically also match non-user agent string builder append methods,
|
||||||
// but no such occurrences are present in the app.
|
// but no such occurrences are present in the app.
|
||||||
|
@ -21,9 +21,10 @@ abstract class BaseTransformInstructionsPatch<T> : BytecodePatch(emptySet()) {
|
|||||||
|
|
||||||
// Returns the patch indices as a Sequence, which will execute lazily.
|
// Returns the patch indices as a Sequence, which will execute lazily.
|
||||||
fun findPatchIndices(classDef: ClassDef, method: Method): Sequence<T>? {
|
fun findPatchIndices(classDef: ClassDef, method: Method): Sequence<T>? {
|
||||||
return method.implementation?.instructions?.asSequence()?.withIndex()?.mapNotNull { (index, instruction) ->
|
return method.implementation?.instructions?.asSequence()?.withIndex()
|
||||||
filterMap(classDef, method, instruction, index)
|
?.mapNotNull { (index, instruction) ->
|
||||||
}
|
filterMap(classDef, method, instruction, index)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
@ -48,8 +49,9 @@ abstract class BaseTransformInstructionsPatch<T> : BytecodePatch(emptySet()) {
|
|||||||
val mutableClass = context.proxy(classDef).mutableClass
|
val mutableClass = context.proxy(classDef).mutableClass
|
||||||
|
|
||||||
methods.map(mutableClass::findMutableMethodOf).forEach methods@{ mutableMethod ->
|
methods.map(mutableClass::findMutableMethodOf).forEach methods@{ mutableMethod ->
|
||||||
val patchIndices = findPatchIndices(mutableClass, mutableMethod)?.toCollection(ArrayDeque())
|
val patchIndices =
|
||||||
?: return@methods
|
findPatchIndices(mutableClass, mutableMethod)?.toCollection(ArrayDeque())
|
||||||
|
?: return@methods
|
||||||
|
|
||||||
while (!patchIndices.isEmpty()) transform(mutableMethod, patchIndices.removeLast())
|
while (!patchIndices.isEmpty()) transform(mutableMethod, patchIndices.removeLast())
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,10 @@ object TranslationsUtils {
|
|||||||
this["res/$directory"].mkdir()
|
this["res/$directory"].mkdir()
|
||||||
|
|
||||||
Files.copy(
|
Files.copy(
|
||||||
inputStreamFromBundledResource("$sourceDirectory/translations", "$language/strings.xml")!!,
|
inputStreamFromBundledResource(
|
||||||
|
"$sourceDirectory/translations",
|
||||||
|
"$language/strings.xml"
|
||||||
|
)!!,
|
||||||
this["res"].resolve("$directory/strings.xml").toPath(),
|
this["res"].resolve("$directory/strings.xml").toPath(),
|
||||||
StandardCopyOption.REPLACE_EXISTING
|
StandardCopyOption.REPLACE_EXISTING
|
||||||
)
|
)
|
||||||
|
@ -5,6 +5,6 @@ import app.revanced.util.fingerprint.LiteralValueFingerprint
|
|||||||
|
|
||||||
internal object InterstitialsContainerFingerprint : LiteralValueFingerprint(
|
internal object InterstitialsContainerFingerprint : LiteralValueFingerprint(
|
||||||
returnType = "V",
|
returnType = "V",
|
||||||
strings= listOf("overlay_controller_param"),
|
strings = listOf("overlay_controller_param"),
|
||||||
literalSupplier = { InterstitialsContainer }
|
literalSupplier = { InterstitialsContainer }
|
||||||
)
|
)
|
@ -102,7 +102,9 @@ object AlternativeThumbnailsPatch : BaseBytecodePatch(
|
|||||||
block: (MutableMethod) -> Unit
|
block: (MutableMethod) -> Unit
|
||||||
) = alsoResolve(fingerprint).also { block(it.mutableMethod) }
|
) = alsoResolve(fingerprint).also { block(it.mutableMethod) }
|
||||||
|
|
||||||
MessageDigestImageUrlFingerprint.resolveAndLetMutableMethod(MessageDigestImageUrlParentFingerprint) {
|
MessageDigestImageUrlFingerprint.resolveAndLetMutableMethod(
|
||||||
|
MessageDigestImageUrlParentFingerprint
|
||||||
|
) {
|
||||||
loadImageUrlMethod = it
|
loadImageUrlMethod = it
|
||||||
addImageUrlHook(ALTERNATIVE_THUMBNAILS_CLASS_DESCRIPTOR, true)
|
addImageUrlHook(ALTERNATIVE_THUMBNAILS_CLASS_DESCRIPTOR, true)
|
||||||
}
|
}
|
||||||
|
@ -6,5 +6,5 @@ import com.android.tools.smali.dexlib2.AccessFlags
|
|||||||
|
|
||||||
internal object MessageDigestImageUrlFingerprint : MethodFingerprint(
|
internal object MessageDigestImageUrlFingerprint : MethodFingerprint(
|
||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
||||||
parameters = listOf("Ljava/lang/String;", "L")
|
parameters = listOf("Ljava/lang/String;", "L")
|
||||||
)
|
)
|
@ -6,7 +6,7 @@ import com.android.tools.smali.dexlib2.AccessFlags
|
|||||||
|
|
||||||
internal object MessageDigestImageUrlParentFingerprint : MethodFingerprint(
|
internal object MessageDigestImageUrlParentFingerprint : MethodFingerprint(
|
||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
returnType = "Ljava/lang/String;",
|
returnType = "Ljava/lang/String;",
|
||||||
parameters = emptyList(),
|
parameters = emptyList(),
|
||||||
strings = listOf("@#&=*+-_.,:!?()/~'%;\$"),
|
strings = listOf("@#&=*+-_.,:!?()/~'%;\$"),
|
||||||
)
|
)
|
@ -7,7 +7,7 @@ import com.android.tools.smali.dexlib2.AccessFlags
|
|||||||
internal object OnFailureFingerprint : MethodFingerprint(
|
internal object OnFailureFingerprint : MethodFingerprint(
|
||||||
returnType = "V",
|
returnType = "V",
|
||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
parameters = listOf(
|
parameters = listOf(
|
||||||
"Lorg/chromium/net/UrlRequest;",
|
"Lorg/chromium/net/UrlRequest;",
|
||||||
"Lorg/chromium/net/UrlResponseInfo;",
|
"Lorg/chromium/net/UrlResponseInfo;",
|
||||||
"Lorg/chromium/net/CronetException;"
|
"Lorg/chromium/net/CronetException;"
|
||||||
|
@ -8,7 +8,7 @@ import com.android.tools.smali.dexlib2.AccessFlags
|
|||||||
internal object OnResponseStartedFingerprint : MethodFingerprint(
|
internal object OnResponseStartedFingerprint : MethodFingerprint(
|
||||||
returnType = "V",
|
returnType = "V",
|
||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
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(
|
strings = listOf(
|
||||||
"Content-Length",
|
"Content-Length",
|
||||||
"Content-Type",
|
"Content-Type",
|
||||||
|
@ -7,7 +7,7 @@ import com.android.tools.smali.dexlib2.AccessFlags
|
|||||||
internal object OnSucceededFingerprint : MethodFingerprint(
|
internal object OnSucceededFingerprint : MethodFingerprint(
|
||||||
returnType = "V",
|
returnType = "V",
|
||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
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, _ ->
|
customFingerprint = { methodDef, _ ->
|
||||||
methodDef.name == "onSucceeded"
|
methodDef.name == "onSucceeded"
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,8 @@ object FeedComponentsPatch : BaseBytecodePatch(
|
|||||||
fingerprint.resultOrThrow().let {
|
fingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val targetIndex = it.scanResult.patternScanResult!!.endIndex
|
val targetIndex = it.scanResult.patternScanResult!!.endIndex
|
||||||
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
val targetRegister =
|
||||||
|
getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||||
|
|
||||||
addInstruction(
|
addInstruction(
|
||||||
targetIndex + 1,
|
targetIndex + 1,
|
||||||
@ -131,7 +132,7 @@ object FeedComponentsPatch : BaseBytecodePatch(
|
|||||||
|
|
||||||
addInstruction(
|
addInstruction(
|
||||||
targetIndex + 1,
|
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 {
|
ChannelTabRendererFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val iteratorIndex = getTargetIndexWithMethodReferenceName("hasNext")
|
val iteratorIndex = getTargetIndexWithMethodReferenceName("hasNext")
|
||||||
val iteratorRegister = getInstruction<FiveRegisterInstruction>(iteratorIndex).registerC
|
val iteratorRegister =
|
||||||
|
getInstruction<FiveRegisterInstruction>(iteratorIndex).registerC
|
||||||
|
|
||||||
val targetIndex = indexOfFirstInstruction {
|
val targetIndex = indexOfFirstInstruction {
|
||||||
val reference = ((this as? ReferenceInstruction)?.reference as? MethodReference)
|
val reference = ((this as? ReferenceInstruction)?.reference as? MethodReference)
|
||||||
|
@ -32,11 +32,17 @@ object AudioTracksPatch : BaseBytecodePatch(
|
|||||||
opcode == Opcode.CHECK_CAST
|
opcode == Opcode.CHECK_CAST
|
||||||
&& (this as ReferenceInstruction).reference.toString() == "Lcom/google/android/libraries/youtube/innertube/model/media/FormatStreamModel;"
|
&& (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 arrayListIndex = getTargetIndexWithReference(
|
||||||
val insertIndex = getTargetIndexWithReference(arrayListIndex, "Ljava/util/List;->isEmpty()Z") + 2
|
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 formatStreamModelRegister =
|
||||||
val arrayListRegister = getInstruction<FiveRegisterInstruction>(arrayListIndex).registerC
|
getInstruction<OneRegisterInstruction>(formatStreamModelIndex).registerA
|
||||||
|
val arrayListRegister =
|
||||||
|
getInstruction<FiveRegisterInstruction>(arrayListIndex).registerC
|
||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
insertIndex, """
|
insertIndex, """
|
||||||
@ -47,7 +53,7 @@ object AudioTracksPatch : BaseBytecodePatch(
|
|||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
formatStreamModelIndex + 1,
|
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"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -174,8 +174,10 @@ object LayoutComponentsPatch : BaseBytecodePatch(
|
|||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val constIndex = getWideLiteralInstructionIndex(AccountSwitcherAccessibility)
|
val constIndex = getWideLiteralInstructionIndex(AccountSwitcherAccessibility)
|
||||||
val insertIndex = getTargetIndex(constIndex, Opcode.IF_EQZ)
|
val insertIndex = getTargetIndex(constIndex, Opcode.IF_EQZ)
|
||||||
val setVisibilityIndex = getTargetIndexWithMethodReferenceName(insertIndex, "setVisibility")
|
val setVisibilityIndex =
|
||||||
val visibilityRegister = getInstruction<FiveRegisterInstruction>(setVisibilityIndex).registerD
|
getTargetIndexWithMethodReferenceName(insertIndex, "setVisibility")
|
||||||
|
val visibilityRegister =
|
||||||
|
getInstruction<FiveRegisterInstruction>(setVisibilityIndex).registerD
|
||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
insertIndex, """
|
insertIndex, """
|
||||||
@ -192,7 +194,8 @@ object LayoutComponentsPatch : BaseBytecodePatch(
|
|||||||
|
|
||||||
SettingsMenuFingerprint.resultOrThrow().let {
|
SettingsMenuFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
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
|
val insertRegister = getInstruction<TwoRegisterInstruction>(insertIndex).registerA
|
||||||
|
|
||||||
addInstruction(
|
addInstruction(
|
||||||
|
@ -29,7 +29,10 @@ object GradientLoadingScreenPatch : BaseBytecodePatch(
|
|||||||
GradientLoadingScreenPrimaryFingerprint to 45412406,
|
GradientLoadingScreenPrimaryFingerprint to 45412406,
|
||||||
GradientLoadingScreenSecondaryFingerprint to 45418917
|
GradientLoadingScreenSecondaryFingerprint to 45418917
|
||||||
).forEach { (fingerprint, literal) ->
|
).forEach { (fingerprint, literal) ->
|
||||||
fingerprint.literalInstructionBooleanHook(literal, "$GENERAL_CLASS_DESCRIPTOR->enableGradientLoadingScreen()Z")
|
fingerprint.literalInstructionBooleanHook(
|
||||||
|
literal,
|
||||||
|
"$GENERAL_CLASS_DESCRIPTOR->enableGradientLoadingScreen()Z"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -8,7 +8,11 @@ import com.android.tools.smali.dexlib2.Opcode
|
|||||||
internal object PivotBarSetTextFingerprint : MethodFingerprint(
|
internal object PivotBarSetTextFingerprint : MethodFingerprint(
|
||||||
returnType = "V",
|
returnType = "V",
|
||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
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(
|
opcodes = listOf(
|
||||||
Opcode.INVOKE_VIRTUAL,
|
Opcode.INVOKE_VIRTUAL,
|
||||||
Opcode.RETURN_VOID
|
Opcode.RETURN_VOID
|
||||||
|
@ -32,10 +32,14 @@ object SplashAnimationPatch : BaseBytecodePatch(
|
|||||||
) {
|
) {
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
|
|
||||||
StartUpResourceIdFingerprint.resolve(context, StartUpResourceIdParentFingerprint.resultOrThrow().classDef)
|
StartUpResourceIdFingerprint.resolve(
|
||||||
|
context,
|
||||||
|
StartUpResourceIdParentFingerprint.resultOrThrow().classDef
|
||||||
|
)
|
||||||
|
|
||||||
val startUpResourceIdMethod = StartUpResourceIdFingerprint.resultOrThrow().mutableMethod
|
val startUpResourceIdMethod = StartUpResourceIdFingerprint.resultOrThrow().mutableMethod
|
||||||
val startUpResourceIdMethodCall = startUpResourceIdMethod.definingClass + "->" + startUpResourceIdMethod.name + "(I)Z"
|
val startUpResourceIdMethodCall =
|
||||||
|
startUpResourceIdMethod.definingClass + "->" + startUpResourceIdMethod.name + "(I)Z"
|
||||||
|
|
||||||
SplashAnimationFingerprint.resultOrThrow().let {
|
SplashAnimationFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
|
@ -118,7 +118,8 @@ object TabletMiniPlayerPatch : BaseBytecodePatch(
|
|||||||
} else {
|
} else {
|
||||||
MiniPlayerOverrideFingerprint.resultOrThrow().let {
|
MiniPlayerOverrideFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val walkerMethod = getWalkerMethod(context, getStringInstructionIndex("appName") + 2)
|
val walkerMethod =
|
||||||
|
getWalkerMethod(context, getStringInstructionIndex("appName") + 2)
|
||||||
|
|
||||||
walkerMethod.apply {
|
walkerMethod.apply {
|
||||||
hook(getTargetIndex(Opcode.RETURN))
|
hook(getTargetIndex(Opcode.RETURN))
|
||||||
|
@ -45,7 +45,6 @@ import app.revanced.util.getTargetIndexWithReference
|
|||||||
import app.revanced.util.getTargetIndexWithReferenceReversed
|
import app.revanced.util.getTargetIndexWithReferenceReversed
|
||||||
import app.revanced.util.getWalkerMethod
|
import app.revanced.util.getWalkerMethod
|
||||||
import app.revanced.util.getWideLiteralInstructionIndex
|
import app.revanced.util.getWideLiteralInstructionIndex
|
||||||
import app.revanced.util.literalInstructionBooleanHook
|
|
||||||
import app.revanced.util.literalInstructionHook
|
import app.revanced.util.literalInstructionHook
|
||||||
import app.revanced.util.patch.BaseBytecodePatch
|
import app.revanced.util.patch.BaseBytecodePatch
|
||||||
import app.revanced.util.resultOrThrow
|
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.
|
// YouTube's headers have the form of AttributeSet, which is decoded from YouTube's built-in classes.
|
||||||
val attributeResolverMethod = AttributeResolverFingerprint.resultOrThrow().mutableMethod
|
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 ->
|
context.findClass(GENERAL_CLASS_DESCRIPTOR)!!.mutableClass.methods.single { method ->
|
||||||
method.name == "getHeaderDrawable"
|
method.name == "getHeaderDrawable"
|
||||||
@ -139,9 +139,10 @@ object ToolBarComponentsPatch : BaseBytecodePatch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Override the header in the search bar.
|
// Override the header in the search bar.
|
||||||
val setActionBarRingoMutableClass = SetActionBarRingoFingerprint.resultOrThrow().mutableClass
|
val setActionBarRingoMutableClass =
|
||||||
setActionBarRingoMutableClass.methods.first {
|
SetActionBarRingoFingerprint.resultOrThrow().mutableClass
|
||||||
method -> MethodUtil.isConstructor(method)
|
setActionBarRingoMutableClass.methods.first { method ->
|
||||||
|
MethodUtil.isConstructor(method)
|
||||||
}.apply {
|
}.apply {
|
||||||
val insertIndex = getTargetIndex(Opcode.IPUT_BOOLEAN)
|
val insertIndex = getTargetIndex(Opcode.IPUT_BOOLEAN)
|
||||||
val insertRegister = getInstruction<TwoRegisterInstruction>(insertIndex).registerA
|
val insertRegister = getInstruction<TwoRegisterInstruction>(insertIndex).registerA
|
||||||
@ -190,7 +191,8 @@ object ToolBarComponentsPatch : BaseBytecodePatch(
|
|||||||
.apply {
|
.apply {
|
||||||
val staticCalls = implementation!!.instructions.withIndex()
|
val staticCalls = implementation!!.instructions.withIndex()
|
||||||
.filter { instruction ->
|
.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?.parameterTypes?.size == 1 &&
|
||||||
methodReference.returnType == "Z"
|
methodReference.returnType == "Z"
|
||||||
}
|
}
|
||||||
@ -321,13 +323,18 @@ object ToolBarComponentsPatch : BaseBytecodePatch(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
SearchBarFingerprint.resolve(context, SearchBarParentFingerprint.resultOrThrow().classDef)
|
SearchBarFingerprint.resolve(
|
||||||
|
context,
|
||||||
|
SearchBarParentFingerprint.resultOrThrow().classDef
|
||||||
|
)
|
||||||
|
|
||||||
SearchBarFingerprint.resultOrThrow().let {
|
SearchBarFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val startIndex = it.scanResult.patternScanResult!!.startIndex
|
val startIndex = it.scanResult.patternScanResult!!.startIndex
|
||||||
val setVisibilityIndex = getTargetIndexWithMethodReferenceName(startIndex, "setVisibility")
|
val setVisibilityIndex =
|
||||||
val setVisibilityInstruction = getInstruction<FiveRegisterInstruction>(setVisibilityIndex)
|
getTargetIndexWithMethodReferenceName(startIndex, "setVisibility")
|
||||||
|
val setVisibilityInstruction =
|
||||||
|
getInstruction<FiveRegisterInstruction>(setVisibilityIndex)
|
||||||
|
|
||||||
replaceInstruction(
|
replaceInstruction(
|
||||||
setVisibilityIndex,
|
setVisibilityIndex,
|
||||||
@ -340,8 +347,10 @@ object ToolBarComponentsPatch : BaseBytecodePatch(
|
|||||||
SearchResultFingerprint.resultOrThrow().let {
|
SearchResultFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val startIndex = getWideLiteralInstructionIndex(VoiceSearch)
|
val startIndex = getWideLiteralInstructionIndex(VoiceSearch)
|
||||||
val setOnClickListenerIndex = getTargetIndexWithMethodReferenceName(startIndex, "setOnClickListener")
|
val setOnClickListenerIndex =
|
||||||
val viewRegister = getInstruction<FiveRegisterInstruction>(setOnClickListenerIndex).registerC
|
getTargetIndexWithMethodReferenceName(startIndex, "setOnClickListener")
|
||||||
|
val viewRegister =
|
||||||
|
getInstruction<FiveRegisterInstruction>(setOnClickListenerIndex).registerC
|
||||||
|
|
||||||
addInstruction(
|
addInstruction(
|
||||||
setOnClickListenerIndex + 1,
|
setOnClickListenerIndex + 1,
|
||||||
|
@ -78,7 +78,7 @@ object CustomBrandingIconPatch : BaseResourcePatch(
|
|||||||
|
|
||||||
override fun execute(context: ResourceContext) {
|
override fun execute(context: ResourceContext) {
|
||||||
AppIcon?.let { appIcon ->
|
AppIcon?.let { appIcon ->
|
||||||
val appIconValue = appIcon.lowercase().replace(" ","_")
|
val appIconValue = appIcon.lowercase().replace(" ", "_")
|
||||||
if (!availableIcon.containsValue(appIconValue)) {
|
if (!availableIcon.containsValue(appIconValue)) {
|
||||||
mipmapDirectories.map { directory ->
|
mipmapDirectories.map { directory ->
|
||||||
ResourceGroup(
|
ResourceGroup(
|
||||||
|
@ -80,7 +80,8 @@ object MinimizedPlaybackPatch : BaseBytecodePatch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
PiPControllerFingerprint.resultOrThrow().let {
|
PiPControllerFingerprint.resultOrThrow().let {
|
||||||
val targetMethod = it.getWalkerMethod(context, it.scanResult.patternScanResult!!.endIndex)
|
val targetMethod =
|
||||||
|
it.getWalkerMethod(context, it.scanResult.patternScanResult!!.endIndex)
|
||||||
|
|
||||||
targetMethod.apply {
|
targetMethod.apply {
|
||||||
val targetRegister = getInstruction<TwoRegisterInstruction>(0).registerA
|
val targetRegister = getInstruction<TwoRegisterInstruction>(0).registerA
|
||||||
|
@ -33,7 +33,8 @@ object OpenLinksDirectlyPatch : BaseBytecodePatch(
|
|||||||
fingerprint.resultOrThrow().let {
|
fingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val insertIndex = getTargetIndexWithMethodReferenceName("parse")
|
val insertIndex = getTargetIndexWithMethodReferenceName("parse")
|
||||||
val insertRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerC
|
val insertRegister =
|
||||||
|
getInstruction<FiveRegisterInstruction>(insertIndex).registerC
|
||||||
|
|
||||||
replaceInstruction(
|
replaceInstruction(
|
||||||
insertIndex,
|
insertIndex,
|
||||||
|
@ -45,13 +45,15 @@ object AmbientModeSwitchPatch : BaseBytecodePatch(
|
|||||||
PowerSaveModeSyntheticFingerprint to true
|
PowerSaveModeSyntheticFingerprint to true
|
||||||
).forEach { (fingerprint, reversed) ->
|
).forEach { (fingerprint, reversed) ->
|
||||||
fingerprint.resultOrThrow().mutableMethod.apply {
|
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 =
|
val targetIndex =
|
||||||
if (reversed)
|
if (reversed)
|
||||||
getTargetIndexReversed(stringIndex, Opcode.INVOKE_DIRECT)
|
getTargetIndexReversed(stringIndex, Opcode.INVOKE_DIRECT)
|
||||||
else
|
else
|
||||||
getTargetIndex(stringIndex, Opcode.INVOKE_DIRECT)
|
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
|
syntheticClassList += targetClass
|
||||||
}
|
}
|
||||||
|
@ -126,16 +126,20 @@ object PlayerButtonsPatch : BaseBytecodePatch(
|
|||||||
TitleAnchorFingerprint.resultOrThrow().mutableMethod.apply {
|
TitleAnchorFingerprint.resultOrThrow().mutableMethod.apply {
|
||||||
val titleAnchorConstIndex = getWideLiteralInstructionIndex(TitleAnchor)
|
val titleAnchorConstIndex = getWideLiteralInstructionIndex(TitleAnchor)
|
||||||
val titleAnchorIndex = getTargetIndex(titleAnchorConstIndex, Opcode.MOVE_RESULT_OBJECT)
|
val titleAnchorIndex = getTargetIndex(titleAnchorConstIndex, Opcode.MOVE_RESULT_OBJECT)
|
||||||
val titleAnchorRegister = getInstruction<OneRegisterInstruction>(titleAnchorIndex).registerA
|
val titleAnchorRegister =
|
||||||
|
getInstruction<OneRegisterInstruction>(titleAnchorIndex).registerA
|
||||||
|
|
||||||
addInstruction(
|
addInstruction(
|
||||||
titleAnchorIndex + 1,
|
titleAnchorIndex + 1,
|
||||||
"invoke-static {v$titleAnchorRegister}, $PLAYER_CLASS_DESCRIPTOR->setTitleAnchorStartMargin(Landroid/view/View;)V"
|
"invoke-static {v$titleAnchorRegister}, $PLAYER_CLASS_DESCRIPTOR->setTitleAnchorStartMargin(Landroid/view/View;)V"
|
||||||
)
|
)
|
||||||
|
|
||||||
val playerCollapseButtonConstIndex = getWideLiteralInstructionIndex(PlayerCollapseButton)
|
val playerCollapseButtonConstIndex =
|
||||||
val playerCollapseButtonIndex = getTargetIndex(playerCollapseButtonConstIndex, Opcode.CHECK_CAST)
|
getWideLiteralInstructionIndex(PlayerCollapseButton)
|
||||||
val playerCollapseButtonRegister = getInstruction<OneRegisterInstruction>(playerCollapseButtonIndex).registerA
|
val playerCollapseButtonIndex =
|
||||||
|
getTargetIndex(playerCollapseButtonConstIndex, Opcode.CHECK_CAST)
|
||||||
|
val playerCollapseButtonRegister =
|
||||||
|
getInstruction<OneRegisterInstruction>(playerCollapseButtonIndex).registerA
|
||||||
|
|
||||||
addInstruction(
|
addInstruction(
|
||||||
playerCollapseButtonIndex + 1,
|
playerCollapseButtonIndex + 1,
|
||||||
|
@ -37,6 +37,7 @@ object CommentsComponentPatch : BaseBytecodePatch(
|
|||||||
) {
|
) {
|
||||||
private const val FILTER_CLASS_DESCRIPTOR =
|
private const val FILTER_CLASS_DESCRIPTOR =
|
||||||
"$COMPONENTS_PATH/CommentsFilter;"
|
"$COMPONENTS_PATH/CommentsFilter;"
|
||||||
|
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
|
|
||||||
// region patch for emoji picker button in shorts
|
// region patch for emoji picker button in shorts
|
||||||
@ -44,7 +45,7 @@ object CommentsComponentPatch : BaseBytecodePatch(
|
|||||||
ShortsLiveStreamEmojiPickerOpacityFingerprint.resultOrThrow().let {
|
ShortsLiveStreamEmojiPickerOpacityFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val insertIndex = implementation!!.instructions.size - 1
|
val insertIndex = implementation!!.instructions.size - 1
|
||||||
val insertRegister= getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||||
|
|
||||||
addInstruction(
|
addInstruction(
|
||||||
insertIndex,
|
insertIndex,
|
||||||
@ -56,12 +57,15 @@ object CommentsComponentPatch : BaseBytecodePatch(
|
|||||||
ShortsLiveStreamEmojiPickerOnClickListenerFingerprint.resultOrThrow().let {
|
ShortsLiveStreamEmojiPickerOnClickListenerFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val emojiPickerEndpointIndex = getWideLiteralInstructionIndex(126326492)
|
val emojiPickerEndpointIndex = getWideLiteralInstructionIndex(126326492)
|
||||||
val emojiPickerOnClickListenerIndex = getTargetIndex(emojiPickerEndpointIndex, Opcode.INVOKE_DIRECT)
|
val emojiPickerOnClickListenerIndex =
|
||||||
val emojiPickerOnClickListenerMethod = getWalkerMethod(context, emojiPickerOnClickListenerIndex)
|
getTargetIndex(emojiPickerEndpointIndex, Opcode.INVOKE_DIRECT)
|
||||||
|
val emojiPickerOnClickListenerMethod =
|
||||||
|
getWalkerMethod(context, emojiPickerOnClickListenerIndex)
|
||||||
|
|
||||||
emojiPickerOnClickListenerMethod.apply {
|
emojiPickerOnClickListenerMethod.apply {
|
||||||
val insertIndex = getTargetIndex(Opcode.IF_EQZ)
|
val insertIndex = getTargetIndex(Opcode.IF_EQZ)
|
||||||
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
val insertRegister =
|
||||||
|
getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
insertIndex, """
|
insertIndex, """
|
||||||
|
@ -170,7 +170,7 @@ object PlayerComponentsPatch : BaseBytecodePatch(
|
|||||||
LayoutCircleFingerprint,
|
LayoutCircleFingerprint,
|
||||||
LayoutIconFingerprint,
|
LayoutIconFingerprint,
|
||||||
LayoutVideoFingerprint
|
LayoutVideoFingerprint
|
||||||
).forEach{ fingerprint ->
|
).forEach { fingerprint ->
|
||||||
fingerprint.resultOrThrow().let {
|
fingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val insertIndex = it.scanResult.patternScanResult!!.endIndex
|
val insertIndex = it.scanResult.patternScanResult!!.endIndex
|
||||||
@ -205,9 +205,10 @@ object PlayerComponentsPatch : BaseBytecodePatch(
|
|||||||
val constRegister = getInstruction<OneRegisterInstruction>(constIndex).registerA
|
val constRegister = getInstruction<OneRegisterInstruction>(constIndex).registerA
|
||||||
val insertIndex = getTargetIndexReversed(constIndex, Opcode.INVOKE_VIRTUAL) + 1
|
val insertIndex = getTargetIndexReversed(constIndex, Opcode.INVOKE_VIRTUAL) + 1
|
||||||
val jumpIndex = implementation!!.instructions.let { instruction ->
|
val jumpIndex = implementation!!.instructions.let { instruction ->
|
||||||
insertIndex + instruction.subList(insertIndex, instruction.size - 1).indexOfFirst { instructions ->
|
insertIndex + instruction.subList(insertIndex, instruction.size - 1)
|
||||||
instructions.opcode == Opcode.GOTO || instructions.opcode == Opcode.GOTO_16
|
.indexOfFirst { instructions ->
|
||||||
}
|
instructions.opcode == Opcode.GOTO || instructions.opcode == Opcode.GOTO_16
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val replaceInstruction = getInstruction<TwoRegisterInstruction>(insertIndex)
|
val replaceInstruction = getInstruction<TwoRegisterInstruction>(insertIndex)
|
||||||
@ -270,7 +271,8 @@ object PlayerComponentsPatch : BaseBytecodePatch(
|
|||||||
val insertIndex = getWideLiteralInstructionIndex(SeekUndoEduOverlayStub)
|
val insertIndex = getWideLiteralInstructionIndex(SeekUndoEduOverlayStub)
|
||||||
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||||
|
|
||||||
val onClickListenerIndex = getTargetIndexWithMethodReferenceName(insertIndex, "setOnClickListener")
|
val onClickListenerIndex =
|
||||||
|
getTargetIndexWithMethodReferenceName(insertIndex, "setOnClickListener")
|
||||||
val constComponent = getConstComponent(insertIndex, onClickListenerIndex - 1)
|
val constComponent = getConstComponent(insertIndex, onClickListenerIndex - 1)
|
||||||
|
|
||||||
if (constComponent.isNotEmpty()) {
|
if (constComponent.isNotEmpty()) {
|
||||||
@ -315,8 +317,10 @@ object PlayerComponentsPatch : BaseBytecodePatch(
|
|||||||
it.mutableClass.methods.find { method ->
|
it.mutableClass.methods.find { method ->
|
||||||
method.parameters == listOf("Landroid/view/View${'$'}OnClickListener;")
|
method.parameters == listOf("Landroid/view/View${'$'}OnClickListener;")
|
||||||
}?.apply {
|
}?.apply {
|
||||||
val setOnClickListenerIndex = getTargetIndexWithMethodReferenceName("setOnClickListener")
|
val setOnClickListenerIndex =
|
||||||
val setOnClickListenerRegister = getInstruction<FiveRegisterInstruction>(setOnClickListenerIndex).registerC
|
getTargetIndexWithMethodReferenceName("setOnClickListener")
|
||||||
|
val setOnClickListenerRegister =
|
||||||
|
getInstruction<FiveRegisterInstruction>(setOnClickListenerIndex).registerC
|
||||||
|
|
||||||
addInstruction(
|
addInstruction(
|
||||||
setOnClickListenerIndex + 1,
|
setOnClickListenerIndex + 1,
|
||||||
|
@ -110,8 +110,10 @@ object DescriptionComponentsPatch : BaseBytecodePatch(
|
|||||||
EngagementPanelTitleParentFingerprint.resultOrThrow().classDef
|
EngagementPanelTitleParentFingerprint.resultOrThrow().classDef
|
||||||
)
|
)
|
||||||
EngagementPanelTitleFingerprint.resultOrThrow().mutableMethod.apply {
|
EngagementPanelTitleFingerprint.resultOrThrow().mutableMethod.apply {
|
||||||
val contentDescriptionIndex = getTargetIndexWithMethodReferenceName("setContentDescription")
|
val contentDescriptionIndex =
|
||||||
val contentDescriptionRegister = getInstruction<FiveRegisterInstruction>(contentDescriptionIndex).registerD
|
getTargetIndexWithMethodReferenceName("setContentDescription")
|
||||||
|
val contentDescriptionRegister =
|
||||||
|
getInstruction<FiveRegisterInstruction>(contentDescriptionIndex).registerD
|
||||||
|
|
||||||
addInstruction(
|
addInstruction(
|
||||||
contentDescriptionIndex,
|
contentDescriptionIndex,
|
||||||
|
@ -2,7 +2,7 @@ package app.revanced.patches.youtube.player.flyoutmenu.hide.fingerprints
|
|||||||
|
|
||||||
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This fingerprint is compatible with YouTube v18.39.xx+
|
* This fingerprint is compatible with YouTube v18.39.xx+
|
||||||
*/
|
*/
|
||||||
internal object PiPModeConfigFingerprint : LiteralValueFingerprint(
|
internal object PiPModeConfigFingerprint : LiteralValueFingerprint(
|
||||||
|
@ -46,11 +46,14 @@ object ChangeTogglePatch : BaseBytecodePatch(
|
|||||||
) {
|
) {
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
|
|
||||||
val additionalSettingsConfigMethod = AdditionalSettingsConfigFingerprint.resultOrThrow().mutableMethod
|
val additionalSettingsConfigMethod =
|
||||||
val methodToCall = additionalSettingsConfigMethod.definingClass + "->" + additionalSettingsConfigMethod.name + "()Z"
|
AdditionalSettingsConfigFingerprint.resultOrThrow().mutableMethod
|
||||||
|
val methodToCall =
|
||||||
|
additionalSettingsConfigMethod.definingClass + "->" + additionalSettingsConfigMethod.name + "()Z"
|
||||||
|
|
||||||
// Resolves fingerprints
|
// Resolves fingerprints
|
||||||
val playbackLoopOnClickListenerResult = PlaybackLoopOnClickListenerFingerprint.resultOrThrow()
|
val playbackLoopOnClickListenerResult =
|
||||||
|
PlaybackLoopOnClickListenerFingerprint.resultOrThrow()
|
||||||
PlaybackLoopInitFingerprint.resolve(context, playbackLoopOnClickListenerResult.classDef)
|
PlaybackLoopInitFingerprint.resolve(context, playbackLoopOnClickListenerResult.classDef)
|
||||||
|
|
||||||
var fingerprintArray = arrayOf(
|
var fingerprintArray = arrayOf(
|
||||||
@ -90,7 +93,8 @@ object ChangeTogglePatch : BaseBytecodePatch(
|
|||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val referenceIndex = indexOfFirstInstruction {
|
val referenceIndex = indexOfFirstInstruction {
|
||||||
opcode == Opcode.INVOKE_VIRTUAL
|
opcode == Opcode.INVOKE_VIRTUAL
|
||||||
&& (this as ReferenceInstruction).reference.toString().endsWith(methodToCall)
|
&& (this as ReferenceInstruction).reference.toString()
|
||||||
|
.endsWith(methodToCall)
|
||||||
}
|
}
|
||||||
if (referenceIndex > 0) {
|
if (referenceIndex > 0) {
|
||||||
val insertRegister =
|
val insertRegister =
|
||||||
@ -117,12 +121,14 @@ object ChangeTogglePatch : BaseBytecodePatch(
|
|||||||
|
|
||||||
val stringReferenceIndex = stableVolumeMethod.indexOfFirstInstruction {
|
val stringReferenceIndex = stableVolumeMethod.indexOfFirstInstruction {
|
||||||
opcode == Opcode.INVOKE_VIRTUAL
|
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)
|
if (stringReferenceIndex < 0)
|
||||||
throw PatchException("Target reference was not found in ${StableVolumeFingerprint.javaClass.simpleName}.")
|
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 {
|
CinematicLightingFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
@ -135,15 +141,20 @@ object ChangeTogglePatch : BaseBytecodePatch(
|
|||||||
val stringIndex = getStringInstructionIndex("menu_item_cinematic_lighting")
|
val stringIndex = getStringInstructionIndex("menu_item_cinematic_lighting")
|
||||||
|
|
||||||
val checkCastIndex = getTargetIndexReversed(stringIndex, Opcode.CHECK_CAST)
|
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 iGetObjectSecondaryIndex = getTargetIndex(checkCastIndex, Opcode.IGET_OBJECT)
|
||||||
|
|
||||||
val checkCastReference = getInstruction<ReferenceInstruction>(checkCastIndex).reference
|
val checkCastReference =
|
||||||
val iGetObjectPrimaryReference = getInstruction<ReferenceInstruction>(iGetObjectPrimaryIndex).reference
|
getInstruction<ReferenceInstruction>(checkCastIndex).reference
|
||||||
val iGetObjectSecondaryReference = getInstruction<ReferenceInstruction>(iGetObjectSecondaryIndex).reference
|
val iGetObjectPrimaryReference =
|
||||||
|
getInstruction<ReferenceInstruction>(iGetObjectPrimaryIndex).reference
|
||||||
|
val iGetObjectSecondaryReference =
|
||||||
|
getInstruction<ReferenceInstruction>(iGetObjectSecondaryIndex).reference
|
||||||
|
|
||||||
val invokeVirtualIndex = getTargetIndex(stringIndex, Opcode.INVOKE_VIRTUAL)
|
val invokeVirtualIndex = getTargetIndex(stringIndex, Opcode.INVOKE_VIRTUAL)
|
||||||
val invokeVirtualInstruction = getInstruction<FiveRegisterInstruction>(invokeVirtualIndex)
|
val invokeVirtualInstruction =
|
||||||
|
getInstruction<FiveRegisterInstruction>(invokeVirtualIndex)
|
||||||
val freeRegisterC = invokeVirtualInstruction.registerC
|
val freeRegisterC = invokeVirtualInstruction.registerC
|
||||||
val freeRegisterD = invokeVirtualInstruction.registerD
|
val freeRegisterD = invokeVirtualInstruction.registerD
|
||||||
val freeRegisterE = invokeVirtualInstruction.registerE
|
val freeRegisterE = invokeVirtualInstruction.registerE
|
||||||
|
@ -182,7 +182,8 @@ object FullscreenComponentsPatch : BaseBytecodePatch(
|
|||||||
val walkerMethod = getWalkerMethod(context, walkerIndex)
|
val walkerMethod = getWalkerMethod(context, walkerIndex)
|
||||||
walkerMethod.apply {
|
walkerMethod.apply {
|
||||||
val insertIndex = implementation!!.instructions.size - 1
|
val insertIndex = implementation!!.instructions.size - 1
|
||||||
val targetRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
val targetRegister =
|
||||||
|
getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
insertIndex, """
|
insertIndex, """
|
||||||
@ -288,7 +289,8 @@ object FullscreenComponentsPatch : BaseBytecodePatch(
|
|||||||
LandScapeModeConfigFingerprint.resultOrThrow().let {
|
LandScapeModeConfigFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val insertIndex = implementation!!.instructions.size - 1
|
val insertIndex = implementation!!.instructions.size - 1
|
||||||
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
val insertRegister =
|
||||||
|
getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
insertIndex, """
|
insertIndex, """
|
||||||
@ -300,7 +302,8 @@ object FullscreenComponentsPatch : BaseBytecodePatch(
|
|||||||
|
|
||||||
BroadcastReceiverFingerprint.resultOrThrow().let { result ->
|
BroadcastReceiverFingerprint.resultOrThrow().let { result ->
|
||||||
result.mutableMethod.apply {
|
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
|
val insertIndex = getTargetIndex(stringIndex, Opcode.IF_EQZ) + 1
|
||||||
|
|
||||||
addInstruction(
|
addInstruction(
|
||||||
|
@ -89,22 +89,29 @@ object OverlayButtonsBytecodePatch : BytecodePatch(
|
|||||||
&& getReference<FieldReference>()?.definingClass == definingClass
|
&& getReference<FieldReference>()?.definingClass == definingClass
|
||||||
&& (this as TwoRegisterInstruction).registerA == registerResolver
|
&& (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 onClickListenerReferenceIndex =
|
||||||
val onClickListenerReference = getInstruction<ReferenceInstruction>(onClickListenerReferenceIndex).reference
|
getTargetIndexWithReference("<init>(Ljava/lang/Object;I[B)V")
|
||||||
val onClickListenerClass = context.findClass((onClickListenerReference as MethodReference).definingClass)!!.mutableClass
|
val onClickListenerReference =
|
||||||
|
getInstruction<ReferenceInstruction>(onClickListenerReferenceIndex).reference
|
||||||
|
val onClickListenerClass =
|
||||||
|
context.findClass((onClickListenerReference as MethodReference).definingClass)!!.mutableClass
|
||||||
|
|
||||||
var invokeInterfaceReference = ""
|
var invokeInterfaceReference = ""
|
||||||
onClickListenerClass.methods.find { method -> method.name == "onClick" }
|
onClickListenerClass.methods.find { method -> method.name == "onClick" }
|
||||||
?.apply {
|
?.apply {
|
||||||
val invokeInterfaceIndex = getTargetIndexWithReference(invokerObjectReference.toString()) + 1
|
val invokeInterfaceIndex =
|
||||||
|
getTargetIndexWithReference(invokerObjectReference.toString()) + 1
|
||||||
if (getInstruction(invokeInterfaceIndex).opcode != Opcode.INVOKE_INTERFACE)
|
if (getInstruction(invokeInterfaceIndex).opcode != Opcode.INVOKE_INTERFACE)
|
||||||
throw PatchException("Opcode does not match")
|
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")
|
} ?: 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 =
|
val smaliInstructions =
|
||||||
"""
|
"""
|
||||||
|
@ -129,7 +129,10 @@ object OverlayButtonsPatch : BaseResourcePatch(
|
|||||||
val resources = commonResources + specificResources
|
val resources = commonResources + specificResources
|
||||||
resources.forEach { resource ->
|
resources.forEach { resource ->
|
||||||
val folderName = if (resource.endsWith(".xml")) "drawable" else "drawable-xxhdpi"
|
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)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ internal object OfflineVideoEndpointFingerprint : MethodFingerprint(
|
|||||||
"Ljava/util/Map;",
|
"Ljava/util/Map;",
|
||||||
"L",
|
"L",
|
||||||
"Ljava/lang/String", // VideoId
|
"Ljava/lang/String", // VideoId
|
||||||
"L"),
|
"L"
|
||||||
|
),
|
||||||
strings = listOf("Object is not an offlineable video: ")
|
strings = listOf("Object is not an offlineable video: ")
|
||||||
)
|
)
|
||||||
|
@ -133,7 +133,8 @@ object SeekbarComponentsPatch : BaseBytecodePatch(
|
|||||||
TotalTimeFingerprint.resultOrThrow().let {
|
TotalTimeFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val charSequenceIndex = getTargetIndexWithMethodReferenceName("getString") + 1
|
val charSequenceIndex = getTargetIndexWithMethodReferenceName("getString") + 1
|
||||||
val charSequenceRegister = getInstruction<OneRegisterInstruction>(charSequenceIndex).registerA
|
val charSequenceRegister =
|
||||||
|
getInstruction<OneRegisterInstruction>(charSequenceIndex).registerA
|
||||||
val textViewIndex = getTargetIndexWithMethodReferenceName("getText")
|
val textViewIndex = getTargetIndexWithMethodReferenceName("getText")
|
||||||
val textViewRegister =
|
val textViewRegister =
|
||||||
getInstruction<FiveRegisterInstruction>(textViewIndex).registerC
|
getInstruction<FiveRegisterInstruction>(textViewIndex).registerC
|
||||||
@ -162,7 +163,8 @@ object SeekbarComponentsPatch : BaseBytecodePatch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
ControlsOverlayStyleFingerprint.resultOrThrow().let {
|
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 {
|
walkerMethod.apply {
|
||||||
val colorRegister = getInstruction<TwoRegisterInstruction>(0).registerA
|
val colorRegister = getInstruction<TwoRegisterInstruction>(0).registerA
|
||||||
|
|
||||||
@ -221,18 +223,19 @@ object SeekbarComponentsPatch : BaseBytecodePatch(
|
|||||||
// region patch for hide seekbar
|
// region patch for hide seekbar
|
||||||
|
|
||||||
SeekbarFingerprint.resultOrThrow().mutableClass.let { mutableClass ->
|
SeekbarFingerprint.resultOrThrow().mutableClass.let { mutableClass ->
|
||||||
SeekbarOnDrawFingerprint.also { it.resolve(context, mutableClass) }.resultOrThrow().let {
|
SeekbarOnDrawFingerprint.also { it.resolve(context, mutableClass) }.resultOrThrow()
|
||||||
it.mutableMethod.apply {
|
.let {
|
||||||
addInstructionsWithLabels(
|
it.mutableMethod.apply {
|
||||||
0, """
|
addInstructionsWithLabels(
|
||||||
|
0, """
|
||||||
invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->hideSeekbar()Z
|
invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->hideSeekbar()Z
|
||||||
move-result v0
|
move-result v0
|
||||||
if-eqz v0, :show
|
if-eqz v0, :show
|
||||||
return-void
|
return-void
|
||||||
""", ExternalLabel("show", getInstruction(0))
|
""", ExternalLabel("show", getInstruction(0))
|
||||||
)
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
@ -240,7 +243,8 @@ object SeekbarComponentsPatch : BaseBytecodePatch(
|
|||||||
// region patch for hide time stamp
|
// region patch for hide time stamp
|
||||||
|
|
||||||
PlayerSeekbarColorFingerprint.resultOrThrow().let { parentResult ->
|
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 {
|
it.mutableMethod.apply {
|
||||||
addInstructionsWithLabels(
|
addInstructionsWithLabels(
|
||||||
0, """
|
0, """
|
||||||
@ -274,7 +278,8 @@ object SeekbarComponentsPatch : BaseBytecodePatch(
|
|||||||
"SETTINGS: RESTORE_OLD_SEEKBAR_THUMBNAILS"
|
"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
|
// endregion
|
||||||
|
|
||||||
|
@ -49,7 +49,8 @@ object SpeedOverlayPatch : BytecodePatch(
|
|||||||
) {
|
) {
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
|
|
||||||
val restoreSlideToSeekBehaviorFingerprintResult = RestoreSlideToSeekBehaviorFingerprint.result
|
val restoreSlideToSeekBehaviorFingerprintResult =
|
||||||
|
RestoreSlideToSeekBehaviorFingerprint.result
|
||||||
val speedOverlayFingerprintResult = SpeedOverlayFingerprint.result
|
val speedOverlayFingerprintResult = SpeedOverlayFingerprint.result
|
||||||
val speedOverlayValueFingerprintResult = SpeedOverlayValueFingerprint.result
|
val speedOverlayValueFingerprintResult = SpeedOverlayValueFingerprint.result
|
||||||
|
|
||||||
@ -130,7 +131,8 @@ object SpeedOverlayPatch : BytecodePatch(
|
|||||||
|
|
||||||
val jumpIndex = scanResult.endIndex + 1
|
val jumpIndex = scanResult.endIndex + 1
|
||||||
val insertIndex = scanResult.endIndex - 1
|
val insertIndex = scanResult.endIndex - 1
|
||||||
val insertRegister = getInstruction<TwoRegisterInstruction>(insertIndex).registerA
|
val insertRegister =
|
||||||
|
getInstruction<TwoRegisterInstruction>(insertIndex).registerA
|
||||||
|
|
||||||
hook(insertIndex, insertRegister, jumpIndex)
|
hook(insertIndex, insertRegister, jumpIndex)
|
||||||
}
|
}
|
||||||
@ -150,7 +152,8 @@ object SpeedOverlayPatch : BytecodePatch(
|
|||||||
|
|
||||||
constructorMethod.apply {
|
constructorMethod.apply {
|
||||||
val syntheticIndex = getTargetIndexReversed(Opcode.NEW_INSTANCE)
|
val syntheticIndex = getTargetIndexReversed(Opcode.NEW_INSTANCE)
|
||||||
val syntheticClass = getInstruction<ReferenceInstruction>(syntheticIndex).reference.toString()
|
val syntheticClass =
|
||||||
|
getInstruction<ReferenceInstruction>(syntheticIndex).reference.toString()
|
||||||
|
|
||||||
val syntheticMethod =
|
val syntheticMethod =
|
||||||
context.findClass(syntheticClass)?.mutableClass
|
context.findClass(syntheticClass)?.mutableClass
|
||||||
@ -170,8 +173,12 @@ object SpeedOverlayPatch : BytecodePatch(
|
|||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
insertIndex = getTargetIndexWithMethodReferenceNameReversed(speedOverlayValueIndex, "removeCallbacks") + 1
|
insertIndex = getTargetIndexWithMethodReferenceNameReversed(
|
||||||
insertRegister = getInstruction<FiveRegisterInstruction>(insertIndex - 1).registerC
|
speedOverlayValueIndex,
|
||||||
|
"removeCallbacks"
|
||||||
|
) + 1
|
||||||
|
insertRegister =
|
||||||
|
getInstruction<FiveRegisterInstruction>(insertIndex - 1).registerC
|
||||||
jumpIndex = getTargetIndex(speedOverlayValueIndex, Opcode.RETURN_VOID) + 1
|
jumpIndex = getTargetIndex(speedOverlayValueIndex, Opcode.RETURN_VOID) + 1
|
||||||
hook(insertIndex, insertRegister, jumpIndex)
|
hook(insertIndex, insertRegister, jumpIndex)
|
||||||
}
|
}
|
||||||
@ -181,7 +188,8 @@ object SpeedOverlayPatch : BytecodePatch(
|
|||||||
SpeedOverlayTextValueFingerprint.resultOrThrow().let {
|
SpeedOverlayTextValueFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val targetIndex = it.scanResult.patternScanResult!!.startIndex
|
val targetIndex = it.scanResult.patternScanResult!!.startIndex
|
||||||
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
val targetRegister =
|
||||||
|
getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
targetIndex + 1, """
|
targetIndex + 1, """
|
||||||
|
@ -161,7 +161,10 @@ object ShortsComponentPatch : BaseBytecodePatch(
|
|||||||
if (insertIndex == 0)
|
if (insertIndex == 0)
|
||||||
throw PatchException("insert index not found")
|
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) {
|
when (returnType) {
|
||||||
"Landroid/widget/TextView;" -> {
|
"Landroid/widget/TextView;" -> {
|
||||||
val insertIndex = implementation!!.instructions.size - 1
|
val insertIndex = implementation!!.instructions.size - 1
|
||||||
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
val insertRegister =
|
||||||
|
getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
insertIndex + 1, """
|
insertIndex + 1, """
|
||||||
@ -196,6 +200,7 @@ object ShortsComponentPatch : BaseBytecodePatch(
|
|||||||
)
|
)
|
||||||
removeInstruction(insertIndex)
|
removeInstruction(insertIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
"V" -> {
|
"V" -> {
|
||||||
addInstructionsWithLabels(
|
addInstructionsWithLabels(
|
||||||
0, """
|
0, """
|
||||||
@ -206,6 +211,7 @@ object ShortsComponentPatch : BaseBytecodePatch(
|
|||||||
""", ExternalLabel("show", getInstruction(0))
|
""", ExternalLabel("show", getInstruction(0))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
throw PatchException("Unknown returnType: $returnType")
|
throw PatchException("Unknown returnType: $returnType")
|
||||||
}
|
}
|
||||||
@ -260,7 +266,8 @@ object ShortsComponentPatch : BaseBytecodePatch(
|
|||||||
|
|
||||||
TextComponentSpecFingerprint.resultOrThrow().let {
|
TextComponentSpecFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
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 =
|
val charSequenceRegister =
|
||||||
getInstruction<FiveRegisterInstruction>(insertIndex).registerC
|
getInstruction<FiveRegisterInstruction>(insertIndex).registerC
|
||||||
|
@ -25,7 +25,8 @@ object ShortsNavigationBarPatch : BytecodePatch(
|
|||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
|
|
||||||
InitializeButtonsFingerprint.resultOrThrow().let { parentResult ->
|
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 {
|
it.mutableMethod.apply {
|
||||||
val startIndex = it.scanResult.patternScanResult!!.startIndex
|
val startIndex = it.scanResult.patternScanResult!!.startIndex
|
||||||
val register = getInstruction<OneRegisterInstruction>(startIndex).registerA
|
val register = getInstruction<OneRegisterInstruction>(startIndex).registerA
|
||||||
@ -39,7 +40,8 @@ object ShortsNavigationBarPatch : BytecodePatch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
RenderBottomNavigationBarFingerprint.resultOrThrow().let {
|
RenderBottomNavigationBarFingerprint.resultOrThrow().let {
|
||||||
val walkerMethod = it.getWalkerMethod(context, it.scanResult.patternScanResult!!.endIndex)
|
val walkerMethod =
|
||||||
|
it.getWalkerMethod(context, it.scanResult.patternScanResult!!.endIndex)
|
||||||
|
|
||||||
walkerMethod.addInstruction(
|
walkerMethod.addInstruction(
|
||||||
0,
|
0,
|
||||||
|
@ -42,9 +42,12 @@ object ShortsRepeatPatch : BaseBytecodePatch(
|
|||||||
injectEnum(enumName, fieldName)
|
injectEnum(enumName, fieldName)
|
||||||
}
|
}
|
||||||
|
|
||||||
val endScreenStringIndex = getStringInstructionIndex("REEL_LOOP_BEHAVIOR_END_SCREEN")
|
val endScreenStringIndex =
|
||||||
val endScreenReferenceIndex = getTargetIndex(endScreenStringIndex, Opcode.SPUT_OBJECT)
|
getStringInstructionIndex("REEL_LOOP_BEHAVIOR_END_SCREEN")
|
||||||
val endScreenReference = getInstruction<ReferenceInstruction>(endScreenReferenceIndex).reference.toString()
|
val endScreenReferenceIndex =
|
||||||
|
getTargetIndex(endScreenStringIndex, Opcode.SPUT_OBJECT)
|
||||||
|
val endScreenReference =
|
||||||
|
getInstruction<ReferenceInstruction>(endScreenReferenceIndex).reference.toString()
|
||||||
|
|
||||||
val enumMethodName = ReelEnumStaticFingerprint.resultOrThrow().mutableMethod.name
|
val enumMethodName = ReelEnumStaticFingerprint.resultOrThrow().mutableMethod.name
|
||||||
val enumMethodCall = "$definingClass->$enumMethodName(I)$definingClass"
|
val enumMethodCall = "$definingClass->$enumMethodName(I)$definingClass"
|
||||||
@ -101,7 +104,8 @@ object ShortsRepeatPatch : BaseBytecodePatch(
|
|||||||
if ((instruction as ReferenceInstruction).reference.toString() != enumMethodCall)
|
if ((instruction as ReferenceInstruction).reference.toString() != enumMethodCall)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
val register = getInstruction<OneRegisterInstruction>(index + 1).registerA
|
val register =
|
||||||
|
getInstruction<OneRegisterInstruction>(index + 1).registerA
|
||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
index + 2, """
|
index + 2, """
|
||||||
@ -109,8 +113,8 @@ object ShortsRepeatPatch : BaseBytecodePatch(
|
|||||||
move-result-object v$register
|
move-result-object v$register
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,13 +38,14 @@ object ResumingShortsOnStartupPatch : BaseBytecodePatch(
|
|||||||
UserWasInShortsABConfigFingerprint.resultOrThrow().mutableMethod.apply {
|
UserWasInShortsABConfigFingerprint.resultOrThrow().mutableMethod.apply {
|
||||||
val startIndex = indexOfOptionalInstruction(this)
|
val startIndex = indexOfOptionalInstruction(this)
|
||||||
val walkerIndex = implementation!!.instructions.let {
|
val walkerIndex = implementation!!.instructions.let {
|
||||||
val subListIndex = it.subList(startIndex, startIndex + 20).indexOfFirst { instruction ->
|
val subListIndex =
|
||||||
val reference = instruction.getReference<MethodReference>()
|
it.subList(startIndex, startIndex + 20).indexOfFirst { instruction ->
|
||||||
instruction.opcode == Opcode.INVOKE_VIRTUAL
|
val reference = instruction.getReference<MethodReference>()
|
||||||
&& reference?.returnType == "Z"
|
instruction.opcode == Opcode.INVOKE_VIRTUAL
|
||||||
&& reference.definingClass != "Lj${'$'}/util/Optional;"
|
&& reference?.returnType == "Z"
|
||||||
&& reference.parameterTypes.size == 0
|
&& reference.definingClass != "Lj${'$'}/util/Optional;"
|
||||||
}
|
&& reference.parameterTypes.size == 0
|
||||||
|
}
|
||||||
if (subListIndex < 0)
|
if (subListIndex < 0)
|
||||||
throw PatchException("subListIndex not found")
|
throw PatchException("subListIndex not found")
|
||||||
|
|
||||||
@ -75,8 +76,10 @@ object ResumingShortsOnStartupPatch : BaseBytecodePatch(
|
|||||||
getReference<MethodReference>()?.name == "isDone"
|
getReference<MethodReference>()?.name == "isDone"
|
||||||
}
|
}
|
||||||
if (listenableInstructionIndex < 0) throw PatchException("Could not find instruction index")
|
if (listenableInstructionIndex < 0) throw PatchException("Could not find instruction index")
|
||||||
val originalInstructionRegister = getInstruction<FiveRegisterInstruction>(listenableInstructionIndex).registerC
|
val originalInstructionRegister =
|
||||||
val freeRegister = getInstruction<OneRegisterInstruction>(listenableInstructionIndex + 1).registerA
|
getInstruction<FiveRegisterInstruction>(listenableInstructionIndex).registerC
|
||||||
|
val freeRegister =
|
||||||
|
getInstruction<OneRegisterInstruction>(listenableInstructionIndex + 1).registerA
|
||||||
|
|
||||||
addInstructionsWithLabels(
|
addInstructionsWithLabels(
|
||||||
listenableInstructionIndex + 1,
|
listenableInstructionIndex + 1,
|
||||||
|
@ -14,7 +14,7 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
|||||||
internal object UserWasInShortsABConfigFingerprint : MethodFingerprint(
|
internal object UserWasInShortsABConfigFingerprint : MethodFingerprint(
|
||||||
returnType = "V",
|
returnType = "V",
|
||||||
strings = listOf("Failed to get offline response: "),
|
strings = listOf("Failed to get offline response: "),
|
||||||
customFingerprint = { methodDef, _ ->
|
customFingerprint = { methodDef, _ ->
|
||||||
indexOfOptionalInstruction(methodDef) >= 0
|
indexOfOptionalInstruction(methodDef) >= 0
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
|
@ -62,7 +62,8 @@ object SwipeControlsPatch : BaseBytecodePatch(
|
|||||||
|
|
||||||
// region patch for swipe controls patch
|
// 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
|
val mainActivityClass = mainActivityMutableClass
|
||||||
|
|
||||||
// inject the wrapper class from integrations into the class hierarchy of MainActivity (WatchWhileActivity)
|
// inject the wrapper class from integrations into the class hierarchy of MainActivity (WatchWhileActivity)
|
||||||
|
@ -43,7 +43,8 @@ object CastButtonPatch : BytecodePatch(
|
|||||||
MenuItemVisibilityFingerprint.resolve(context, toolbarMenuItemInitializeResult.classDef)
|
MenuItemVisibilityFingerprint.resolve(context, toolbarMenuItemInitializeResult.classDef)
|
||||||
|
|
||||||
toolbarMenuItemInitializeMethod = toolbarMenuItemInitializeResult.mutableMethod
|
toolbarMenuItemInitializeMethod = toolbarMenuItemInitializeResult.mutableMethod
|
||||||
toolbarMenuItemVisibilityMethod = MenuItemVisibilityFingerprint.resultOrThrow().mutableMethod
|
toolbarMenuItemVisibilityMethod =
|
||||||
|
MenuItemVisibilityFingerprint.resultOrThrow().mutableMethod
|
||||||
|
|
||||||
playerButtonMethod = PlayerButtonFingerprint.resultOrThrow().mutableMethod
|
playerButtonMethod = PlayerButtonFingerprint.resultOrThrow().mutableMethod
|
||||||
|
|
||||||
|
@ -32,7 +32,8 @@ object CairoSettingsPatch : BytecodePatch(
|
|||||||
*/
|
*/
|
||||||
CarioFragmentConfigFingerprint.result?.let {
|
CarioFragmentConfigFingerprint.result?.let {
|
||||||
it.mutableMethod.apply {
|
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
|
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||||
|
|
||||||
addInstruction(
|
addInstruction(
|
||||||
|
@ -76,10 +76,12 @@ object SpoofClientPatch : BaseBytecodePatch(
|
|||||||
BuildInitPlaybackRequestFingerprint.resultOrThrow().let {
|
BuildInitPlaybackRequestFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val moveUriStringIndex = it.scanResult.patternScanResult!!.startIndex
|
val moveUriStringIndex = it.scanResult.patternScanResult!!.startIndex
|
||||||
val targetRegister = getInstruction<OneRegisterInstruction>(moveUriStringIndex).registerA
|
val targetRegister =
|
||||||
|
getInstruction<OneRegisterInstruction>(moveUriStringIndex).registerA
|
||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
moveUriStringIndex + 1, """
|
moveUriStringIndex + 1,
|
||||||
|
"""
|
||||||
invoke-static { v$targetRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->blockInitPlaybackRequest(Ljava/lang/String;)Ljava/lang/String;
|
invoke-static { v$targetRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->blockInitPlaybackRequest(Ljava/lang/String;)Ljava/lang/String;
|
||||||
move-result-object v$targetRegister
|
move-result-object v$targetRegister
|
||||||
""",
|
""",
|
||||||
@ -94,10 +96,12 @@ object SpoofClientPatch : BaseBytecodePatch(
|
|||||||
BuildPlayerRequestURIFingerprint.resultOrThrow().let {
|
BuildPlayerRequestURIFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val invokeToStringIndex = it.scanResult.patternScanResult!!.startIndex
|
val invokeToStringIndex = it.scanResult.patternScanResult!!.startIndex
|
||||||
val uriRegister = getInstruction<FiveRegisterInstruction>(invokeToStringIndex).registerC
|
val uriRegister =
|
||||||
|
getInstruction<FiveRegisterInstruction>(invokeToStringIndex).registerC
|
||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
invokeToStringIndex, """
|
invokeToStringIndex,
|
||||||
|
"""
|
||||||
invoke-static { v$uriRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->blockGetWatchRequest(Landroid/net/Uri;)Landroid/net/Uri;
|
invoke-static { v$uriRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->blockGetWatchRequest(Landroid/net/Uri;)Landroid/net/Uri;
|
||||||
move-result-object v$uriRegister
|
move-result-object v$uriRegister
|
||||||
""",
|
""",
|
||||||
@ -111,50 +115,59 @@ object SpoofClientPatch : BaseBytecodePatch(
|
|||||||
|
|
||||||
val (clientInfoField, clientInfoClientTypeField, clientInfoClientVersionField) =
|
val (clientInfoField, clientInfoClientTypeField, clientInfoClientVersionField) =
|
||||||
SetPlayerRequestClientTypeFingerprint.resultOrThrow().let { result ->
|
SetPlayerRequestClientTypeFingerprint.resultOrThrow().let { result ->
|
||||||
with (result.mutableMethod) {
|
with(result.mutableMethod) {
|
||||||
// Field in the player request object that holds the client info object.
|
// Field in the player request object that holds the client info object.
|
||||||
val clientInfoField = getInstructions().find { instruction ->
|
val clientInfoField = getInstructions().find { instruction ->
|
||||||
// requestMessage.clientInfo = clientInfoBuilder.build();
|
// requestMessage.clientInfo = clientInfoBuilder.build();
|
||||||
instruction.opcode == Opcode.IPUT_OBJECT &&
|
instruction.opcode == Opcode.IPUT_OBJECT &&
|
||||||
instruction.getReference<FieldReference>()?.type == CLIENT_INFO_CLASS_DESCRIPTOR
|
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.
|
// Client info object's client type field.
|
||||||
val clientInfoClientTypeField = getInstruction(result.scanResult.patternScanResult!!.endIndex)
|
val clientInfoClientTypeField =
|
||||||
.getReference<FieldReference>() ?: throw PatchException("Could not find clientInfoClientTypeField")
|
getInstruction(result.scanResult.patternScanResult!!.endIndex)
|
||||||
|
.getReference<FieldReference>()
|
||||||
|
?: throw PatchException("Could not find clientInfoClientTypeField")
|
||||||
|
|
||||||
val clientInfoVersionIndex = getStringInstructionIndex("10.29")
|
val clientInfoVersionIndex = getStringInstructionIndex("10.29")
|
||||||
val clientInfoVersionRegister = getInstruction<OneRegisterInstruction>(clientInfoVersionIndex).registerA
|
val clientInfoVersionRegister =
|
||||||
|
getInstruction<OneRegisterInstruction>(clientInfoVersionIndex).registerA
|
||||||
val clientInfoClientVersionFieldIndex = implementation!!.instructions.let {
|
val clientInfoClientVersionFieldIndex = implementation!!.instructions.let {
|
||||||
clientInfoVersionIndex + it.subList(clientInfoVersionIndex, it.size - 1).indexOfFirst { instruction ->
|
clientInfoVersionIndex + it.subList(clientInfoVersionIndex, it.size - 1)
|
||||||
instruction.opcode == Opcode.IPUT_OBJECT
|
.indexOfFirst { instruction ->
|
||||||
&& (instruction as TwoRegisterInstruction).registerA == clientInfoVersionRegister
|
instruction.opcode == Opcode.IPUT_OBJECT
|
||||||
}
|
&& (instruction as TwoRegisterInstruction).registerA == clientInfoVersionRegister
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Client info object's client version field.
|
// Client info object's client version field.
|
||||||
val clientInfoClientVersionField = getInstruction(clientInfoClientVersionFieldIndex)
|
val clientInfoClientVersionField =
|
||||||
.getReference<FieldReference>() ?: throw PatchException("Could not find clientInfoClientVersionField")
|
getInstruction(clientInfoClientVersionFieldIndex)
|
||||||
|
.getReference<FieldReference>()
|
||||||
|
?: throw PatchException("Could not find clientInfoClientVersionField")
|
||||||
|
|
||||||
Triple(clientInfoField, clientInfoClientTypeField, clientInfoClientVersionField)
|
Triple(clientInfoField, clientInfoClientTypeField, clientInfoClientVersionField)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val clientInfoClientModelField = CreatePlayerRequestBodyWithModelFingerprint.resultOrThrow().mutableMethod.let {
|
val clientInfoClientModelField =
|
||||||
val instructions = it.getInstructions()
|
CreatePlayerRequestBodyWithModelFingerprint.resultOrThrow().mutableMethod.let {
|
||||||
val getClientModelIndex = indexOfModelInstruction(it)
|
val instructions = it.getInstructions()
|
||||||
|
val getClientModelIndex = indexOfModelInstruction(it)
|
||||||
|
|
||||||
// The next IPUT_OBJECT instruction after getting the client model is setting the client model field.
|
// The next IPUT_OBJECT instruction after getting the client model is setting the client model field.
|
||||||
instructions.subList(
|
instructions.subList(
|
||||||
getClientModelIndex,
|
getClientModelIndex,
|
||||||
instructions.size,
|
instructions.size,
|
||||||
).find { instruction ->
|
).find { instruction ->
|
||||||
val reference = instruction.getReference<FieldReference>()
|
val reference = instruction.getReference<FieldReference>()
|
||||||
instruction.opcode == Opcode.IPUT_OBJECT
|
instruction.opcode == Opcode.IPUT_OBJECT
|
||||||
&& reference?.definingClass == CLIENT_INFO_CLASS_DESCRIPTOR
|
&& reference?.definingClass == CLIENT_INFO_CLASS_DESCRIPTOR
|
||||||
&& reference.type == "Ljava/lang/String;"
|
&& reference.type == "Ljava/lang/String;"
|
||||||
}?.getReference<FieldReference>() ?: throw PatchException("Could not find clientInfoClientModelField")
|
}?.getReference<FieldReference>()
|
||||||
}
|
?: throw PatchException("Could not find clientInfoClientModelField")
|
||||||
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
@ -167,12 +180,13 @@ object SpoofClientPatch : BaseBytecodePatch(
|
|||||||
|
|
||||||
val checkCastInstruction = getInstruction<OneRegisterInstruction>(checkCastIndex)
|
val checkCastInstruction = getInstruction<OneRegisterInstruction>(checkCastIndex)
|
||||||
val requestMessageInstanceRegister = checkCastInstruction.registerA
|
val requestMessageInstanceRegister = checkCastInstruction.registerA
|
||||||
val clientInfoContainerClassName = checkCastInstruction.getReference<TypeReference>()!!.type
|
val clientInfoContainerClassName =
|
||||||
|
checkCastInstruction.getReference<TypeReference>()!!.type
|
||||||
|
|
||||||
addInstruction(
|
addInstruction(
|
||||||
checkCastIndex + 1,
|
checkCastIndex + 1,
|
||||||
"invoke-static { v$requestMessageInstanceRegister }," +
|
"invoke-static { v$requestMessageInstanceRegister }," +
|
||||||
" $definingClass->$setClientInfoMethodName($clientInfoContainerClassName)V",
|
" $definingClass->$setClientInfoMethodName($clientInfoContainerClassName)V",
|
||||||
)
|
)
|
||||||
|
|
||||||
// Change client info to use the spoofed values.
|
// Change client info to use the spoofed values.
|
||||||
@ -181,7 +195,13 @@ object SpoofClientPatch : BaseBytecodePatch(
|
|||||||
ImmutableMethod(
|
ImmutableMethod(
|
||||||
definingClass,
|
definingClass,
|
||||||
setClientInfoMethodName,
|
setClientInfoMethodName,
|
||||||
listOf(ImmutableMethodParameter(clientInfoContainerClassName, annotations, "clientInfoContainer")),
|
listOf(
|
||||||
|
ImmutableMethodParameter(
|
||||||
|
clientInfoContainerClassName,
|
||||||
|
annotations,
|
||||||
|
"clientInfoContainer"
|
||||||
|
)
|
||||||
|
),
|
||||||
"V",
|
"V",
|
||||||
AccessFlags.PRIVATE or AccessFlags.STATIC,
|
AccessFlags.PRIVATE or AccessFlags.STATIC,
|
||||||
annotations,
|
annotations,
|
||||||
@ -229,7 +249,7 @@ object SpoofClientPatch : BaseBytecodePatch(
|
|||||||
|
|
||||||
PlayerResponseMethodHookPatch += PlayerResponseMethodHookPatch.Hook.PlayerParameter(
|
PlayerResponseMethodHookPatch += PlayerResponseMethodHookPatch.Hook.PlayerParameter(
|
||||||
"$INTEGRATIONS_CLASS_DESCRIPTOR->setPlayerResponseVideoId(" +
|
"$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
|
// endregion
|
||||||
@ -238,18 +258,19 @@ object SpoofClientPatch : BaseBytecodePatch(
|
|||||||
|
|
||||||
PlayerGestureConfigSyntheticFingerprint.resultOrThrow().let {
|
PlayerGestureConfigSyntheticFingerprint.resultOrThrow().let {
|
||||||
arrayOf(3, 9).forEach { offSet ->
|
arrayOf(3, 9).forEach { offSet ->
|
||||||
it.getWalkerMethod(context, it.scanResult.patternScanResult!!.endIndex - offSet).apply {
|
it.getWalkerMethod(context, it.scanResult.patternScanResult!!.endIndex - offSet)
|
||||||
val index = implementation!!.instructions.size - 1
|
.apply {
|
||||||
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
val index = implementation!!.instructions.size - 1
|
||||||
|
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
index,
|
index,
|
||||||
"""
|
"""
|
||||||
invoke-static {v$register}, $INTEGRATIONS_CLASS_DESCRIPTOR->enablePlayerGesture(Z)Z
|
invoke-static {v$register}, $INTEGRATIONS_CLASS_DESCRIPTOR->enablePlayerGesture(Z)Z
|
||||||
move-result v$register
|
move-result v$register
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package app.revanced.patches.youtube.utils.fix.client.fingerprints
|
package app.revanced.patches.youtube.utils.fix.client.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patcher.fingerprint.annotation.FuzzyPatternScanMethod
|
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
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.patches.youtube.utils.fix.client.fingerprints.PlayerGestureConfigSyntheticFingerprint.indexOfDownAndOutAllowedInstruction
|
||||||
import app.revanced.util.getReference
|
import app.revanced.util.getReference
|
||||||
import app.revanced.util.indexOfFirstInstruction
|
import app.revanced.util.indexOfFirstInstruction
|
||||||
|
@ -28,14 +28,18 @@ object DoubleBackToClosePatch : BytecodePatch(
|
|||||||
/**
|
/**
|
||||||
* Hook onBackPressed method inside MainActivity (WatchWhileActivity)
|
* 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
|
* Inject the methods which start of ScrollView
|
||||||
*/
|
*/
|
||||||
ScrollPositionFingerprint.resultOrThrow().let {
|
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
|
val insertIndex = walkerMethod.implementation!!.instructions.size - 1 - 1
|
||||||
|
|
||||||
walkerMethod.injectScrollView(insertIndex, "onStartScrollView")
|
walkerMethod.injectScrollView(insertIndex, "onStartScrollView")
|
||||||
@ -46,11 +50,12 @@ object DoubleBackToClosePatch : BytecodePatch(
|
|||||||
* Inject the methods which stop of ScrollView
|
* Inject the methods which stop of ScrollView
|
||||||
*/
|
*/
|
||||||
ScrollTopParentFingerprint.resultOrThrow().let { parentResult ->
|
ScrollTopParentFingerprint.resultOrThrow().let { parentResult ->
|
||||||
ScrollTopFingerprint.also { it.resolve(context, parentResult.classDef) }.resultOrThrow().let {
|
ScrollTopFingerprint.also { it.resolve(context, parentResult.classDef) }.resultOrThrow()
|
||||||
val insertIndex = it.scanResult.patternScanResult!!.endIndex
|
.let {
|
||||||
|
val insertIndex = it.scanResult.patternScanResult!!.endIndex
|
||||||
|
|
||||||
it.mutableMethod.injectScrollView(insertIndex, "onStopScrollView")
|
it.mutableMethod.injectScrollView(insertIndex, "onStopScrollView")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -33,8 +33,12 @@ object FullscreenButtonViewStubPatch : BytecodePatch(
|
|||||||
).forEach { (fingerprint, literalValue) ->
|
).forEach { (fingerprint, literalValue) ->
|
||||||
fingerprint.result?.let {
|
fingerprint.result?.let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val targetIndex = getTargetIndex(getWideLiteralInstructionIndex(literalValue.toLong()), Opcode.MOVE_RESULT)
|
val targetIndex = getTargetIndex(
|
||||||
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
getWideLiteralInstructionIndex(literalValue.toLong()),
|
||||||
|
Opcode.MOVE_RESULT
|
||||||
|
)
|
||||||
|
val targetRegister =
|
||||||
|
getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||||
|
|
||||||
addInstruction(
|
addInstruction(
|
||||||
targetIndex + 1,
|
targetIndex + 1,
|
||||||
|
@ -6,8 +6,8 @@ import com.android.tools.smali.dexlib2.AccessFlags
|
|||||||
import com.android.tools.smali.dexlib2.Opcode
|
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(
|
internal object StoryboardRendererDecoderSpecFingerprint : MethodFingerprint(
|
||||||
returnType = "V",
|
returnType = "V",
|
||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
|
@ -27,7 +27,8 @@ object ShortsPlaybackPatch : BytecodePatch(
|
|||||||
*/
|
*/
|
||||||
ShortsPlaybackFingerprint.result?.let {
|
ShortsPlaybackFingerprint.result?.let {
|
||||||
it.mutableMethod.apply {
|
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
|
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||||
|
|
||||||
addInstruction(
|
addInstruction(
|
||||||
|
@ -32,14 +32,18 @@ object SuggestedVideoEndScreenPatch : BytecodePatch(
|
|||||||
* Automatically closing the suggested video end screen is not appropriate as it will disable the autoplay behavior.
|
* Automatically closing the suggested video end screen is not appropriate as it will disable the autoplay behavior.
|
||||||
*/
|
*/
|
||||||
RemoveOnLayoutChangeListenerFingerprint.resultOrThrow().let {
|
RemoveOnLayoutChangeListenerFingerprint.resultOrThrow().let {
|
||||||
val walkerIndex = it.getWalkerMethod(context, it.scanResult.patternScanResult!!.endIndex)
|
val walkerIndex =
|
||||||
|
it.getWalkerMethod(context, it.scanResult.patternScanResult!!.endIndex)
|
||||||
|
|
||||||
walkerIndex.apply {
|
walkerIndex.apply {
|
||||||
val invokeInterfaceIndex = getTargetIndex(Opcode.INVOKE_INTERFACE)
|
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 invokeInterfaceReference =
|
||||||
val iGetObjectReference = getInstruction<ReferenceInstruction>(iGetObjectIndex).reference
|
getInstruction<ReferenceInstruction>(invokeInterfaceIndex).reference
|
||||||
|
val iGetObjectReference =
|
||||||
|
getInstruction<ReferenceInstruction>(iGetObjectIndex).reference
|
||||||
|
|
||||||
addInstructionsWithLabels(
|
addInstructionsWithLabels(
|
||||||
0,
|
0,
|
||||||
|
@ -15,7 +15,12 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
|
|||||||
fromPackageName = ORIGINAL_PACKAGE_NAME_YOUTUBE,
|
fromPackageName = ORIGINAL_PACKAGE_NAME_YOUTUBE,
|
||||||
mainActivityOnCreateFingerprint = MainActivityFingerprint,
|
mainActivityOnCreateFingerprint = MainActivityFingerprint,
|
||||||
integrationsPatchDependency = IntegrationsPatch::class,
|
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,
|
gmsCoreSupportResourcePatch = GmsCoreSupportResourcePatch,
|
||||||
compatiblePackages = COMPATIBLE_PACKAGE
|
compatiblePackages = COMPATIBLE_PACKAGE
|
||||||
)
|
)
|
||||||
|
@ -20,7 +20,8 @@ object Constants {
|
|||||||
const val VIDEO_PATH = "$PATCHES_PATH/video"
|
const val VIDEO_PATH = "$PATCHES_PATH/video"
|
||||||
|
|
||||||
const val ADS_CLASS_DESCRIPTOR = "$ADS_PATH/AdsPatch;"
|
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 FEED_CLASS_DESCRIPTOR = "$FEED_PATH/FeedPatch;"
|
||||||
const val GENERAL_CLASS_DESCRIPTOR = "$GENERAL_PATH/GeneralPatch;"
|
const val GENERAL_CLASS_DESCRIPTOR = "$GENERAL_PATH/GeneralPatch;"
|
||||||
const val PLAYER_CLASS_DESCRIPTOR = "$PLAYER_PATH/PlayerPatch;"
|
const val PLAYER_CLASS_DESCRIPTOR = "$PLAYER_PATH/PlayerPatch;"
|
||||||
|
@ -72,14 +72,16 @@ object NavigationBarHookPatch : BytecodePatch(
|
|||||||
resolve(context, PivotBarConstructorFingerprint.resultOrThrow().classDef)
|
resolve(context, PivotBarConstructorFingerprint.resultOrThrow().classDef)
|
||||||
}.resultOrThrow().mutableMethod.apply {
|
}.resultOrThrow().mutableMethod.apply {
|
||||||
// Hook the current navigation bar enum value. Note, the 'You' tab does not have an enum value.
|
// 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) {
|
addHook(Hook.SET_LAST_APP_NAVIGATION_ENUM) {
|
||||||
opcode == Opcode.INVOKE_STATIC &&
|
opcode == Opcode.INVOKE_STATIC &&
|
||||||
getReference<MethodReference>()?.definingClass == navigationEnumClassName
|
getReference<MethodReference>()?.definingClass == navigationEnumClassName
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hook the creation of navigation tab views.
|
// Hook the creation of navigation tab views.
|
||||||
val drawableTabMethod = PivotBarButtonsCreateDrawableViewFingerprint.resultOrThrow().mutableMethod
|
val drawableTabMethod =
|
||||||
|
PivotBarButtonsCreateDrawableViewFingerprint.resultOrThrow().mutableMethod
|
||||||
addHook(Hook.NAVIGATION_TAB_LOADED) predicate@{
|
addHook(Hook.NAVIGATION_TAB_LOADED) predicate@{
|
||||||
MethodUtil.methodSignaturesMatch(
|
MethodUtil.methodSignaturesMatch(
|
||||||
getReference<MethodReference>() ?: return@predicate false,
|
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@{
|
addHook(Hook.NAVIGATION_IMAGE_RESOURCE_TAB_LOADED) predicate@{
|
||||||
MethodUtil.methodSignaturesMatch(
|
MethodUtil.methodSignaturesMatch(
|
||||||
getReference<MethodReference>() ?: return@predicate false,
|
getReference<MethodReference>() ?: return@predicate false,
|
||||||
@ -111,11 +114,15 @@ object NavigationBarHookPatch : BytecodePatch(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
navigationTabCreatedCallback = context.findClass(INTEGRATIONS_CLASS_DESCRIPTOR)?.mutableClass?.methods?.first { method ->
|
navigationTabCreatedCallback =
|
||||||
method.name == "navigationTabCreatedCallback"
|
context.findClass(INTEGRATIONS_CLASS_DESCRIPTOR)?.mutableClass?.methods?.first { method ->
|
||||||
} ?: throw PatchException("Could not find navigationTabCreatedCallback 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 {
|
val hookNavigationButtonCreated: (String) -> Unit by lazy {
|
||||||
@ -133,7 +140,10 @@ object NavigationBarHookPatch : BytecodePatch(
|
|||||||
private enum class Hook(val methodName: String, val parameters: String) {
|
private enum class Hook(val methodName: String, val parameters: String) {
|
||||||
SET_LAST_APP_NAVIGATION_ENUM("setLastAppNavigationEnum", "Ljava/lang/Enum;"),
|
SET_LAST_APP_NAVIGATION_ENUM("setLastAppNavigationEnum", "Ljava/lang/Enum;"),
|
||||||
NAVIGATION_TAB_LOADED("navigationTabLoaded", "Landroid/view/View;"),
|
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;"),
|
SEARCH_BAR_RESULTS_VIEW_LOADED("searchBarResultsViewLoaded", "Landroid/view/View;"),
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -32,7 +32,8 @@ object PlayerControlsVisibilityHookPatch : BytecodePatch(
|
|||||||
|
|
||||||
it.mutableClass.methods.find { method -> method.name == "<init>" }?.apply {
|
it.mutableClass.methods.find { method -> method.name == "<init>" }?.apply {
|
||||||
val targetIndex = getTargetIndex(Opcode.IPUT_OBJECT)
|
val targetIndex = getTargetIndex(Opcode.IPUT_OBJECT)
|
||||||
val targetRegister = getInstruction<TwoRegisterInstruction>(targetIndex).registerA
|
val targetRegister =
|
||||||
|
getInstruction<TwoRegisterInstruction>(targetIndex).registerA
|
||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
targetIndex + 1, """
|
targetIndex + 1, """
|
||||||
|
@ -59,7 +59,8 @@ object PlayerTypeHookPatch : BytecodePatch(
|
|||||||
// region patch for set video state
|
// region patch for set video state
|
||||||
|
|
||||||
YouTubeControlsOverlayFingerprint.resultOrThrow().let { parentResult ->
|
YouTubeControlsOverlayFingerprint.resultOrThrow().let { parentResult ->
|
||||||
VideoStateFingerprint.also { it.resolve(context, parentResult.classDef)
|
VideoStateFingerprint.also {
|
||||||
|
it.resolve(context, parentResult.classDef)
|
||||||
}.resultOrThrow().let {
|
}.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val endIndex = it.scanResult.patternScanResult!!.endIndex
|
val endIndex = it.scanResult.patternScanResult!!.endIndex
|
||||||
@ -84,7 +85,8 @@ object PlayerTypeHookPatch : BytecodePatch(
|
|||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val targetIndex = getStringInstructionIndex("VL") - 1
|
val targetIndex = getStringInstructionIndex("VL") - 1
|
||||||
val targetReference = getInstruction<ReferenceInstruction>(targetIndex).reference
|
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>" }
|
targetClass.methods.find { method -> method.name == "<init>" }
|
||||||
?.apply {
|
?.apply {
|
||||||
|
@ -175,7 +175,8 @@ object SharedResourceIdPatch : ResourcePatch() {
|
|||||||
RightComment = getId(DRAWABLE, "ic_right_comment_32c")
|
RightComment = getId(DRAWABLE, "ic_right_comment_32c")
|
||||||
ScrimOverlay = getId(ID, "scrim_overlay")
|
ScrimOverlay = getId(ID, "scrim_overlay")
|
||||||
Scrubbing = getId(DIMEN, "vertical_touch_offset_to_enter_fine_scrubbing")
|
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")
|
SeekUndoEduOverlayStub = getId(ID, "seek_undo_edu_overlay_stub")
|
||||||
SingleLoopEduSnackBarText = getId(STRING, "single_loop_edu_snackbar_text")
|
SingleLoopEduSnackBarText = getId(STRING, "single_loop_edu_snackbar_text")
|
||||||
SlidingDialogAnimation = getId(STYLE, "SlidingDialogAnimation")
|
SlidingDialogAnimation = getId(STYLE, "SlidingDialogAnimation")
|
||||||
@ -186,9 +187,11 @@ object SharedResourceIdPatch : ResourcePatch() {
|
|||||||
TotalTime = getId(STRING, "total_time")
|
TotalTime = getId(STRING, "total_time")
|
||||||
TouchArea = getId(ID, "touch_area")
|
TouchArea = getId(ID, "touch_area")
|
||||||
VideoQualityBottomSheet = getId(LAYOUT, "video_quality_bottom_sheet_list_fragment_title")
|
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")
|
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")
|
YtOutlinePiPWhite = getId(DRAWABLE, "yt_outline_picture_in_picture_white_24")
|
||||||
YtOutlineVideoCamera = getId(DRAWABLE, "yt_outline_video_camera_black_24")
|
YtOutlineVideoCamera = getId(DRAWABLE, "yt_outline_video_camera_black_24")
|
||||||
YtOutlineXWhite = getId(DRAWABLE, "yt_outline_x_white_24")
|
YtOutlineXWhite = getId(DRAWABLE, "yt_outline_x_white_24")
|
||||||
|
@ -70,13 +70,17 @@ object ReturnYouTubeDislikePatch : BaseBytecodePatch(
|
|||||||
|
|
||||||
TextComponentContextFingerprint.resultOrThrow().let {
|
TextComponentContextFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val conversionContextFieldIndex = getTargetIndexWithFieldReferenceType("Ljava/util/Map;") - 1
|
val conversionContextFieldIndex =
|
||||||
|
getTargetIndexWithFieldReferenceType("Ljava/util/Map;") - 1
|
||||||
val conversionContextFieldReference =
|
val conversionContextFieldReference =
|
||||||
getInstruction<ReferenceInstruction>(conversionContextFieldIndex).reference
|
getInstruction<ReferenceInstruction>(conversionContextFieldIndex).reference
|
||||||
|
|
||||||
val charSequenceIndex = getTargetIndexWithFieldReferenceType("Ljava/util/BitSet;") - 1
|
val charSequenceIndex =
|
||||||
val charSequenceRegister = getInstruction<TwoRegisterInstruction>(charSequenceIndex).registerA
|
getTargetIndexWithFieldReferenceType("Ljava/util/BitSet;") - 1
|
||||||
val freeRegister = getInstruction<TwoRegisterInstruction>(charSequenceIndex).registerB
|
val charSequenceRegister =
|
||||||
|
getInstruction<TwoRegisterInstruction>(charSequenceIndex).registerA
|
||||||
|
val freeRegister =
|
||||||
|
getInstruction<TwoRegisterInstruction>(charSequenceIndex).registerB
|
||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
charSequenceIndex - 1, """
|
charSequenceIndex - 1, """
|
||||||
|
@ -71,7 +71,8 @@ object ReturnYouTubeDislikeShortsPatch : BytecodePatch(
|
|||||||
if (SettingsPatch.upward1834) {
|
if (SettingsPatch.upward1834) {
|
||||||
TextComponentSpecFingerprint.resultOrThrow().let {
|
TextComponentSpecFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
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 =
|
val charSequenceRegister =
|
||||||
getInstruction<FiveRegisterInstruction>(insertIndex).registerC
|
getInstruction<FiveRegisterInstruction>(insertIndex).registerC
|
||||||
|
@ -46,11 +46,21 @@ object SettingsBytecodePatch : BytecodePatch(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MainActivityResolvePatch.injectOnCreateMethodCall(INTEGRATIONS_INITIALIZATION_CLASS_DESCRIPTOR, "setExtendedUtils")
|
MainActivityResolvePatch.injectOnCreateMethodCall(
|
||||||
MainActivityResolvePatch.injectOnCreateMethodCall(INTEGRATIONS_INITIALIZATION_CLASS_DESCRIPTOR, "onCreate")
|
INTEGRATIONS_INITIALIZATION_CLASS_DESCRIPTOR,
|
||||||
MainActivityResolvePatch.injectConstructorMethodCall(INTEGRATIONS_UTILS_CLASS_DESCRIPTOR, "setActivity")
|
"setExtendedUtils"
|
||||||
|
)
|
||||||
|
MainActivityResolvePatch.injectOnCreateMethodCall(
|
||||||
|
INTEGRATIONS_INITIALIZATION_CLASS_DESCRIPTOR,
|
||||||
|
"onCreate"
|
||||||
|
)
|
||||||
|
MainActivityResolvePatch.injectConstructorMethodCall(
|
||||||
|
INTEGRATIONS_UTILS_CLASS_DESCRIPTOR,
|
||||||
|
"setActivity"
|
||||||
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun MutableMethod.injectCall(index: Int) {
|
private fun MutableMethod.injectCall(index: Int) {
|
||||||
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
||||||
|
|
||||||
|
@ -199,9 +199,11 @@ object SettingsPatch : BaseResourcePatch(
|
|||||||
|
|
||||||
// region set ReVanced Integrations Version
|
// 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 versionNameField = buildConfigMutableClass.fields.single { it.name == "VERSION_NAME" }
|
||||||
val versionName = versionNameField.initialValue.toString().trim().replace("\"","").replace(""", "")
|
val versionName =
|
||||||
|
versionNameField.initialValue.toString().trim().replace("\"", "").replace(""", "")
|
||||||
|
|
||||||
contexts.updatePatchStatusSettings(
|
contexts.updatePatchStatusSettings(
|
||||||
"ReVanced Integrations",
|
"ReVanced Integrations",
|
||||||
|
@ -133,7 +133,8 @@ object SponsorBlockBytecodePatch : BytecodePatch(
|
|||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val targetIndex = getWideLiteralInstructionIndex(InsetOverlayViewLayout)
|
val targetIndex = getWideLiteralInstructionIndex(InsetOverlayViewLayout)
|
||||||
val checkCastIndex = getTargetIndex(targetIndex, Opcode.CHECK_CAST)
|
val checkCastIndex = getTargetIndex(targetIndex, Opcode.CHECK_CAST)
|
||||||
val targetRegister = getInstruction<OneRegisterInstruction>(checkCastIndex).registerA
|
val targetRegister =
|
||||||
|
getInstruction<OneRegisterInstruction>(checkCastIndex).registerA
|
||||||
|
|
||||||
addInstruction(
|
addInstruction(
|
||||||
checkCastIndex + 1,
|
checkCastIndex + 1,
|
||||||
@ -146,8 +147,12 @@ object SponsorBlockBytecodePatch : BytecodePatch(
|
|||||||
RectangleFieldInvalidatorFingerprint.resultOrThrow().let { result ->
|
RectangleFieldInvalidatorFingerprint.resultOrThrow().let { result ->
|
||||||
result.mutableMethod.apply {
|
result.mutableMethod.apply {
|
||||||
val invalidateIndex = getTargetIndexWithMethodReferenceNameReversed("invalidate")
|
val invalidateIndex = getTargetIndexWithMethodReferenceNameReversed("invalidate")
|
||||||
val rectangleIndex = getTargetIndexWithFieldReferenceTypeReversed(invalidateIndex + 1, "Landroid/graphics/Rect;")
|
val rectangleIndex = getTargetIndexWithFieldReferenceTypeReversed(
|
||||||
val rectangleFieldName = (getInstruction<ReferenceInstruction>(rectangleIndex).reference as FieldReference).name
|
invalidateIndex + 1,
|
||||||
|
"Landroid/graphics/Rect;"
|
||||||
|
)
|
||||||
|
val rectangleFieldName =
|
||||||
|
(getInstruction<ReferenceInstruction>(rectangleIndex).reference as FieldReference).name
|
||||||
|
|
||||||
SegmentPlaybackControllerFingerprint.resultOrThrow().let {
|
SegmentPlaybackControllerFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
|
@ -25,9 +25,10 @@ object ViewGroupMarginLayoutParamsHookPatch : BytecodePatch(
|
|||||||
|
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
|
|
||||||
val method = context.findClass(INTEGRATIONS_CLASS_DESCRIPTOR)?.mutableClass?.methods?.first { method ->
|
val method =
|
||||||
method.name == "hideViewGroupByMarginLayoutParams"
|
context.findClass(INTEGRATIONS_CLASS_DESCRIPTOR)?.mutableClass?.methods?.first { method ->
|
||||||
} ?: throw PatchException("Could not find hideViewGroupByMarginLayoutParams method")
|
method.name == "hideViewGroupByMarginLayoutParams"
|
||||||
|
} ?: throw PatchException("Could not find hideViewGroupByMarginLayoutParams method")
|
||||||
|
|
||||||
SetViewGroupMarginFingerprint.resolve(
|
SetViewGroupMarginFingerprint.resolve(
|
||||||
context,
|
context,
|
||||||
|
@ -92,6 +92,7 @@ object VideoInformationPatch : BytecodePatch(
|
|||||||
private const val REGISTER_VIDEO_ID = 2
|
private const val REGISTER_VIDEO_ID = 2
|
||||||
private const val REGISTER_VIDEO_TITLE = 3
|
private const val REGISTER_VIDEO_TITLE = 3
|
||||||
private const val REGISTER_VIDEO_LENGTH = 4
|
private const val REGISTER_VIDEO_LENGTH = 4
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
private const val REGISTER_VIDEO_LENGTH_DUMMY = 5
|
private const val REGISTER_VIDEO_LENGTH_DUMMY = 5
|
||||||
private const val REGISTER_VIDEO_IS_LIVE = 6
|
private const val REGISTER_VIDEO_IS_LIVE = 6
|
||||||
@ -118,7 +119,8 @@ object VideoInformationPatch : BytecodePatch(
|
|||||||
internal lateinit var videoEndMethod: MutableMethod
|
internal lateinit var videoEndMethod: MutableMethod
|
||||||
|
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
val videoInformationMutableClass = context.findClass(INTEGRATIONS_CLASS_DESCRIPTOR)!!.mutableClass
|
val videoInformationMutableClass =
|
||||||
|
context.findClass(INTEGRATIONS_CLASS_DESCRIPTOR)!!.mutableClass
|
||||||
|
|
||||||
VideoEndFingerprint.resultOrThrow().let {
|
VideoEndFingerprint.resultOrThrow().let {
|
||||||
|
|
||||||
@ -173,7 +175,8 @@ object VideoInformationPatch : BytecodePatch(
|
|||||||
true
|
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.hookVideoId("$INTEGRATIONS_CLASS_DESCRIPTOR->setVideoId(Ljava/lang/String;)V")
|
||||||
VideoIdPatch.hookPlayerResponseVideoId(
|
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,
|
// Call before any other video id hooks,
|
||||||
// so they can use VideoInformation and check if the video id is for a Short.
|
// so they can use VideoInformation and check if the video id is for a Short.
|
||||||
PlayerResponseMethodHookPatch += PlayerResponseMethodHookPatch.Hook.PlayerParameterBeforeVideoId(
|
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
|
* Hook current playback speed
|
||||||
@ -278,7 +283,8 @@ object VideoInformationPatch : BytecodePatch(
|
|||||||
speedSelectionInsertMethod = this
|
speedSelectionInsertMethod = this
|
||||||
val speedSelectionValueInstructionIndex = getTargetIndex(Opcode.IGET)
|
val speedSelectionValueInstructionIndex = getTargetIndex(Opcode.IGET)
|
||||||
|
|
||||||
val setPlaybackSpeedContainerClassFieldIndex = getTargetIndexReversed(speedSelectionValueInstructionIndex, Opcode.IGET_OBJECT)
|
val setPlaybackSpeedContainerClassFieldIndex =
|
||||||
|
getTargetIndexReversed(speedSelectionValueInstructionIndex, Opcode.IGET_OBJECT)
|
||||||
val setPlaybackSpeedContainerClassFieldReference =
|
val setPlaybackSpeedContainerClassFieldReference =
|
||||||
getInstruction<ReferenceInstruction>(setPlaybackSpeedContainerClassFieldIndex).reference.toString()
|
getInstruction<ReferenceInstruction>(setPlaybackSpeedContainerClassFieldIndex).reference.toString()
|
||||||
|
|
||||||
@ -447,7 +453,7 @@ object VideoInformationPatch : BytecodePatch(
|
|||||||
"invoke-static { p1, p2 }, $targetMethodClass->$targetMethodName(J)V"
|
"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 {
|
resultOrThrow().mutableMethod.apply {
|
||||||
val targetIndex = indexOfFirstInstruction {
|
val targetIndex = indexOfFirstInstruction {
|
||||||
opcode == Opcode.INVOKE_INTERFACE
|
opcode == Opcode.INVOKE_INTERFACE
|
||||||
@ -465,7 +471,13 @@ object VideoInformationPatch : BytecodePatch(
|
|||||||
ImmutableMethod(
|
ImmutableMethod(
|
||||||
definingClass,
|
definingClass,
|
||||||
"setVideoInformation",
|
"setVideoInformation",
|
||||||
listOf(ImmutableMethodParameter(PLAYER_RESPONSE_MODEL_CLASS_DESCRIPTOR, annotations, null)),
|
listOf(
|
||||||
|
ImmutableMethodParameter(
|
||||||
|
PLAYER_RESPONSE_MODEL_CLASS_DESCRIPTOR,
|
||||||
|
annotations,
|
||||||
|
null
|
||||||
|
)
|
||||||
|
),
|
||||||
"V",
|
"V",
|
||||||
AccessFlags.PRIVATE or AccessFlags.FINAL,
|
AccessFlags.PRIVATE or AccessFlags.FINAL,
|
||||||
annotations,
|
annotations,
|
||||||
|
@ -9,5 +9,5 @@ internal object VideoTitleFingerprint : LiteralValueFingerprint(
|
|||||||
returnType = "V",
|
returnType = "V",
|
||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
parameters = emptyList(),
|
parameters = emptyList(),
|
||||||
literalSupplier = { NotificationBigPictureIconWidth }
|
literalSupplier = { NotificationBigPictureIconWidth }
|
||||||
)
|
)
|
||||||
|
@ -125,7 +125,8 @@ object VideoPlaybackPatch : BaseBytecodePatch(
|
|||||||
QualityChangedFromRecyclerViewFingerprint.resultOrThrow().classDef
|
QualityChangedFromRecyclerViewFingerprint.resultOrThrow().classDef
|
||||||
)
|
)
|
||||||
|
|
||||||
val newMethod = PlaybackSpeedChangedFromRecyclerViewFingerprint.resultOrThrow().mutableMethod
|
val newMethod =
|
||||||
|
PlaybackSpeedChangedFromRecyclerViewFingerprint.resultOrThrow().mutableMethod
|
||||||
|
|
||||||
arrayOf(
|
arrayOf(
|
||||||
newMethod,
|
newMethod,
|
||||||
@ -293,7 +294,8 @@ object VideoPlaybackPatch : BaseBytecodePatch(
|
|||||||
ByteBufferArrayFingerprint.also { it.resolve(context, classDef) }.resultOrThrow().let {
|
ByteBufferArrayFingerprint.also { it.resolve(context, classDef) }.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val insertIndex = it.scanResult.patternScanResult!!.endIndex
|
val insertIndex = it.scanResult.patternScanResult!!.endIndex
|
||||||
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
val insertRegister =
|
||||||
|
getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
insertIndex, """
|
insertIndex, """
|
||||||
|
@ -95,7 +95,8 @@ object PlayerResponseMethodHookPatch :
|
|||||||
internal class VideoId(methodDescriptor: String) : Hook(methodDescriptor)
|
internal class VideoId(methodDescriptor: String) : Hook(methodDescriptor)
|
||||||
|
|
||||||
internal class PlayerParameter(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
|
override fun toString() = methodDescriptor
|
||||||
}
|
}
|
||||||
|
@ -32,15 +32,17 @@ object VideoIdPatch : BytecodePatch(
|
|||||||
*
|
*
|
||||||
* @param consumer Consumer that receives the method, insert index and video id register index.
|
* @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 ->
|
fun MethodFingerprint.setFields(consumer: (MutableMethod, Int, Int) -> Unit) =
|
||||||
val videoIdRegisterIndex = result.scanResult.patternScanResult!!.endIndex
|
resultOrThrow().let { result ->
|
||||||
|
val videoIdRegisterIndex = result.scanResult.patternScanResult!!.endIndex
|
||||||
|
|
||||||
result.mutableMethod.let {
|
result.mutableMethod.let {
|
||||||
val videoIdRegister = it.getInstruction<OneRegisterInstruction>(videoIdRegisterIndex).registerA
|
val videoIdRegister =
|
||||||
val insertIndex = videoIdRegisterIndex + 1
|
it.getInstruction<OneRegisterInstruction>(videoIdRegisterIndex).registerA
|
||||||
consumer(it, insertIndex, videoIdRegister)
|
val insertIndex = videoIdRegisterIndex + 1
|
||||||
|
consumer(it, insertIndex, videoIdRegister)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
VideoIdFingerprint.resolve(context, VideoIdParentFingerprint.resultOrThrow().classDef)
|
VideoIdFingerprint.resolve(context, VideoIdParentFingerprint.resultOrThrow().classDef)
|
||||||
|
|
||||||
|
@ -181,7 +181,8 @@ fun BytecodeContext.literalInstructionHook(
|
|||||||
.mutableClass
|
.mutableClass
|
||||||
.findMutableMethodOf(method).apply {
|
.findMutableMethodOf(method).apply {
|
||||||
val index = getWideLiteralInstructionIndex(literal)
|
val index = getWideLiteralInstructionIndex(literal)
|
||||||
val register = (instruction as OneRegisterInstruction).registerA.toString()
|
val register =
|
||||||
|
(instruction as OneRegisterInstruction).registerA.toString()
|
||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
index + 1,
|
index + 1,
|
||||||
@ -205,8 +206,7 @@ fun Method.getWideLiteralInstructionIndex(literal: Long) = implementation?.let {
|
|||||||
}
|
}
|
||||||
} ?: -1
|
} ?: -1
|
||||||
|
|
||||||
fun Method.getEmptyStringInstructionIndex()
|
fun Method.getEmptyStringInstructionIndex() = getStringInstructionIndex("")
|
||||||
= getStringInstructionIndex("")
|
|
||||||
|
|
||||||
fun Method.getStringInstructionIndex(value: String) = implementation?.let {
|
fun Method.getStringInstructionIndex(value: String) = implementation?.let {
|
||||||
it.instructions.indexOfFirst { instruction ->
|
it.instructions.indexOfFirst { instruction ->
|
||||||
@ -300,8 +300,8 @@ fun Method.getTargetIndexWithFieldReferenceName(filedName: String) = implementat
|
|||||||
}
|
}
|
||||||
} ?: -1
|
} ?: -1
|
||||||
|
|
||||||
fun MutableMethod.getTargetIndexWithFieldReferenceNameReversed(returnType: String)
|
fun MutableMethod.getTargetIndexWithFieldReferenceNameReversed(returnType: String) =
|
||||||
= getTargetIndexWithFieldReferenceTypeReversed(implementation!!.instructions.size - 1, returnType)
|
getTargetIndexWithFieldReferenceTypeReversed(implementation!!.instructions.size - 1, returnType)
|
||||||
|
|
||||||
fun MutableMethod.getTargetIndexWithFieldReferenceName(startIndex: Int, filedName: String) =
|
fun MutableMethod.getTargetIndexWithFieldReferenceName(startIndex: Int, filedName: String) =
|
||||||
implementation!!.instructions.let {
|
implementation!!.instructions.let {
|
||||||
@ -310,7 +310,10 @@ fun MutableMethod.getTargetIndexWithFieldReferenceName(startIndex: Int, filedNam
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun MutableMethod.getTargetIndexWithFieldReferenceNameReversed(startIndex: Int, filedName: String): Int {
|
fun MutableMethod.getTargetIndexWithFieldReferenceNameReversed(
|
||||||
|
startIndex: Int,
|
||||||
|
filedName: String
|
||||||
|
): Int {
|
||||||
for (index in startIndex downTo 0) {
|
for (index in startIndex downTo 0) {
|
||||||
val instruction = getInstruction(index)
|
val instruction = getInstruction(index)
|
||||||
if (instruction.getReference<FieldReference>()?.name != filedName)
|
if (instruction.getReference<FieldReference>()?.name != filedName)
|
||||||
@ -327,8 +330,8 @@ fun Method.getTargetIndexWithFieldReferenceType(returnType: String) = implementa
|
|||||||
}
|
}
|
||||||
} ?: -1
|
} ?: -1
|
||||||
|
|
||||||
fun MutableMethod.getTargetIndexWithFieldReferenceTypeReversed(returnType: String)
|
fun MutableMethod.getTargetIndexWithFieldReferenceTypeReversed(returnType: String) =
|
||||||
= getTargetIndexWithFieldReferenceTypeReversed(implementation!!.instructions.size - 1, returnType)
|
getTargetIndexWithFieldReferenceTypeReversed(implementation!!.instructions.size - 1, returnType)
|
||||||
|
|
||||||
fun MutableMethod.getTargetIndexWithFieldReferenceType(startIndex: Int, returnType: String) =
|
fun MutableMethod.getTargetIndexWithFieldReferenceType(startIndex: Int, returnType: String) =
|
||||||
implementation!!.instructions.let {
|
implementation!!.instructions.let {
|
||||||
@ -337,7 +340,10 @@ fun MutableMethod.getTargetIndexWithFieldReferenceType(startIndex: Int, returnTy
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun MutableMethod.getTargetIndexWithFieldReferenceTypeReversed(startIndex: Int, returnType: String): Int {
|
fun MutableMethod.getTargetIndexWithFieldReferenceTypeReversed(
|
||||||
|
startIndex: Int,
|
||||||
|
returnType: String
|
||||||
|
): Int {
|
||||||
for (index in startIndex downTo 0) {
|
for (index in startIndex downTo 0) {
|
||||||
val instruction = getInstruction(index)
|
val instruction = getInstruction(index)
|
||||||
if (instruction.getReference<FieldReference>()?.type != returnType)
|
if (instruction.getReference<FieldReference>()?.type != returnType)
|
||||||
@ -354,8 +360,11 @@ fun Method.getTargetIndexWithMethodReferenceName(methodName: String) = implement
|
|||||||
}
|
}
|
||||||
} ?: -1
|
} ?: -1
|
||||||
|
|
||||||
fun MutableMethod.getTargetIndexWithMethodReferenceNameReversed(methodName: String)
|
fun MutableMethod.getTargetIndexWithMethodReferenceNameReversed(methodName: String) =
|
||||||
= getTargetIndexWithMethodReferenceNameReversed(implementation!!.instructions.size - 1, methodName)
|
getTargetIndexWithMethodReferenceNameReversed(
|
||||||
|
implementation!!.instructions.size - 1,
|
||||||
|
methodName
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
fun MutableMethod.getTargetIndexWithMethodReferenceName(startIndex: Int, methodName: String) =
|
fun MutableMethod.getTargetIndexWithMethodReferenceName(startIndex: Int, methodName: String) =
|
||||||
@ -365,7 +374,10 @@ fun MutableMethod.getTargetIndexWithMethodReferenceName(startIndex: Int, methodN
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun MutableMethod.getTargetIndexWithMethodReferenceNameReversed(startIndex: Int, methodName: String): Int {
|
fun MutableMethod.getTargetIndexWithMethodReferenceNameReversed(
|
||||||
|
startIndex: Int,
|
||||||
|
methodName: String
|
||||||
|
): Int {
|
||||||
for (index in startIndex downTo 0) {
|
for (index in startIndex downTo 0) {
|
||||||
val instruction = getInstruction(index)
|
val instruction = getInstruction(index)
|
||||||
if (instruction.getReference<MethodReference>()?.name != methodName)
|
if (instruction.getReference<MethodReference>()?.name != methodName)
|
||||||
@ -494,11 +506,13 @@ fun List<MethodFingerprint>.returnEarly(bool: Boolean = false) {
|
|||||||
const/4 v0, $const
|
const/4 v0, $const
|
||||||
return-object v0
|
return-object v0
|
||||||
"""
|
"""
|
||||||
|
|
||||||
'V' -> "return-void"
|
'V' -> "return-void"
|
||||||
'I', 'Z' -> """
|
'I', 'Z' -> """
|
||||||
const/4 v0, $const
|
const/4 v0, $const
|
||||||
return v0
|
return v0
|
||||||
"""
|
"""
|
||||||
|
|
||||||
else -> throw Exception("This case should never happen.")
|
else -> throw Exception("This case should never happen.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user