Compare commits

...

12 Commits

Author SHA1 Message Date
semantic-release-bot
2d20ed857c chore(release): 2.188.0-dev.14 [skip ci]
# [2.188.0-dev.14](https://github.com/ReVanced/revanced-patches/compare/v2.188.0-dev.13...v2.188.0-dev.14) (2023-08-13)

### Bug Fixes

* allow using `PreferenceScreen` outside of current module ([eb20cc4](eb20cc477f))
2023-08-13 16:39:06 +00:00
oSumAtrIX
eb20cc477f fix: allow using PreferenceScreen outside of current module 2023-08-13 18:36:07 +02:00
semantic-release-bot
d002eaaca6 chore(release): 2.188.0-dev.13 [skip ci]
# [2.188.0-dev.13](https://github.com/ReVanced/revanced-patches/compare/v2.188.0-dev.12...v2.188.0-dev.13) (2023-08-13)

### Features

* **YouTube - External downloads:** Recommend Seal instead of PowerTube ([#2803](https://github.com/ReVanced/revanced-patches/issues/2803)) ([aef6813](aef68134b5))
2023-08-13 11:42:46 +00:00
KAZI MMT
aef68134b5 feat(YouTube - External downloads): Recommend Seal instead of PowerTube (#2803) 2023-08-13 13:40:01 +02:00
semantic-release-bot
5deaa6476f chore(release): 2.188.0-dev.12 [skip ci]
# [2.188.0-dev.12](https://github.com/ReVanced/revanced-patches/compare/v2.188.0-dev.11...v2.188.0-dev.12) (2023-08-10)

### Features

* Add `Override certificate pinning` patch ([#2781](https://github.com/ReVanced/revanced-patches/issues/2781)) ([78d831f](78d831fc63))
2023-08-10 18:44:34 +00:00
Aunali321
78d831fc63 feat: Add Override certificate pinning patch (#2781)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2023-08-10 20:41:31 +02:00
semantic-release-bot
46809c3819 chore(release): 2.188.0-dev.11 [skip ci]
# [2.188.0-dev.11](https://github.com/ReVanced/revanced-patches/compare/v2.188.0-dev.10...v2.188.0-dev.11) (2023-08-09)

### Bug Fixes

* **Client spoof:** Remove exception from option ([8f559ca](8f559ca170))
2023-08-09 15:58:17 +00:00
oSumAtrIX
8f559ca170 fix(Client spoof): Remove exception from option
Turning off will cause playback issues even when being subscribed to YouTube Premium
2023-08-09 17:55:18 +02:00
semantic-release-bot
48ea11f571 chore(release): 2.188.0-dev.10 [skip ci]
# [2.188.0-dev.10](https://github.com/ReVanced/revanced-patches/compare/v2.188.0-dev.9...v2.188.0-dev.10) (2023-08-09)

### Features

* **Tasker:** Remove `Unlock trial` patch ([2ff3400](2ff3400ef1))
2023-08-09 10:26:50 +00:00
oSumAtrIX
2ff3400ef1 feat(Tasker): Remove Unlock trial patch 2023-08-09 12:23:56 +02:00
semantic-release-bot
bc8ce81bbc chore(release): 2.188.0-dev.9 [skip ci]
# [2.188.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v2.188.0-dev.8...v2.188.0-dev.9) (2023-08-07)

### Features

* **YouTube - Hide video action buttons:** Hide individual action buttons ([#2723](https://github.com/ReVanced/revanced-patches/issues/2723)) ([7c131bf](7c131bfe1b))
2023-08-07 14:37:51 +00:00
LisoUseInAIKyrios
7c131bfe1b feat(YouTube - Hide video action buttons): Hide individual action buttons (#2723) 2023-08-07 18:34:53 +04:00
25 changed files with 199 additions and 118 deletions

View File

@@ -1,3 +1,45 @@
# [2.188.0-dev.14](https://github.com/ReVanced/revanced-patches/compare/v2.188.0-dev.13...v2.188.0-dev.14) (2023-08-13)
### Bug Fixes
* allow using `PreferenceScreen` outside of current module ([fe94013](https://github.com/ReVanced/revanced-patches/commit/fe94013a2235953b32fed6e0710a252698a264b3))
# [2.188.0-dev.13](https://github.com/ReVanced/revanced-patches/compare/v2.188.0-dev.12...v2.188.0-dev.13) (2023-08-13)
### Features
* **YouTube - External downloads:** Recommend Seal instead of PowerTube ([#2803](https://github.com/ReVanced/revanced-patches/issues/2803)) ([082e067](https://github.com/ReVanced/revanced-patches/commit/082e067338026d05046ed5f398a1261aa20d3cb3))
# [2.188.0-dev.12](https://github.com/ReVanced/revanced-patches/compare/v2.188.0-dev.11...v2.188.0-dev.12) (2023-08-10)
### Features
* Add `Override certificate pinning` patch ([#2781](https://github.com/ReVanced/revanced-patches/issues/2781)) ([94ed738](https://github.com/ReVanced/revanced-patches/commit/94ed738515aa6e1a1d346b85b54805e68e36f94c))
# [2.188.0-dev.11](https://github.com/ReVanced/revanced-patches/compare/v2.188.0-dev.10...v2.188.0-dev.11) (2023-08-09)
### Bug Fixes
* **Client spoof:** Remove exception from option ([9c69f87](https://github.com/ReVanced/revanced-patches/commit/9c69f876902496c101eac295e581c15e02bfaf29))
# [2.188.0-dev.10](https://github.com/ReVanced/revanced-patches/compare/v2.188.0-dev.9...v2.188.0-dev.10) (2023-08-09)
### Features
* **Tasker:** Remove `Unlock trial` patch ([8354a87](https://github.com/ReVanced/revanced-patches/commit/8354a879cfc6028820e2bb0e01d6f607e145c0f6))
# [2.188.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v2.188.0-dev.8...v2.188.0-dev.9) (2023-08-07)
### Features
* **YouTube - Hide video action buttons:** Hide individual action buttons ([#2723](https://github.com/ReVanced/revanced-patches/issues/2723)) ([220f694](https://github.com/ReVanced/revanced-patches/commit/220f694b12e7ed013753c8215d181936ab2205c3))
# [2.188.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v2.188.0-dev.7...v2.188.0-dev.8) (2023-08-07) # [2.188.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v2.188.0-dev.7...v2.188.0-dev.8) (2023-08-07)

View File

@@ -1,4 +1,4 @@
org.gradle.parallel = true org.gradle.parallel = true
org.gradle.caching = true org.gradle.caching = true
kotlin.code.style = official kotlin.code.style = official
version = 2.188.0-dev.8 version = 2.188.0-dev.14

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,79 @@
package app.revanced.patches.all.misc.network.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.*
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.all.misc.debugging.patch.EnableAndroidDebuggingPatch
import org.w3c.dom.Element
import java.io.File
@Patch(false)
@Name("Override certificate pinning")
@Description("Overrides certificate pinning, allowing to inspect traffic via a proxy.")
@DependsOn([EnableAndroidDebuggingPatch::class])
class OverrideCertificatePinningPatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult {
val resXmlDirectory = context["res/xml"]
// Add android:networkSecurityConfig="@xml/network_security_config" and the "networkSecurityConfig" attribute if it does not exist.
context.xmlEditor["AndroidManifest.xml"].use { editor ->
val document = editor.file
val applicationNode = document.getElementsByTagName("application").item(0) as Element
if (!applicationNode.hasAttribute("networkSecurityConfig")) {
document.createAttribute("android:networkSecurityConfig")
.apply { value = "@xml/network_security_config" }.let(applicationNode.attributes::setNamedItem)
}
}
// In case the file does not exist create the "network_security_config.xml" file.
File(resXmlDirectory, "network_security_config.xml").apply {
if (!exists()) {
createNewFile()
writeText(
"""
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
<certificates
src="user"
overridePins="true" />
</trust-anchors>
</base-config>
<debug-overrides>
<trust-anchors>
<certificates src="system" />
<certificates
src="user"
overridePins="true" />
</trust-anchors>
</debug-overrides>
</network-security-config>
"""
)
} else {
// If the file already exists.
readText().let { text ->
if (!text.contains("<certificates src=\"user\" />")) {
writeText(
text.replace(
"<trust-anchors>",
"<trust-anchors>\n<certificates src=\"user\" overridePins=\"true\" />\n<certificates src=\"system\" />"
)
)
}
}
}
}
return PatchResultSuccess()
}
}

View File

@@ -12,7 +12,7 @@ import org.w3c.dom.Element
* @param tag The tag of the preference. * @param tag The tag of the preference.
* @param summary The summary of the preference. * @param summary The summary of the preference.
*/ */
internal abstract class BasePreference( abstract class BasePreference(
val key: String?, val key: String?,
val title: StringResource, val title: StringResource,
val summary: StringResource? = null, val summary: StringResource? = null,

View File

@@ -9,7 +9,7 @@ import org.w3c.dom.Element
* @param name The name of the resource. * @param name The name of the resource.
* @param tag The tag of the resource. * @param tag The tag of the resource.
*/ */
internal abstract class BaseResource( abstract class BaseResource(
val name: String, val name: String,
val tag: String val tag: String
) { ) {

View File

@@ -12,7 +12,7 @@ import org.w3c.dom.Document
* @param summary The summary of the preference. * @param summary The summary of the preference.
* @param default The default value of the preference. * @param default The default value of the preference.
*/ */
internal abstract class DefaultBasePreference<T>( abstract class DefaultBasePreference<T>(
key: String?, key: String?,
title: StringResource, title: StringResource,
summary: StringResource? = null, summary: StringResource? = null,

View File

@@ -10,7 +10,7 @@ import org.w3c.dom.Document
* @param name The name of the array resource. * @param name The name of the array resource.
* @param items The items of the array resource. * @param items The items of the array resource.
*/ */
internal class ArrayResource( class ArrayResource(
name: String, name: String,
val items: List<StringResource> val items: List<StringResource>
) : BaseResource(name, "string-array") { ) : BaseResource(name, "string-array") {

View File

@@ -15,7 +15,7 @@ import org.w3c.dom.Document
* @param summary The summary of the list preference. * @param summary The summary of the list preference.
* @param default The default entry value of the list preference. * @param default The default entry value of the list preference.
*/ */
internal class ListPreference( class ListPreference(
key: String, key: String,
title: StringResource, title: StringResource,
val entries: ArrayResource, val entries: ArrayResource,

View File

@@ -15,7 +15,7 @@ import org.w3c.dom.Element
* @param title The title of the preference. * @param title The title of the preference.
* @param summary The summary of the text preference. * @param summary The summary of the text preference.
*/ */
internal class NonInteractivePreference( class NonInteractivePreference(
title: StringResource, title: StringResource,
summary: StringResource, summary: StringResource,
) : BasePreference(null, title, summary, "Preference") { ) : BasePreference(null, title, summary, "Preference") {

View File

@@ -12,7 +12,7 @@ import org.w3c.dom.Document
* @param summary The summary of the text preference. * @param summary The summary of the text preference.
* @param intent The intent of the preference. * @param intent The intent of the preference.
*/ */
internal class Preference( class Preference(
key: String, key: String,
title: StringResource, title: StringResource,
summary: StringResource, summary: StringResource,
@@ -33,7 +33,7 @@ internal class Preference(
}) })
} }
internal class Intent( class Intent(
internal val targetPackage: String, internal val targetPackage: String,
internal val data: String, internal val data: String,
internal val targetClass: String internal val targetClass: String

View File

@@ -11,7 +11,7 @@ import org.w3c.dom.Document
* @param title The title of the preference. * @param title The title of the preference.
* @param preferences Child preferences of this category. * @param preferences Child preferences of this category.
*/ */
internal open class PreferenceCategory( open class PreferenceCategory(
key: String, key: String,
title: StringResource, title: StringResource,
var preferences: List<BasePreference>, var preferences: List<BasePreference>,

View File

@@ -13,7 +13,7 @@ import org.w3c.dom.Document
* @param preferences Child preferences of this screen. * @param preferences Child preferences of this screen.
* @param summary The summary of the text preference. * @param summary The summary of the text preference.
*/ */
internal open class PreferenceScreen( open class PreferenceScreen(
key: String, key: String,
title: StringResource, title: StringResource,
var preferences: List<BasePreference>, var preferences: List<BasePreference>,

View File

@@ -11,7 +11,7 @@ import org.w3c.dom.Document
* @param value The value of the string. * @param value The value of the string.
* @param formatted If the string is formatted. If false, the attribute will be set. * @param formatted If the string is formatted. If false, the attribute will be set.
*/ */
internal class StringResource( class StringResource(
name: String, name: String,
val value: String, val value: String,
val formatted: Boolean = true val formatted: Boolean = true

View File

@@ -18,7 +18,7 @@ import org.w3c.dom.Element
* @param userDialogMessage The message to show in a dialog when the user toggles the preference. * @param userDialogMessage The message to show in a dialog when the user toggles the preference.
* @param default The default value of the switch. * @param default The default value of the switch.
*/ */
internal class SwitchPreference( class SwitchPreference(
key: String, title: StringResource, key: String, title: StringResource,
val summaryOn: StringResource, val summaryOn: StringResource,
val summaryOff: StringResource, val summaryOff: StringResource,

View File

@@ -13,7 +13,7 @@ import org.w3c.dom.Document
* @param summary The summary of the text preference. * @param summary The summary of the text preference.
* @param default The default value of the text preference. * @param default The default value of the text preference.
*/ */
internal class TextPreference( class TextPreference(
key: String?, key: String?,
title: StringResource, title: StringResource,
summary: StringResource?, summary: StringResource?,

View File

@@ -6,7 +6,7 @@ import app.revanced.patches.shared.settings.preference.impl.PreferenceScreen
import app.revanced.patches.shared.settings.preference.impl.StringResource import app.revanced.patches.shared.settings.preference.impl.StringResource
import java.io.Closeable import java.io.Closeable
internal abstract class AbstractPreferenceScreen( abstract class AbstractPreferenceScreen(
private val root: MutableList<Screen> = mutableListOf() private val root: MutableList<Screen> = mutableListOf()
) : Closeable { ) : Closeable {

View File

@@ -1,8 +0,0 @@
package app.revanced.patches.tasker.trial.unlock.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility([Package("net.dinglisch.android.taskerm")])
@Target(AnnotationTarget.CLASS)
internal annotation class UnlockTrialCompatibility

View File

@@ -1,7 +0,0 @@
package app.revanced.patches.tasker.trial.unlock.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object CheckLicenseFingerprint : MethodFingerprint(
strings = listOf("Can't check license")
)

View File

@@ -1,30 +0,0 @@
package app.revanced.patches.tasker.trial.unlock.patch
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.tasker.trial.unlock.annotations.UnlockTrialCompatibility
import app.revanced.patches.tasker.trial.unlock.fingerprints.CheckLicenseFingerprint
@Patch
@Name("Unlock trial")
@Description("Unlocks the trial version.")
@UnlockTrialCompatibility
class UnlockLicensePatch : BytecodePatch(
listOf(
CheckLicenseFingerprint
)
) {
override fun execute(context: BytecodeContext) = CheckLicenseFingerprint
.result
?.mutableMethod
// Return the method early, which prompts the user with a non dismissible dialog, when the trial period is over.
?.addInstruction(0, "return-void")
?.let { PatchResultSuccess() }
?: CheckLicenseFingerprint.toErrorResult()
}

View File

@@ -30,7 +30,7 @@ class ExternalDownloadsResourcePatch : ResourcePatch {
TextPreference( TextPreference(
"revanced_external_downloader_name", "revanced_external_downloader_name",
StringResource("revanced_external_downloader_name_title", "Downloader package name"), StringResource("revanced_external_downloader_name_title", "Downloader package name"),
StringResource("revanced_external_downloader_name_summary", "Package name of your installed external downloader app, such as NewPipe or PowerTube"), StringResource("revanced_external_downloader_name_summary", "Package name of your installed external downloader app, such as NewPipe or Seal"),
InputType.TEXT InputType.TEXT
) )
), ),
@@ -50,4 +50,4 @@ class ExternalDownloadsResourcePatch : ResourcePatch {
return PatchResultSuccess() return PatchResultSuccess()
} }
} }

View File

@@ -34,6 +34,30 @@ class HideButtonsPatch : ResourcePatch {
StringResource("revanced_hide_like_dislike_button_summary_on", "Like and dislike buttons are hidden"), StringResource("revanced_hide_like_dislike_button_summary_on", "Like and dislike buttons are hidden"),
StringResource("revanced_hide_like_dislike_button_summary_off", "Like and dislike buttons are shown") StringResource("revanced_hide_like_dislike_button_summary_off", "Like and dislike buttons are shown")
), ),
SwitchPreference(
"revanced_hide_live_chat_button",
StringResource("revanced_hide_live_chat_button_title", "Hide live chat button"),
StringResource("revanced_hide_live_chat_button_summary_on", "Live chat button is hidden"),
StringResource("revanced_hide_live_chat_button_summary_off", "Live chat button is shown")
),
SwitchPreference(
"revanced_hide_share_button",
StringResource("revanced_hide_share_button_title", "Hide share button"),
StringResource("revanced_hide_share_button_summary_on", "Share button is hidden"),
StringResource("revanced_hide_share_button_summary_off", "Share button is shown")
),
SwitchPreference(
"revanced_hide_report_button",
StringResource("revanced_hide_report_button_title", "Hide report button"),
StringResource("revanced_hide_report_button_summary_on", "Report button is hidden"),
StringResource("revanced_hide_report_button_summary_off", "Report button is shown")
),
SwitchPreference(
"revanced_hide_remix_button",
StringResource("revanced_hide_remix_button_title", "Hide remix button"),
StringResource("revanced_hide_remix_button_summary_on", "Remix button is hidden"),
StringResource("revanced_hide_remix_button_summary_off", "Remix button is shown")
),
SwitchPreference( SwitchPreference(
"revanced_hide_download_button", "revanced_hide_download_button",
StringResource("revanced_hide_download_button_title", "Hide download button"), StringResource("revanced_hide_download_button_title", "Hide download button"),
@@ -41,24 +65,28 @@ class HideButtonsPatch : ResourcePatch {
StringResource("revanced_hide_download_button_summary_off", "Download button is shown") StringResource("revanced_hide_download_button_summary_off", "Download button is shown")
), ),
SwitchPreference( SwitchPreference(
"revanced_hide_playlist_button", "revanced_hide_thanks_button",
StringResource("revanced_hide_playlist_button_title", "Hide playlist button"), StringResource("revanced_hide_thanks_button_title", "Hide thanks button"),
StringResource("revanced_hide_playlist_button_summary_on", "Playlist button is hidden"), StringResource("revanced_hide_thanks_button_summary_on", "Thanks button is hidden"),
StringResource("revanced_hide_playlist_button_summary_off", "Playlist button is shown") StringResource("revanced_hide_thanks_button_summary_off", "Thanks button is shown")
), ),
SwitchPreference( SwitchPreference(
"revanced_hide_clip_button", "revanced_hide_clip_button",
StringResource("revanced_hide_clip_button_title", "Hide clip button"), StringResource("revanced_hide_clip_button_title", "Hide clip button"),
StringResource("revanced_hide_clip_button_summary_on", "Clip button is hidden"), StringResource("revanced_hide_clip_button_summary_on", "Clip button is hidden"),
StringResource("revanced_hide_clip_button_summary_off", "Clip button is shown"), StringResource("revanced_hide_clip_button_summary_off", "Clip button is shown"),
StringResource("revanced_hide_clip_button_user_dialog_message",
"Hiding the clip button might not work reliably. In the case it does not work, it can only be hidden by enabling \\'Hide all other action buttons\\'")
), ),
SwitchPreference( SwitchPreference(
"revanced_hide_action_buttons", "revanced_hide_playlist_button",
StringResource("revanced_hide_action_buttons_title", "Hide all other action buttons"), StringResource("revanced_hide_playlist_button_title", "Hide save to playlist button"),
StringResource("revanced_hide_action_buttons_summary_on", "Share, remix, thanks, shop, live chat buttons are hidden"), StringResource("revanced_hide_playlist_button_summary_on", "Save button is hidden"),
StringResource("revanced_hide_action_buttons_summary_off", "Share, remix, thanks, shop, live chat buttons are shown") StringResource("revanced_hide_playlist_button_summary_off", "Save button is shown")
),
SwitchPreference(
"revanced_hide_shop_button",
StringResource("revanced_hide_shop_button_title", "Hide shop button"),
StringResource("revanced_hide_shop_button_summary_on", "Shop button is hidden"),
StringResource("revanced_hide_shop_button_summary_off", "Shop button is shown")
) )
), ),
StringResource("revanced_hide_buttons_preference_screen_summary", "Hide or show buttons under videos") StringResource("revanced_hide_buttons_preference_screen_summary", "Hide or show buttons under videos")

View File

@@ -8,7 +8,6 @@ import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
import app.revanced.patches.shared.settings.preference.impl.StringResource import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.*
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
@DependsOn([SettingsPatch::class, ResourceMappingPatch::class]) @DependsOn([SettingsPatch::class, ResourceMappingPatch::class])
@@ -27,7 +26,7 @@ class SpoofSignatureVerificationResourcePatch : ResourcePatch {
+ "• Seekbar thumbnails are always hidden"), + "• Seekbar thumbnails are always hidden"),
StringResource("revanced_spoof_signature_verification_summary_off", "App signature not spoofed\\n\\nVideo playback may not work"), StringResource("revanced_spoof_signature_verification_summary_off", "App signature not spoofed\\n\\nVideo playback may not work"),
StringResource("revanced_spoof_signature_verification_user_dialog_message", StringResource("revanced_spoof_signature_verification_user_dialog_message",
"If you do not have a YouTube Premium subscription,\\n\\nthen turning off this setting will cause video playback issues.") "Turning off this setting will cause video playback issues.")
) )
) )

View File

@@ -9,23 +9,19 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWith
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.removeInstructions import app.revanced.patcher.extensions.InstructionExtensions.removeInstructions
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.util.proxy.mutableTypes.MutableField.Companion.toMutable
import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.litho.filter.fingerprints.* import app.revanced.patches.youtube.misc.litho.filter.fingerprints.*
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction
import org.jf.dexlib2.iface.instruction.Instruction import org.jf.dexlib2.iface.instruction.Instruction
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
import org.jf.dexlib2.iface.instruction.ReferenceInstruction import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.immutable.ImmutableField
import java.io.Closeable import java.io.Closeable
@DependsOn([IntegrationsPatch::class]) @DependsOn([IntegrationsPatch::class])
@@ -41,32 +37,29 @@ class LithoFilterPatch : BytecodePatch(
* Additionally, the method contains a reference to the components identifier. * Additionally, the method contains a reference to the components identifier.
* The identifier is used to filter components by their identifier. * The identifier is used to filter components by their identifier.
* *
* In addition to that, a static field is added to the class of this method. (See protobufBufferField). * The protobuf buffer is passed along from a different injection point before the filtering occurs.
* This field holds a reference to the protobuf buffer object. * The buffer is a large byte array that represents the component tree.
* The field is being set in another method that holds a reference to the protobuf buffer object.
* The object contains a large byte array that represents the component tree.
* This byte array is searched for strings that indicate the current component. * This byte array is searched for strings that indicate the current component.
* *
* The following pseudo code shows how the patch works: * The following pseudo code shows how the patch works:
* *
* class ComponentContextParser {
* public static ByteBuffer buffer; // Inserted by this patch.
*
* public ComponentContext parseBytesToComponentContext(...) {
* ...
* if (filter(identifier, pathBuilder, buffer)); // Inserted by this patch.
* return emptyComponent;
* ...
* }
* }
*
* class SomeOtherClass { * class SomeOtherClass {
* // Called before ComponentContextParser.parseBytesToComponentContext method. * // Called before ComponentContextParser.parseBytesToComponentContext method.
* public void someOtherMethod(ByteBuffer byteBuffer) { * public void someOtherMethod(ByteBuffer byteBuffer) {
* ComponentContextParser.buffer = byteBuffer; // Inserted by this patch. * IntegrationsClass.setProtoBuffer(byteBuffer); // Inserted by this patch.
* ... * ...
* } * }
* } * }
*
* class ComponentContextParser {
*
* public ComponentContext parseBytesToComponentContext(...) {
* ...
* if (IntegrationsClass.filter(identifier, pathBuilder)); // Inserted by this patch.
* return emptyComponent;
* ...
* }
* }
*/ */
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
ComponentContextParserFingerprint.result?.also { ComponentContextParserFingerprint.result?.also {
@@ -78,21 +71,12 @@ class LithoFilterPatch : BytecodePatch(
return fingerprint.toErrorResult() return fingerprint.toErrorResult()
} }
}?.let { bytesToComponentContextMethod -> }?.let { bytesToComponentContextMethod ->
// region Add a static field that holds a reference to the protobuf buffer object.
val protobufBufferField = ImmutableField(
bytesToComponentContextMethod.mutableClass.type,
"buffer",
"Ljava/nio/ByteBuffer;",
AccessFlags.PUBLIC or AccessFlags.STATIC,
null,
null,
null
).toMutable()
bytesToComponentContextMethod.mutableClass.staticFields.add(protobufBufferField)
// Set the field with the reference to the protobuf buffer object. // region Pass the buffer into Integrations.
ProtobufBufferReferenceFingerprint.result ProtobufBufferReferenceFingerprint.result
?.mutableMethod?.addInstruction(0, "sput-object p2, $protobufBufferField") ?.mutableMethod?.addInstruction(0,
" invoke-static { p2 }, $INTEGRATIONS_CLASS_DESCRIPTOR->setProtoBuffer(Ljava/nio/ByteBuffer;)V")
?: return ProtobufBufferReferenceFingerprint.toErrorResult() ?: return ProtobufBufferReferenceFingerprint.toErrorResult()
// endregion // endregion
@@ -135,17 +119,13 @@ class LithoFilterPatch : BytecodePatch(
// region Patch the method. // region Patch the method.
// Insert the instructions that are responsible // Insert the instructions that are responsible
// to return an EmptyComponent instead of the original component if the filter method returns false. // to return an EmptyComponent instead of the original component if the filter method returns true.
addInstructionsWithLabels( addInstructionsWithLabels(
insertHookIndex, insertHookIndex,
""" """
# Register "free1" holds the protobuf buffer object
sget-object v$free1, $protobufBufferField
# Invoke the filter method. # Invoke the filter method.
invoke-static { v$stringBuilderRegister, v$identifierRegister, v$free1 }, $FILTER_METHOD_DESCRIPTOR invoke-static { v$identifierRegister, v$stringBuilderRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->filter(Ljava/lang/String;Ljava/lang/StringBuilder;)Z
move-result v$free1 move-result v$free1
if-eqz v$free1, :unfiltered if-eqz v$free1, :unfiltered
@@ -197,9 +177,7 @@ class LithoFilterPatch : BytecodePatch(
private val Instruction.descriptor private val Instruction.descriptor
get() = (this as ReferenceInstruction).reference.toString() get() = (this as ReferenceInstruction).reference.toString()
private const val FILTER_METHOD_DESCRIPTOR = const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/components/LithoFilterPatch;"
"Lapp/revanced/integrations/patches/components/LithoFilterPatch;" +
"->filter(Ljava/lang/StringBuilder;Ljava/lang/String;Ljava/nio/ByteBuffer;)Z"
internal lateinit var addFilter: (String) -> Unit internal lateinit var addFilter: (String) -> Unit
private set private set

View File

@@ -123,7 +123,7 @@ class SettingsPatch : BytecodePatch(
/** /**
* Preference screens patches should add their settings to. * Preference screens patches should add their settings to.
*/ */
internal object PreferenceScreen : AbstractPreferenceScreen() { object PreferenceScreen : AbstractPreferenceScreen() {
val ADS = Screen("ads", "Ads", "Ad related settings") val ADS = Screen("ads", "Ads", "Ad related settings")
val INTERACTIONS = Screen("interactions", "Interaction", "Settings related to interactions") val INTERACTIONS = Screen("interactions", "Interaction", "Settings related to interactions")
val LAYOUT = Screen("layout", "Layout", "Settings related to the layout") val LAYOUT = Screen("layout", "Layout", "Settings related to the layout")