refactor: fix package and code structure

This commit is contained in:
inotia00 2024-03-31 06:15:20 +09:00
parent e7aa9c1b41
commit 135f8d852d
210 changed files with 1396 additions and 1414 deletions

View File

@ -16,13 +16,13 @@ import app.revanced.patches.music.ads.music.MusicAdsPatch
import app.revanced.patches.music.navigation.component.NavigationBarComponentPatch import app.revanced.patches.music.navigation.component.NavigationBarComponentPatch
import app.revanced.patches.music.utils.integrations.Constants.ADS_PATH import app.revanced.patches.music.utils.integrations.Constants.ADS_PATH
import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH
import app.revanced.patches.music.utils.litho.LithoFilterPatch
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.ButtonContainer import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.ButtonContainer
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.FloatingLayout import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.FloatingLayout
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.InterstitialsContainer import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.InterstitialsContainer
import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.shared.litho.LithoFilterPatch
import app.revanced.util.exception import app.revanced.util.exception
import app.revanced.util.getWideLiteralInstructionIndex import app.revanced.util.getWideLiteralInstructionIndex
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction

View File

@ -1,8 +1,9 @@
package app.revanced.patches.music.ads.music package app.revanced.patches.music.ads.music
import app.revanced.patches.music.utils.integrations.Constants.ADS_PATH import app.revanced.patches.music.utils.integrations.Constants.ADS_PATH
import app.revanced.patches.shared.patch.ads.AbstractAdsPatch import app.revanced.patches.shared.ads.AbstractAdsPatch
object MusicAdsPatch : AbstractAdsPatch( object MusicAdsPatch : AbstractAdsPatch(
"$ADS_PATH/MusicAdsPatch;->hideMusicAds()Z" "$ADS_PATH/MusicAdsPatch;",
"hideMusicAds"
) )

View File

@ -11,11 +11,11 @@ import app.revanced.patches.music.flyoutpanel.component.fingerprints.SleepTimerF
import app.revanced.patches.music.flyoutpanel.shared.FlyoutPanelMenuItemPatch import app.revanced.patches.music.flyoutpanel.shared.FlyoutPanelMenuItemPatch
import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH
import app.revanced.patches.music.utils.integrations.Constants.FLYOUT import app.revanced.patches.music.utils.integrations.Constants.FLYOUT
import app.revanced.patches.music.utils.litho.LithoFilterPatch
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.EndButtonsContainer import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.EndButtonsContainer
import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.shared.litho.LithoFilterPatch
import app.revanced.util.exception import app.revanced.util.exception
import app.revanced.util.getTargetIndex import app.revanced.util.getTargetIndex
import app.revanced.util.getWideLiteralInstructionIndex import app.revanced.util.getWideLiteralInstructionIndex

View File

@ -5,13 +5,13 @@ import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.utils.integrations.Constants.UTILS_PATH import app.revanced.patches.music.utils.integrations.Constants.UTILS_PATH
import app.revanced.patches.shared.patch.litho.LithoThemePatch import app.revanced.patches.shared.drawable.DrawableColorPatch
import org.w3c.dom.Element import org.w3c.dom.Element
@Patch( @Patch(
name = "Amoled", name = "Amoled",
description = "Applies a pure black theme to some components.", description = "Applies a pure black theme to some components.",
dependencies = [LithoThemePatch::class], dependencies = [DrawableColorPatch::class],
compatiblePackages = [ compatiblePackages = [
CompatiblePackage( CompatiblePackage(
"com.google.android.apps.youtube.music", "com.google.android.apps.youtube.music",
@ -34,7 +34,7 @@ import org.w3c.dom.Element
object AmoledPatch : ResourcePatch() { object AmoledPatch : ResourcePatch() {
override fun execute(context: ResourceContext) { override fun execute(context: ResourceContext) {
LithoThemePatch.injectCall("$UTILS_PATH/LithoThemePatch;->applyLithoTheme(I)I") DrawableColorPatch.injectCall("$UTILS_PATH/DrawableColorPatch;->getColor(I)I")
context.xmlEditor["res/values/colors.xml"].use { editor -> context.xmlEditor["res/values/colors.xml"].use { editor ->
val resourcesNode = editor.file.getElementsByTagName("resources").item(0) as Element val resourcesNode = editor.file.getElementsByTagName("resources").item(0) as Element

View File

@ -7,7 +7,7 @@ import app.revanced.patches.music.utils.integrations.Constants.GENERAL
import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.music.video.videoid.VideoIdPatch import app.revanced.patches.music.video.videoid.VideoIdPatch
import app.revanced.patches.shared.patch.captions.AbstractAutoCaptionsPatch import app.revanced.patches.shared.captions.AbstractAutoCaptionsPatch
@Patch( @Patch(
name = "Disable auto captions", name = "Disable auto captions",

View File

@ -5,9 +5,9 @@ import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH
import app.revanced.patches.music.utils.litho.LithoFilterPatch
import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.shared.litho.LithoFilterPatch
@Patch( @Patch(
name = "Hide button shelf", name = "Hide button shelf",

View File

@ -5,9 +5,9 @@ import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH
import app.revanced.patches.music.utils.litho.LithoFilterPatch
import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.shared.litho.LithoFilterPatch
@Patch( @Patch(
name = "Hide carousel shelf", name = "Hide carousel shelf",

View File

@ -5,9 +5,9 @@ import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH
import app.revanced.patches.music.utils.litho.LithoFilterPatch
import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.shared.litho.LithoFilterPatch
@Patch( @Patch(
name = "Hide channel guidelines", name = "Hide channel guidelines",

View File

@ -5,9 +5,9 @@ import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH
import app.revanced.patches.music.utils.litho.LithoFilterPatch
import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.shared.litho.LithoFilterPatch
@Patch( @Patch(
name = "Enable custom filter", name = "Enable custom filter",

View File

@ -6,7 +6,7 @@ import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.utils.integrations.Constants.GENERAL import app.revanced.patches.music.utils.integrations.Constants.GENERAL
import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.shared.patch.dialog.AbstractRemoveViewerDiscretionDialogPatch import app.revanced.patches.shared.dialog.AbstractRemoveViewerDiscretionDialogPatch
@Patch( @Patch(
name = "Remove viewer discretion dialog", name = "Remove viewer discretion dialog",

View File

@ -5,9 +5,9 @@ import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH
import app.revanced.patches.music.utils.litho.LithoFilterPatch
import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.shared.litho.LithoFilterPatch
@Patch( @Patch(
name = "Hide emoji picker and time stamp", name = "Hide emoji picker and time stamp",

View File

@ -5,9 +5,9 @@ import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH
import app.revanced.patches.music.utils.litho.LithoFilterPatch
import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.shared.litho.LithoFilterPatch
@Patch( @Patch(
name = "Hide playlist card", name = "Hide playlist card",

View File

@ -5,9 +5,9 @@ import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH
import app.revanced.patches.music.utils.litho.LithoFilterPatch
import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.shared.litho.LithoFilterPatch
@Patch( @Patch(
name = "Hide sample shelf", name = "Hide sample shelf",

View File

@ -2,7 +2,7 @@ package app.revanced.patches.music.general.voicesearch
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.shared.patch.voicesearch.AbstractVoiceSearchButtonPatch import app.revanced.patches.shared.voicesearch.AbstractVoiceSearchButtonPatch
@Patch( @Patch(
name = "Hide voice search button", name = "Hide voice search button",

View File

@ -6,7 +6,7 @@ import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatchOption import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatchOption
import app.revanced.patches.music.utils.integrations.Constants.LANGUAGE_LIST import app.revanced.patches.music.utils.integrations.Constants.LANGUAGE_LIST
import app.revanced.patches.shared.patch.elements.AbstractRemoveStringsElementsPatch import app.revanced.patches.shared.elements.AbstractRemoveStringsElementsPatch
@Patch( @Patch(
name = "Custom branding name YouTube Music", name = "Custom branding name YouTube Music",

View File

@ -2,7 +2,7 @@ package app.revanced.patches.music.layout.doubletapbackground
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.shared.patch.overlaybackground.AbstractOverlayBackgroundPatch import app.revanced.patches.shared.overlaybackground.AbstractOverlayBackgroundPatch
@Patch( @Patch(
name = "Hide double tap overlay filter", name = "Hide double tap overlay filter",

View File

@ -2,7 +2,7 @@ package app.revanced.patches.music.layout.doubletapbackground
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.shared.patch.overlaybackground.AbstractOverlayBackgroundPatch import app.revanced.patches.shared.overlaybackground.AbstractOverlayBackgroundPatch
@Patch( @Patch(
name = "Hide player overlay filter", name = "Hide player overlay filter",

View File

@ -6,7 +6,7 @@ import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.utils.integrations.Constants.MISC_PATH import app.revanced.patches.music.utils.integrations.Constants.MISC_PATH
import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.shared.patch.opus.AbstractOpusCodecsPatch import app.revanced.patches.shared.opus.AbstractOpusCodecsPatch
@Patch( @Patch(
name = "Enable opus codec", name = "Enable opus codec",

View File

@ -7,7 +7,7 @@ import app.revanced.patches.music.utils.integrations.Constants.MISC_PATH
import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.music.utils.settings.SettingsPatch.contexts import app.revanced.patches.music.utils.settings.SettingsPatch.contexts
import app.revanced.patches.shared.patch.versionspoof.AbstractVersionSpoofPatch import app.revanced.patches.shared.versionspoof.AbstractVersionSpoofPatch
import app.revanced.util.copyXmlNode import app.revanced.util.copyXmlNode
@Patch( @Patch(

View File

@ -7,8 +7,8 @@ import app.revanced.patches.music.misc.tracking.fingerprints.ShareLinkFormatterF
import app.revanced.patches.music.utils.integrations.Constants.MISC_PATH import app.revanced.patches.music.utils.integrations.Constants.MISC_PATH
import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.shared.fingerprints.tracking.CopyTextEndpointFingerprint import app.revanced.patches.shared.tracking.AbstractSanitizeUrlQueryPatch
import app.revanced.patches.shared.patch.tracking.AbstractSanitizeUrlQueryPatch import app.revanced.patches.shared.tracking.fingerprints.CopyTextEndpointFingerprint
@Patch( @Patch(
name = "Sanitize sharing links", name = "Sanitize sharing links",

View File

@ -3,7 +3,7 @@ package app.revanced.patches.music.misc.translations
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.utils.settings.SettingsPatch import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.shared.patch.translations.AbstractTranslationsPatch import app.revanced.patches.shared.translations.AbstractTranslationsPatch
@Patch( @Patch(
name = "Translations", name = "Translations",

View File

@ -8,8 +8,8 @@ import app.revanced.patcher.extensions.or
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.utils.fingerprints.SwitchToggleColorFingerprint
import app.revanced.patches.music.utils.fingerprints.MiniPlayerConstructorFingerprint import app.revanced.patches.music.utils.fingerprints.MiniPlayerConstructorFingerprint
import app.revanced.patches.music.utils.fingerprints.SwitchToggleColorFingerprint
import app.revanced.patches.music.utils.integrations.Constants.PLAYER import app.revanced.patches.music.utils.integrations.Constants.PLAYER
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.ColorGrey import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.ColorGrey

View File

@ -6,8 +6,8 @@ import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.DomFileEditor import app.revanced.patcher.util.DomFileEditor
import app.revanced.patches.music.utils.settings.SettingsPatch import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.util.adoptChild import app.revanced.util.adoptChild
import app.revanced.util.insertNode
import app.revanced.util.doRecursively import app.revanced.util.doRecursively
import app.revanced.util.insertNode
import org.w3c.dom.Element import org.w3c.dom.Element
import java.io.Closeable import java.io.Closeable

View File

@ -1,5 +1,5 @@
package app.revanced.patches.music.utils.fix.clientspoof package app.revanced.patches.music.utils.fix.clientspoof
import app.revanced.patches.shared.patch.clientspoof.AbstractClientSpoofPatch import app.revanced.patches.shared.clientspoof.AbstractClientSpoofPatch
object ClientSpoofPatch : AbstractClientSpoofPatch("com.google.android.apps.youtube.music") object ClientSpoofPatch : AbstractClientSpoofPatch("com.google.android.apps.youtube.music")

View File

@ -8,7 +8,7 @@ import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.music.utils.fix.fileprovider.fingerprints.FileProviderResolverFingerprint import app.revanced.patches.music.utils.fix.fileprovider.fingerprints.FileProviderResolverFingerprint
import app.revanced.patches.shared.patch.packagename.PackageNamePatch import app.revanced.patches.shared.packagename.PackageNamePatch
import app.revanced.util.exception import app.revanced.util.exception
@Patch(dependencies = [PackageNamePatch::class]) @Patch(dependencies = [PackageNamePatch::class])

View File

@ -1,12 +1,10 @@
package app.revanced.patches.music.utils.integrations package app.revanced.patches.music.utils.integrations
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.utils.integrations.Constants.INTEGRATIONS_PATH
import app.revanced.patches.music.utils.integrations.fingerprints.InitFingerprint import app.revanced.patches.music.utils.integrations.fingerprints.InitFingerprint
import app.revanced.patches.shared.patch.integrations.AbstractIntegrationsPatch import app.revanced.patches.shared.integrations.BaseIntegrationsPatch
@Patch(requiresIntegrations = true) @Patch(requiresIntegrations = true)
object IntegrationsPatch : AbstractIntegrationsPatch( object IntegrationsPatch : BaseIntegrationsPatch(
"$INTEGRATIONS_PATH/utils/ReVancedUtils;",
setOf(InitFingerprint), setOf(InitFingerprint),
) )

View File

@ -1,8 +1,9 @@
package app.revanced.patches.music.utils.integrations.fingerprints package app.revanced.patches.music.utils.integrations.fingerprints
import app.revanced.patches.shared.patch.integrations.AbstractIntegrationsPatch.IntegrationsFingerprint import app.revanced.patches.shared.integrations.BaseIntegrationsPatch.IntegrationsFingerprint
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
@Suppress("DEPRECATION")
object InitFingerprint : IntegrationsFingerprint( object InitFingerprint : IntegrationsFingerprint(
returnType = "V", returnType = "V",
parameters = emptyList(), parameters = emptyList(),

View File

@ -1,37 +0,0 @@
package app.revanced.patches.music.utils.intenthook
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.music.utils.integrations.Constants.INTEGRATIONS_PATH
import app.revanced.patches.music.utils.integrations.IntegrationsPatch
import app.revanced.patches.music.utils.intenthook.fingerprints.GoogleApiActivityFingerprint
import app.revanced.util.exception
@Patch(
dependencies = [IntegrationsPatch::class],
requiresIntegrations = true
)
object IntentHookPatch : BytecodePatch(
setOf(GoogleApiActivityFingerprint)
) {
override fun execute(context: BytecodeContext) {
GoogleApiActivityFingerprint.result?.let {
it.mutableMethod.apply {
addInstructionsWithLabels(
1, """
invoke-static {p0}, $INTEGRATIONS_PATH/settingsmenu/ReVancedSettingActivity;->initializeSettings(Landroid/app/Activity;)Z
move-result v0
if-eqz v0, :show
return-void
""", ExternalLabel("show", getInstruction(1))
)
}
} ?: throw GoogleApiActivityFingerprint.exception
}
}

View File

@ -1,55 +0,0 @@
package app.revanced.patches.music.utils.litho
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.removeInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH
import app.revanced.patches.music.utils.litho.fingerprints.LithoFilterFingerprint
import app.revanced.patches.shared.patch.litho.ComponentParserPatch
import app.revanced.util.exception
import java.io.Closeable
@Patch(dependencies = [ComponentParserPatch::class])
object LithoFilterPatch : BytecodePatch(
setOf(LithoFilterFingerprint)
), Closeable {
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
"$COMPONENTS_PATH/LithoFilterPatch;"
internal lateinit var addFilter: (String) -> Unit
private set
private var filterCount = 0
override fun execute(context: BytecodeContext) {
ComponentParserPatch.injectCall(INTEGRATIONS_CLASS_DESCRIPTOR)
LithoFilterFingerprint.result?.let {
it.mutableMethod.apply {
removeInstructions(0, 6)
addFilter = { classDescriptor ->
addInstructions(
0, """
new-instance v1, $classDescriptor
invoke-direct {v1}, $classDescriptor-><init>()V
const/16 v2, ${filterCount++}
aput-object v1, v0, v2
"""
)
}
}
} ?: throw LithoFilterFingerprint.exception
}
override fun close() = LithoFilterFingerprint.result!!
.mutableMethod.addInstructions(
0, """
const/16 v0, $filterCount
new-array v0, v0, [$COMPONENTS_PATH/Filter;
"""
)
}

View File

@ -17,8 +17,8 @@ import app.revanced.patches.music.utils.microg.fingerprints.CastDynamiteModuleV2
import app.revanced.patches.music.utils.microg.fingerprints.GooglePlayUtilityFingerprint import app.revanced.patches.music.utils.microg.fingerprints.GooglePlayUtilityFingerprint
import app.revanced.patches.music.utils.microg.fingerprints.PrimeFingerprint import app.revanced.patches.music.utils.microg.fingerprints.PrimeFingerprint
import app.revanced.patches.music.utils.microg.fingerprints.ServiceCheckFingerprint import app.revanced.patches.music.utils.microg.fingerprints.ServiceCheckFingerprint
import app.revanced.patches.shared.patch.microg.MicroGBytecodeHelper import app.revanced.patches.shared.microg.MicroGBytecodeHelper
import app.revanced.patches.shared.patch.packagename.PackageNamePatch import app.revanced.patches.shared.packagename.PackageNamePatch
@Patch( @Patch(
name = "MicroG support", name = "MicroG support",

View File

@ -11,10 +11,10 @@ import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.ResourceUtils.addMicroGPreference import app.revanced.patches.music.utils.settings.ResourceUtils.addMicroGPreference
import app.revanced.patches.music.utils.settings.ResourceUtils.setMicroG import app.revanced.patches.music.utils.settings.ResourceUtils.setMicroG
import app.revanced.patches.music.utils.settings.SettingsPatch import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.shared.patch.microg.Constants.MICROG_PACKAGE_NAME import app.revanced.patches.shared.microg.Constants.MICROG_PACKAGE_NAME
import app.revanced.patches.shared.patch.microg.MicroGManifestHelper.addSpoofingMetadata import app.revanced.patches.shared.microg.MicroGManifestHelper.addSpoofingMetadata
import app.revanced.patches.shared.patch.microg.MicroGResourceHelper.patchManifest import app.revanced.patches.shared.microg.MicroGResourceHelper.patchManifest
import app.revanced.patches.shared.patch.packagename.PackageNamePatch import app.revanced.patches.shared.packagename.PackageNamePatch
@Patch( @Patch(
dependencies = [ dependencies = [

View File

@ -90,7 +90,7 @@ object OverrideQualityHookPatch : BytecodePatch(
addInstruction( addInstruction(
textIndex + 1, textIndex + 1,
"sput-object v$textRegister, $INTEGRATIONS_VIDEO_HELPER_CLASS_DESCRIPTOR->currentQuality:Ljava/lang/String;" "sput-object v$textRegister, $INTEGRATIONS_VIDEO_UTILS_CLASS_DESCRIPTOR->currentQuality:Ljava/lang/String;"
) )
} }
} ?: throw VideoQualityTextFingerprint.exception } ?: throw VideoQualityTextFingerprint.exception
@ -99,8 +99,8 @@ object OverrideQualityHookPatch : BytecodePatch(
private const val INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR = private const val INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR =
"$VIDEO_PATH/VideoQualityPatch;" "$VIDEO_PATH/VideoQualityPatch;"
private const val INTEGRATIONS_VIDEO_HELPER_CLASS_DESCRIPTOR = private const val INTEGRATIONS_VIDEO_UTILS_CLASS_DESCRIPTOR =
"$INTEGRATIONS_PATH/utils/VideoHelpers;" "$INTEGRATIONS_PATH/utils/VideoUtils;"
private lateinit var QUALITY_CLASS: String private lateinit var QUALITY_CLASS: String
private lateinit var QUALITY_METHOD: String private lateinit var QUALITY_METHOD: String

View File

@ -39,8 +39,8 @@ object OverrideSpeedHookPatch : BytecodePatch(
private const val INTEGRATIONS_PLAYBACK_SPEED_CLASS_DESCRIPTOR = private const val INTEGRATIONS_PLAYBACK_SPEED_CLASS_DESCRIPTOR =
"$VIDEO_PATH/PlaybackSpeedPatch;" "$VIDEO_PATH/PlaybackSpeedPatch;"
private const val INTEGRATIONS_VIDEO_HELPER_CLASS_DESCRIPTOR = private const val INTEGRATIONS_VIDEO_UTILS_CLASS_DESCRIPTOR =
"$INTEGRATIONS_PATH/utils/VideoHelpers;" "$INTEGRATIONS_PATH/utils/VideoUtils;"
private lateinit var iGetObjectReference: Reference private lateinit var iGetObjectReference: Reference
private lateinit var invokeInterfaceReference: Reference private lateinit var invokeInterfaceReference: Reference
@ -100,7 +100,7 @@ object OverrideSpeedHookPatch : BytecodePatch(
speedMethod.addInstruction( speedMethod.addInstruction(
speedMethod.implementation!!.instructions.size - 1, speedMethod.implementation!!.instructions.size - 1,
"sput p1, $INTEGRATIONS_VIDEO_HELPER_CLASS_DESCRIPTOR->currentSpeed:F" "sput p1, $INTEGRATIONS_VIDEO_UTILS_CLASS_DESCRIPTOR->currentSpeed:F"
) )
addInstructions( addInstructions(

View File

@ -3,15 +3,15 @@ package app.revanced.patches.music.utils.resourceid
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.shared.patch.mapping.ResourceMappingPatch import app.revanced.patches.shared.mapping.ResourceMappingPatch
import app.revanced.patches.shared.patch.mapping.ResourceType import app.revanced.patches.shared.mapping.ResourceType
import app.revanced.patches.shared.patch.mapping.ResourceType.BOOL import app.revanced.patches.shared.mapping.ResourceType.BOOL
import app.revanced.patches.shared.patch.mapping.ResourceType.COLOR import app.revanced.patches.shared.mapping.ResourceType.COLOR
import app.revanced.patches.shared.patch.mapping.ResourceType.DIMEN import app.revanced.patches.shared.mapping.ResourceType.DIMEN
import app.revanced.patches.shared.patch.mapping.ResourceType.ID import app.revanced.patches.shared.mapping.ResourceType.ID
import app.revanced.patches.shared.patch.mapping.ResourceType.LAYOUT import app.revanced.patches.shared.mapping.ResourceType.LAYOUT
import app.revanced.patches.shared.patch.mapping.ResourceType.STRING import app.revanced.patches.shared.mapping.ResourceType.STRING
import app.revanced.patches.shared.patch.mapping.ResourceType.STYLE import app.revanced.patches.shared.mapping.ResourceType.STYLE
@Patch(dependencies = [ResourceMappingPatch::class]) @Patch(dependencies = [ResourceMappingPatch::class])
object SharedResourceIdPatch : ResourcePatch() { object SharedResourceIdPatch : ResourcePatch() {

View File

@ -68,7 +68,7 @@ object ReturnYouTubeDislikeBytecodePatch : BytecodePatch(
addInstructions( addInstructions(
insertIndex, """ insertIndex, """
invoke-static {v$insertRegister}, $INTEGRATIONS_RYD_CLASS_DESCRIPTOR->onComponentCreated(Landroid/text/Spanned;)Landroid/text/Spanned; invoke-static {v$insertRegister}, $INTEGRATIONS_RYD_CLASS_DESCRIPTOR->onSpannedCreated(Landroid/text/Spanned;)Landroid/text/Spanned;
move-result-object v$insertRegister move-result-object v$insertRegister
""" """
) )

View File

@ -2,16 +2,23 @@ package app.revanced.patches.music.utils.settings
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.music.utils.integrations.Constants.INTEGRATIONS_PATH import app.revanced.patches.music.utils.integrations.Constants.INTEGRATIONS_PATH
import app.revanced.patches.music.utils.integrations.IntegrationsPatch import app.revanced.patches.music.utils.integrations.IntegrationsPatch
import app.revanced.patches.music.utils.mainactivity.MainActivityResolvePatch import app.revanced.patches.music.utils.mainactivity.MainActivityResolvePatch
import app.revanced.patches.music.utils.mainactivity.MainActivityResolvePatch.injectInit import app.revanced.patches.music.utils.mainactivity.MainActivityResolvePatch.injectInit
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.settings.fingerprints.SharedSettingFingerprint
import app.revanced.util.exception import app.revanced.util.exception
import app.revanced.util.getTargetIndex
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@ -24,19 +31,36 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
) )
object SettingsBytecodePatch : BytecodePatch( object SettingsBytecodePatch : BytecodePatch(
setOf( setOf(
GoogleApiActivityFingerprint,
PreferenceFingerprint, PreferenceFingerprint,
SharedSettingFingerprint,
SettingsHeadersFragmentFingerprint SettingsHeadersFragmentFingerprint
) )
) { ) {
private const val INTEGRATIONS_ACTIVITY_CLASS_DESCRIPTOR = private const val INTEGRATIONS_ACTIVITY_CLASS_DESCRIPTOR =
"$INTEGRATIONS_PATH/settingsmenu/ReVancedSettingActivity;" "$INTEGRATIONS_PATH/settings/ActivityHook;"
private const val INTEGRATIONS_FRAGMENT_CLASS_DESCRIPTOR = private const val INTEGRATIONS_FRAGMENT_CLASS_DESCRIPTOR =
"$INTEGRATIONS_PATH/settingsmenu/ReVancedSettingsFragment;" "$INTEGRATIONS_PATH/settings/preference/ReVancedPreferenceFragment;"
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
/** /**
* Inject settings Activity. * Set SharedPrefCategory
*/
SharedSettingFingerprint.result?.let {
it.mutableMethod.apply {
val stringIndex = getTargetIndex(Opcode.CONST_STRING)
val stringRegister = getInstruction<OneRegisterInstruction>(stringIndex).registerA
replaceInstruction(
stringIndex,
"const-string v$stringRegister, \"youtube\""
)
}
} ?: throw SharedSettingFingerprint.exception
/**
* Inject settings Activity
*/ */
SettingsHeadersFragmentFingerprint.result?.let { SettingsHeadersFragmentFingerprint.result?.let {
it.mutableMethod.apply { it.mutableMethod.apply {
@ -51,7 +75,7 @@ object SettingsBytecodePatch : BytecodePatch(
} ?: throw SettingsHeadersFragmentFingerprint.exception } ?: throw SettingsHeadersFragmentFingerprint.exception
/** /**
* Values are loaded when preferences change. * Values are loaded when preferences change
*/ */
PreferenceFingerprint.result?.let { PreferenceFingerprint.result?.let {
it.mutableMethod.apply { it.mutableMethod.apply {
@ -66,8 +90,24 @@ object SettingsBytecodePatch : BytecodePatch(
} }
} ?: throw PreferenceFingerprint.exception } ?: throw PreferenceFingerprint.exception
/**
* Inject dummy Activity for intent
*/
GoogleApiActivityFingerprint.result?.let {
it.mutableMethod.apply {
addInstructionsWithLabels(
1, """
invoke-static {p0}, $INTEGRATIONS_ACTIVITY_CLASS_DESCRIPTOR->initialize(Landroid/app/Activity;)Z
move-result v0
if-eqz v0, :show
return-void
""", ExternalLabel("show", getInstruction(1))
)
}
} ?: throw GoogleApiActivityFingerprint.exception
injectInit("InitializationPatch", "setDeviceInformation") injectInit("InitializationPatch", "setDeviceInformation")
injectInit("InitializationPatch", "initializeReVancedSettings") injectInit("InitializationPatch", "onCreate")
} }
} }

View File

@ -4,7 +4,6 @@ import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.utils.fix.accessibility.AccessibilityNodeInfoPatch import app.revanced.patches.music.utils.fix.accessibility.AccessibilityNodeInfoPatch
import app.revanced.patches.music.utils.intenthook.IntentHookPatch
import app.revanced.patches.music.utils.settings.ResourceUtils.YOUTUBE_MUSIC_SETTINGS_KEY import app.revanced.patches.music.utils.settings.ResourceUtils.YOUTUBE_MUSIC_SETTINGS_KEY
import app.revanced.patches.music.utils.settings.ResourceUtils.addMusicPreference import app.revanced.patches.music.utils.settings.ResourceUtils.addMusicPreference
import app.revanced.patches.music.utils.settings.ResourceUtils.addMusicPreferenceCategory import app.revanced.patches.music.utils.settings.ResourceUtils.addMusicPreferenceCategory
@ -12,7 +11,7 @@ import app.revanced.patches.music.utils.settings.ResourceUtils.addMusicPreferenc
import app.revanced.patches.music.utils.settings.ResourceUtils.addMusicPreferenceWithoutSummary import app.revanced.patches.music.utils.settings.ResourceUtils.addMusicPreferenceWithoutSummary
import app.revanced.patches.music.utils.settings.ResourceUtils.addReVancedMusicPreference import app.revanced.patches.music.utils.settings.ResourceUtils.addReVancedMusicPreference
import app.revanced.patches.music.utils.settings.ResourceUtils.sortMusicPreferenceCategory import app.revanced.patches.music.utils.settings.ResourceUtils.sortMusicPreferenceCategory
import app.revanced.patches.shared.patch.settings.AbstractSettingsResourcePatch import app.revanced.patches.shared.settings.AbstractSettingsResourcePatch
import app.revanced.util.ResourceGroup import app.revanced.util.ResourceGroup
import app.revanced.util.copyResources import app.revanced.util.copyResources
import app.revanced.util.copyXmlNode import app.revanced.util.copyXmlNode
@ -26,7 +25,6 @@ import java.util.concurrent.TimeUnit
description = "Adds ReVanced Extended settings to YouTube Music.", description = "Adds ReVanced Extended settings to YouTube Music.",
dependencies = [ dependencies = [
AccessibilityNodeInfoPatch::class, AccessibilityNodeInfoPatch::class,
IntentHookPatch::class,
SettingsBytecodePatch::class SettingsBytecodePatch::class
], ],
compatiblePackages = [ compatiblePackages = [
@ -47,7 +45,7 @@ import java.util.concurrent.TimeUnit
) )
] ]
) )
@Suppress("unused") @Suppress("DEPRECATION", "unused")
object SettingsPatch : AbstractSettingsResourcePatch( object SettingsPatch : AbstractSettingsResourcePatch(
"music/settings" "music/settings"
), Closeable { ), Closeable {

View File

@ -1,4 +1,4 @@
package app.revanced.patches.music.utils.intenthook.fingerprints package app.revanced.patches.music.utils.settings.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint

View File

@ -6,7 +6,7 @@ import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.utils.integrations.Constants.VIDEO_PATH import app.revanced.patches.music.utils.integrations.Constants.VIDEO_PATH
import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.shared.patch.customspeed.AbstractCustomPlaybackSpeedPatch import app.revanced.patches.shared.customspeed.AbstractCustomPlaybackSpeedPatch
@Patch( @Patch(
name = "Custom playback speed", name = "Custom playback speed",

View File

@ -3,6 +3,7 @@ package app.revanced.patches.reddit.ad.banner
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.ResourcePatch
@Suppress("DEPRECATION")
object HideBannerPatch : ResourcePatch() { object HideBannerPatch : ResourcePatch() {
private const val RESOURCE_FILE_PATH = "res/layout/merge_listheader_link_detail.xml" private const val RESOURCE_FILE_PATH = "res/layout/merge_listheader_link_detail.xml"
override fun execute(context: ResourceContext) { override fun execute(context: ResourceContext) {

View File

@ -4,26 +4,22 @@ import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.reddit.ad.comments.fingerprints.HideCommentAdsFingerprint import app.revanced.patches.reddit.ad.comments.fingerprints.HideCommentAdsFingerprint
import app.revanced.patches.reddit.utils.integrations.Constants.PATCHES_PATH
import app.revanced.util.exception import app.revanced.util.exception
import app.revanced.util.getWalkerMethod
object HideCommentAdsPatch : BytecodePatch( object HideCommentAdsPatch : BytecodePatch(
setOf(HideCommentAdsFingerprint) setOf(HideCommentAdsFingerprint)
) { ) {
private const val INTEGRATION_METHOD_DESCRIPTOR = private const val INTEGRATION_METHOD_DESCRIPTOR =
"Lapp/revanced/integrations/reddit/patches/GeneralAdsPatch;" + "$PATCHES_PATH/GeneralAdsPatch;->hideCommentAds()Z"
"->hideCommentAds()Z"
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
HideCommentAdsFingerprint.result?.let { HideCommentAdsFingerprint.result?.apply {
with( val walkerMethod = getWalkerMethod(context, scanResult.patternScanResult!!.startIndex)
context walkerMethod.apply {
.toMethodWalker(it.method)
.nextMethod(it.scanResult.patternScanResult!!.startIndex, true)
.getMethod() as MutableMethod
) {
addInstructionsWithLabels( addInstructionsWithLabels(
0, """ 0, """
invoke-static {}, $INTEGRATION_METHOD_DESCRIPTOR invoke-static {}, $INTEGRATION_METHOD_DESCRIPTOR

View File

@ -5,7 +5,6 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patcher.util.smali.ExternalLabel
@ -13,13 +12,14 @@ import app.revanced.patches.reddit.ad.banner.HideBannerPatch
import app.revanced.patches.reddit.ad.comments.HideCommentAdsPatch import app.revanced.patches.reddit.ad.comments.HideCommentAdsPatch
import app.revanced.patches.reddit.ad.general.fingerprints.AdPostFingerprint import app.revanced.patches.reddit.ad.general.fingerprints.AdPostFingerprint
import app.revanced.patches.reddit.ad.general.fingerprints.NewAdPostFingerprint import app.revanced.patches.reddit.ad.general.fingerprints.NewAdPostFingerprint
import app.revanced.patches.reddit.utils.integrations.Constants.PATCHES_PATH
import app.revanced.patches.reddit.utils.settings.SettingsBytecodePatch.updateSettingsStatus import app.revanced.patches.reddit.utils.settings.SettingsBytecodePatch.updateSettingsStatus
import app.revanced.patches.reddit.utils.settings.SettingsPatch import app.revanced.patches.reddit.utils.settings.SettingsPatch
import app.revanced.util.exception import app.revanced.util.exception
import app.revanced.util.getTargetIndexWithFieldReferenceName
import app.revanced.util.getTargetIndexWithMethodReferenceName
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction22c
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
@Patch( @Patch(
name = "Hide ads", name = "Hide ads",
@ -44,26 +44,17 @@ object HideAdsPatch : BytecodePatch(
) )
) { ) {
private const val INTEGRATIONS_OLD_METHOD_DESCRIPTOR = private const val INTEGRATIONS_OLD_METHOD_DESCRIPTOR =
"Lapp/revanced/integrations/reddit/patches/GeneralAdsPatch;" + "$PATCHES_PATH/GeneralAdsPatch;->hideOldPostAds(Ljava/util/List;)Ljava/util/List;"
"->hideOldPostAds(Ljava/util/List;)Ljava/util/List;"
private const val INTEGRATIONS_NEW_METHOD_DESCRIPTOR = private const val INTEGRATIONS_NEW_METHOD_DESCRIPTOR =
"Lapp/revanced/integrations/reddit/patches/GeneralAdsPatch;" + "$PATCHES_PATH/GeneralAdsPatch;->hideNewPostAds()Z"
"->hideNewPostAds()Z"
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
// region Filter promoted ads (does not work in popular or latest feed) // region Filter promoted ads (does not work in popular or latest feed)
AdPostFingerprint.result?.let { AdPostFingerprint.result?.let {
it.mutableMethod.apply { it.mutableMethod.apply {
val targetIndex = it.scanResult.patternScanResult!!.endIndex val targetIndex = getTargetIndexWithFieldReferenceName("children")
val targetReference = getInstruction<ReferenceInstruction>(targetIndex).reference val targetRegister = getInstruction<TwoRegisterInstruction>(targetIndex).registerA
val targetReferenceName = (targetReference as FieldReference).name
if (targetReferenceName != "children")
throw PatchException("Method signature reference name did not match: $targetReferenceName")
val targetRegister = getInstruction<Instruction22c>(targetIndex).registerA
addInstructions( addInstructions(
targetIndex, """ targetIndex, """
@ -79,13 +70,7 @@ object HideAdsPatch : BytecodePatch(
// By removing the appending instruction no ad posts gets appended to the feed. // By removing the appending instruction no ad posts gets appended to the feed.
NewAdPostFingerprint.result?.let { NewAdPostFingerprint.result?.let {
it.mutableMethod.apply { it.mutableMethod.apply {
val targetIndex = it.scanResult.patternScanResult!!.endIndex val targetIndex = getTargetIndexWithMethodReferenceName("add")
val targetParameter =
getInstruction<ReferenceInstruction>(targetIndex).reference.toString()
if (!targetParameter.endsWith("Ljava/util/ArrayList;->add(Ljava/lang/Object;)Z"))
throw PatchException("Method signature parameter did not match: $targetParameter")
val targetRegister = val targetRegister =
getInstruction<FiveRegisterInstruction>(targetIndex).registerD + 1 getInstruction<FiveRegisterInstruction>(targetIndex).registerD + 1
@ -99,7 +84,7 @@ object HideAdsPatch : BytecodePatch(
} }
} ?: throw NewAdPostFingerprint.exception } ?: throw NewAdPostFingerprint.exception
updateSettingsStatus("GeneralAds") updateSettingsStatus("enableGeneralAds")
} }
} }

View File

@ -9,10 +9,6 @@ object AdPostFingerprint : MethodFingerprint(
returnType = "V", returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
opcodes = listOf( opcodes = listOf(
Opcode.CONST_STRING,
null,
Opcode.CONST_STRING,
null,
Opcode.INVOKE_DIRECT, Opcode.INVOKE_DIRECT,
Opcode.IPUT_OBJECT Opcode.IPUT_OBJECT
), ),

View File

@ -8,9 +8,7 @@ import com.android.tools.smali.dexlib2.Opcode
object NewAdPostFingerprint : MethodFingerprint( object NewAdPostFingerprint : MethodFingerprint(
returnType = "L", returnType = "L",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
opcodes = listOf( opcodes = listOf(Opcode.INVOKE_VIRTUAL),
Opcode.INVOKE_VIRTUAL,
),
strings = listOf( strings = listOf(
"chain", "chain",
"feedElement" "feedElement"

View File

@ -1,7 +1,6 @@
package app.revanced.patches.reddit.layout.branding.name package app.revanced.patches.reddit.layout.branding.name
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
@ -23,48 +22,61 @@ import java.nio.file.Files
], ],
use = false use = false
) )
@Suppress("unused") @Suppress("DEPRECATION", "unused")
object CustomBrandingNamePatch : ResourcePatch() { object CustomBrandingNamePatch : ResourcePatch() {
private const val ORIGINAL_APP_NAME = "Reddit"
private const val APP_NAME = "RVX Reddit" private const val APP_NAME = "RVX Reddit"
private val AppName by stringPatchOption( private val AppName by stringPatchOption(
key = "AppName", key = "AppName",
default = APP_NAME, default = ORIGINAL_APP_NAME,
values = mapOf(
"Default" to APP_NAME,
"Original" to ORIGINAL_APP_NAME,
),
title = "App name", title = "App name",
description = "The name of the app." description = "The name of the app."
) )
override fun execute(context: ResourceContext) { override fun execute(context: ResourceContext) {
val appName = AppName val appName = if (AppName != null) {
?: throw PatchException("Invalid app name.") AppName!!
} else {
val resDirectory = context["res"] println("WARNING: Invalid name name. Does not apply patches.")
ORIGINAL_APP_NAME
val valuesV24Directory = resDirectory.resolve("values-v24")
if (!valuesV24Directory.isDirectory)
Files.createDirectories(valuesV24Directory.toPath())
val stringsXml = valuesV24Directory.resolve("strings.xml")
if (!stringsXml.exists()) {
FileWriter(stringsXml).use {
it.write("<?xml version=\"1.0\" encoding=\"utf-8\"?><resources></resources>")
}
} }
context.xmlEditor["res/values-v24/strings.xml"].use { editor -> if (appName != ORIGINAL_APP_NAME) {
val document = editor.file val resDirectory = context["res"]
mapOf( val valuesV24Directory = resDirectory.resolve("values-v24")
"app_name" to appName if (!valuesV24Directory.isDirectory)
).forEach { (k, v) -> Files.createDirectories(valuesV24Directory.toPath())
val stringElement = document.createElement("string")
stringElement.setAttribute("name", k) val stringsXml = valuesV24Directory.resolve("strings.xml")
stringElement.textContent = v
document.getElementsByTagName("resources").item(0).appendChild(stringElement) if (!stringsXml.exists()) {
FileWriter(stringsXml).use {
it.write("<?xml version=\"1.0\" encoding=\"utf-8\"?><resources></resources>")
}
} }
context.xmlEditor["res/values-v24/strings.xml"].use { editor ->
val document = editor.file
mapOf(
"app_name" to appName
).forEach { (k, v) ->
val stringElement = document.createElement("string")
stringElement.setAttribute("name", k)
stringElement.textContent = v
document.getElementsByTagName("resources").item(0).appendChild(stringElement)
}
}
} else {
println("INFO: App name will remain unchanged as it matches the original.")
} }
} }
} }

View File

@ -1,7 +1,6 @@
package app.revanced.patches.reddit.layout.branding.packagename package app.revanced.patches.reddit.layout.branding.packagename
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
@ -23,21 +22,22 @@ import java.io.Closeable
], ],
use = false use = false
) )
@Suppress("unused") @Suppress("DEPRECATION", "unused")
object ChangePackageNamePatch : ResourcePatch(), Closeable { object ChangePackageNamePatch : ResourcePatch(), Closeable {
private const val PACKAGE_NAME_REDDIT = "com.reddit.frontpage" private const val PACKAGE_NAME_REDDIT = "com.reddit.frontpage"
private const val CLONE_PACKAGE_NAME_REDDIT = "$PACKAGE_NAME_REDDIT.revanced" private const val CLONE_PACKAGE_NAME_REDDIT = "$PACKAGE_NAME_REDDIT.revanced"
private const val DEFAULT_PACKAGE_NAME_REDDIT = "$PACKAGE_NAME_REDDIT.rvx" private const val DEFAULT_PACKAGE_NAME_REDDIT = "$PACKAGE_NAME_REDDIT.rvx"
private lateinit var context: ResourceContext private lateinit var context: ResourceContext
private lateinit var redditPackageName: String private var redditPackageName = PACKAGE_NAME_REDDIT
private val PackageNameReddit by stringPatchOption( private val PackageNameReddit by stringPatchOption(
key = "PackageNameReddit", key = "PackageNameReddit",
default = DEFAULT_PACKAGE_NAME_REDDIT, default = PACKAGE_NAME_REDDIT,
values = mapOf( values = mapOf(
"Clone" to CLONE_PACKAGE_NAME_REDDIT, "Clone" to CLONE_PACKAGE_NAME_REDDIT,
"Default" to DEFAULT_PACKAGE_NAME_REDDIT "Default" to DEFAULT_PACKAGE_NAME_REDDIT,
"Original" to PACKAGE_NAME_REDDIT,
), ),
title = "Package name of Reddit", title = "Package name of Reddit",
description = "The name of the package to rename the app to." description = "The name of the package to rename the app to."
@ -46,35 +46,44 @@ object ChangePackageNamePatch : ResourcePatch(), Closeable {
override fun execute(context: ResourceContext) { override fun execute(context: ResourceContext) {
this.context = context this.context = context
redditPackageName = PackageNameReddit if (PackageNameReddit != null) {
?: throw PatchException("Invalid package name.") redditPackageName = PackageNameReddit!!
} else {
println("WARNING: Invalid package name. Does not apply patches.")
}
// Ensure device runs Android. if (redditPackageName != PACKAGE_NAME_REDDIT) {
try { // Ensure device runs Android.
// RVX Manager try {
// ==== // RVX Manager
// For some reason, in Android AAPT2, a compilation error occurs when changing the [strings.xml] of the Reddit // ====
// This only affects RVX Manager, and has not yet found a valid workaround // For some reason, in Android AAPT2, a compilation error occurs when changing the [strings.xml] of the Reddit
Class.forName("android.os.Environment") // This only affects RVX Manager, and has not yet found a valid workaround
} catch (_: ClassNotFoundException) { Class.forName("android.os.Environment")
// CLI } catch (_: ClassNotFoundException) {
context.replacePackageName(redditPackageName) // CLI
context.replacePackageName(redditPackageName)
}
} else {
println("INFO: Package name will remain unchanged as it matches the original.")
} }
} }
override fun close() { override fun close() {
context["AndroidManifest.xml"].apply { if (redditPackageName != PACKAGE_NAME_REDDIT) {
writeText( context["AndroidManifest.xml"].apply {
readText() writeText(
.replace( readText()
"package=\"$PACKAGE_NAME_REDDIT", .replace(
"package=\"$redditPackageName" "package=\"$PACKAGE_NAME_REDDIT",
) "package=\"$redditPackageName"
.replace( )
"$PACKAGE_NAME_REDDIT.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION", .replace(
"$redditPackageName.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION" "$PACKAGE_NAME_REDDIT.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION",
) "$redditPackageName.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION"
) )
)
}
} }
} }

View File

@ -7,6 +7,7 @@ import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.reddit.layout.navigation.fingerprints.BottomNavScreenFingerprint import app.revanced.patches.reddit.layout.navigation.fingerprints.BottomNavScreenFingerprint
import app.revanced.patches.reddit.utils.integrations.Constants.PATCHES_PATH
import app.revanced.patches.reddit.utils.settings.SettingsBytecodePatch.updateSettingsStatus import app.revanced.patches.reddit.utils.settings.SettingsBytecodePatch.updateSettingsStatus
import app.revanced.patches.reddit.utils.settings.SettingsPatch import app.revanced.patches.reddit.utils.settings.SettingsPatch
import app.revanced.util.exception import app.revanced.util.exception
@ -31,8 +32,7 @@ object NavigationButtonsPatch : BytecodePatch(
setOf(BottomNavScreenFingerprint) setOf(BottomNavScreenFingerprint)
) { ) {
private const val INTEGRATIONS_METHOD_DESCRIPTOR = private const val INTEGRATIONS_METHOD_DESCRIPTOR =
"Lapp/revanced/integrations/reddit/patches/NavigationButtonsPatch;" + "$PATCHES_PATH/NavigationButtonsPatch;->hideNavigationButtons(Landroid/view/ViewGroup;)V"
"->hideNavigationButtons(Landroid/view/ViewGroup;)V"
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
@ -49,7 +49,7 @@ object NavigationButtonsPatch : BytecodePatch(
} }
} ?: throw BottomNavScreenFingerprint.exception } ?: throw BottomNavScreenFingerprint.exception
updateSettingsStatus("NavigationButtons") updateSettingsStatus("enableNavigationButtons")
} }
} }

View File

@ -5,6 +5,7 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
object PremiumIconFingerprint : MethodFingerprint( object PremiumIconFingerprint : MethodFingerprint(
returnType = "Z", returnType = "Z",
customFingerprint = { methodDef, classDef -> customFingerprint = { methodDef, classDef ->
methodDef.definingClass.endsWith("/MyAccount;") && methodDef.name == "isPremiumSubscriber" && classDef.sourceFile == "MyAccount.kt" methodDef.definingClass.endsWith("/MyAccount;")
&& methodDef.name == "isPremiumSubscriber" && classDef.sourceFile == "MyAccount.kt"
} }
) )

View File

@ -8,16 +8,17 @@ import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.reddit.layout.recentlyvisited.fingerprints.CommunityDrawerPresenterFingerprint import app.revanced.patches.reddit.layout.recentlyvisited.fingerprints.CommunityDrawerPresenterFingerprint
import app.revanced.patches.reddit.utils.integrations.Constants.PATCHES_PATH
import app.revanced.patches.reddit.utils.settings.SettingsBytecodePatch.updateSettingsStatus import app.revanced.patches.reddit.utils.settings.SettingsBytecodePatch.updateSettingsStatus
import app.revanced.patches.reddit.utils.settings.SettingsPatch import app.revanced.patches.reddit.utils.settings.SettingsPatch
import app.revanced.util.exception import app.revanced.util.exception
import app.revanced.util.getReference
import app.revanced.util.getTargetIndex import app.revanced.util.getTargetIndex
import app.revanced.util.getTargetIndexReversed import app.revanced.util.getTargetIndexReversed
import app.revanced.util.getTargetIndexWithFieldReferenceName
import app.revanced.util.getTargetIndexWithReference
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
import com.android.tools.smali.dexlib2.iface.reference.Reference import com.android.tools.smali.dexlib2.iface.reference.Reference
@Patch( @Patch(
@ -39,8 +40,7 @@ object RecentlyVisitedShelfPatch : BytecodePatch(
setOf(CommunityDrawerPresenterFingerprint) setOf(CommunityDrawerPresenterFingerprint)
) { ) {
private const val INTEGRATIONS_METHOD_DESCRIPTOR = private const val INTEGRATIONS_METHOD_DESCRIPTOR =
"Lapp/revanced/integrations/reddit/patches/RecentlyVisitedShelfPatch;" + "$PATCHES_PATH/RecentlyVisitedShelfPatch;->hideRecentlyVisitedShelf(Ljava/util/List;)Ljava/util/List;"
"->hideRecentlyVisitedShelf(Ljava/util/List;)Ljava/util/List;"
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
@ -49,20 +49,14 @@ object RecentlyVisitedShelfPatch : BytecodePatch(
it.mutableClass.methods.find { method -> method.name == "<init>" } it.mutableClass.methods.find { method -> method.name == "<init>" }
?.apply { ?.apply {
val recentlyVisitedFieldIndex = implementation!!.instructions.indexOfFirst { instruction -> val recentlyVisitedFieldIndex = getTargetIndexWithFieldReferenceName("RECENTLY_VISITED")
instruction.opcode == Opcode.SGET_OBJECT
&& instruction.getReference<FieldReference>()?.name == "RECENTLY_VISITED"
}
val recentlyVisitedObjectIndex = getTargetIndex(recentlyVisitedFieldIndex, Opcode.IPUT_OBJECT) val recentlyVisitedObjectIndex = getTargetIndex(recentlyVisitedFieldIndex, Opcode.IPUT_OBJECT)
recentlyVisitedReference = recentlyVisitedReference =
getInstruction<ReferenceInstruction>(recentlyVisitedObjectIndex).reference getInstruction<ReferenceInstruction>(recentlyVisitedObjectIndex).reference
} ?: throw PatchException("Constructor method not found!") } ?: throw PatchException("Constructor method not found!")
it.mutableMethod.apply { it.mutableMethod.apply {
val recentlyVisitedObjectIndex = implementation!!.instructions.indexOfFirst { instruction -> val recentlyVisitedObjectIndex = getTargetIndexWithReference(recentlyVisitedReference.toString())
instruction.opcode == Opcode.IGET_OBJECT
&& (instruction as? ReferenceInstruction)?.reference == recentlyVisitedReference
}
arrayOf( arrayOf(
getTargetIndex(recentlyVisitedObjectIndex, Opcode.INVOKE_STATIC), getTargetIndex(recentlyVisitedObjectIndex, Opcode.INVOKE_STATIC),
getTargetIndexReversed(recentlyVisitedObjectIndex, Opcode.INVOKE_STATIC) getTargetIndexReversed(recentlyVisitedObjectIndex, Opcode.INVOKE_STATIC)
@ -80,7 +74,7 @@ object RecentlyVisitedShelfPatch : BytecodePatch(
} }
} ?: throw CommunityDrawerPresenterFingerprint.exception } ?: throw CommunityDrawerPresenterFingerprint.exception
updateSettingsStatus("RecentlyVisitedShelf") updateSettingsStatus("enableRecentlyVisitedShelf")
} }
} }

View File

@ -8,6 +8,7 @@ import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.reddit.layout.screenshotpopup.fingerprints.ScreenshotTakenBannerFingerprint import app.revanced.patches.reddit.layout.screenshotpopup.fingerprints.ScreenshotTakenBannerFingerprint
import app.revanced.patches.reddit.utils.integrations.Constants.PATCHES_PATH
import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.reddit.utils.settings.SettingsBytecodePatch.updateSettingsStatus import app.revanced.patches.reddit.utils.settings.SettingsBytecodePatch.updateSettingsStatus
import app.revanced.patches.reddit.utils.settings.SettingsPatch import app.revanced.patches.reddit.utils.settings.SettingsPatch
@ -32,8 +33,7 @@ object ScreenshotPopupPatch : BytecodePatch(
setOf(ScreenshotTakenBannerFingerprint) setOf(ScreenshotTakenBannerFingerprint)
) { ) {
private const val INTEGRATIONS_METHOD_DESCRIPTOR = private const val INTEGRATIONS_METHOD_DESCRIPTOR =
"Lapp/revanced/integrations/reddit/patches/ScreenshotPopupPatch;" + "$PATCHES_PATH/ScreenshotPopupPatch;->disableScreenshotPopup()Z"
"->disableScreenshotPopup()Z"
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
@ -50,7 +50,7 @@ object ScreenshotPopupPatch : BytecodePatch(
} }
} ?: throw ScreenshotTakenBannerFingerprint.exception } ?: throw ScreenshotTakenBannerFingerprint.exception
updateSettingsStatus("ScreenshotPopup") updateSettingsStatus("enableScreenshotPopup")
} }
} }

View File

@ -8,6 +8,7 @@ import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.reddit.layout.subredditdialog.fingerprints.FrequentUpdatesSheetScreenFingerprint import app.revanced.patches.reddit.layout.subredditdialog.fingerprints.FrequentUpdatesSheetScreenFingerprint
import app.revanced.patches.reddit.layout.subredditdialog.fingerprints.RedditAlertDialogsFingerprint import app.revanced.patches.reddit.layout.subredditdialog.fingerprints.RedditAlertDialogsFingerprint
import app.revanced.patches.reddit.utils.integrations.Constants.PATCHES_PATH
import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch.CancelButton import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch.CancelButton
import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch.TextAppearanceRedditBaseOldButtonColored import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch.TextAppearanceRedditBaseOldButtonColored
@ -40,7 +41,7 @@ object RemoveSubRedditDialogPatch : BytecodePatch(
) )
) { ) {
private const val INTEGRATIONS_CLASS_DESCRIPTOR = private const val INTEGRATIONS_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/reddit/patches/RemoveSubRedditDialogPatch;" "$PATCHES_PATH/RemoveSubRedditDialogPatch;"
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
@ -68,7 +69,7 @@ object RemoveSubRedditDialogPatch : BytecodePatch(
} }
} ?: throw RedditAlertDialogsFingerprint.exception } ?: throw RedditAlertDialogsFingerprint.exception
updateSettingsStatus("RemoveSubRedditDialog") updateSettingsStatus("enableSubRedditDialog")
} }
} }

View File

@ -7,6 +7,7 @@ import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.reddit.layout.toolbar.fingerprints.HomePagerScreenFingerprint import app.revanced.patches.reddit.layout.toolbar.fingerprints.HomePagerScreenFingerprint
import app.revanced.patches.reddit.utils.integrations.Constants.PATCHES_PATH
import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch.ToolBarNavSearchCtaContainer import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch.ToolBarNavSearchCtaContainer
import app.revanced.patches.reddit.utils.settings.SettingsBytecodePatch.updateSettingsStatus import app.revanced.patches.reddit.utils.settings.SettingsBytecodePatch.updateSettingsStatus
@ -38,8 +39,7 @@ object ToolBarButtonPatch : BytecodePatch(
setOf(HomePagerScreenFingerprint) setOf(HomePagerScreenFingerprint)
) { ) {
private const val INTEGRATIONS_METHOD_DESCRIPTOR = private const val INTEGRATIONS_METHOD_DESCRIPTOR =
"Lapp/revanced/integrations/reddit/patches/ToolBarButtonPatch;" + "$PATCHES_PATH/ToolBarButtonPatch;->hideToolBarButton(Landroid/view/View;)V"
"->hideToolBarButton(Landroid/view/View;)V"
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
@ -57,7 +57,7 @@ object ToolBarButtonPatch : BytecodePatch(
} }
} ?: throw HomePagerScreenFingerprint.exception } ?: throw HomePagerScreenFingerprint.exception
updateSettingsStatus("ToolBarButton") updateSettingsStatus("enableToolBarButton")
} }
} }

View File

@ -6,6 +6,7 @@ import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.reddit.misc.openlink.fingerprints.ScreenNavigatorFingerprint import app.revanced.patches.reddit.misc.openlink.fingerprints.ScreenNavigatorFingerprint
import app.revanced.patches.reddit.utils.integrations.Constants.PATCHES_PATH
import app.revanced.patches.reddit.utils.settings.SettingsBytecodePatch.updateSettingsStatus import app.revanced.patches.reddit.utils.settings.SettingsBytecodePatch.updateSettingsStatus
import app.revanced.patches.reddit.utils.settings.SettingsPatch import app.revanced.patches.reddit.utils.settings.SettingsPatch
import app.revanced.util.exception import app.revanced.util.exception
@ -29,8 +30,7 @@ object OpenLinksDirectlyPatch : BytecodePatch(
setOf(ScreenNavigatorFingerprint) setOf(ScreenNavigatorFingerprint)
) { ) {
private const val INTEGRATIONS_METHOD_DESCRIPTOR = private const val INTEGRATIONS_METHOD_DESCRIPTOR =
"Lapp/revanced/integrations/reddit/patches/OpenLinksDirectlyPatch;" + "$PATCHES_PATH/OpenLinksDirectlyPatch;->parseRedirectUri(Landroid/net/Uri;)Landroid/net/Uri;"
"->parseRedirectUri(Landroid/net/Uri;)Landroid/net/Uri;"
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
ScreenNavigatorFingerprint.result?.let { ScreenNavigatorFingerprint.result?.let {
@ -44,7 +44,7 @@ object OpenLinksDirectlyPatch : BytecodePatch(
} }
} ?: throw ScreenNavigatorFingerprint.exception } ?: throw ScreenNavigatorFingerprint.exception
updateSettingsStatus("OpenLinksDirectly") updateSettingsStatus("enableOpenLinksDirectly")
} }
} }

View File

@ -8,6 +8,7 @@ import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.reddit.misc.openlink.fingerprints.ScreenNavigatorFingerprint import app.revanced.patches.reddit.misc.openlink.fingerprints.ScreenNavigatorFingerprint
import app.revanced.patches.reddit.utils.integrations.Constants.PATCHES_PATH
import app.revanced.patches.reddit.utils.settings.SettingsBytecodePatch.updateSettingsStatus import app.revanced.patches.reddit.utils.settings.SettingsBytecodePatch.updateSettingsStatus
import app.revanced.patches.reddit.utils.settings.SettingsPatch import app.revanced.patches.reddit.utils.settings.SettingsPatch
import app.revanced.util.exception import app.revanced.util.exception
@ -32,7 +33,7 @@ object OpenLinksExternallyPatch : BytecodePatch(
setOf(ScreenNavigatorFingerprint) setOf(ScreenNavigatorFingerprint)
) { ) {
private const val INTEGRATIONS_METHOD_DESCRIPTOR = private const val INTEGRATIONS_METHOD_DESCRIPTOR =
"Lapp/revanced/integrations/reddit/patches/OpenLinksExternallyPatch;" "$PATCHES_PATH/OpenLinksExternallyPatch;"
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
ScreenNavigatorFingerprint.result?.let { ScreenNavigatorFingerprint.result?.let {
@ -50,7 +51,7 @@ object OpenLinksExternallyPatch : BytecodePatch(
} }
} ?: throw ScreenNavigatorFingerprint.exception } ?: throw ScreenNavigatorFingerprint.exception
updateSettingsStatus("OpenLinksExternally") updateSettingsStatus("enableOpenLinksExternally")
} }
} }

View File

@ -8,6 +8,7 @@ import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.reddit.misc.tracking.url.fingerprints.ShareLinkFormatterFingerprint import app.revanced.patches.reddit.misc.tracking.url.fingerprints.ShareLinkFormatterFingerprint
import app.revanced.patches.reddit.utils.integrations.Constants.PATCHES_PATH
import app.revanced.patches.reddit.utils.settings.SettingsBytecodePatch.updateSettingsStatus import app.revanced.patches.reddit.utils.settings.SettingsBytecodePatch.updateSettingsStatus
import app.revanced.patches.reddit.utils.settings.SettingsPatch import app.revanced.patches.reddit.utils.settings.SettingsPatch
import app.revanced.util.exception import app.revanced.util.exception
@ -31,13 +32,11 @@ object SanitizeUrlQueryPatch : BytecodePatch(
setOf(ShareLinkFormatterFingerprint) setOf(ShareLinkFormatterFingerprint)
) { ) {
private const val SANITIZE_METHOD_DESCRIPTOR = private const val SANITIZE_METHOD_DESCRIPTOR =
"Lapp/revanced/integrations/reddit/patches/SanitizeUrlQueryPatch;" + "$PATCHES_PATH/SanitizeUrlQueryPatch;->stripQueryParameters()Z"
"->stripQueryParameters()Z"
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
ShareLinkFormatterFingerprint.result?.let { result -> ShareLinkFormatterFingerprint.result?.let { result ->
result.mutableMethod.apply { result.mutableMethod.apply {
addInstructionsWithLabels( addInstructionsWithLabels(
0, 0,
""" """
@ -50,7 +49,7 @@ object SanitizeUrlQueryPatch : BytecodePatch(
} }
} ?: throw ShareLinkFormatterFingerprint.exception } ?: throw ShareLinkFormatterFingerprint.exception
updateSettingsStatus("SanitizeUrlQuery") updateSettingsStatus("enableSanitizeUrlQuery")
} }
} }

View File

@ -0,0 +1,7 @@
package app.revanced.patches.reddit.utils.integrations
@Suppress("MemberVisibilityCanBePrivate")
object Constants {
const val INTEGRATIONS_PATH = "Lapp/revanced/integrations/reddit"
const val PATCHES_PATH = "$INTEGRATIONS_PATH/patches"
}

View File

@ -2,10 +2,9 @@ package app.revanced.patches.reddit.utils.integrations
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.reddit.utils.integrations.fingerprints.InitFingerprint import app.revanced.patches.reddit.utils.integrations.fingerprints.InitFingerprint
import app.revanced.patches.shared.patch.integrations.AbstractIntegrationsPatch import app.revanced.patches.shared.integrations.BaseIntegrationsPatch
@Patch(requiresIntegrations = true) @Patch(requiresIntegrations = true)
object IntegrationsPatch : AbstractIntegrationsPatch( object IntegrationsPatch : BaseIntegrationsPatch(
"Lapp/revanced/integrations/reddit/utils/ReVancedUtils;",
setOf(InitFingerprint), setOf(InitFingerprint),
) )

View File

@ -1,7 +1,8 @@
package app.revanced.patches.reddit.utils.integrations.fingerprints package app.revanced.patches.reddit.utils.integrations.fingerprints
import app.revanced.patches.shared.patch.integrations.AbstractIntegrationsPatch.IntegrationsFingerprint import app.revanced.patches.shared.integrations.BaseIntegrationsPatch.IntegrationsFingerprint
@Suppress("DEPRECATION")
object InitFingerprint : IntegrationsFingerprint( object InitFingerprint : IntegrationsFingerprint(
customFingerprint = { methodDef, _ -> customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("/FrontpageApplication;") && methodDef.definingClass.endsWith("/FrontpageApplication;") &&

View File

@ -3,32 +3,27 @@ package app.revanced.patches.reddit.utils.resourceid
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.shared.patch.mapping.ResourceMappingPatch import app.revanced.patches.shared.mapping.ResourceMappingPatch
import app.revanced.patches.shared.patch.mapping.ResourceType import app.revanced.patches.shared.mapping.ResourceMappingPatch.getId
import app.revanced.patches.shared.patch.mapping.ResourceType.ID import app.revanced.patches.shared.mapping.ResourceType.ID
import app.revanced.patches.shared.patch.mapping.ResourceType.STRING import app.revanced.patches.shared.mapping.ResourceType.STRING
import app.revanced.patches.shared.patch.mapping.ResourceType.STYLE import app.revanced.patches.shared.mapping.ResourceType.STYLE
@Patch(dependencies = [ResourceMappingPatch::class]) @Patch(dependencies = [ResourceMappingPatch::class])
object SharedResourceIdPatch : ResourcePatch() { object SharedResourceIdPatch : ResourcePatch() {
var CancelButton: Long = -1L var CancelButton = -1L
var LabelAcknowledgements: Long = -1L var LabelAcknowledgements = -1L
var ScreenShotShareBanner: Long = -1L var ScreenShotShareBanner = -1L
var TextAppearanceRedditBaseOldButtonColored: Long = -1L var TextAppearanceRedditBaseOldButtonColored = -1L
var ToolBarNavSearchCtaContainer: Long = -1L var ToolBarNavSearchCtaContainer = -1L
override fun execute(context: ResourceContext) { override fun execute(context: ResourceContext) {
fun find(resourceType: ResourceType, resourceName: String) = ResourceMappingPatch CancelButton = getId(ID, "cancel_button")
.resourceMappings LabelAcknowledgements = getId(STRING, "label_acknowledgements")
.find { it.type == resourceType.value && it.name == resourceName }?.id ScreenShotShareBanner = getId(STRING, "screenshot_share_banner_title")
?: -1 TextAppearanceRedditBaseOldButtonColored = getId(STYLE, "TextAppearance.RedditBase.OldButton.Colored")
ToolBarNavSearchCtaContainer = getId(ID, "toolbar_nav_search_cta_container")
CancelButton = find(ID, "cancel_button")
LabelAcknowledgements = find(STRING, "label_acknowledgements")
ScreenShotShareBanner = find(STRING, "screenshot_share_banner_title")
TextAppearanceRedditBaseOldButtonColored = find(STYLE, "TextAppearance.RedditBase.OldButton.Colored")
ToolBarNavSearchCtaContainer = find(ID, "toolbar_nav_search_cta_container")
} }
} }

View File

@ -4,16 +4,21 @@ import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.reddit.utils.integrations.Constants.INTEGRATIONS_PATH
import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch.LabelAcknowledgements import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch.LabelAcknowledgements
import app.revanced.patches.reddit.utils.settings.fingerprints.AcknowledgementsLabelBuilderFingerprint import app.revanced.patches.reddit.utils.settings.fingerprints.AcknowledgementsLabelBuilderFingerprint
import app.revanced.patches.reddit.utils.settings.fingerprints.OssLicensesMenuActivityOnCreateFingerprint import app.revanced.patches.reddit.utils.settings.fingerprints.OssLicensesMenuActivityOnCreateFingerprint
import app.revanced.patches.reddit.utils.settings.fingerprints.SettingsStatusLoadFingerprint import app.revanced.patches.reddit.utils.settings.fingerprints.SettingsStatusLoadFingerprint
import app.revanced.patches.shared.settings.fingerprints.SharedSettingFingerprint
import app.revanced.util.exception import app.revanced.util.exception
import app.revanced.util.getTargetIndex
import app.revanced.util.getWideLiteralInstructionIndex import app.revanced.util.getWideLiteralInstructionIndex
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Patch(dependencies = [SharedResourceIdPatch::class]) @Patch(dependencies = [SharedResourceIdPatch::class])
@ -21,25 +26,39 @@ object SettingsBytecodePatch : BytecodePatch(
setOf( setOf(
AcknowledgementsLabelBuilderFingerprint, AcknowledgementsLabelBuilderFingerprint,
OssLicensesMenuActivityOnCreateFingerprint, OssLicensesMenuActivityOnCreateFingerprint,
SharedSettingFingerprint,
SettingsStatusLoadFingerprint SettingsStatusLoadFingerprint
) )
) { ) {
private const val INTEGRATIONS_METHOD_DESCRIPTOR = private const val INTEGRATIONS_METHOD_DESCRIPTOR =
"Lapp/revanced/integrations/reddit/settingsmenu/ReVancedSettingActivity;->initializeSettings(Landroid/app/Activity;)V" "$INTEGRATIONS_PATH/settings/ActivityHook;->initialize(Landroid/app/Activity;)V"
private lateinit var settingsMethod: MutableMethod private lateinit var settingsMethod: MutableMethod
internal fun updateSettingsStatus(description: String) { internal fun updateSettingsStatus(description: String) {
settingsMethod.apply { settingsMethod.addInstruction(
addInstruction( 0,
0, "invoke-static {}, $INTEGRATIONS_PATH/settings/SettingsStatus;->$description()V"
"invoke-static {}, Lapp/revanced/integrations/reddit/settingsmenu/SettingsStatus;->$description()V" )
)
}
} }
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
/**
* Set SharedPrefCategory
*/
SharedSettingFingerprint.result?.let {
it.mutableMethod.apply {
val stringIndex = getTargetIndex(Opcode.CONST_STRING)
val stringRegister = getInstruction<OneRegisterInstruction>(stringIndex).registerA
replaceInstruction(
stringIndex,
"const-string v$stringRegister, \"reddit_revanced\""
)
}
} ?: throw SharedSettingFingerprint.exception
/** /**
* Replace settings label * Replace settings label
*/ */

View File

@ -11,8 +11,7 @@ import kotlin.io.path.exists
@Patch( @Patch(
name = "Settings", name = "Settings",
description = "Adds ReVanced Extended settings to Reddit.", description = "Adds ReVanced Extended settings to Reddit.",
dependencies = dependencies = [
[
IntegrationsPatch::class, IntegrationsPatch::class,
SettingsBytecodePatch::class SettingsBytecodePatch::class
], ],
@ -27,6 +26,7 @@ import kotlin.io.path.exists
], ],
requiresIntegrations = true, requiresIntegrations = true,
) )
@Suppress("DEPRECATION")
object SettingsPatch : ResourcePatch() { object SettingsPatch : ResourcePatch() {
override fun execute(context: ResourceContext) { override fun execute(context: ResourceContext) {

View File

@ -1,10 +1,11 @@
package app.revanced.patches.reddit.utils.settings.fingerprints package app.revanced.patches.reddit.utils.settings.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.reddit.utils.integrations.Constants.INTEGRATIONS_PATH
object SettingsStatusLoadFingerprint : MethodFingerprint( object SettingsStatusLoadFingerprint : MethodFingerprint(
customFingerprint = { methodDef, _ -> customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("Lapp/revanced/integrations/reddit/settingsmenu/SettingsStatus;") && methodDef.definingClass.endsWith("$INTEGRATIONS_PATH/settings/SettingsStatus;") &&
methodDef.name == "load" methodDef.name == "load"
} }
) )

View File

@ -0,0 +1,62 @@
package app.revanced.patches.shared.ads
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.shared.ads.fingerprints.MusicAdsFingerprint
import app.revanced.patches.shared.ads.fingerprints.VideoAdsFingerprint
import app.revanced.util.exception
import app.revanced.util.getWalkerMethod
import app.revanced.util.indexOfFirstInstruction
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
abstract class AbstractAdsPatch(
private val classDescriptor: String,
private val methodDescriptor: String
) : BytecodePatch(
setOf(
MusicAdsFingerprint,
VideoAdsFingerprint
)
) {
override fun execute(context: BytecodeContext) {
MusicAdsFingerprint.result?.let {
it.mutableMethod.apply {
val targetIndex = indexOfFirstInstruction {
val reference = ((this as? ReferenceInstruction)?.reference as? MethodReference)
opcode == Opcode.INVOKE_VIRTUAL
&& reference?.returnType == "V"
&& reference.parameterTypes.size == 1
&& reference.parameterTypes.first() == "Z"
}
getWalkerMethod(context, targetIndex)
.addInstructions(
0, """
invoke-static {p1}, $classDescriptor->$methodDescriptor(Z)Z
move-result p1
"""
)
}
} ?: throw MusicAdsFingerprint.exception
VideoAdsFingerprint.result?.let {
it.mutableMethod.apply {
addInstructionsWithLabels(
0, """
invoke-static {}, $classDescriptor->$methodDescriptor()Z
move-result v0
if-nez v0, :show_ads
return-void
""", ExternalLabel("show_ads", getInstruction(0))
)
}
} ?: throw VideoAdsFingerprint.exception
}
}

View File

@ -1,12 +1,11 @@
package app.revanced.patches.shared.fingerprints.ads package app.revanced.patches.shared.ads.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.util.fingerprint.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.NarrowLiteralInstruction
object LegacyAdsFingerprint : MethodFingerprint( object MusicAdsFingerprint : LiteralValueFingerprint(
returnType = "V", returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = emptyList(), parameters = emptyList(),
@ -20,9 +19,5 @@ object LegacyAdsFingerprint : MethodFingerprint(
Opcode.IPUT_WIDE, Opcode.IPUT_WIDE,
Opcode.CONST_4, Opcode.CONST_4,
), ),
customFingerprint = { methodDef, _ -> literalSupplier = { 4 }
methodDef.implementation!!.instructions.any {
((it as? NarrowLiteralInstruction)?.narrowLiteral == 4)
}
}
) )

View File

@ -1,8 +1,8 @@
package app.revanced.patches.shared.fingerprints.ads package app.revanced.patches.shared.ads.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
object MainstreamAdsFingerprint : MethodFingerprint( object VideoAdsFingerprint : MethodFingerprint(
returnType = "V", returnType = "V",
strings = listOf("markFillRequested", "requestEnterSlot") strings = listOf("markFillRequested", "requestEnterSlot")
) )

View File

@ -1,14 +1,15 @@
package app.revanced.patches.shared.patch.captions package app.revanced.patches.shared.captions
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patches.shared.captions.fingerprints.StartVideoInformerFingerprint
import app.revanced.patches.shared.fingerprints.captions.StartVideoInformerFingerprint import app.revanced.patches.shared.captions.fingerprints.SubtitleTrackFingerprint
import app.revanced.patches.shared.fingerprints.captions.SubtitleTrackFingerprint
import app.revanced.util.exception import app.revanced.util.exception
import app.revanced.util.getWalkerMethod
import app.revanced.util.indexOfFirstInstruction
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
@ -34,20 +35,17 @@ abstract class AbstractAutoCaptionsPatch(
} ?: throw StartVideoInformerFingerprint.exception } ?: throw StartVideoInformerFingerprint.exception
SubtitleTrackFingerprint.result?.let { SubtitleTrackFingerprint.result?.let {
val targetMethod = context val targetMethod = it.getWalkerMethod(context, it.scanResult.patternScanResult!!.startIndex + 1)
.toMethodWalker(it.method)
.nextMethod(it.scanResult.patternScanResult!!.startIndex + 1, true)
.getMethod() as MutableMethod
targetMethod.apply { targetMethod.apply {
val insertIndex = implementation!!.instructions.indexOfFirst { instruction -> val targetIndex = indexOfFirstInstruction {
instruction.opcode == Opcode.INVOKE_VIRTUAL opcode == Opcode.INVOKE_VIRTUAL
&& ((instruction as? ReferenceInstruction)?.reference as? MethodReference)?.returnType == "Z" && ((this as? ReferenceInstruction)?.reference as? MethodReference)?.returnType == "Z"
} + 2 } + 1
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA val insertRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
addInstructions( addInstructions(
insertIndex, """ targetIndex + 1, """
invoke-static {v$insertRegister}, $classDescriptor->disableAutoCaptions(Z)Z invoke-static {v$insertRegister}, $classDescriptor->disableAutoCaptions(Z)Z
move-result v$insertRegister move-result v$insertRegister
""" """

View File

@ -1,4 +1,4 @@
package app.revanced.patches.shared.fingerprints.captions package app.revanced.patches.shared.captions.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint

View File

@ -1,4 +1,4 @@
package app.revanced.patches.shared.fingerprints.captions package app.revanced.patches.shared.captions.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint

View File

@ -1,12 +1,12 @@
package app.revanced.patches.shared.patch.clientspoof package app.revanced.patches.shared.clientspoof
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.shared.patch.transformation.BaseTransformInstructionsPatch import app.revanced.patches.shared.transformation.BaseTransformInstructionsPatch
import app.revanced.patches.shared.patch.transformation.IMethodCall import app.revanced.patches.shared.transformation.IMethodCall
import app.revanced.patches.shared.patch.transformation.Instruction35cInfo import app.revanced.patches.shared.transformation.Instruction35cInfo
import app.revanced.patches.shared.patch.transformation.filterMapInstruction35c import app.revanced.patches.shared.transformation.filterMapInstruction35c
import app.revanced.util.getReference import app.revanced.util.getReference
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction21c import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction21c

View File

@ -1,20 +1,19 @@
package app.revanced.patches.shared.patch.customspeed package app.revanced.patches.shared.customspeed
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patches.shared.fingerprints.customspeed.SpeedArrayGeneratorFingerprint import app.revanced.patches.shared.customspeed.fingerprints.SpeedArrayGeneratorFingerprint
import app.revanced.patches.shared.fingerprints.customspeed.SpeedLimiterFallBackFingerprint import app.revanced.patches.shared.customspeed.fingerprints.SpeedLimiterFallBackFingerprint
import app.revanced.patches.shared.fingerprints.customspeed.SpeedLimiterFingerprint import app.revanced.patches.shared.customspeed.fingerprints.SpeedLimiterFingerprint
import app.revanced.util.exception import app.revanced.util.exception
import com.android.tools.smali.dexlib2.Opcode import app.revanced.util.getTargetIndexWithFieldReferenceType
import app.revanced.util.getTargetIndexWithMethodReferenceName
import app.revanced.util.indexOfFirstInstruction
import com.android.tools.smali.dexlib2.iface.instruction.NarrowLiteralInstruction import com.android.tools.smali.dexlib2.iface.instruction.NarrowLiteralInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
abstract class AbstractCustomPlaybackSpeedPatch( abstract class AbstractCustomPlaybackSpeedPatch(
private val descriptor: String, private val descriptor: String,
@ -38,44 +37,25 @@ abstract class AbstractCustomPlaybackSpeedPatch(
""" """
) )
val targetInstruction = implementation!!.instructions val sizeIndex = getTargetIndexWithMethodReferenceName("size") + 1
val sizeRegister = getInstruction<OneRegisterInstruction>(sizeIndex).registerA
for ((index, instruction) in targetInstruction.withIndex()) { addInstructions(
if (instruction.opcode != Opcode.INVOKE_INTERFACE) continue sizeIndex + 1, """
invoke-static {v$sizeRegister}, $descriptor->getSize(I)I
val sizeInstruction = getInstruction<Instruction35c>(index) move-result v$sizeRegister
if ((sizeInstruction.reference as MethodReference).name != "size") continue
val register = getInstruction<OneRegisterInstruction>(index + 1).registerA
addInstructions(
index + 2, """
invoke-static {v$register}, $descriptor->getSize(I)I
move-result v$register
""" """
) )
break
}
val arrayIndex = getTargetIndexWithFieldReferenceType("[F")
val arrayRegister = getInstruction<OneRegisterInstruction>(arrayIndex).registerA
for ((index, instruction) in targetInstruction.withIndex()) { addInstructions(
if (instruction.opcode != Opcode.SGET_OBJECT) continue arrayIndex + 1, """
invoke-static {v$arrayRegister}, $descriptor->getArray([F)[F
val targetReference = move-result-object v$arrayRegister
getInstruction<ReferenceInstruction>(index).reference.toString() """
)
if (targetReference.endsWith(":[F")) {
val register = getInstruction<OneRegisterInstruction>(index).registerA
addInstructions(
index + 1, """
invoke-static {v$register}, $descriptor->getArray([F)[F
move-result-object v$register
"""
)
break
}
}
} }
} ?: throw SpeedArrayGeneratorFingerprint.exception } ?: throw SpeedArrayGeneratorFingerprint.exception
@ -88,12 +68,12 @@ abstract class AbstractCustomPlaybackSpeedPatch(
arrayOf( arrayOf(
speedLimiterParentResult, speedLimiterParentResult,
speedLimiterResult speedLimiterResult
).forEach { result -> ).forEach {
result.mutableMethod.apply { it.mutableMethod.apply {
val limiterMinConstIndex = val limiterMinConstIndex =
implementation!!.instructions.indexOfFirst { (it as? NarrowLiteralInstruction)?.narrowLiteral == 0.25f.toRawBits() } indexOfFirstInstruction { (this as? NarrowLiteralInstruction)?.narrowLiteral == 0.25f.toRawBits() }
val limiterMaxConstIndex = val limiterMaxConstIndex =
implementation!!.instructions.indexOfFirst { (it as? NarrowLiteralInstruction)?.narrowLiteral == 2.0f.toRawBits() } indexOfFirstInstruction { (this as? NarrowLiteralInstruction)?.narrowLiteral == 2.0f.toRawBits() }
val limiterMinConstDestination = val limiterMinConstDestination =
getInstruction<OneRegisterInstruction>(limiterMinConstIndex).registerA getInstruction<OneRegisterInstruction>(limiterMinConstIndex).registerA

View File

@ -1,4 +1,4 @@
package app.revanced.patches.shared.fingerprints.customspeed package app.revanced.patches.shared.customspeed.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint

View File

@ -1,4 +1,4 @@
package app.revanced.patches.shared.fingerprints.customspeed package app.revanced.patches.shared.customspeed.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint

View File

@ -1,4 +1,4 @@
package app.revanced.patches.shared.fingerprints.customspeed package app.revanced.patches.shared.customspeed.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint

View File

@ -1,4 +1,4 @@
package app.revanced.patches.shared.patch.dialog package app.revanced.patches.shared.dialog
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
@ -6,11 +6,11 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.shared.fingerprints.dialog.CreateDialogFingerprint import app.revanced.patches.shared.dialog.fingerprints.CreateDialogFingerprint
import app.revanced.util.exception import app.revanced.util.exception
import app.revanced.util.getTargetIndexWithMethodReferenceName
import app.revanced.util.getWalkerMethod
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
abstract class AbstractRemoveViewerDiscretionDialogPatch( abstract class AbstractRemoveViewerDiscretionDialogPatch(
private val classDescriptor: String, private val classDescriptor: String,
@ -22,9 +22,7 @@ abstract class AbstractRemoveViewerDiscretionDialogPatch(
} }
) { ) {
private fun MutableMethod.invoke(isAgeVerified: Boolean) { private fun MutableMethod.invoke(isAgeVerified: Boolean) {
val showDialogIndex = implementation!!.instructions.indexOfFirst { instruction -> val showDialogIndex = getTargetIndexWithMethodReferenceName("show")
((instruction as? ReferenceInstruction)?.reference as? MethodReference)?.name == "show"
}
val dialogRegister = getInstruction<FiveRegisterInstruction>(showDialogIndex).registerC val dialogRegister = getInstruction<FiveRegisterInstruction>(showDialogIndex).registerC
val methodName = val methodName =
@ -46,11 +44,8 @@ abstract class AbstractRemoveViewerDiscretionDialogPatch(
if (additionalFingerprints.isNotEmpty()) { if (additionalFingerprints.isNotEmpty()) {
additionalFingerprints.forEach { fingerprint -> additionalFingerprints.forEach { fingerprint ->
fingerprint.result?.let { fingerprint.result?.let {
val targetMethod = context.toMethodWalker(it.method) it.getWalkerMethod(context, it.scanResult.patternScanResult!!.endIndex - 1)
.nextMethod(it.scanResult.patternScanResult!!.endIndex - 1, true) .invoke(true)
.getMethod() as MutableMethod
targetMethod.invoke(true)
} ?: throw fingerprint.exception } ?: throw fingerprint.exception
} }
} }

View File

@ -1,4 +1,4 @@
package app.revanced.patches.shared.fingerprints.dialog package app.revanced.patches.shared.dialog.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags

View File

@ -0,0 +1,44 @@
package app.revanced.patches.shared.drawable
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.shared.drawable.fingerprints.DrawableFingerprint
import app.revanced.util.exception
import app.revanced.util.getTargetIndexWithMethodReferenceNameReversed
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
object DrawableColorPatch : BytecodePatch(
setOf(DrawableFingerprint)
) {
override fun execute(context: BytecodeContext) {
DrawableFingerprint.result?.mutableMethod?.apply {
insertMethod = this
insertIndex = getTargetIndexWithMethodReferenceNameReversed("setColor")
insertRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerD
} ?: throw DrawableFingerprint.exception
}
private var offset = 0
private var insertIndex: Int = 0
private var insertRegister: Int = 0
private lateinit var insertMethod: MutableMethod
fun injectCall(
methodDescriptor: String
) {
insertMethod.addInstructions(
insertIndex + offset, """
invoke-static {v$insertRegister}, $methodDescriptor
move-result v$insertRegister
"""
)
offset += 2
}
}

View File

@ -1,11 +1,11 @@
package app.revanced.patches.shared.fingerprints.litho package app.revanced.patches.shared.drawable.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
object LithoThemeFingerprint : MethodFingerprint( object DrawableFingerprint : MethodFingerprint(
returnType = "V", returnType = "V",
accessFlags = AccessFlags.PROTECTED or AccessFlags.FINAL, accessFlags = AccessFlags.PROTECTED or AccessFlags.FINAL,
parameters = listOf("L"), parameters = listOf("L"),
@ -15,5 +15,8 @@ object LithoThemeFingerprint : MethodFingerprint(
Opcode.INVOKE_VIRTUAL, // Paint.setColor: inject point Opcode.INVOKE_VIRTUAL, // Paint.setColor: inject point
Opcode.RETURN_VOID Opcode.RETURN_VOID
), ),
customFingerprint = { methodDef, _ -> methodDef.name == "onBoundsChange" } customFingerprint = { methodDef, classDef ->
methodDef.name == "onBoundsChange"
&& classDef.superclass == "Landroid/graphics/drawable/Drawable;"
}
) )

View File

@ -1,9 +1,10 @@
package app.revanced.patches.shared.patch.elements package app.revanced.patches.shared.elements
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.ResourcePatch
import kotlin.io.path.exists import kotlin.io.path.exists
@Suppress("DEPRECATION")
abstract class AbstractRemoveStringsElementsPatch( abstract class AbstractRemoveStringsElementsPatch(
private val paths: Array<String>, private val paths: Array<String>,
private val replacements: Array<String> private val replacements: Array<String>

View File

@ -0,0 +1,106 @@
package app.revanced.patches.shared.integrations
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchException
import app.revanced.patches.shared.integrations.BaseIntegrationsPatch.IntegrationsFingerprint.IRegisterResolver
import app.revanced.patches.shared.integrations.Constants.INTEGRATIONS_UTILS_CLASS_DESCRIPTOR
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.ClassDef
import com.android.tools.smali.dexlib2.iface.Method
abstract class BaseIntegrationsPatch(
private val hooks: Set<IntegrationsFingerprint>,
) : BytecodePatch(hooks) {
@Deprecated(
"Use the constructor without the integrationsDescriptor parameter",
ReplaceWith("BaseIntegrationsPatch(hooks)"),
)
@Suppress("UNUSED_PARAMETER")
constructor(
integrationsDescriptor: String,
hooks: Set<IntegrationsFingerprint>,
) : this(hooks)
override fun execute(context: BytecodeContext) {
if (context.findClass(INTEGRATIONS_UTILS_CLASS_DESCRIPTOR) == null) {
throw PatchException(
"Integrations have not been merged yet. This patch can not succeed without merging the integrations.",
)
}
hooks.forEach { hook ->
hook.invoke(INTEGRATIONS_UTILS_CLASS_DESCRIPTOR)
}
}
/**
* [MethodFingerprint] for integrations.
*
* @param contextRegisterResolver A [IRegisterResolver] to get the register.
* @see MethodFingerprint
*/
abstract class IntegrationsFingerprint(
returnType: String? = null,
accessFlags: Int? = null,
parameters: Iterable<String>? = null,
opcodes: Iterable<Opcode?>? = null,
strings: Iterable<String>? = null,
customFingerprint: ((methodDef: Method, classDef: ClassDef) -> Boolean)? = null,
private val insertIndexResolver: ((Method) -> Int) = object : IHookInsertIndexResolver {},
private val contextRegisterResolver: (Method) -> Int = object : IRegisterResolver {}
) : MethodFingerprint(
returnType,
accessFlags,
parameters,
opcodes,
strings,
customFingerprint,
) {
@Deprecated("Previous constructor that is missing the insert index." +
"Here only for binary compatibility, " +
"and this can be removed after the next major version update.")
constructor(
returnType: String? = null,
accessFlags: Int? = null,
parameters: Iterable<String>? = null,
opcodes: Iterable<Opcode?>? = null,
strings: Iterable<String>? = null,
customFingerprint: ((methodDef: Method, classDef: ClassDef) -> Boolean)? = null,
contextRegisterResolver: (Method) -> Int = object : IRegisterResolver {}
) : this(
returnType,
accessFlags,
parameters,
opcodes,
strings,
customFingerprint,
object : IHookInsertIndexResolver {},
contextRegisterResolver
)
fun invoke(integrationsDescriptor: String) {
result?.mutableMethod?.let { method ->
val insertIndex = insertIndexResolver(method)
val contextRegister = contextRegisterResolver(method)
method.addInstruction(
insertIndex,
"invoke-static/range { v$contextRegister .. v$contextRegister }, " +
"$integrationsDescriptor->setContext(Landroid/content/Context;)V",
)
} ?: throw PatchException("Could not find hook target fingerprint.")
}
interface IHookInsertIndexResolver : (Method) -> Int {
override operator fun invoke(method: Method) = 0
}
interface IRegisterResolver : (Method) -> Int {
override operator fun invoke(method: Method) = method.implementation!!.registerCount - 1
}
}
}

View File

@ -0,0 +1,10 @@
package app.revanced.patches.shared.integrations
@Suppress("MemberVisibilityCanBePrivate")
object Constants {
const val INTEGRATIONS_PATH = "Lapp/revanced/integrations/shared"
const val COMPONENTS_PATH = "$INTEGRATIONS_PATH/patches/components"
const val INTEGRATIONS_SETTING_CLASS_DESCRIPTOR = "$INTEGRATIONS_PATH/settings/Setting;"
const val INTEGRATIONS_UTILS_CLASS_DESCRIPTOR = "$INTEGRATIONS_PATH/utils/Utils;"
}

View File

@ -0,0 +1,119 @@
package app.revanced.patches.shared.litho
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.removeInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.shared.integrations.Constants.COMPONENTS_PATH
import app.revanced.patches.shared.litho.fingerprints.LithoFilterPatchConstructorFingerprint
import app.revanced.patches.shared.litho.fingerprints.PathBuilderFingerprint
import app.revanced.patches.shared.litho.fingerprints.SetByteBufferFingerprint
import app.revanced.util.exception
import app.revanced.util.getEmptyStringInstructionIndex
import app.revanced.util.getTargetIndex
import app.revanced.util.getTargetIndexReversed
import app.revanced.util.getTargetIndexWithFieldReferenceType
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction35c
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
import java.io.Closeable
@Suppress("unused")
object LithoFilterPatch : BytecodePatch(
setOf(
LithoFilterPatchConstructorFingerprint,
PathBuilderFingerprint,
SetByteBufferFingerprint
)
), Closeable {
private const val INTEGRATIONS_LITHO_FILER_CLASS_DESCRIPTOR =
"$COMPONENTS_PATH/LithoFilterPatch;"
private const val INTEGRATIONS_FILER_CLASS_DESCRIPTOR =
"$COMPONENTS_PATH/Filter;"
internal lateinit var addFilter: (String) -> Unit
private set
private var filterCount = 0
override fun execute(context: BytecodeContext) {
SetByteBufferFingerprint.result?.let {
it.mutableMethod.apply {
val insertIndex = getTargetIndex(Opcode.IF_EQZ) + 1
addInstruction(
insertIndex,
"invoke-static { p2 }, $INTEGRATIONS_LITHO_FILER_CLASS_DESCRIPTOR->setProtoBuffer(Ljava/nio/ByteBuffer;)V"
)
}
} ?: throw SetByteBufferFingerprint.exception
PathBuilderFingerprint.result?.let {
it.mutableMethod.apply {
val emptyComponentMethodIndex = it.scanResult.patternScanResult!!.startIndex + 1
val emptyComponentMethodReference =
getInstruction<ReferenceInstruction>(emptyComponentMethodIndex).reference
val emptyComponentFieldReference =
getInstruction<ReferenceInstruction>(emptyComponentMethodIndex + 2).reference
val stringBuilderIndex = getTargetIndexWithFieldReferenceType("Ljava/lang/StringBuilder;")
val stringBuilderRegister = getInstruction<TwoRegisterInstruction>(stringBuilderIndex).registerA
val emptyStringIndex = getEmptyStringInstructionIndex()
val identifierIndex = getTargetIndexReversed(emptyStringIndex, Opcode.IPUT_OBJECT)
val identifierRegister = getInstruction<TwoRegisterInstruction>(identifierIndex).registerA
val objectIndex = getTargetIndex(emptyStringIndex, Opcode.INVOKE_VIRTUAL)
val objectRegister = getInstruction<BuilderInstruction35c>(objectIndex).registerC
val insertIndex = stringBuilderIndex + 1
addInstructionsWithLabels(
insertIndex, """
invoke-static {v$stringBuilderRegister, v$identifierRegister, v$objectRegister}, $INTEGRATIONS_LITHO_FILER_CLASS_DESCRIPTOR->filter(Ljava/lang/StringBuilder;Ljava/lang/String;Ljava/lang/Object;)Z
move-result v$stringBuilderRegister
if-eqz v$stringBuilderRegister, :filter
move-object/from16 v0, p1
invoke-static {v0}, $emptyComponentMethodReference
move-result-object v0
iget-object v0, v0, $emptyComponentFieldReference
return-object v0
""", ExternalLabel("filter", getInstruction(insertIndex))
)
}
} ?: throw PathBuilderFingerprint.exception
LithoFilterPatchConstructorFingerprint.result?.let {
it.mutableMethod.apply {
removeInstructions(0, 6)
addFilter = { classDescriptor ->
addInstructions(
0, """
new-instance v1, $classDescriptor
invoke-direct {v1}, $classDescriptor-><init>()V
const/16 v2, ${filterCount++}
aput-object v1, v0, v2
"""
)
}
}
} ?: throw LithoFilterPatchConstructorFingerprint.exception
}
override fun close() = LithoFilterPatchConstructorFingerprint.result!!
.mutableMethod.addInstructions(
0, """
const/16 v0, $filterCount
new-array v0, v0, [$INTEGRATIONS_FILER_CLASS_DESCRIPTOR
"""
)
}

View File

@ -1,11 +1,11 @@
package app.revanced.patches.music.utils.litho.fingerprints package app.revanced.patches.shared.litho.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH import app.revanced.patches.shared.integrations.Constants.COMPONENTS_PATH
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
object LithoFilterFingerprint : MethodFingerprint( object LithoFilterPatchConstructorFingerprint : MethodFingerprint(
returnType = "V", returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC or AccessFlags.CONSTRUCTOR, accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC or AccessFlags.CONSTRUCTOR,
customFingerprint = { methodDef, _ -> customFingerprint = { methodDef, _ ->

View File

@ -1,11 +1,11 @@
package app.revanced.patches.shared.fingerprints.litho package app.revanced.patches.shared.litho.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
object EmptyComponentBuilderFingerprint : MethodFingerprint( object PathBuilderFingerprint : MethodFingerprint(
returnType = "L", returnType = "L",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
opcodes = listOf( opcodes = listOf(

View File

@ -1,11 +1,11 @@
package app.revanced.patches.shared.fingerprints.litho package app.revanced.patches.shared.litho.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
object GeneralByteBufferFingerprint : MethodFingerprint( object SetByteBufferFingerprint : MethodFingerprint(
returnType = "V", returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("I", "Ljava/nio/ByteBuffer;"), parameters = listOf("I", "Ljava/nio/ByteBuffer;"),
@ -26,5 +26,10 @@ object GeneralByteBufferFingerprint : MethodFingerprint(
Opcode.IPUT, Opcode.IPUT,
Opcode.IPUT, Opcode.IPUT,
Opcode.GOTO Opcode.GOTO
) ),
// Check method count and field count to support both YouTube and YouTube Music
customFingerprint = { _, classDef ->
classDef.methods.count() > 6
&& classDef.fields.count() > 4
}
) )

View File

@ -1,4 +1,4 @@
package app.revanced.patches.shared.patch.mapping package app.revanced.patches.shared.mapping
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.ResourcePatch
@ -7,6 +7,7 @@ import java.util.Collections
import java.util.concurrent.Executors import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
@Suppress("DEPRECATION")
object ResourceMappingPatch : ResourcePatch() { object ResourceMappingPatch : ResourcePatch() {
internal lateinit var resourceMappings: List<ResourceElement> internal lateinit var resourceMappings: List<ResourceElement>
private set private set
@ -58,4 +59,8 @@ object ResourceMappingPatch : ResourcePatch() {
} }
data class ResourceElement(val type: String, val name: String, val id: Long) data class ResourceElement(val type: String, val name: String, val id: Long)
fun getId(resourceType: ResourceType, resourceName: String) = resourceMappings
.find { it.type == resourceType.value && it.name == resourceName }?.id
?: -1
} }

View File

@ -1,4 +1,4 @@
package app.revanced.patches.shared.patch.mapping package app.revanced.patches.shared.mapping
enum class ResourceType(val value: String) { enum class ResourceType(val value: String) {
ATTR("attr"), ATTR("attr"),

View File

@ -1,4 +1,4 @@
package app.revanced.patches.shared.patch.microg package app.revanced.patches.shared.microg
/** /**
* constants for microG builds with signature spoofing * constants for microG builds with signature spoofing

View File

@ -1,4 +1,4 @@
package app.revanced.patches.shared.patch.microg package app.revanced.patches.shared.microg
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
@ -6,10 +6,10 @@ import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patcher.util.proxy.mutableTypes.MutableClass import app.revanced.patcher.util.proxy.mutableTypes.MutableClass
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.shared.patch.microg.Constants.ACTIONS import app.revanced.patches.shared.microg.Constants.ACTIONS
import app.revanced.patches.shared.patch.microg.Constants.AUTHORITIES import app.revanced.patches.shared.microg.Constants.AUTHORITIES
import app.revanced.patches.shared.patch.microg.Constants.MICROG_VENDOR import app.revanced.patches.shared.microg.Constants.MICROG_VENDOR
import app.revanced.patches.shared.patch.microg.Constants.PERMISSIONS import app.revanced.patches.shared.microg.Constants.PERMISSIONS
import app.revanced.util.exception import app.revanced.util.exception
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction21c import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction21c

View File

@ -1,16 +1,17 @@
package app.revanced.patches.shared.patch.microg package app.revanced.patches.shared.microg
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.ResourceContext
import app.revanced.patches.shared.patch.microg.Constants.META_GMS_PACKAGE_NAME import app.revanced.patches.shared.microg.Constants.META_GMS_PACKAGE_NAME
import app.revanced.patches.shared.patch.microg.Constants.META_SPOOFED_PACKAGE_NAME import app.revanced.patches.shared.microg.Constants.META_SPOOFED_PACKAGE_NAME
import app.revanced.patches.shared.patch.microg.Constants.META_SPOOFED_PACKAGE_SIGNATURE import app.revanced.patches.shared.microg.Constants.META_SPOOFED_PACKAGE_SIGNATURE
import app.revanced.patches.shared.patch.microg.Constants.MICROG_VENDOR import app.revanced.patches.shared.microg.Constants.MICROG_VENDOR
import org.w3c.dom.Element import org.w3c.dom.Element
import org.w3c.dom.Node import org.w3c.dom.Node
/** /**
* helper class for adding manifest metadata needed for microG builds with signature spoofing * helper class for adding manifest metadata needed for microG builds with signature spoofing
*/ */
@Suppress("DEPRECATION")
object MicroGManifestHelper { object MicroGManifestHelper {
/** /**

View File

@ -1,10 +1,11 @@
package app.revanced.patches.shared.patch.microg package app.revanced.patches.shared.microg
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.ResourceContext
/** /**
* Helper class for applying resource patches needed for the microg-support patches. * Helper class for applying resource patches needed for the microg-support patches.
*/ */
@Suppress("DEPRECATION")
object MicroGResourceHelper { object MicroGResourceHelper {
/** /**
* Patch the manifest to work with MicroG. * Patch the manifest to work with MicroG.

View File

@ -1,4 +1,4 @@
package app.revanced.patches.shared.patch.opus package app.revanced.patches.shared.opus
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
@ -6,8 +6,8 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.shared.fingerprints.opus.CodecReferenceFingerprint import app.revanced.patches.shared.opus.fingerprints.CodecReferenceFingerprint
import app.revanced.patches.shared.fingerprints.opus.CodecSelectorFingerprint import app.revanced.patches.shared.opus.fingerprints.CodecSelectorFingerprint
import app.revanced.util.exception import app.revanced.util.exception
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@ -62,5 +62,5 @@ abstract class AbstractOpusCodecsPatch(
} }
lateinit var targetReference: Reference private lateinit var targetReference: Reference
} }

View File

@ -1,4 +1,4 @@
package app.revanced.patches.shared.fingerprints.opus package app.revanced.patches.shared.opus.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint

View File

@ -1,4 +1,4 @@
package app.revanced.patches.shared.fingerprints.opus package app.revanced.patches.shared.opus.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint

View File

@ -1,4 +1,4 @@
package app.revanced.patches.shared.patch.overlaybackground package app.revanced.patches.shared.overlaybackground
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.ResourcePatch
@ -6,6 +6,7 @@ import app.revanced.util.doRecursively
import org.w3c.dom.Element import org.w3c.dom.Element
import kotlin.io.path.exists import kotlin.io.path.exists
@Suppress("DEPRECATION")
abstract class AbstractOverlayBackgroundPatch( abstract class AbstractOverlayBackgroundPatch(
private val files: Array<String>, private val files: Array<String>,
private val targetId: Array<String>, private val targetId: Array<String>,

View File

@ -1,4 +1,4 @@
package app.revanced.patches.shared.patch.packagename package app.revanced.patches.shared.packagename
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.ResourcePatch

View File

@ -1,50 +0,0 @@
package app.revanced.patches.shared.patch.ads
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.shared.fingerprints.ads.LegacyAdsFingerprint
import app.revanced.patches.shared.fingerprints.ads.MainstreamAdsFingerprint
import app.revanced.util.exception
abstract class AbstractAdsPatch(
private val descriptor: String
) : BytecodePatch(
setOf(
LegacyAdsFingerprint,
MainstreamAdsFingerprint
)
) {
override fun execute(context: BytecodeContext) {
LegacyAdsFingerprint.result?.let {
(context.toMethodWalker(it.method)
.nextMethod(13, true)
.getMethod() as MutableMethod).apply {
addInstructions(
0, """
invoke-static {}, $descriptor
move-result v1
"""
)
}
} ?: throw LegacyAdsFingerprint.exception
MainstreamAdsFingerprint.result?.let {
it.mutableMethod.apply {
addInstructionsWithLabels(
0, """
invoke-static {}, $descriptor
move-result v0
if-nez v0, :show_ads
return-void
""", ExternalLabel("show_ads", getInstruction(0))
)
}
}
}
}

View File

@ -1,64 +0,0 @@
package app.revanced.patches.shared.patch.integrations
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchException
import app.revanced.patches.shared.patch.integrations.AbstractIntegrationsPatch.IntegrationsFingerprint.RegisterResolver
import app.revanced.util.exception
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.ClassDef
import com.android.tools.smali.dexlib2.iface.Method
abstract class AbstractIntegrationsPatch(
private val integrationsDescriptor: String,
private val hooks: Set<IntegrationsFingerprint>
) : BytecodePatch(hooks) {
/**
* [MethodFingerprint] for integrations.
*
* @param contextRegisterResolver A [RegisterResolver] to get the register.
* @see MethodFingerprint
*/
abstract class IntegrationsFingerprint(
returnType: String? = null,
accessFlags: Int? = null,
parameters: Iterable<String>? = null,
opcodes: Iterable<Opcode?>? = null,
strings: Iterable<String>? = null,
customFingerprint: ((methodDef: Method, classDef: ClassDef) -> Boolean)? = null,
private val contextRegisterResolver: (Method) -> Int = object : RegisterResolver {}
) : MethodFingerprint(
returnType,
accessFlags,
parameters,
opcodes,
strings,
customFingerprint
) {
fun invoke(integrationsDescriptor: String) {
result?.mutableMethod?.let { method ->
val contextRegister = contextRegisterResolver(method)
method.addInstruction(
0,
"sput-object v$contextRegister, " +
"$integrationsDescriptor->context:Landroid/content/Context;"
)
} ?: throw exception
}
interface RegisterResolver : (Method) -> Int {
override operator fun invoke(method: Method) = method.implementation!!.registerCount - 1
}
}
override fun execute(context: BytecodeContext) {
if (context.findClass(integrationsDescriptor) == null) throw PatchException(
"Integrations have not been merged yet. This patch can not succeed without merging the integrations."
)
for (hook in hooks) hook.invoke(integrationsDescriptor)
}
}

View File

@ -1,106 +0,0 @@
package app.revanced.patches.shared.patch.litho
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.shared.fingerprints.litho.EmptyComponentBuilderFingerprint
import app.revanced.patches.shared.fingerprints.litho.GeneralByteBufferFingerprint
import app.revanced.util.exception
import app.revanced.util.getEmptyStringInstructionIndex
import app.revanced.util.getReference
import app.revanced.util.getTargetIndex
import app.revanced.util.getTargetIndexReversed
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction35c
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
import kotlin.properties.Delegates
object ComponentParserPatch : BytecodePatch(
setOf(
EmptyComponentBuilderFingerprint,
GeneralByteBufferFingerprint
)
) {
private lateinit var emptyComponentLabel: String
private lateinit var byteBufferMethod: MutableMethod
internal lateinit var pathBuilderMethod: MutableMethod
private var emptyComponentIndex by Delegates.notNull<Int>()
private var insertIndex by Delegates.notNull<Int>()
private var identifierRegister by Delegates.notNull<Int>()
private var objectRegister by Delegates.notNull<Int>()
private var stringBuilderRegister by Delegates.notNull<Int>()
internal fun injectCall(descriptor: String) {
byteBufferMethod.apply {
val insertIndex = getTargetIndex(0, Opcode.IF_EQZ) + 1
addInstruction(
insertIndex,
"invoke-static { p2 }, $descriptor->setProtoBuffer(Ljava/nio/ByteBuffer;)V"
)
}
pathBuilderMethod.apply {
addInstructionsWithLabels(
insertIndex, """
invoke-static {v$stringBuilderRegister, v$identifierRegister, v$objectRegister}, $descriptor->filter(Ljava/lang/StringBuilder;Ljava/lang/String;Ljava/lang/Object;)Z
move-result v$stringBuilderRegister
if-eqz v$stringBuilderRegister, :filter
""" + emptyComponentLabel,
ExternalLabel("filter", getInstruction(insertIndex))
)
}
}
override fun execute(context: BytecodeContext) {
byteBufferMethod = GeneralByteBufferFingerprint.result?.mutableMethod
?: throw GeneralByteBufferFingerprint.exception
EmptyComponentBuilderFingerprint.result?.let {
it.mutableMethod.apply {
pathBuilderMethod = this
emptyComponentIndex = it.scanResult.patternScanResult!!.startIndex + 1
val builderMethodDescriptor =
getInstruction<ReferenceInstruction>(emptyComponentIndex).reference
val emptyComponentFieldDescriptor =
getInstruction<ReferenceInstruction>(emptyComponentIndex + 2).reference
emptyComponentLabel = """
move-object/from16 v0, p1
invoke-static {v0}, $builderMethodDescriptor
move-result-object v0
iget-object v0, v0, $emptyComponentFieldDescriptor
return-object v0
"""
val stringBuilderIndex =
implementation!!.instructions.indexOfFirst { instruction ->
instruction.getReference<FieldReference>()?.type == "Ljava/lang/StringBuilder;"
}
stringBuilderRegister =
getInstruction<TwoRegisterInstruction>(stringBuilderIndex).registerA
insertIndex = stringBuilderIndex + 1
val emptyStringIndex = getEmptyStringInstructionIndex()
val identifierIndex = getTargetIndexReversed(emptyStringIndex, Opcode.IPUT_OBJECT)
identifierRegister =
getInstruction<TwoRegisterInstruction>(identifierIndex).registerA
val objectIndex = getTargetIndex(emptyStringIndex, Opcode.INVOKE_VIRTUAL)
objectRegister = getInstruction<BuilderInstruction35c>(objectIndex).registerC
}
} ?: throw EmptyComponentBuilderFingerprint.exception
}
}

View File

@ -1,52 +0,0 @@
package app.revanced.patches.shared.patch.litho
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.shared.fingerprints.litho.LithoThemeFingerprint
import app.revanced.util.exception
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
object LithoThemePatch : BytecodePatch(
setOf(LithoThemeFingerprint)
) {
override fun execute(context: BytecodeContext) {
LithoThemeFingerprint.result?.mutableMethod?.let {
with(it.implementation!!.instructions) {
for (index in size - 1 downTo 0) {
val invokeInstruction = this[index] as? ReferenceInstruction ?: continue
if ((invokeInstruction.reference as MethodReference).name != "setColor") continue
insertIndex = index
insertRegister = (this[index] as Instruction35c).registerD
insertMethod = it
break
}
}
} ?: throw LithoThemeFingerprint.exception
}
private var offset = 0
private var insertIndex: Int = 0
private var insertRegister: Int = 0
private lateinit var insertMethod: MutableMethod
fun injectCall(
methodDescriptor: String
) {
insertMethod.addInstructions(
insertIndex + offset, """
invoke-static {v$insertRegister}, $methodDescriptor
move-result v$insertRegister
"""
)
offset += 2
}
}

View File

@ -1,58 +0,0 @@
package app.revanced.patches.shared.patch.versionspoof
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patches.shared.fingerprints.versionspoof.ClientInfoFingerprint
import app.revanced.patches.shared.fingerprints.versionspoof.ClientInfoParentFingerprint
import app.revanced.util.exception
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.dexbacked.reference.DexBackedFieldReference
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
abstract class AbstractVersionSpoofPatch(
private val descriptor: String
) : BytecodePatch(
setOf(ClientInfoParentFingerprint)
) {
override fun execute(context: BytecodeContext) {
ClientInfoParentFingerprint.result?.let { parentResult ->
ClientInfoFingerprint.also {
it.resolve(
context,
parentResult.classDef
)
}.result?.mutableMethod?.let {
it.apply {
var insertIndex = 0
val insertInstructions = implementation!!.instructions
val targetString = "Landroid/os/Build\$VERSION;->RELEASE:Ljava/lang/String;"
for ((index, instruction) in insertInstructions.withIndex()) {
if (instruction.opcode != Opcode.SGET_OBJECT) continue
val indexString =
((instruction as? ReferenceInstruction)?.reference as? DexBackedFieldReference).toString()
if (indexString != targetString) continue
val targetRegister = (instruction as OneRegisterInstruction).registerA
insertIndex = index - 1
addInstructions(
insertIndex, """
invoke-static {v$targetRegister}, $descriptor
move-result-object v$targetRegister
"""
)
break
}
if (insertIndex <= 0) throw ClientInfoFingerprint.exception
}
} ?: throw ClientInfoFingerprint.exception
} ?: throw ClientInfoParentFingerprint.exception
}
}

Some files were not shown because too many files have changed in this diff Show More