chore: merge branch dev to main (#2480)

This commit is contained in:
oSumAtrIX 2023-07-01 02:36:56 +02:00 committed by GitHub
commit 1503df2b04
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
111 changed files with 976 additions and 549 deletions

View File

@ -4,5 +4,5 @@
<component name="FrameworkDetectionExcludesConfiguration"> <component name="FrameworkDetectionExcludesConfiguration">
<file type="web" url="file://$PROJECT_DIR$" /> <file type="web" url="file://$PROJECT_DIR$" />
</component> </component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="azul-17" project-jdk-type="JavaSDK" /> <component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="azul-17" project-jdk-type="JavaSDK" />
</project> </project>

View File

@ -1,3 +1,89 @@
# [2.179.0-dev.12](https://github.com/revanced/revanced-patches/compare/v2.179.0-dev.11...v2.179.0-dev.12) (2023-07-01)
### Features
* **baconreader:** add `change-oauth-client-id` patch ([#2535](https://github.com/revanced/revanced-patches/issues/2535)) ([6f5e007](https://github.com/revanced/revanced-patches/commit/6f5e007a78dc5e1ed3935a3436ac1de7eb719ea1))
# [2.179.0-dev.11](https://github.com/revanced/revanced-patches/compare/v2.179.0-dev.10...v2.179.0-dev.11) (2023-07-01)
# [2.179.0-dev.10](https://github.com/revanced/revanced-patches/compare/v2.179.0-dev.9...v2.179.0-dev.10) (2023-06-30)
### Features
* **redditisfun/change-oauth-client-id:** add compatibility for paid versions ([#2536](https://github.com/revanced/revanced-patches/issues/2536)) ([e739d2f](https://github.com/revanced/revanced-patches/commit/e739d2fa16bbd0125db82c0758928addbd9950c9))
# [2.179.0-dev.9](https://github.com/revanced/revanced-patches/compare/v2.179.0-dev.8...v2.179.0-dev.9) (2023-06-30)
### Features
* **redditisfun:** add `change-oauth-client-id` patch ([14809cd](https://github.com/revanced/revanced-patches/commit/14809cd4510ad9514b4a4820187a81681669374c))
# [2.179.0-dev.8](https://github.com/revanced/revanced-patches/compare/v2.179.0-dev.7...v2.179.0-dev.8) (2023-06-29)
### Features
* **reddit:** add `disable-screenshot-popup` patch ([#2387](https://github.com/revanced/revanced-patches/issues/2387)) ([473e051](https://github.com/revanced/revanced-patches/commit/473e0512314dfa9790cf83b4cfcc7505058d3a51))
# [2.179.0-dev.7](https://github.com/revanced/revanced-patches/compare/v2.179.0-dev.6...v2.179.0-dev.7) (2023-06-28)
### Bug Fixes
* **youtube:** improve patching speed ([#2514](https://github.com/revanced/revanced-patches/issues/2514)) ([77bb761](https://github.com/revanced/revanced-patches/commit/77bb761b0bb38613ad9d5017c881396afa471558))
# [2.179.0-dev.6](https://github.com/revanced/revanced-patches/compare/v2.179.0-dev.5...v2.179.0-dev.6) (2023-06-27)
### Bug Fixes
* **syncforreddit/change-oauth-client-id:** add dev edition ([#2516](https://github.com/revanced/revanced-patches/issues/2516)) ([7c7294b](https://github.com/revanced/revanced-patches/commit/7c7294b750f54390dd2308de63cc09545010b17f))
# [2.179.0-dev.5](https://github.com/revanced/revanced-patches/compare/v2.179.0-dev.4...v2.179.0-dev.5) (2023-06-27)
### Bug Fixes
* **relayforreddit/change-oauth-client-id:** change client id instead of developer key ([#2508](https://github.com/revanced/revanced-patches/issues/2508)) ([4befb44](https://github.com/revanced/revanced-patches/commit/4befb4414638c5936f99d8d63d73c729efc773a5))
# [2.179.0-dev.4](https://github.com/revanced/revanced-patches/compare/v2.179.0-dev.3...v2.179.0-dev.4) (2023-06-27)
# [2.179.0-dev.3](https://github.com/revanced/revanced-patches/compare/v2.179.0-dev.2...v2.179.0-dev.3) (2023-06-26)
### Bug Fixes
* **enable-android-debugging:** remove json options ([#2497](https://github.com/revanced/revanced-patches/issues/2497)) ([3e25f5f](https://github.com/revanced/revanced-patches/commit/3e25f5f8df24a585dc1097aa16877841f0c6b74a))
# [2.179.0-dev.2](https://github.com/revanced/revanced-patches/compare/v2.179.0-dev.1...v2.179.0-dev.2) (2023-06-25)
### Features
* **relayforreddit:** add `change-oauth-client-id` patch ([#2491](https://github.com/revanced/revanced-patches/issues/2491)) ([fe66f40](https://github.com/revanced/revanced-patches/commit/fe66f4089d6365564c8097d3c7a1bc842c343194))
# [2.179.0-dev.1](https://github.com/revanced/revanced-patches/compare/v2.178.1-dev.1...v2.179.0-dev.1) (2023-06-24)
### Bug Fixes
* **syncforreddit:** use correct overriding method signature ([#2483](https://github.com/revanced/revanced-patches/issues/2483)) ([f9770cf](https://github.com/revanced/revanced-patches/commit/f9770cf1babce61cd32f6ca9140103419d8d094d))
### Features
* **infinityforreddit:** add `change-oauth-client-id` patch ([#2452](https://github.com/revanced/revanced-patches/issues/2452)) ([9efd790](https://github.com/revanced/revanced-patches/commit/9efd7904acc6dc70f45c6c0f835c839473d9205f))
## [2.178.1-dev.1](https://github.com/revanced/revanced-patches/compare/v2.178.0...v2.178.1-dev.1) (2023-06-23)
### Bug Fixes
* **youtube/client-spoof:** update settings text for known side effects of spoof signature ([#2476](https://github.com/revanced/revanced-patches/issues/2476)) ([6756f80](https://github.com/revanced/revanced-patches/commit/6756f80e3e0c09376a1fd613d28644bdaa24da57))
# [2.178.0](https://github.com/revanced/revanced-patches/compare/v2.177.0...v2.178.0) (2023-06-21) # [2.178.0](https://github.com/revanced/revanced-patches/compare/v2.177.0...v2.178.0) (2023-06-21)

141
README.md
View File

@ -128,6 +128,17 @@ The official ReVanced Patches.
| `show-deleted-messages` | Shows deleted chat messages behind a clickable spoiler. | 15.4.1 | | `show-deleted-messages` | Shows deleted chat messages behind a clickable spoiler. | 15.4.1 |
</details> </details>
### [📦 `com.reddit.frontpage`](https://play.google.com/store/apps/details?id=com.reddit.frontpage)
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `disable-screenshot-popup` | Disables the popup that shows up when taking a screenshot. | all |
| `hide-ads` | Removes ads from the Reddit. | all |
| `premium-icon-reddit` | Unlocks premium Reddit app icons. | all |
| `sanitize-sharing-links` | Removes (tracking) query parameters from the URLs when sharing links. | all |
</details>
### [📦 `com.twitter.android`](https://play.google.com/store/apps/details?id=com.twitter.android) ### [📦 `com.twitter.android`](https://play.google.com/store/apps/details?id=com.twitter.android)
<details> <details>
@ -149,16 +160,6 @@ The official ReVanced Patches.
| `hide-inbox-ads` | Hides ads in inbox. | all | | `hide-inbox-ads` | Hides ads in inbox. | all |
</details> </details>
### [📦 `com.reddit.frontpage`](https://play.google.com/store/apps/details?id=com.reddit.frontpage)
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `hide-ads` | Removes ads from the Reddit. | all |
| `premium-icon-reddit` | Unlocks premium Reddit app icons. | all |
| `sanitize-sharing-links` | Removes (tracking) query parameters from the URLs when sharing links. | all |
</details>
### [📦 `com.laurencedawson.reddit_sync`](https://play.google.com/store/apps/details?id=com.laurencedawson.reddit_sync) ### [📦 `com.laurencedawson.reddit_sync`](https://play.google.com/store/apps/details?id=com.laurencedawson.reddit_sync)
<details> <details>
@ -204,12 +205,60 @@ The official ReVanced Patches.
| `spoof-signature` | Spoofs the signature of the app. | all | | `spoof-signature` | Spoofs the signature of the app. | all |
</details> </details>
### [📦 `ml.docilealligator.infinityforreddit`](https://play.google.com/store/apps/details?id=ml.docilealligator.infinityforreddit)
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `change-oauth-client-id` | Changes the OAuth client ID. | all |
</details>
### [📦 `free.reddit.news`](https://play.google.com/store/apps/details?id=free.reddit.news)
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `change-oauth-client-id` | Changes the OAuth client ID. | all |
</details>
### [📦 `reddit.news`](https://play.google.com/store/apps/details?id=reddit.news)
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `change-oauth-client-id` | Changes the OAuth client ID. | all |
</details>
### [📦 `com.onelouder.baconreader`](https://play.google.com/store/apps/details?id=com.onelouder.baconreader)
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `change-oauth-client-id` | Changes the OAuth client ID. | all |
</details>
### [📦 `com.rubenmayayo.reddit`](https://play.google.com/store/apps/details?id=com.rubenmayayo.reddit) ### [📦 `com.rubenmayayo.reddit`](https://play.google.com/store/apps/details?id=com.rubenmayayo.reddit)
<details> <details>
| 💊 Patch | 📜 Description | 🏹 Target Version | | 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:| |:--------:|:--------------:|:-----------------:|
| `change-oauth-client-id` | Changes the OAuth client ID in Boost for Reddit. | all | | `change-oauth-client-id` | Changes the OAuth client ID. | all |
</details>
### [📦 `com.andrewshu.android.reddit`](https://play.google.com/store/apps/details?id=com.andrewshu.android.reddit)
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `change-oauth-client-id` | Changes the OAuth client ID. | all |
</details>
### [📦 `com.andrewshu.android.redditdonation`](https://play.google.com/store/apps/details?id=com.andrewshu.android.redditdonation)
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `change-oauth-client-id` | Changes the OAuth client ID. | all |
</details> </details>
### [📦 `com.laurencedawson.reddit_sync.pro`](https://play.google.com/store/apps/details?id=com.laurencedawson.reddit_sync.pro) ### [📦 `com.laurencedawson.reddit_sync.pro`](https://play.google.com/store/apps/details?id=com.laurencedawson.reddit_sync.pro)
@ -220,6 +269,14 @@ The official ReVanced Patches.
| `change-oauth-client-id` | Changes the OAuth client ID. | all | | `change-oauth-client-id` | Changes the OAuth client ID. | all |
</details> </details>
### [📦 `com.laurencedawson.reddit_sync.dev`](https://play.google.com/store/apps/details?id=com.laurencedawson.reddit_sync.dev)
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `change-oauth-client-id` | Changes the OAuth client ID. | all |
</details>
### [📦 `com.myprog.hexedit`](https://play.google.com/store/apps/details?id=com.myprog.hexedit) ### [📦 `com.myprog.hexedit`](https://play.google.com/store/apps/details?id=com.myprog.hexedit)
<details> <details>
@ -236,14 +293,6 @@ The official ReVanced Patches.
| `enable-on-demand` | Enables listening to songs on-demand, allowing to play any song from playlists, albums or artists without limitations. This does not remove ads. | all | | `enable-on-demand` | Enables listening to songs on-demand, allowing to play any song from playlists, albums or artists without limitations. This does not remove ads. | all |
</details> </details>
### [📦 `com.vanced.android.youtube`](https://play.google.com/store/apps/details?id=com.vanced.android.youtube)
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `hide-ads` | Removes general ads. | all |
</details>
### [📦 `com.nis.app`](https://play.google.com/store/apps/details?id=com.nis.app) ### [📦 `com.nis.app`](https://play.google.com/store/apps/details?id=com.nis.app)
<details> <details>
@ -252,6 +301,14 @@ The official ReVanced Patches.
| `hide-ads` | Removes ads from Inshorts. | all | | `hide-ads` | Removes ads from Inshorts. | all |
</details> </details>
### [📦 `com.vanced.android.youtube`](https://play.google.com/store/apps/details?id=com.vanced.android.youtube)
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `hide-ads` | Removes general ads. | all |
</details>
### [📦 `com.instagram.android`](https://play.google.com/store/apps/details?id=com.instagram.android) ### [📦 `com.instagram.android`](https://play.google.com/store/apps/details?id=com.instagram.android)
<details> <details>
@ -340,12 +397,20 @@ The official ReVanced Patches.
| `unlock-prime` | Unlocks Nova Prime and all functions of the app. | all | | `unlock-prime` | Unlocks Nova Prime and all functions of the app. | all |
</details> </details>
### [📦 `com.candylink.openvpn`](https://play.google.com/store/apps/details?id=com.candylink.openvpn) ### [📦 `org.totschnig.myexpenses`](https://play.google.com/store/apps/details?id=org.totschnig.myexpenses)
<details> <details>
| 💊 Patch | 📜 Description | 🏹 Target Version | | 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:| |:--------:|:--------------:|:-----------------:|
| `unlock-pro` | Unlocks premium features. | all | | `unlock-pro` | Unlocks all professional features. | 3.4.9 |
</details>
### [📦 `ginlemon.iconpackstudio`](https://play.google.com/store/apps/details?id=ginlemon.iconpackstudio)
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `unlock-pro` | Unlocks all pro features. | all |
</details> </details>
### [📦 `com.zombodroid.MemeGenerator`](https://play.google.com/store/apps/details?id=com.zombodroid.MemeGenerator) ### [📦 `com.zombodroid.MemeGenerator`](https://play.google.com/store/apps/details?id=com.zombodroid.MemeGenerator)
@ -356,7 +421,7 @@ The official ReVanced Patches.
| `unlock-pro` | Unlocks pro features. | 4.6377 | | `unlock-pro` | Unlocks pro features. | 4.6377 |
</details> </details>
### [📦 `com.wakdev.apps.nfctools.se`](https://play.google.com/store/apps/details?id=com.wakdev.apps.nfctools.se) ### [📦 `co.windyapp.android`](https://play.google.com/store/apps/details?id=co.windyapp.android)
<details> <details>
| 💊 Patch | 📜 Description | 🏹 Target Version | | 💊 Patch | 📜 Description | 🏹 Target Version |
@ -364,7 +429,15 @@ The official ReVanced Patches.
| `unlock-pro` | Unlocks all pro features. | all | | `unlock-pro` | Unlocks all pro features. | all |
</details> </details>
### [📦 `ginlemon.iconpackstudio`](https://play.google.com/store/apps/details?id=ginlemon.iconpackstudio) ### [📦 `com.vsco.cam`](https://play.google.com/store/apps/details?id=com.vsco.cam)
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `unlock-pro` | Unlocks pro features. | all |
</details>
### [📦 `com.wakdev.apps.nfctools.se`](https://play.google.com/store/apps/details?id=com.wakdev.apps.nfctools.se)
<details> <details>
| 💊 Patch | 📜 Description | 🏹 Target Version | | 💊 Patch | 📜 Description | 🏹 Target Version |
@ -380,28 +453,12 @@ The official ReVanced Patches.
| `unlock-pro` | Unlocks pro features. | all | | `unlock-pro` | Unlocks pro features. | all |
</details> </details>
### [📦 `com.vsco.cam`](https://play.google.com/store/apps/details?id=com.vsco.cam) ### [📦 `com.candylink.openvpn`](https://play.google.com/store/apps/details?id=com.candylink.openvpn)
<details> <details>
| 💊 Patch | 📜 Description | 🏹 Target Version | | 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:| |:--------:|:--------------:|:-----------------:|
| `unlock-pro` | Unlocks pro features. | all | | `unlock-pro` | Unlocks premium features. | all |
</details>
### [📦 `org.totschnig.myexpenses`](https://play.google.com/store/apps/details?id=org.totschnig.myexpenses)
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `unlock-pro` | Unlocks all professional features. | 3.4.9 |
</details>
### [📦 `com.awedea.nyx`](https://play.google.com/store/apps/details?id=com.awedea.nyx)
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `unlock-pro` | Unlocks all pro features. | all |
</details> </details>
### [📦 `tv.trakt.trakt`](https://play.google.com/store/apps/details?id=tv.trakt.trakt) ### [📦 `tv.trakt.trakt`](https://play.google.com/store/apps/details?id=tv.trakt.trakt)
@ -412,7 +469,7 @@ The official ReVanced Patches.
| `unlock-pro` | Unlocks pro features. | all | | `unlock-pro` | Unlocks pro features. | all |
</details> </details>
### [📦 `co.windyapp.android`](https://play.google.com/store/apps/details?id=co.windyapp.android) ### [📦 `com.awedea.nyx`](https://play.google.com/store/apps/details?id=com.awedea.nyx)
<details> <details>
| 💊 Patch | 📜 Description | 🏹 Target Version | | 💊 Patch | 📜 Description | 🏹 Target Version |

View File

@ -27,7 +27,7 @@ repositories {
} }
dependencies { dependencies {
implementation("app.revanced:revanced-patcher:11.0.0") implementation("app.revanced:revanced-patcher:11.0.3")
implementation("app.revanced:multidexlib2:2.5.3-a3836654") implementation("app.revanced:multidexlib2:2.5.3-a3836654")
// Required for meta // Required for meta
implementation("com.google.code.gson:gson:2.10.1") implementation("com.google.code.gson:gson:2.10.1")

View File

@ -1,2 +1,2 @@
kotlin.code.style = official kotlin.code.style = official
version = 2.178.0 version = 2.179.0-dev.12

File diff suppressed because one or more lines are too long

View File

@ -57,17 +57,28 @@ internal fun MutableMethod.injectHideViewCall(
"invoke-static { v$viewRegister }, $classDescriptor->$targetMethod(Landroid/view/View;)V" "invoke-static { v$viewRegister }, $classDescriptor->$targetMethod(Landroid/view/View;)V"
) )
internal fun MutableMethod.findIndexForIdResource(resourceName: String): Int { internal fun Method.findIndexForIdResource(resourceName: String): Int {
fun getIdResourceId(resourceName: String) = ResourceMappingPatch.resourceMappings.single { fun getIdResourceId(resourceName: String) = ResourceMappingPatch.resourceMappings.single {
it.type == "id" && it.name == resourceName it.type == "id" && it.name == resourceName
}.id }.id
val resourceId = getIdResourceId(resourceName) return indexOfFirstConstantInstructionValue(getIdResourceId(resourceName))
return implementation!!.instructions.indexOfFirst { }
if (it.opcode != Opcode.CONST) return@indexOfFirst false
val literal = (it as WideLiteralInstruction).wideLiteral /**
* @return the first constant instruction with the value, or -1 if not found.
*/
fun Method.indexOfFirstConstantInstructionValue(constantValue: Long): Int {
return implementation?.let {
it.instructions.indexOfFirst { instruction ->
instruction.opcode == Opcode.CONST && (instruction as WideLiteralInstruction).wideLiteral == constantValue
}
} ?: -1
}
return@indexOfFirst resourceId == literal /**
} * @return if the method contains a constant with the given value.
} */
fun Method.containsConstantInstructionValue(constantValue: Long): Boolean {
return indexOfFirstConstantInstructionValue(constantValue) >= 0
}

View File

@ -14,29 +14,17 @@ import org.w3c.dom.Element
@Version("0.0.1") @Version("0.0.1")
class EnableAndroidDebuggingPatch : ResourcePatch { class EnableAndroidDebuggingPatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult { override fun execute(context: ResourceContext): PatchResult {
if (debuggable == true) { context.xmlEditor["AndroidManifest.xml"].use { dom ->
context.xmlEditor["AndroidManifest.xml"].use { dom -> val applicationNode = dom
val applicationNode = dom .file
.file .getElementsByTagName("application")
.getElementsByTagName("application") .item(0) as Element
.item(0) as Element
// set application as debuggable // set application as debuggable
applicationNode.setAttribute("android:debuggable", "true") applicationNode.setAttribute("android:debuggable", "true")
}
} }
return PatchResultSuccess() return PatchResultSuccess()
} }
companion object : OptionsContainer() {
var debuggable: Boolean? by option(
PatchOption.BooleanOption(
key = "debuggable",
default = false,
title = "App debugging",
description = "Whether to make the app debuggable on Android.",
)
)
}
} }

View File

@ -1,10 +1,9 @@
package app.revanced.patches.music.misc.androidauto.fingerprints package app.revanced.patches.music.misc.androidauto.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.music.misc.androidauto.patch.BypassCertificateChecksPatch
object CheckCertificateFingerprint : MethodFingerprint( object CheckCertificateFingerprint : MethodFingerprint(
"Z", returnType = "Z",
strings = listOf("No match") // Unique in combination with boolean return type parameters = listOf("Ljava/lang/String;"),
strings = listOf("X509", "Failed to get public key.", "Failed to get certificate.")
) )

View File

@ -1,19 +1,21 @@
package app.revanced.patches.reddit.customclients package app.revanced.patches.reddit.customclients
import android.os.Environment import android.os.Environment
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
import app.revanced.patcher.patch.* import app.revanced.patcher.patch.*
import java.io.File import java.io.File
abstract class AbstractChangeOAuthClientIdPatch( abstract class AbstractChangeOAuthClientIdPatch(
private val redirectUri: String, private val redirectUri: String,
private val options: ChangeOAuthClientIdOptionsContainer, private val options: ChangeOAuthClientIdOptionsContainer,
private val fingerprint: MethodFingerprint, private val fingerprints: List<MethodFingerprint>
) : BytecodePatch(listOf(fingerprint)) { ) : BytecodePatch(fingerprints) {
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
if (options.clientId == null) { if (options.clientId == null) {
// Test if on Android // Ensure device runs Android.
try { try {
Class.forName("android.os.Environment") Class.forName("android.os.Environment")
} catch (e: ClassNotFoundException) { } catch (e: ClassNotFoundException) {
@ -36,10 +38,10 @@ abstract class AbstractChangeOAuthClientIdPatch(
}.let { options.clientId = it.readText().trim() } }.let { options.clientId = it.readText().trim() }
} }
return fingerprint.patch(context) return fingerprints.map { it.result ?: throw it.toErrorResult() }.patch(context)
} }
abstract fun MethodFingerprint.patch(context: BytecodeContext): PatchResult abstract fun List<MethodFingerprintResult>.patch(context: BytecodeContext): PatchResult
companion object Options { companion object Options {
open class ChangeOAuthClientIdOptionsContainer : OptionsContainer() { open class ChangeOAuthClientIdOptionsContainer : OptionsContainer() {

View File

@ -0,0 +1,11 @@
package app.revanced.patches.reddit.customclients
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.patch.annotations.Patch
@Target(AnnotationTarget.CLASS)
@Patch
@Name("change-oauth-client-id")
@Description("Changes the OAuth client ID.")
annotation class ChangeOAuthClientIdPatchAnnotation

View File

@ -0,0 +1,7 @@
package app.revanced.patches.reddit.customclients.baconreader.api.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object GetAuthorizationUrlFingerprint: MethodFingerprint(
strings = listOf("client_id=zACVn0dSFGdWqQ"),
)

View File

@ -0,0 +1,12 @@
package app.revanced.patches.reddit.customclients.baconreader.api.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object GetClientIdFingerprint : MethodFingerprint(
strings = listOf("client_id=zACVn0dSFGdWqQ"),
customFingerprint = custom@{ methodDef, classDef ->
if (!classDef.type.endsWith("RedditOAuth;")) return@custom false
methodDef.name == "getAuthorizeUrl"
}
)

View File

@ -0,0 +1,7 @@
package app.revanced.patches.reddit.customclients.baconreader.api.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object RequestTokenFingerprint : MethodFingerprint(
strings = listOf("zACVn0dSFGdWqQ", "kDm2tYpu9DqyWFFyPlNcXGEni4k"), // App ID and secret.
)

View File

@ -0,0 +1,47 @@
package app.revanced.patches.reddit.customclients.baconreader.api.patch
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patches.reddit.customclients.AbstractChangeOAuthClientIdPatch
import app.revanced.patches.reddit.customclients.ChangeOAuthClientIdPatchAnnotation
import app.revanced.patches.reddit.customclients.baconreader.api.fingerprints.GetAuthorizationUrlFingerprint
import app.revanced.patches.reddit.customclients.baconreader.api.fingerprints.RequestTokenFingerprint
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
@ChangeOAuthClientIdPatchAnnotation
@Compatibility([Package("com.onelouder.baconreader")])
class ChangeOAuthClientIdPatch : AbstractChangeOAuthClientIdPatch(
"http://baconreader.com/auth", Options, listOf(GetAuthorizationUrlFingerprint, RequestTokenFingerprint)
) {
override fun List<MethodFingerprintResult>.patch(context: BytecodeContext): PatchResult {
fun MethodFingerprintResult.patch(replacementString: String) {
val clientIdIndex = scanResult.stringsScanResult!!.matches.first().index
mutableMethod.apply {
val clientIdRegister = getInstruction<OneRegisterInstruction>(clientIdIndex).registerA
replaceInstruction(
clientIdIndex,
"const-string v$clientIdRegister, \"$replacementString\""
)
}
}
// Patch client id in authorization url.
first().patch("client_id=$clientId")
// Patch client id for access token request.
last().patch(clientId!!)
return PatchResultSuccess()
}
companion object Options : AbstractChangeOAuthClientIdPatch.Options.ChangeOAuthClientIdOptionsContainer()
}

View File

@ -1,34 +1,29 @@
package app.revanced.patches.reddit.customclients.boostforreddit.api.patch package app.revanced.patches.reddit.customclients.boostforreddit.api.patch
import app.revanced.extensions.toErrorResult import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.* import app.revanced.patcher.annotation.Package
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.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
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.Patch
import app.revanced.patches.reddit.customclients.AbstractChangeOAuthClientIdPatch import app.revanced.patches.reddit.customclients.AbstractChangeOAuthClientIdPatch
import app.revanced.patches.reddit.customclients.ChangeOAuthClientIdPatchAnnotation
import app.revanced.patches.reddit.customclients.boostforreddit.api.fingerprints.GetClientIdFingerprint import app.revanced.patches.reddit.customclients.boostforreddit.api.fingerprints.GetClientIdFingerprint
@Patch @ChangeOAuthClientIdPatchAnnotation
@Name("change-oauth-client-id")
@Description("Changes the OAuth client ID in Boost for Reddit.")
@Compatibility([Package("com.rubenmayayo.reddit")]) @Compatibility([Package("com.rubenmayayo.reddit")])
@Version("0.0.1")
class ChangeOAuthClientIdPatch : AbstractChangeOAuthClientIdPatch( class ChangeOAuthClientIdPatch : AbstractChangeOAuthClientIdPatch(
"http://rubenmayayo.com", "http://rubenmayayo.com", Options, listOf(GetClientIdFingerprint)
Options,
GetClientIdFingerprint
) { ) {
override fun MethodFingerprint.patch(context: BytecodeContext): PatchResult { override fun List<MethodFingerprintResult>.patch(context: BytecodeContext): PatchResult {
result?.mutableMethod?.addInstructions( first().mutableMethod.addInstructions(
0, 0,
""" """
const-string v0, "$clientId" const-string v0, "$clientId"
return-object v0 return-object v0
""" """
) ?: return toErrorResult() )
return PatchResultSuccess() return PatchResultSuccess()
} }

View File

@ -0,0 +1,12 @@
package app.revanced.patches.reddit.customclients.infinityforreddit.api.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
abstract class AbstractClientIdFingerprint(classTypeSuffix: String, methodName: String) : MethodFingerprint(
strings = listOf("NOe2iKrPPzwscA"),
customFingerprint = custom@{ methodDef, classDef ->
if (!classDef.type.endsWith(classTypeSuffix)) return@custom false
methodDef.name == methodName
}
)

View File

@ -0,0 +1,6 @@
package app.revanced.patches.reddit.customclients.infinityforreddit.api.fingerprints
object GetHTTPBasicAuthHeaderFingerprint : AbstractClientIdFingerprint(
"APIUtils;",
"getHTTPBasicAuthHeader"
)

View File

@ -0,0 +1,6 @@
package app.revanced.patches.reddit.customclients.infinityforreddit.api.fingerprints
object LoginActivityOnCreateFingerprint : AbstractClientIdFingerprint(
"LoginActivity;",
"onCreate"
)

View File

@ -0,0 +1,41 @@
package app.revanced.patches.reddit.customclients.infinityforreddit.api.patch
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patches.reddit.customclients.AbstractChangeOAuthClientIdPatch
import app.revanced.patches.reddit.customclients.ChangeOAuthClientIdPatchAnnotation
import app.revanced.patches.reddit.customclients.infinityforreddit.api.fingerprints.GetHTTPBasicAuthHeaderFingerprint
import app.revanced.patches.reddit.customclients.infinityforreddit.api.fingerprints.LoginActivityOnCreateFingerprint
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
@ChangeOAuthClientIdPatchAnnotation
@Compatibility([Package("ml.docilealligator.infinityforreddit")])
class ChangeOAuthClientIdPatch : AbstractChangeOAuthClientIdPatch(
"infinity://localhost",
Options,
listOf(GetHTTPBasicAuthHeaderFingerprint, LoginActivityOnCreateFingerprint)
) {
override fun List<MethodFingerprintResult>.patch(context: BytecodeContext): PatchResult {
forEach {
val clientIdIndex = it.scanResult.stringsScanResult!!.matches.first().index
it.mutableMethod.apply {
val oAuthClientIdRegister = getInstruction<OneRegisterInstruction>(clientIdIndex).registerA
replaceInstruction(
clientIdIndex,
"const-string v$oAuthClientIdRegister, \"$clientId\""
)
}
}
return PatchResultSuccess()
}
companion object Options : AbstractChangeOAuthClientIdPatch.Options.ChangeOAuthClientIdOptionsContainer()
}

View File

@ -0,0 +1,7 @@
package app.revanced.patches.reddit.customclients.redditisfun.api.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
abstract class AbstractClientIdFingerprint(string: String) : MethodFingerprint(
strings = listOfNotNull("yyOCBp.RHJhDKd", string),
)

View File

@ -0,0 +1,5 @@
package app.revanced.patches.reddit.customclients.redditisfun.api.fingerprints
object BasicAuthorizationFingerprint : AbstractClientIdFingerprint(
string = "fJOxVwBUyo*=f:<OoejWs:AqmIJ", // Encrypted basic authorization string.
)

View File

@ -0,0 +1,5 @@
package app.revanced.patches.reddit.customclients.redditisfun.api.fingerprints
object BuildAuthorizationStringFingerprint : AbstractClientIdFingerprint(
string = "client_id"
)

View File

@ -0,0 +1,57 @@
package app.revanced.patches.reddit.customclients.redditisfun.api.patch
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult.MethodFingerprintScanResult.StringsScanResult.StringMatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patches.reddit.customclients.AbstractChangeOAuthClientIdPatch
import app.revanced.patches.reddit.customclients.ChangeOAuthClientIdPatchAnnotation
import app.revanced.patches.reddit.customclients.redditisfun.api.fingerprints.BasicAuthorizationFingerprint
import app.revanced.patches.reddit.customclients.redditisfun.api.fingerprints.BuildAuthorizationStringFingerprint
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
@ChangeOAuthClientIdPatchAnnotation
@Compatibility([Package("com.andrewshu.android.reddit"), Package("com.andrewshu.android.redditdonation")])
class ChangeOAuthClientIdPatch : AbstractChangeOAuthClientIdPatch(
"redditisfun://auth",
Options,
listOf(
BuildAuthorizationStringFingerprint,
BasicAuthorizationFingerprint,
)
) {
override fun List<MethodFingerprintResult>.patch(context: BytecodeContext): PatchResult {
/**
* Replaces a one register instruction with a const-string instruction
* at the index returned by [getReplacementIndex].
*
* @param string The string to replace the instruction with.
* @param getReplacementIndex A function that returns the index of the instruction to replace
* using the [StringMatch] list from the [MethodFingerprintResult].
*/
fun MethodFingerprintResult.replaceWith(
string: String,
getReplacementIndex: List<StringMatch>.() -> Int,
) = mutableMethod.apply {
val replacementIndex = scanResult.stringsScanResult!!.matches.getReplacementIndex()
val clientIdRegister = getInstruction<OneRegisterInstruction>(replacementIndex).registerA
replaceInstruction(replacementIndex, "const-string v$clientIdRegister, \"$string\"")
}
// Patch OAuth authorization.
first().replaceWith(clientId!!) { first().index + 4 }
// Path basic authorization.
last().replaceWith("$clientId:") { last().index + 7 }
return PatchResultSuccess()
}
companion object Options : AbstractChangeOAuthClientIdPatch.Options.ChangeOAuthClientIdOptionsContainer()
}

View File

@ -0,0 +1,7 @@
package app.revanced.patches.reddit.customclients.relayforreddit.api.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
abstract class AbstractClientIdFingerprint(string: String) : MethodFingerprint(
strings = listOfNotNull("dj-xCIZQYiLbEg", string),
)

View File

@ -0,0 +1,3 @@
package app.revanced.patches.reddit.customclients.relayforreddit.api.fingerprints
object GetLoggedInBearerTokenFingerprint : AbstractClientIdFingerprint("authorization_code")

View File

@ -0,0 +1,3 @@
package app.revanced.patches.reddit.customclients.relayforreddit.api.fingerprints
object GetLoggedOutBearerTokenFingerprint : AbstractClientIdFingerprint("https://oauth.reddit.com/grants/installed_client")

View File

@ -0,0 +1,3 @@
package app.revanced.patches.reddit.customclients.relayforreddit.api.fingerprints
object GetRefreshTokenFingerprint : AbstractClientIdFingerprint("refresh_token")

View File

@ -0,0 +1,3 @@
package app.revanced.patches.reddit.customclients.relayforreddit.api.fingerprints
object LoginActivityClientIdFingerprint : AbstractClientIdFingerprint("&duration=permanent")

View File

@ -0,0 +1,48 @@
package app.revanced.patches.reddit.customclients.relayforreddit.api.patch
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patches.reddit.customclients.AbstractChangeOAuthClientIdPatch
import app.revanced.patches.reddit.customclients.ChangeOAuthClientIdPatchAnnotation
import app.revanced.patches.reddit.customclients.relayforreddit.api.fingerprints.GetLoggedInBearerTokenFingerprint
import app.revanced.patches.reddit.customclients.relayforreddit.api.fingerprints.GetLoggedOutBearerTokenFingerprint
import app.revanced.patches.reddit.customclients.relayforreddit.api.fingerprints.LoginActivityClientIdFingerprint
import app.revanced.patches.reddit.customclients.relayforreddit.api.fingerprints.GetRefreshTokenFingerprint
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
@ChangeOAuthClientIdPatchAnnotation
@Compatibility([Package("free.reddit.news"), Package("reddit.news")])
class ChangeOAuthClientIdPatch : AbstractChangeOAuthClientIdPatch(
"dbrady://relay",
Options,
listOf(
LoginActivityClientIdFingerprint,
GetLoggedInBearerTokenFingerprint,
GetLoggedOutBearerTokenFingerprint,
GetRefreshTokenFingerprint
)
) {
override fun List<MethodFingerprintResult>.patch(context: BytecodeContext): PatchResult {
forEach {
val clientIdIndex = it.scanResult.stringsScanResult!!.matches.first().index
it.mutableMethod.apply {
val clientIdRegister = getInstruction<OneRegisterInstruction>(clientIdIndex).registerA
it.mutableMethod.replaceInstruction(
clientIdIndex,
"const-string v$clientIdRegister, \"$clientId\""
)
}
}
return PatchResultSuccess()
}
companion object Options : AbstractChangeOAuthClientIdPatch.Options.ChangeOAuthClientIdOptionsContainer()
}

View File

@ -1,17 +1,18 @@
package app.revanced.patches.reddit.customclients.syncforreddit.api.patch package app.revanced.patches.reddit.customclients.syncforreddit.api.patch
import app.revanced.extensions.toErrorResult import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.* import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
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.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.fingerprint.method.impl.MethodFingerprintResult
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.Patch
import app.revanced.patches.reddit.customclients.AbstractChangeOAuthClientIdPatch import app.revanced.patches.reddit.customclients.AbstractChangeOAuthClientIdPatch
import app.revanced.patches.reddit.customclients.ChangeOAuthClientIdPatchAnnotation
import app.revanced.patches.reddit.customclients.syncforreddit.api.fingerprints.GetAuthorizationStringFingerprint import app.revanced.patches.reddit.customclients.syncforreddit.api.fingerprints.GetAuthorizationStringFingerprint
import app.revanced.patches.reddit.customclients.syncforreddit.api.fingerprints.GetBearerTokenFingerprint import app.revanced.patches.reddit.customclients.syncforreddit.api.fingerprints.GetBearerTokenFingerprint
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
@ -19,47 +20,50 @@ import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.reference.StringReference import org.jf.dexlib2.iface.reference.StringReference
import java.util.* import java.util.*
@Patch @ChangeOAuthClientIdPatchAnnotation
@Name("change-oauth-client-id") @Compatibility(
@Description("Changes the OAuth client ID.") [
@Compatibility([Package("com.laurencedawson.reddit_sync"), Package("com.laurencedawson.reddit_sync.pro")]) Package("com.laurencedawson.reddit_sync"),
@Version("0.0.1") Package("com.laurencedawson.reddit_sync.pro"),
Package("com.laurencedawson.reddit_sync.dev")
]
)
class ChangeOAuthClientIdPatch : AbstractChangeOAuthClientIdPatch( class ChangeOAuthClientIdPatch : AbstractChangeOAuthClientIdPatch(
"http://redditsync/auth", "http://redditsync/auth", Options, listOf(GetAuthorizationStringFingerprint)
Options,
GetAuthorizationStringFingerprint,
) { ) {
override fun MethodFingerprint.patch(context: BytecodeContext): PatchResult { override fun List<MethodFingerprintResult>.patch(context: BytecodeContext): PatchResult {
result?.also { result -> forEach { fingerprintResult ->
GetBearerTokenFingerprint.also { it.resolve(context, result.classDef) }.result?.mutableMethod?.apply { fingerprintResult.also { result ->
val auth = Base64.getEncoder().encodeToString("$clientId:".toByteArray(Charsets.UTF_8)) GetBearerTokenFingerprint.also { it.resolve(context, result.classDef) }.result?.mutableMethod?.apply {
addInstructions( val auth = Base64.getEncoder().encodeToString("$clientId:".toByteArray(Charsets.UTF_8))
0, addInstructions(
""" 0,
"""
const-string v0, "Basic $auth" const-string v0, "Basic $auth"
return-object v0 return-object v0
""" """
) )
} ?: return GetBearerTokenFingerprint.toErrorResult() } ?: return GetBearerTokenFingerprint.toErrorResult()
}?.let { }.let {
val occurrenceIndex = it.scanResult.stringsScanResult!!.matches.first().index val occurrenceIndex = it.scanResult.stringsScanResult!!.matches.first().index
it.mutableMethod.apply { it.mutableMethod.apply {
val authorizationStringInstruction = getInstruction<ReferenceInstruction>(occurrenceIndex) val authorizationStringInstruction = getInstruction<ReferenceInstruction>(occurrenceIndex)
val targetRegister = (authorizationStringInstruction as OneRegisterInstruction).registerA val targetRegister = (authorizationStringInstruction as OneRegisterInstruction).registerA
val reference = authorizationStringInstruction.reference as StringReference val reference = authorizationStringInstruction.reference as StringReference
val newAuthorizationUrl = reference.string.replace( val newAuthorizationUrl = reference.string.replace(
"client_id=.*?&".toRegex(), "client_id=.*?&".toRegex(),
"client_id=$clientId&" "client_id=$clientId&"
) )
replaceInstruction( replaceInstruction(
occurrenceIndex, occurrenceIndex,
"const-string v$targetRegister, \"$newAuthorizationUrl\"" "const-string v$targetRegister, \"$newAuthorizationUrl\""
) )
}
} }
} ?: return toErrorResult() }
return PatchResultSuccess() return PatchResultSuccess()
} }

View File

@ -0,0 +1,8 @@
package app.revanced.patches.reddit.layout.disablescreenshotpopup.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility([Package("com.reddit.frontpage")])
@Target(AnnotationTarget.CLASS)
internal annotation class DisableScreenshotPopupCompatibility

View File

@ -0,0 +1,14 @@
package app.revanced.patches.reddit.layout.disablescreenshotpopup.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object DisableScreenshotPopupFingerprint : MethodFingerprint(
"V",
parameters = listOf("Landroidx/compose/runtime/", "I"),
customFingerprint = custom@{ methodDef, classDef ->
if (!classDef.type.endsWith("\$ScreenshotTakenBannerKt\$lambda-1\$1;"))
return@custom false
methodDef.name == "invoke"
}
)

View File

@ -0,0 +1,30 @@
package app.revanced.patches.reddit.layout.disablescreenshotpopup.patch
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.reddit.layout.disablescreenshotpopup.annotations.DisableScreenshotPopupCompatibility
import app.revanced.patches.reddit.layout.disablescreenshotpopup.fingerprints.DisableScreenshotPopupFingerprint
@Patch
@Name("disable-screenshot-popup")
@Description("Disables the popup that shows up when taking a screenshot.")
@DisableScreenshotPopupCompatibility
@Version("0.0.1")
class DisableScreenshotPopupPatch : BytecodePatch(
listOf(DisableScreenshotPopupFingerprint)
) {
override fun execute(context: BytecodeContext): PatchResult {
DisableScreenshotPopupFingerprint.result?.mutableMethod?.addInstruction(0, "return-void")
?: return DisableScreenshotPopupFingerprint.toErrorResult()
return PatchResultSuccess()
}
}

View File

@ -4,7 +4,7 @@ import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
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.addInstructions
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
@ -21,7 +21,7 @@ class RemoveDebuggingDetectionPatch : BytecodePatch(
listOf(DebuggingDetectionFingerprint) listOf(DebuggingDetectionFingerprint)
) { ) {
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
DebuggingDetectionFingerprint.result!!.mutableMethod.addInstructionsWithLabels( DebuggingDetectionFingerprint.result!!.mutableMethod.addInstructions(
0, 0,
""" """
const/4 v0, 0x0 const/4 v0, 0x0

View File

@ -1,10 +1,13 @@
package app.revanced.patches.shared.fingerprints package app.revanced.patches.shared.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
object WatchWhileActivityFingerprint : MethodFingerprint( object WatchWhileActivityFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
parameters = listOf(),
customFingerprint = { methodDef, _ -> customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("WatchWhileActivity;") && methodDef.name == "<init>" methodDef.definingClass.endsWith("WatchWhileActivity;")
} }
) )

View File

@ -1,11 +1,14 @@
package app.revanced.patches.shared.misc.fix.verticalscroll.fingerprints package app.revanced.patches.shared.misc.fix.verticalscroll.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
object CanScrollVerticallyFingerprint : MethodFingerprint( object CanScrollVerticallyFingerprint : MethodFingerprint(
"Z", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
returnType = "Z",
parameters = emptyList(), parameters = emptyList(),
opcodes = listOf( opcodes = listOf(
Opcode.MOVE_RESULT, Opcode.MOVE_RESULT,

View File

@ -14,6 +14,7 @@ import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.util.resources.ResourceUtils import app.revanced.util.resources.ResourceUtils
import app.revanced.util.resources.ResourceUtils.copyResources import app.revanced.util.resources.ResourceUtils.copyResources
import org.w3c.dom.Node import org.w3c.dom.Node
import java.io.Closeable
/** /**
* Abstract settings resource patch * Abstract settings resource patch
@ -24,7 +25,7 @@ import org.w3c.dom.Node
abstract class AbstractSettingsResourcePatch( abstract class AbstractSettingsResourcePatch(
private val preferenceFileName: String, private val preferenceFileName: String,
private val sourceDirectory: String, private val sourceDirectory: String,
) : ResourcePatch { ) : ResourcePatch, Closeable {
override fun execute(context: ResourceContext): PatchResult { override fun execute(context: ResourceContext): PatchResult {
/* /*
* used for self-restart * used for self-restart

View File

@ -53,6 +53,7 @@ class SettingsPatch : BytecodePatch(
} - 6 } - 6
// fixme: instead use Method.indexOfFirstConstantInstructionValue()
val copyrightPolicyIndex = instructions.indexOfFirst { val copyrightPolicyIndex = instructions.indexOfFirst {
(it as? WideLiteralInstruction)?.wideLiteral == copyrightPolicyLabelId (it as? WideLiteralInstruction)?.wideLiteral == copyrightPolicyLabelId
} + 2 } + 2

View File

@ -29,6 +29,7 @@ import app.revanced.patches.twitch.misc.settings.fingerprints.SettingsMenuItemEn
import app.revanced.patches.twitch.misc.settings.resource.patch.SettingsResourcePatch import app.revanced.patches.twitch.misc.settings.resource.patch.SettingsResourcePatch
import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.immutable.ImmutableField import org.jf.dexlib2.immutable.ImmutableField
import java.io.Closeable
@Patch @Patch
@DependsOn([IntegrationsPatch::class, SettingsResourcePatch::class]) @DependsOn([IntegrationsPatch::class, SettingsResourcePatch::class])
@ -43,7 +44,7 @@ class SettingsPatch : BytecodePatch(
MenuGroupsUpdatedFingerprint, MenuGroupsUpdatedFingerprint,
MenuGroupsOnClickFingerprint MenuGroupsOnClickFingerprint
) )
) { ), Closeable {
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
// Hook onCreate to handle fragment creation // Hook onCreate to handle fragment creation
SettingsActivityOnCreateFingerprint.result?.apply { SettingsActivityOnCreateFingerprint.result?.apply {

View File

@ -3,7 +3,7 @@ package app.revanced.patches.vsco.misc.pro.patch
import app.revanced.extensions.toErrorResult import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.* import app.revanced.patcher.annotation.*
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.addInstruction
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
@ -22,7 +22,7 @@ class UnlockProPatch : BytecodePatch(
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
RevCatSubscriptionFingerprint.result?.mutableMethod?.apply { RevCatSubscriptionFingerprint.result?.mutableMethod?.apply {
// Set isSubscribed to true. // Set isSubscribed to true.
addInstructionsWithLabels( addInstruction(
0, 0,
""" """
const p1, 0x1 const p1, 0x1

View File

@ -1,9 +1,14 @@
package app.revanced.patches.youtube.ad.getpremium.bytecode.fingerprints package app.revanced.patches.youtube.ad.getpremium.bytecode.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
object GetPremiumViewFingerprint : MethodFingerprint( object GetPremiumViewFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PROTECTED or AccessFlags.FINAL,
returnType = "V",
parameters = listOf("I", "I"),
opcodes = listOf( opcodes = listOf(
Opcode.ADD_INT_2ADDR, Opcode.ADD_INT_2ADDR,
Opcode.ADD_INT_2ADDR, Opcode.ADD_INT_2ADDR,

View File

@ -1,23 +1,12 @@
package app.revanced.patches.youtube.interaction.seekbar.fingerprints package app.revanced.patches.youtube.interaction.seekbar.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.interaction.seekbar.patch.EnableSeekbarTappingResourcePatch import app.revanced.patches.youtube.interaction.seekbar.patch.EnableSeekbarTappingResourcePatch
import app.revanced.util.patch.LiteralValueFingerprint
import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
object AccessibilityPlayerProgressTimeFingerprint : LiteralValueFingerprint(
object AccessibilityPlayerProgressTimeFingerprint : MethodFingerprint(
returnType = "L", returnType = "L",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
customFingerprint = { methodDef, _ -> literal = EnableSeekbarTappingResourcePatch.accessibilityPlayerProgressTime
methodDef.implementation?.instructions?.any { instruction ->
if (instruction.opcode != Opcode.CONST) return@any false
val wideLiteral = (instruction as WideLiteralInstruction).wideLiteral
EnableSeekbarTappingResourcePatch.accessibilityPlayerProgressTime == wideLiteral
} ?: false
}
) )

View File

@ -1,10 +1,13 @@
package app.revanced.patches.youtube.interaction.swipecontrols.fingerprints package app.revanced.patches.youtube.interaction.swipecontrols.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
object SwipeControlsHostActivityFingerprint : MethodFingerprint( object SwipeControlsHostActivityFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
parameters = listOf(),
customFingerprint = { methodDef, _ -> customFingerprint = { methodDef, _ ->
methodDef.definingClass == "Lapp/revanced/integrations/swipecontrols/SwipeControlsHostActivity;" && methodDef.name == "<init>" methodDef.definingClass == "Lapp/revanced/integrations/swipecontrols/SwipeControlsHostActivity;"
} }
) )

View File

@ -1,13 +1,10 @@
package app.revanced.patches.youtube.layout.autocaptions.fingerprints package app.revanced.patches.youtube.layout.autocaptions.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
@FuzzyPatternScanMethod(3)
object StartVideoInformerFingerprint : MethodFingerprint( object StartVideoInformerFingerprint : MethodFingerprint(
"V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L", "L", "L", "L"), listOf( "V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L", "L", "L", "L"), listOf(
Opcode.INVOKE_STATIC, Opcode.INVOKE_STATIC,

View File

@ -6,7 +6,10 @@ import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
object SubtitleButtonControllerFingerprint : MethodFingerprint( object SubtitleButtonControllerFingerprint : MethodFingerprint(
"V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L"), listOf( returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("Lcom/google/android/libraries/youtube/player/subtitles/model/SubtitleTrack;"),
opcodes = listOf(
Opcode.IGET_OBJECT, Opcode.IGET_OBJECT,
Opcode.IF_NEZ, Opcode.IF_NEZ,
Opcode.RETURN_VOID, Opcode.RETURN_VOID,
@ -16,5 +19,8 @@ object SubtitleButtonControllerFingerprint : MethodFingerprint(
Opcode.CONST, Opcode.CONST,
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT, Opcode.IGET_OBJECT,
) ),
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("SubtitleButtonController;")
}
) )

View File

@ -14,5 +14,8 @@ object SubtitleTrackFingerprint : MethodFingerprint(
Opcode.MOVE_RESULT, Opcode.MOVE_RESULT,
Opcode.RETURN, Opcode.RETURN,
), ),
strings = listOf("DISABLE_CAPTIONS_OPTION") strings = listOf("DISABLE_CAPTIONS_OPTION"),
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("SubtitleTrack;")
}
) )

View File

@ -1,5 +1,6 @@
package app.revanced.patches.youtube.layout.buttons.autoplay.patch package app.revanced.patches.youtube.layout.buttons.autoplay.patch
import app.revanced.extensions.findIndexForIdResource
import app.revanced.extensions.toErrorResult import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
@ -23,7 +24,6 @@ import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
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.iface.instruction.WideLiteralInstruction
import org.jf.dexlib2.iface.reference.MethodReference import org.jf.dexlib2.iface.reference.MethodReference
@Patch @Patch
@ -48,15 +48,8 @@ class HideAutoplayButtonPatch : BytecodePatch(
LayoutConstructorFingerprint.result?.mutableMethod?.apply { LayoutConstructorFingerprint.result?.mutableMethod?.apply {
val layoutGenMethodInstructions = implementation!!.instructions val layoutGenMethodInstructions = implementation!!.instructions
// resolve the offsets such as ... // resolve the offsets of where to insert the branch instructions and ...
val autoNavPreviewStubId = ResourceMappingPatch.resourceMappings.single { val insertIndex = findIndexForIdResource("autonav_preview_stub")
it.name == "autonav_preview_stub"
}.id
// where to insert the branch instructions and ...
val insertIndex = layoutGenMethodInstructions.indexOfFirst {
(it as? WideLiteralInstruction)?.wideLiteral == autoNavPreviewStubId
}
// where to branch away // where to branch away
val branchIndex = val branchIndex =

View File

@ -1,15 +1,13 @@
package app.revanced.patches.youtube.layout.buttons.navigation.fingerprints package app.revanced.patches.youtube.layout.buttons.navigation.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.extensions.or
import app.revanced.patches.youtube.layout.buttons.navigation.patch.ResolvePivotBarFingerprintsPatch import app.revanced.patches.youtube.layout.buttons.navigation.patch.ResolvePivotBarFingerprintsPatch
import org.jf.dexlib2.Opcode import app.revanced.util.patch.LiteralValueFingerprint
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction import org.jf.dexlib2.AccessFlags
object InitializeButtonsFingerprint : MethodFingerprint( object InitializeButtonsFingerprint : LiteralValueFingerprint(
customFingerprint = { methodDef, _ -> accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
methodDef.implementation?.instructions?.any { returnType = "V",
it.opcode == Opcode.CONST && (it as WideLiteralInstruction).wideLiteral == parameters = listOf(),
ResolvePivotBarFingerprintsPatch.imageOnlyTabResourceId literal = ResolvePivotBarFingerprintsPatch.imageOnlyTabResourceId
} == true
}
) )

View File

@ -5,5 +5,5 @@ import org.jf.dexlib2.Opcode
object PlayerControlsVisibilityModelFingerprint : MethodFingerprint( object PlayerControlsVisibilityModelFingerprint : MethodFingerprint(
opcodes = listOf(Opcode.INVOKE_DIRECT_RANGE), opcodes = listOf(Opcode.INVOKE_DIRECT_RANGE),
strings = listOf("hasNext", "hasPrevious", "Missing required properties:") strings = listOf("Missing required properties:", "hasNext", "hasPrevious")
) )

View File

@ -1,11 +1,13 @@
package app.revanced.patches.youtube.layout.hide.albumcards.bytecode.fingerprints package app.revanced.patches.youtube.layout.hide.albumcards.bytecode.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.extensions.or
import app.revanced.patches.youtube.layout.hide.albumcards.resource.patch.AlbumCardsResourcePatch import app.revanced.patches.youtube.layout.hide.albumcards.resource.patch.AlbumCardsResourcePatch
import app.revanced.util.patch.LiteralValueFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
object AlbumCardsFingerprint : MethodFingerprint( object AlbumCardsFingerprint : LiteralValueFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
opcodes = listOf( opcodes = listOf(
Opcode.MOVE_RESULT_OBJECT, Opcode.MOVE_RESULT_OBJECT,
Opcode.CONST, Opcode.CONST,
@ -14,10 +16,5 @@ object AlbumCardsFingerprint : MethodFingerprint(
Opcode.MOVE_RESULT_OBJECT, Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST, Opcode.CHECK_CAST,
), ),
customFingerprint = { methodDef, _ -> literal = AlbumCardsResourcePatch.albumCardId
methodDef.implementation?.instructions?.any { instruction ->
instruction.opcode.ordinal == Opcode.CONST.ordinal &&
(instruction as? WideLiteralInstruction)?.wideLiteral == AlbumCardsResourcePatch.albumCardId
} == true
}
) )

View File

@ -1,11 +1,13 @@
package app.revanced.patches.youtube.layout.hide.breakingnews.bytecode.fingerprints package app.revanced.patches.youtube.layout.hide.breakingnews.bytecode.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.extensions.or
import app.revanced.patches.youtube.layout.hide.breakingnews.resource.patch.BreakingNewsResourcePatch import app.revanced.patches.youtube.layout.hide.breakingnews.resource.patch.BreakingNewsResourcePatch
import app.revanced.util.patch.LiteralValueFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
object BreakingNewsFingerprint : MethodFingerprint( object BreakingNewsFingerprint : LiteralValueFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
opcodes = listOf( opcodes = listOf(
Opcode.CONST, Opcode.CONST,
Opcode.CONST_4, Opcode.CONST_4,
@ -14,10 +16,5 @@ object BreakingNewsFingerprint : MethodFingerprint(
Opcode.CHECK_CAST, Opcode.CHECK_CAST,
Opcode.IPUT_OBJECT, Opcode.IPUT_OBJECT,
), ),
customFingerprint = { methodDef, _ -> literal = BreakingNewsResourcePatch.horizontalCardListId
methodDef.implementation?.instructions?.any { instruction ->
instruction.opcode.ordinal == Opcode.CONST.ordinal &&
(instruction as? WideLiteralInstruction)?.wideLiteral == BreakingNewsResourcePatch.horizontalCardListId
} == true
}
) )

View File

@ -1,20 +1,17 @@
package app.revanced.patches.youtube.layout.hide.crowdfundingbox.bytecode.fingerprints package app.revanced.patches.youtube.layout.hide.crowdfundingbox.bytecode.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.extensions.or
import app.revanced.patches.youtube.layout.hide.crowdfundingbox.resource.patch.CrowdfundingBoxResourcePatch import app.revanced.patches.youtube.layout.hide.crowdfundingbox.resource.patch.CrowdfundingBoxResourcePatch
import app.revanced.util.patch.LiteralValueFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
object CrowdfundingBoxFingerprint : MethodFingerprint( object CrowdfundingBoxFingerprint : LiteralValueFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
opcodes = listOf( opcodes = listOf(
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT, Opcode.MOVE_RESULT_OBJECT,
Opcode.IPUT_OBJECT, Opcode.IPUT_OBJECT,
), ),
customFingerprint = { methodDef, _ -> literal = CrowdfundingBoxResourcePatch.crowdfundingBoxId
methodDef.implementation?.instructions?.any { instruction ->
instruction.opcode.ordinal == Opcode.CONST.ordinal &&
(instruction as? WideLiteralInstruction)?.wideLiteral == CrowdfundingBoxResourcePatch.crowdfundingBoxId
} == true
}
) )

View File

@ -1,11 +1,11 @@
package app.revanced.patches.youtube.layout.hide.endscreencards.bytecode.fingerprints package app.revanced.patches.youtube.layout.hide.endscreencards.bytecode.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.hide.endscreencards.resource.patch.HideEndscreenCardsResourcePatch import app.revanced.patches.youtube.layout.hide.endscreencards.resource.patch.HideEndscreenCardsResourcePatch
import app.revanced.util.patch.LiteralValueFingerprint
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
object LayoutCircleFingerprint : MethodFingerprint( object LayoutCircleFingerprint : LiteralValueFingerprint(
returnType = "Landroid/view/View;",
opcodes = listOf( opcodes = listOf(
Opcode.CONST, Opcode.CONST,
Opcode.CONST_4, Opcode.CONST_4,
@ -13,10 +13,5 @@ object LayoutCircleFingerprint : MethodFingerprint(
Opcode.MOVE_RESULT_OBJECT, Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST, Opcode.CHECK_CAST,
), ),
customFingerprint = { methodDef, _ -> literal = HideEndscreenCardsResourcePatch.layoutCircle
methodDef.implementation?.instructions?.any { instruction ->
instruction.opcode.ordinal == Opcode.CONST.ordinal &&
(instruction as? WideLiteralInstruction)?.wideLiteral == HideEndscreenCardsResourcePatch.layoutCircle
} == true
}
) )

View File

@ -1,11 +1,11 @@
package app.revanced.patches.youtube.layout.hide.endscreencards.bytecode.fingerprints package app.revanced.patches.youtube.layout.hide.endscreencards.bytecode.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.hide.endscreencards.resource.patch.HideEndscreenCardsResourcePatch import app.revanced.patches.youtube.layout.hide.endscreencards.resource.patch.HideEndscreenCardsResourcePatch
import app.revanced.util.patch.LiteralValueFingerprint
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
object LayoutIconFingerprint : MethodFingerprint( object LayoutIconFingerprint : LiteralValueFingerprint(
returnType = "Landroid/view/View;",
opcodes = listOf( opcodes = listOf(
Opcode.CONST_4, Opcode.CONST_4,
Opcode.CONST, Opcode.CONST,
@ -13,10 +13,5 @@ object LayoutIconFingerprint : MethodFingerprint(
Opcode.MOVE_RESULT_OBJECT, Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST, Opcode.CHECK_CAST,
), ),
customFingerprint = { methodDef, _ -> literal = HideEndscreenCardsResourcePatch.layoutIcon
methodDef.implementation?.instructions?.any { instruction ->
instruction.opcode.ordinal == Opcode.CONST.ordinal &&
(instruction as? WideLiteralInstruction)?.wideLiteral == HideEndscreenCardsResourcePatch.layoutIcon
} == true
}
) )

View File

@ -1,11 +1,11 @@
package app.revanced.patches.youtube.layout.hide.endscreencards.bytecode.fingerprints package app.revanced.patches.youtube.layout.hide.endscreencards.bytecode.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.hide.endscreencards.resource.patch.HideEndscreenCardsResourcePatch import app.revanced.patches.youtube.layout.hide.endscreencards.resource.patch.HideEndscreenCardsResourcePatch
import app.revanced.util.patch.LiteralValueFingerprint
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
object LayoutVideoFingerprint : MethodFingerprint( object LayoutVideoFingerprint : LiteralValueFingerprint(
returnType = "Landroid/view/View;",
opcodes = listOf( opcodes = listOf(
Opcode.CONST, Opcode.CONST,
Opcode.CONST_4, Opcode.CONST_4,
@ -13,10 +13,5 @@ object LayoutVideoFingerprint : MethodFingerprint(
Opcode.MOVE_RESULT_OBJECT, Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST, Opcode.CHECK_CAST,
), ),
customFingerprint = { methodDef, _ -> literal = HideEndscreenCardsResourcePatch.layoutVideo
methodDef.implementation?.instructions?.any { instruction ->
instruction.opcode.ordinal == Opcode.CONST.ordinal &&
(instruction as? WideLiteralInstruction)?.wideLiteral == HideEndscreenCardsResourcePatch.layoutVideo
} == true
}
) )

View File

@ -1,14 +1,19 @@
package app.revanced.patches.youtube.layout.hide.filterbar.fingerprints package app.revanced.patches.youtube.layout.hide.filterbar.fingerprints
import app.revanced.patches.youtube.layout.hide.filterbar.patch.HideFilterBarResourcePatch.Companion.filterBarHeightId import app.revanced.patcher.extensions.or
import app.revanced.patches.youtube.layout.hide.filterbar.patch.HideFilterBarResourcePatch
import app.revanced.util.patch.LiteralValueFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
object FilterBarHeightFingerprint : LiteralOpcodesFingerprint( object FilterBarHeightFingerprint : LiteralValueFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
opcodes = listOf( opcodes = listOf(
Opcode.CONST, Opcode.CONST,
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT, Opcode.MOVE_RESULT,
Opcode.IPUT Opcode.IPUT
), ),
filterBarHeightId literal = HideFilterBarResourcePatch.filterBarHeightId
) )

View File

@ -1,19 +0,0 @@
package app.revanced.patches.youtube.layout.hide.filterbar.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
abstract class LiteralOpcodesFingerprint(opcodes: List<Opcode>, literal: Long) : MethodFingerprint(
opcodes = opcodes,
customFingerprint = { methodDef, _ ->
methodDef.implementation?.instructions?.any { instruction ->
if (instruction.opcode != Opcode.CONST) return@any false
val wideLiteral = (instruction as WideLiteralInstruction).wideLiteral
literal == wideLiteral
} ?: false
}
)

View File

@ -1,13 +1,18 @@
package app.revanced.patches.youtube.layout.hide.filterbar.fingerprints package app.revanced.patches.youtube.layout.hide.filterbar.fingerprints
import app.revanced.patches.youtube.layout.hide.filterbar.patch.HideFilterBarResourcePatch.Companion.relatedChipCloudMarginId import app.revanced.patcher.extensions.or
import app.revanced.patches.youtube.layout.hide.filterbar.patch.HideFilterBarResourcePatch
import app.revanced.util.patch.LiteralValueFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
object RelatedChipCloudFingerprint : LiteralOpcodesFingerprint( object RelatedChipCloudFingerprint : LiteralValueFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
opcodes = listOf( opcodes = listOf(
Opcode.CONST, Opcode.CONST,
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT Opcode.MOVE_RESULT_OBJECT
), ),
relatedChipCloudMarginId literal = HideFilterBarResourcePatch.relatedChipCloudMarginId
) )

View File

@ -1,9 +1,14 @@
package app.revanced.patches.youtube.layout.hide.filterbar.fingerprints package app.revanced.patches.youtube.layout.hide.filterbar.fingerprints
import app.revanced.patches.youtube.layout.hide.filterbar.patch.HideFilterBarResourcePatch.Companion.barContainerHeightId import app.revanced.patcher.extensions.or
import app.revanced.patches.youtube.layout.hide.filterbar.patch.HideFilterBarResourcePatch
import app.revanced.util.patch.LiteralValueFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
object SearchResultsChipBarFingerprint : LiteralOpcodesFingerprint( object SearchResultsChipBarFingerprint : LiteralValueFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
opcodes = listOf( opcodes = listOf(
Opcode.CONST, Opcode.CONST,
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
@ -11,5 +16,5 @@ object SearchResultsChipBarFingerprint : LiteralOpcodesFingerprint(
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT Opcode.MOVE_RESULT_OBJECT
), ),
barContainerHeightId literal = HideFilterBarResourcePatch.barContainerHeightId
) )

View File

@ -1,19 +1,19 @@
package app.revanced.patches.youtube.layout.hide.floatingmicrophone.fingerprints package app.revanced.patches.youtube.layout.hide.floatingmicrophone.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.extensions.or
import app.revanced.util.patch.LiteralValueFingerprint
import app.revanced.patches.youtube.layout.hide.floatingmicrophone.patch.HideFloatingMicrophoneButtonResourcePatch import app.revanced.patches.youtube.layout.hide.floatingmicrophone.patch.HideFloatingMicrophoneButtonResourcePatch
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
object ShowFloatingMicrophoneButtonFingerprint : MethodFingerprint( object ShowFloatingMicrophoneButtonFingerprint : LiteralValueFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
returnType = "V",
parameters = listOf(),
opcodes = listOf( opcodes = listOf(
Opcode.IGET_BOOLEAN, Opcode.IGET_BOOLEAN,
Opcode.IF_EQZ, Opcode.IF_EQZ,
Opcode.RETURN_VOID Opcode.RETURN_VOID
), ),
customFingerprint = { methodDef, _ -> literal = HideFloatingMicrophoneButtonResourcePatch.fabButtonId
methodDef.implementation?.instructions?.any {
(it as? WideLiteralInstruction)?.wideLiteral == HideFloatingMicrophoneButtonResourcePatch.fabButtonId
} == true
}
) )

View File

@ -5,7 +5,8 @@ import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.AccessFlags
object InfocardsIncognitoFingerprint : MethodFingerprint( object InfocardsIncognitoFingerprint : MethodFingerprint(
"Ljava/lang/Boolean;", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
AccessFlags.PUBLIC or AccessFlags.FINAL, returnType = "Ljava/lang/Boolean;",
parameters = listOf("L", "J"),
strings = listOf("vibrator") strings = listOf("vibrator")
) )

View File

@ -1,19 +1,15 @@
package app.revanced.patches.youtube.layout.hide.infocards.fingerprints package app.revanced.patches.youtube.layout.hide.infocards.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.util.patch.LiteralValueFingerprint
import app.revanced.patches.youtube.layout.hide.infocards.resource.patch.HideInfocardsResourcePatch import app.revanced.patches.youtube.layout.hide.infocards.resource.patch.HideInfocardsResourcePatch
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
object InfocardsMethodCallFingerprint : MethodFingerprint( object InfocardsMethodCallFingerprint : LiteralValueFingerprint(
opcodes = listOf( opcodes = listOf(
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT, Opcode.IGET_OBJECT,
Opcode.INVOKE_INTERFACE, Opcode.INVOKE_INTERFACE,
), ),
customFingerprint = { methodDef, _ -> strings = listOf("Missing ControlsOverlayPresenter for InfoCards to work."),
methodDef.implementation?.instructions?.any { instruction -> literal = HideInfocardsResourcePatch.drawerResourceId
(instruction as? WideLiteralInstruction)?.wideLiteral == HideInfocardsResourcePatch.drawerResourceId
} == true
}
) )

View File

@ -1,13 +1,12 @@
package app.revanced.patches.youtube.layout.hide.loadmorebutton.bytecode.fingerprints package app.revanced.patches.youtube.layout.hide.loadmorebutton.bytecode.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.util.patch.LiteralValueFingerprint
import app.revanced.patches.youtube.layout.hide.loadmorebutton.resource.patch.HideLoadMoreButtonResourcePatch import app.revanced.patches.youtube.layout.hide.loadmorebutton.resource.patch.HideLoadMoreButtonResourcePatch
import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
object HideLoadMoreButtonFingerprint : MethodFingerprint( object HideLoadMoreButtonFingerprint : LiteralValueFingerprint(
returnType = "V", returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
parameters = listOf("L", "L", "L", "L"), parameters = listOf("L", "L", "L", "L"),
@ -17,13 +16,5 @@ object HideLoadMoreButtonFingerprint : MethodFingerprint(
Opcode.INVOKE_STATIC, Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT Opcode.MOVE_RESULT_OBJECT
), ),
customFingerprint = { methodDef, _ -> literal = HideLoadMoreButtonResourcePatch.expandButtonDownId
methodDef.implementation?.instructions?.any {
if (it.opcode != Opcode.CONST) return@any false
val literal = (it as WideLiteralInstruction).wideLiteral
literal == HideLoadMoreButtonResourcePatch.expandButtonDownId
} ?: false
}
) )

View File

@ -1,11 +1,12 @@
package app.revanced.patches.youtube.layout.hide.personalinformation.bytecode.fingerprints package app.revanced.patches.youtube.layout.hide.personalinformation.bytecode.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.util.patch.LiteralValueFingerprint
import app.revanced.patches.youtube.layout.hide.personalinformation.resource.patch.HideEmailAddressResourcePatch import app.revanced.patches.youtube.layout.hide.personalinformation.resource.patch.HideEmailAddressResourcePatch
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
object AccountSwitcherAccessibilityLabelFingerprint : MethodFingerprint( object AccountSwitcherAccessibilityLabelFingerprint : LiteralValueFingerprint(
returnType = "V",
parameters = listOf("L", "Ljava/lang/Object;"),
opcodes = listOf( opcodes = listOf(
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT, Opcode.IGET_OBJECT,
@ -15,10 +16,5 @@ object AccountSwitcherAccessibilityLabelFingerprint : MethodFingerprint(
Opcode.APUT_OBJECT, Opcode.APUT_OBJECT,
Opcode.CONST, Opcode.CONST,
), ),
customFingerprint = { methodDef, _ -> literal = HideEmailAddressResourcePatch.accountSwitcherAccessibilityLabelId
methodDef.implementation?.instructions?.any { instruction ->
instruction.opcode.ordinal == Opcode.CONST.ordinal &&
(instruction as? WideLiteralInstruction)?.wideLiteral == HideEmailAddressResourcePatch.accountSwitcherAccessibilityLabelId
} == true
}
) )

View File

@ -1,13 +1,12 @@
package app.revanced.patches.youtube.layout.hide.player.overlay.bytecode.fingerprints package app.revanced.patches.youtube.layout.hide.player.overlay.bytecode.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.util.patch.LiteralValueFingerprint
import app.revanced.patches.youtube.layout.hide.player.overlay.resource.patch.HidePlayerOverlayResourcePatch import app.revanced.patches.youtube.layout.hide.player.overlay.resource.patch.HidePlayerOverlayResourcePatch
import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
object CreatePlayerOverviewFingerprint : MethodFingerprint( object CreatePlayerOverviewFingerprint : LiteralValueFingerprint(
returnType = "V", returnType = "V",
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL, accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
opcodes = listOf( opcodes = listOf(
@ -16,13 +15,5 @@ object CreatePlayerOverviewFingerprint : MethodFingerprint(
Opcode.MOVE_RESULT_OBJECT, Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST Opcode.CHECK_CAST
), ),
customFingerprint = { methodDef, _ -> literal = HidePlayerOverlayResourcePatch.scrimOverlayId
methodDef.implementation?.instructions?.any {
if (it.opcode != Opcode.CONST) return@any false
val literal = (it as WideLiteralInstruction).wideLiteral
literal == HidePlayerOverlayResourcePatch.scrimOverlayId
} ?: false
}
) )

View File

@ -1,5 +1,6 @@
package app.revanced.patches.youtube.layout.hide.player.overlay.bytecode.patch package app.revanced.patches.youtube.layout.hide.player.overlay.bytecode.patch
import app.revanced.extensions.indexOfFirstConstantInstructionValue
import app.revanced.extensions.toErrorResult import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
@ -16,7 +17,6 @@ import app.revanced.patches.youtube.layout.hide.player.overlay.annotations.HideP
import app.revanced.patches.youtube.layout.hide.player.overlay.bytecode.fingerprints.CreatePlayerOverviewFingerprint import app.revanced.patches.youtube.layout.hide.player.overlay.bytecode.fingerprints.CreatePlayerOverviewFingerprint
import app.revanced.patches.youtube.layout.hide.player.overlay.resource.patch.HidePlayerOverlayResourcePatch import app.revanced.patches.youtube.layout.hide.player.overlay.resource.patch.HidePlayerOverlayResourcePatch
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
@Patch @Patch
@Name("hide-player-overlay") @Name("hide-player-overlay")
@ -28,11 +28,8 @@ class HidePlayerOverlayPatch : BytecodePatch(listOf(CreatePlayerOverviewFingerpr
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
CreatePlayerOverviewFingerprint.result?.let { result -> CreatePlayerOverviewFingerprint.result?.let { result ->
result.mutableMethod.apply { result.mutableMethod.apply {
val viewRegisterIndex = implementation!!.instructions.indexOfFirst { val viewRegisterIndex =
val literal = (it as? WideLiteralInstruction)?.wideLiteral indexOfFirstConstantInstructionValue(HidePlayerOverlayResourcePatch.scrimOverlayId) + 3
literal == HidePlayerOverlayResourcePatch.scrimOverlayId
} + 3
val viewRegister = getInstruction<OneRegisterInstruction>(viewRegisterIndex).registerA val viewRegister = getInstruction<OneRegisterInstruction>(viewRegisterIndex).registerA
val insertIndex = viewRegisterIndex + 1 val insertIndex = viewRegisterIndex + 1

View File

@ -1,19 +1,13 @@
package app.revanced.patches.youtube.layout.hide.shorts.bytecode.fingerprints package app.revanced.patches.youtube.layout.hide.shorts.bytecode.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.extensions.or
import app.revanced.util.patch.LiteralValueFingerprint
import app.revanced.patches.youtube.layout.hide.shorts.resource.patch.HideShortsComponentsResourcePatch import app.revanced.patches.youtube.layout.hide.shorts.resource.patch.HideShortsComponentsResourcePatch
import org.jf.dexlib2.Opcode import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
object CreateShortsButtonsFingerprint : MethodFingerprint( object CreateShortsButtonsFingerprint : LiteralValueFingerprint(
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
returnType = "V",
parameters = listOf("Z", "Z", "L"), parameters = listOf("Z", "Z", "L"),
customFingerprint = { methodDef, _ -> literal = HideShortsComponentsResourcePatch.reelPlayerRightLargeIconSize
methodDef.implementation?.instructions?.any {
if (it.opcode != Opcode.CONST) return@any false
val literal = (it as WideLiteralInstruction).wideLiteral
literal == HideShortsComponentsResourcePatch.reelPlayerRightLargeIconSize
} ?: false
}
) )

View File

@ -1,19 +1,13 @@
package app.revanced.patches.youtube.layout.hide.shorts.bytecode.fingerprints package app.revanced.patches.youtube.layout.hide.shorts.bytecode.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.extensions.or
import app.revanced.util.patch.LiteralValueFingerprint
import app.revanced.patches.youtube.layout.hide.shorts.resource.patch.HideShortsComponentsResourcePatch import app.revanced.patches.youtube.layout.hide.shorts.resource.patch.HideShortsComponentsResourcePatch
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
object ReelConstructorFingerprint : MethodFingerprint( object ReelConstructorFingerprint : LiteralValueFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
opcodes = listOf(Opcode.INVOKE_VIRTUAL), opcodes = listOf(Opcode.INVOKE_VIRTUAL),
customFingerprint = { method, _ -> literal = HideShortsComponentsResourcePatch.reelMultipleItemShelfId
method.implementation?.instructions?.any {
if (it.opcode != Opcode.CONST) return@any false
val literal = (it as WideLiteralInstruction).wideLiteral
literal == HideShortsComponentsResourcePatch.reelMultipleItemShelfId
} ?: false
}
) )

View File

@ -1,25 +1,28 @@
package app.revanced.patches.youtube.layout.hide.time.fingerprints package app.revanced.patches.youtube.layout.hide.time.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
@FuzzyPatternScanMethod(3)
object TimeCounterFingerprint : MethodFingerprint( object TimeCounterFingerprint : MethodFingerprint(
"V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), listOf( accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf(),
returnType = "V",
opcodes = listOf(
Opcode.SUB_LONG_2ADDR,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IGET_OBJECT, Opcode.IGET_OBJECT,
Opcode.IGET_WIDE, Opcode.IGET_WIDE,
Opcode.CONST_WIDE_16, Opcode.INVOKE_STATIC,
Opcode.CMP_LONG, Opcode.MOVE_RESULT_OBJECT,
Opcode.IF_LEZ, Opcode.INVOKE_INTERFACE,
Opcode.IGET_OBJECT, Opcode.RETURN_VOID,
Opcode.IF_EQZ, ),
Opcode.INVOKE_VIRTUAL, customFingerprint = { _, classDef ->
Opcode.MOVE_RESULT, // On older devices this fingerprint resolves very slowly.
Opcode.IF_EQZ, // Speed this up by checking for the number of methods.
Opcode.GOTO, classDef.methods.count() == 14
) }
) )

View File

@ -1,5 +1,6 @@
package app.revanced.patches.youtube.layout.hide.time.patch package app.revanced.patches.youtube.layout.hide.time.patch
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
@ -38,7 +39,8 @@ class HideTimestampPatch : BytecodePatch(
) )
) )
TimeCounterFingerprint.result!!.mutableMethod.addInstructionsWithLabels( TimeCounterFingerprint.result?.apply {
mutableMethod.addInstructionsWithLabels(
0, 0,
""" """
invoke-static { }, Lapp/revanced/integrations/patches/HideTimestampPatch;->hideTimestamp()Z invoke-static { }, Lapp/revanced/integrations/patches/HideTimestampPatch;->hideTimestamp()Z
@ -48,7 +50,8 @@ class HideTimestampPatch : BytecodePatch(
:hide_time :hide_time
nop nop
""" """
) )
} ?: return TimeCounterFingerprint.toErrorResult()
return PatchResultSuccess() return PatchResultSuccess()
} }

View File

@ -1,11 +1,11 @@
package app.revanced.patches.youtube.layout.panels.fullscreen.remove.fingerprints package app.revanced.patches.youtube.layout.panels.fullscreen.remove.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
object FullscreenViewAdderParentFingerprint : MethodFingerprint( object FullscreenViewAdderParentFingerprint : MethodFingerprint(
parameters = listOf("L", "L"), returnType = "V",
parameters = listOf("Landroid/content/Context;", "Landroid/view/View;"),
opcodes = listOf( opcodes = listOf(
Opcode.GOTO, Opcode.GOTO,
Opcode.IGET_BOOLEAN, Opcode.IGET_BOOLEAN,

View File

@ -1,12 +1,9 @@
package app.revanced.patches.youtube.layout.panels.popup.fingerprints package app.revanced.patches.youtube.layout.panels.popup.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.AccessFlags
@FuzzyPatternScanMethod(3)
object EngagementPanelControllerFingerprint : MethodFingerprint( object EngagementPanelControllerFingerprint : MethodFingerprint(
returnType = "L", returnType = "L",
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL, accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,

View File

@ -1,13 +1,12 @@
package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.util.patch.LiteralValueFingerprint
import app.revanced.patches.youtube.layout.returnyoutubedislike.resource.patch.ReturnYouTubeDislikeResourcePatch import app.revanced.patches.youtube.layout.returnyoutubedislike.resource.patch.ReturnYouTubeDislikeResourcePatch
import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
object DislikesOldLayoutTextViewFingerprint : MethodFingerprint( object DislikesOldLayoutTextViewFingerprint : LiteralValueFingerprint(
returnType = "V", returnType = "V",
parameters = listOf("L"), parameters = listOf("L"),
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
@ -19,10 +18,5 @@ object DislikesOldLayoutTextViewFingerprint : MethodFingerprint(
Opcode.IF_NEZ, // textview register Opcode.IF_NEZ, // textview register
Opcode.GOTO, Opcode.GOTO,
), ),
customFingerprint = { methodDef, _ -> literal = ReturnYouTubeDislikeResourcePatch.oldUIDislikeId
methodDef.implementation?.instructions?.any { instruction ->
instruction.opcode.ordinal == Opcode.CONST.ordinal &&
(instruction as? WideLiteralInstruction)?.wideLiteral == ReturnYouTubeDislikeResourcePatch.oldUIDislikeId
} == true
}
) )

View File

@ -1,9 +1,12 @@
package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
object ShortsTextViewFingerprint : MethodFingerprint( object ShortsTextViewFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PROTECTED or AccessFlags.FINAL,
returnType = "V", returnType = "V",
parameters = listOf("L", "L"), parameters = listOf("L", "L"),
opcodes = listOf( opcodes = listOf(

View File

@ -6,7 +6,9 @@ import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
object SetWordmarkHeaderFingerprint : MethodFingerprint( object SetWordmarkHeaderFingerprint : MethodFingerprint(
"V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L"), accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
returnType = "V",
parameters = listOf("Landroid/widget/ImageView;"),
opcodes = listOf( opcodes = listOf(
Opcode.IGET_OBJECT, Opcode.IGET_OBJECT,
Opcode.INVOKE_STATIC, Opcode.INVOKE_STATIC,
@ -17,6 +19,5 @@ object SetWordmarkHeaderFingerprint : MethodFingerprint(
Opcode.IGET_OBJECT, Opcode.IGET_OBJECT,
Opcode.CONST, Opcode.CONST,
Opcode.INVOKE_STATIC, Opcode.INVOKE_STATIC,
), )
customFingerprint = { methodDef, _ -> methodDef.parameterTypes.first() == "Landroid/widget/ImageView;" }
) )

View File

@ -1,15 +1,15 @@
package app.revanced.patches.youtube.layout.seekbar.bytecode.fingerprints package app.revanced.patches.youtube.layout.seekbar.bytecode.fingerprints
import app.revanced.extensions.containsConstantInstructionValue
import app.revanced.patcher.extensions.or 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.patches.youtube.layout.seekbar.resource.SeekbarColorResourcePatch import app.revanced.patches.youtube.layout.seekbar.resource.SeekbarColorResourcePatch
import app.revanced.util.patch.indexOfFirstConstantInstruction
import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.AccessFlags
object CreateDarkThemeSeekbarFingerprint : MethodFingerprint( object CreateDarkThemeSeekbarFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
customFingerprint = { method, _ -> customFingerprint = { method, _ ->
method.indexOfFirstConstantInstruction(SeekbarColorResourcePatch.inlineTimeBarColorizedBarPlayedColorDarkId) != -1 method.containsConstantInstructionValue(SeekbarColorResourcePatch.inlineTimeBarColorizedBarPlayedColorDarkId)
&& method.indexOfFirstConstantInstruction(SeekbarColorResourcePatch.inlineTimeBarPlayedNotHighlightedColorId) != -1 && method.containsConstantInstructionValue(SeekbarColorResourcePatch.inlineTimeBarPlayedNotHighlightedColorId)
} }
) )

View File

@ -5,5 +5,8 @@ import org.jf.dexlib2.Opcode
object SetSeekbarClickedColorFingerprint : MethodFingerprint( object SetSeekbarClickedColorFingerprint : MethodFingerprint(
opcodes = listOf(Opcode.CONST_HIGH16), opcodes = listOf(Opcode.CONST_HIGH16),
strings = listOf("YOUTUBE", "PREROLL", "POSTROLL") strings = listOf("YOUTUBE", "PREROLL", "POSTROLL"),
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("ControlsOverlayStyle;")
}
) )

View File

@ -1,5 +1,6 @@
package app.revanced.patches.youtube.layout.seekbar.bytecode.patch package app.revanced.patches.youtube.layout.seekbar.bytecode.patch
import app.revanced.extensions.indexOfFirstConstantInstructionValue
import app.revanced.extensions.toErrorResult import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
@ -19,7 +20,6 @@ import app.revanced.patches.youtube.layout.seekbar.resource.SeekbarColorResource
import app.revanced.patches.youtube.layout.theme.bytecode.patch.LithoColorHookPatch import app.revanced.patches.youtube.layout.theme.bytecode.patch.LithoColorHookPatch
import app.revanced.patches.youtube.layout.theme.bytecode.patch.LithoColorHookPatch.Companion.lithoColorOverrideHook import app.revanced.patches.youtube.layout.theme.bytecode.patch.LithoColorHookPatch.Companion.lithoColorOverrideHook
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.util.patch.indexOfFirstConstantInstruction
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction
@ -32,7 +32,7 @@ class SeekbarColorBytecodePatch : BytecodePatch(
) { ) {
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
CreateDarkThemeSeekbarFingerprint.result?.mutableMethod?.apply { CreateDarkThemeSeekbarFingerprint.result?.mutableMethod?.apply {
var registerIndex = indexOfFirstConstantInstruction(SeekbarColorResourcePatch.inlineTimeBarColorizedBarPlayedColorDarkId) + 2 var registerIndex = indexOfFirstConstantInstructionValue(SeekbarColorResourcePatch.inlineTimeBarColorizedBarPlayedColorDarkId) + 2
var colorRegister = (getInstruction(registerIndex) as OneRegisterInstruction).registerA var colorRegister = (getInstruction(registerIndex) as OneRegisterInstruction).registerA
addInstructions( addInstructions(
registerIndex + 1, registerIndex + 1,
@ -42,7 +42,7 @@ class SeekbarColorBytecodePatch : BytecodePatch(
""" """
) )
registerIndex = indexOfFirstConstantInstruction(SeekbarColorResourcePatch.inlineTimeBarPlayedNotHighlightedColorId) + 2 registerIndex = indexOfFirstConstantInstructionValue(SeekbarColorResourcePatch.inlineTimeBarPlayedNotHighlightedColorId) + 2
colorRegister = (getInstruction(registerIndex) as OneRegisterInstruction).registerA colorRegister = (getInstruction(registerIndex) as OneRegisterInstruction).registerA
addInstructions( addInstructions(
registerIndex + 1, registerIndex + 1,

View File

@ -8,7 +8,7 @@ import org.jf.dexlib2.Opcode
object AppendTimeFingerprint : MethodFingerprint( object AppendTimeFingerprint : MethodFingerprint(
"V", "V",
AccessFlags.PUBLIC or AccessFlags.FINAL, AccessFlags.PUBLIC or AccessFlags.FINAL,
listOf("L", "L", "L"), listOf("Ljava/lang/CharSequence;", "Ljava/lang/CharSequence;", "Ljava/lang/CharSequence;"),
listOf( listOf(
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT, Opcode.MOVE_RESULT_OBJECT,

View File

@ -1,23 +0,0 @@
package app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@FuzzyPatternScanMethod(2)
object MiniPlayerDimensionsCalculatorFingerprint : MethodFingerprint(
"V",
AccessFlags.PUBLIC or AccessFlags.FINAL,
listOf("L"),
listOf(
Opcode.INVOKE_DIRECT,
Opcode.MOVE_RESULT,
Opcode.IF_NEZ,
Opcode.FLOAT_TO_DOUBLE,
Opcode.CONST_WIDE_HIGH16,
Opcode.CMPL_DOUBLE,
)
)

View File

@ -0,0 +1,23 @@
package app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
object MiniPlayerDimensionsCalculatorParentFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
returnType = "V",
parameters = listOf("F"),
opcodes = listOf(
Opcode.CONST_HIGH16,
Opcode.ADD_FLOAT_2ADDR,
Opcode.MUL_FLOAT,
Opcode.CONST_4,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT,
Opcode.FLOAT_TO_INT,
Opcode.INVOKE_INTERFACE,
Opcode.RETURN_VOID,
)
)

View File

@ -8,7 +8,7 @@ import org.jf.dexlib2.Opcode
object MiniPlayerResponseModelSizeCheckFingerprint : MethodFingerprint( object MiniPlayerResponseModelSizeCheckFingerprint : MethodFingerprint(
"L", "L",
AccessFlags.PUBLIC or AccessFlags.FINAL, AccessFlags.PUBLIC or AccessFlags.FINAL,
listOf("L", "L"), listOf("Ljava/lang/Object;", "Ljava/lang/Object;"),
listOf( listOf(
Opcode.RETURN_OBJECT, Opcode.RETURN_OBJECT,
Opcode.CHECK_CAST, Opcode.CHECK_CAST,

View File

@ -32,7 +32,7 @@ import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
@Version("0.0.1") @Version("0.0.1")
class TabletMiniPlayerPatch : BytecodePatch( class TabletMiniPlayerPatch : BytecodePatch(
listOf( listOf(
MiniPlayerDimensionsCalculatorFingerprint, MiniPlayerDimensionsCalculatorParentFingerprint,
MiniPlayerResponseModelSizeCheckFingerprint, MiniPlayerResponseModelSizeCheckFingerprint,
MiniPlayerOverrideParentFingerprint MiniPlayerOverrideParentFingerprint
) )
@ -48,7 +48,8 @@ class TabletMiniPlayerPatch : BytecodePatch(
) )
// First resolve the fingerprints via the parent fingerprint. // First resolve the fingerprints via the parent fingerprint.
val miniPlayerClass = MiniPlayerDimensionsCalculatorFingerprint.result!!.classDef MiniPlayerDimensionsCalculatorParentFingerprint.result ?: return MiniPlayerDimensionsCalculatorParentFingerprint.toErrorResult()
val miniPlayerClass = MiniPlayerDimensionsCalculatorParentFingerprint.result!!.classDef
/* /*
* No context parameter method. * No context parameter method.

View File

@ -6,7 +6,10 @@ import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
object LithoThemeFingerprint : MethodFingerprint( object LithoThemeFingerprint : MethodFingerprint(
"V", AccessFlags.PROTECTED or AccessFlags.FINAL, listOf("L"), listOf( returnType = "V",
accessFlags = AccessFlags.PROTECTED or AccessFlags.FINAL,
parameters = listOf("Landroid/graphics/Rect;"),
opcodes = listOf(
Opcode.APUT, Opcode.APUT,
Opcode.NEW_INSTANCE, Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT, Opcode.INVOKE_DIRECT,
@ -22,5 +25,8 @@ object LithoThemeFingerprint : MethodFingerprint(
Opcode.IGET_OBJECT, Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
Opcode.RETURN_VOID Opcode.RETURN_VOID
) ),
customFingerprint = { methodDef, _ ->
methodDef.name == "onBoundsChange"
}
) )

View File

@ -9,7 +9,6 @@ import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.all.misc.debugging.patch.EnableAndroidDebuggingPatch
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.debugging.annotations.DebuggingCompatibility import app.revanced.patches.youtube.misc.debugging.annotations.DebuggingCompatibility
@ -18,7 +17,7 @@ import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
@Patch @Patch
@Name("enable-debugging") @Name("enable-debugging")
@DependsOn([IntegrationsPatch::class, SettingsPatch::class, EnableAndroidDebuggingPatch::class]) @DependsOn([IntegrationsPatch::class, SettingsPatch::class])
@Description("Adds debugging options.") @Description("Adds debugging options.")
@DebuggingCompatibility @DebuggingCompatibility
@Version("0.0.2") @Version("0.0.2")

View File

@ -1,9 +1,13 @@
package app.revanced.patches.youtube.misc.fix.backtoexitgesture.fingerprints package app.revanced.patches.youtube.misc.fix.backtoexitgesture.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
object OnBackPressedFingerprint : MethodFingerprint( object OnBackPressedFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
returnType = "V",
opcodes = listOf( opcodes = listOf(
Opcode.RETURN_VOID Opcode.RETURN_VOID
), ),

View File

@ -1,9 +1,14 @@
package app.revanced.patches.youtube.misc.fix.backtoexitgesture.fingerprints package app.revanced.patches.youtube.misc.fix.backtoexitgesture.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
object RecyclerViewScrollingFingerprint : MethodFingerprint( object RecyclerViewScrollingFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
returnType = "V",
parameters = listOf(),
opcodes = listOf( opcodes = listOf(
Opcode.IGET_OBJECT, Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT, Opcode.IGET_OBJECT,

View File

@ -1,9 +1,13 @@
package app.revanced.patches.youtube.misc.fix.backtoexitgesture.fingerprints package app.revanced.patches.youtube.misc.fix.backtoexitgesture.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
object RecyclerViewTopScrollingParentFingerprint : MethodFingerprint( object RecyclerViewTopScrollingParentFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
parameters = listOf("L", "L", "Landroid/view/ViewGroup;", "Landroid/view/ViewGroup;"),
opcodes = listOf( opcodes = listOf(
Opcode.INVOKE_DIRECT, Opcode.INVOKE_DIRECT,
Opcode.IPUT_OBJECT, Opcode.IPUT_OBJECT,
@ -14,7 +18,4 @@ object RecyclerViewTopScrollingParentFingerprint : MethodFingerprint(
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
Opcode.NEW_INSTANCE Opcode.NEW_INSTANCE
), ),
customFingerprint = { methodDef, _ ->
methodDef.name == "<init>"
}
) )

View File

@ -1,11 +0,0 @@
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object SubtitleWindowSettingsConstructorFingerprint : MethodFingerprint(
parameters = listOf("I", "I", "I", "Z", "Z"),
customFingerprint = { methodDef, _ ->
methodDef.definingClass == "Lcom/google/android/libraries/youtube/player/subtitles/model/SubtitleWindowSettings;"
&& methodDef.name == "<init>"
}
)

View File

@ -17,11 +17,9 @@ 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.OpenCronetDataSourceFingerprint import app.revanced.patches.youtube.misc.fix.playback.fingerprints.OpenCronetDataSourceFingerprint
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.ProtobufParameterBuilderFingerprint import app.revanced.patches.youtube.misc.fix.playback.fingerprints.ProtobufParameterBuilderFingerprint
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.SubtitleWindowSettingsConstructorFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.playertype.patch.PlayerTypeHookPatch import app.revanced.patches.youtube.misc.playertype.patch.PlayerTypeHookPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.video.videoid.patch.VideoIdPatch
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
@Name("spoof-signature-verification") @Name("spoof-signature-verification")
@ -30,14 +28,12 @@ import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
IntegrationsPatch::class, IntegrationsPatch::class,
SettingsPatch::class, SettingsPatch::class,
PlayerTypeHookPatch::class, PlayerTypeHookPatch::class,
VideoIdPatch::class
]) ])
@Version("0.0.1") @Version("0.0.1")
class SpoofSignatureVerificationPatch : BytecodePatch( class SpoofSignatureVerificationPatch : BytecodePatch(
listOf( listOf(
ProtobufParameterBuilderFingerprint, ProtobufParameterBuilderFingerprint,
OpenCronetDataSourceFingerprint, OpenCronetDataSourceFingerprint,
SubtitleWindowSettingsConstructorFingerprint,
) )
) { ) {
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
@ -48,7 +44,8 @@ class SpoofSignatureVerificationPatch : BytecodePatch(
StringResource("revanced_spoof_signature_verification_summary_on", StringResource("revanced_spoof_signature_verification_summary_on",
"App signature spoofed\\n\\n" "App signature spoofed\\n\\n"
+ "Side effects include:\\n" + "Side effects include:\\n"
+ "• End screen cards are always hidden\\n" + "• Ambient mode may not work\\n"
+ "• Seekbar thumbnails are hidden\\n"
+ "• Downloading videos may not work"), + "• Downloading videos may not work"),
StringResource("revanced_spoof_signature_verification_summary_off", "App signature not spoofed"), StringResource("revanced_spoof_signature_verification_summary_off", "App signature not spoofed"),
StringResource("revanced_spoof_signature_verification_user_dialog_message", StringResource("revanced_spoof_signature_verification_user_dialog_message",
@ -56,9 +53,6 @@ class SpoofSignatureVerificationPatch : BytecodePatch(
) )
) )
// Hook video id, required for subtitle fix.
VideoIdPatch.injectCall("$INTEGRATIONS_CLASS_DESCRIPTOR->setCurrentVideoId(Ljava/lang/String;)V")
// hook parameter // hook parameter
ProtobufParameterBuilderFingerprint.result?.let { ProtobufParameterBuilderFingerprint.result?.let {
val setParamMethod = context val setParamMethod = context
@ -95,25 +89,6 @@ class SpoofSignatureVerificationPatch : BytecodePatch(
} ?: return OpenCronetDataSourceFingerprint.toErrorResult() } ?: return OpenCronetDataSourceFingerprint.toErrorResult()
// hook override subtitles
SubtitleWindowSettingsConstructorFingerprint.result?.let {
it.mutableMethod.apply {
addInstructions(
0,
"""
invoke-static {p1, p2, p3, p4, p5}, $INTEGRATIONS_CLASS_DESCRIPTOR->getSubtitleWindowSettingsOverride(IIIZZ)[I
move-result-object v0
const/4 v1, 0x0
aget p1, v0, v1 # ap, anchor position
const/4 v1, 0x1
aget p2, v0, v1 # ah, horizontal anchor
const/4 v1, 0x2
aget p3, v0, v1 # av, vertical anchor
"""
)
}
} ?: return SubtitleWindowSettingsConstructorFingerprint.toErrorResult()
return PatchResultSuccess() return PatchResultSuccess()
} }

View File

@ -1,6 +1,8 @@
package app.revanced.patches.youtube.misc.integrations.fingerprints package app.revanced.patches.youtube.misc.integrations.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patches.shared.integrations.patch.AbstractIntegrationsPatch.IntegrationsFingerprint import app.revanced.patches.shared.integrations.patch.AbstractIntegrationsPatch.IntegrationsFingerprint
import org.jf.dexlib2.AccessFlags
/** /**
* Old API activity to embed YouTube into 3rd party Android apps. * Old API activity to embed YouTube into 3rd party Android apps.
@ -10,6 +12,9 @@ import app.revanced.patches.shared.integrations.patch.AbstractIntegrationsPatch.
* https://developers.google.com/youtube/android/player * https://developers.google.com/youtube/android/player
*/ */
object StandalonePlayerActivityFingerprint : IntegrationsFingerprint( object StandalonePlayerActivityFingerprint : IntegrationsFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
returnType = "V",
parameters = listOf("L"),
customFingerprint = { methodDef, _ -> customFingerprint = { methodDef, _ ->
methodDef.definingClass == "Lcom/google/android/youtube/api/StandalonePlayerActivity;" methodDef.definingClass == "Lcom/google/android/youtube/api/StandalonePlayerActivity;"
&& methodDef.name == "onCreate" && methodDef.name == "onCreate"

View File

@ -9,5 +9,5 @@ object ComponentContextParserFingerprint : MethodFingerprint(
Opcode.IPUT_OBJECT, Opcode.IPUT_OBJECT,
Opcode.NEW_INSTANCE Opcode.NEW_INSTANCE
), ),
strings = listOf("Component was not found %s because it was removed due to duplicate converter bindings") strings = listOf("Component was not found %s because it was removed due to duplicate converter bindings.")
) )

View File

@ -1,11 +1,13 @@
package app.revanced.patches.youtube.misc.litho.filter.fingerprints package app.revanced.patches.youtube.misc.litho.filter.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
object LithoFilterFingerprint : MethodFingerprint( object LithoFilterFingerprint : MethodFingerprint(
customFingerprint = custom@{ method, classDef -> accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC or AccessFlags.CONSTRUCTOR,
if (method.name != "<clinit>") return@custom false returnType = "V",
customFingerprint = { _, classDef ->
classDef.type.endsWith("LithoFilterPatch;") classDef.type.endsWith("LithoFilterPatch;")
} }
) )

View File

@ -1,13 +1,10 @@
package app.revanced.patches.youtube.misc.minimizedplayback.fingerprints package app.revanced.patches.youtube.misc.minimizedplayback.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value.
object MinimizedPlaybackManagerFingerprint : MethodFingerprint( object MinimizedPlaybackManagerFingerprint : MethodFingerprint(
"Z", "Z",
AccessFlags.PUBLIC or AccessFlags.STATIC, AccessFlags.PUBLIC or AccessFlags.STATIC,

View File

@ -1,16 +1,14 @@
package app.revanced.patches.youtube.misc.minimizedplayback.fingerprints package app.revanced.patches.youtube.misc.minimizedplayback.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
@FuzzyPatternScanMethod(2)
object MinimizedPlaybackSettingsFingerprint : MethodFingerprint( object MinimizedPlaybackSettingsFingerprint : MethodFingerprint(
"L", returnType = "L",
AccessFlags.PUBLIC or AccessFlags.FINAL, accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf(),
opcodes = listOf( opcodes = listOf(
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT, Opcode.MOVE_RESULT,

View File

@ -0,0 +1,14 @@
package app.revanced.patches.youtube.misc.minimizedplayback.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
/**
* Class fingerprint for [MinimizedPlaybackSettingsFingerprint]
*/
object MinimizedPlaybackSettingsParentFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
parameters = listOf("Landroid/content/Context;", "Landroid/support/v4/media/session/MediaSessionCompat"),
strings = listOf("sessionToken must not be null")
)

View File

@ -8,6 +8,7 @@ import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.data.toMethodWalker import app.revanced.patcher.data.toMethodWalker
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.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
@ -21,6 +22,7 @@ import app.revanced.patches.youtube.misc.minimizedplayback.annotations.Minimized
import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.KidsMinimizedPlaybackPolicyControllerFingerprint import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.KidsMinimizedPlaybackPolicyControllerFingerprint
import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.MinimizedPlaybackManagerFingerprint import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.MinimizedPlaybackManagerFingerprint
import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.MinimizedPlaybackSettingsFingerprint import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.MinimizedPlaybackSettingsFingerprint
import app.revanced.patches.youtube.misc.minimizedplayback.fingerprints.MinimizedPlaybackSettingsParentFingerprint
import app.revanced.patches.youtube.misc.playertype.patch.PlayerTypeHookPatch import app.revanced.patches.youtube.misc.playertype.patch.PlayerTypeHookPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import org.jf.dexlib2.iface.instruction.ReferenceInstruction import org.jf.dexlib2.iface.instruction.ReferenceInstruction
@ -35,7 +37,7 @@ import org.jf.dexlib2.iface.reference.MethodReference
class MinimizedPlaybackPatch : BytecodePatch( class MinimizedPlaybackPatch : BytecodePatch(
listOf( listOf(
MinimizedPlaybackManagerFingerprint, MinimizedPlaybackManagerFingerprint,
MinimizedPlaybackSettingsFingerprint, MinimizedPlaybackSettingsParentFingerprint,
KidsMinimizedPlaybackPolicyControllerFingerprint KidsMinimizedPlaybackPolicyControllerFingerprint
) )
) { ) {
@ -60,6 +62,8 @@ class MinimizedPlaybackPatch : BytecodePatch(
} ?: return MinimizedPlaybackManagerFingerprint.toErrorResult() } ?: return MinimizedPlaybackManagerFingerprint.toErrorResult()
// Enable minimized playback option in YouTube settings // Enable minimized playback option in YouTube settings
MinimizedPlaybackSettingsParentFingerprint.result ?: return MinimizedPlaybackSettingsParentFingerprint.toErrorResult()
MinimizedPlaybackSettingsFingerprint.resolve(context, MinimizedPlaybackSettingsParentFingerprint.result!!.classDef)
MinimizedPlaybackSettingsFingerprint.result?.apply { MinimizedPlaybackSettingsFingerprint.result?.apply {
val booleanCalls = method.implementation!!.instructions.withIndex() val booleanCalls = method.implementation!!.instructions.withIndex()
.filter { ((it.value as? ReferenceInstruction)?.reference as? MethodReference)?.returnType == "Z" } .filter { ((it.value as? ReferenceInstruction)?.reference as? MethodReference)?.returnType == "Z" }

View File

@ -5,42 +5,33 @@ import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
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.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
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.patches.shared.mapping.misc.patch.ResourceMappingPatch
import app.revanced.patches.youtube.misc.playercontrols.annotation.PlayerControlsCompatibility import app.revanced.patches.youtube.misc.playercontrols.annotation.PlayerControlsCompatibility
import app.revanced.patches.youtube.misc.playercontrols.fingerprints.BottomControlsInflateFingerprint import app.revanced.patches.youtube.misc.playercontrols.fingerprints.BottomControlsInflateFingerprint
import app.revanced.patches.youtube.misc.playercontrols.fingerprints.PlayerControlsVisibilityFingerprint import app.revanced.patches.youtube.misc.playercontrols.fingerprints.PlayerControlsVisibilityFingerprint
import app.revanced.patches.youtube.misc.playercontrols.resource.patch.BottomControlsResourcePatch
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
@Name("player-controls-bytecode-patch") @Name("player-controls-bytecode-patch")
@DependsOn([ResourceMappingPatch::class]) @DependsOn([BottomControlsResourcePatch::class])
@Description("Manages the code for the player controls of the YouTube player.") @Description("Manages the code for the player controls of the YouTube player.")
@PlayerControlsCompatibility @PlayerControlsCompatibility
@Version("0.0.1") @Version("0.0.1")
class PlayerControlsBytecodePatch : BytecodePatch( class PlayerControlsBytecodePatch : BytecodePatch(
listOf(PlayerControlsVisibilityFingerprint) listOf(PlayerControlsVisibilityFingerprint, BottomControlsInflateFingerprint)
) { ) {
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
showPlayerControlsFingerprintResult = PlayerControlsVisibilityFingerprint.result!! showPlayerControlsFingerprintResult = PlayerControlsVisibilityFingerprint.result!!
bottomUiContainerResourceId = ResourceMappingPatch
.resourceMappings
.single { it.type == "id" && it.name == "bottom_ui_container_stub" }.id
// TODO: another solution is required, this is hacky
listOf(BottomControlsInflateFingerprint).resolve(context, context.classes)
inflateFingerprintResult = BottomControlsInflateFingerprint.result!! inflateFingerprintResult = BottomControlsInflateFingerprint.result!!
return PatchResultSuccess() return PatchResultSuccess()
} }
internal companion object { internal companion object {
var bottomUiContainerResourceId: Long = 0
lateinit var showPlayerControlsFingerprintResult: MethodFingerprintResult lateinit var showPlayerControlsFingerprintResult: MethodFingerprintResult

View File

@ -1,21 +1,19 @@
package app.revanced.patches.youtube.misc.playercontrols.fingerprints package app.revanced.patches.youtube.misc.playercontrols.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.util.patch.LiteralValueFingerprint
import app.revanced.patches.youtube.misc.playercontrols.bytecode.patch.PlayerControlsBytecodePatch import app.revanced.patches.youtube.misc.playercontrols.resource.patch.BottomControlsResourcePatch
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
object BottomControlsInflateFingerprint : MethodFingerprint( object BottomControlsInflateFingerprint : LiteralValueFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL or AccessFlags.SYNTHETIC,
returnType = "L",
parameters = listOf(),
opcodes = listOf( opcodes = listOf(
Opcode.CHECK_CAST, Opcode.CHECK_CAST,
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT Opcode.MOVE_RESULT_OBJECT
), ),
customFingerprint = { methodDef, _ -> literal = BottomControlsResourcePatch.bottomUiContainerResourceId
methodDef.implementation?.instructions?.any { instruction ->
instruction.opcode.ordinal == Opcode.CONST.ordinal &&
(instruction as? WideLiteralInstruction)?.wideLiteral == PlayerControlsBytecodePatch.bottomUiContainerResourceId
} == true
}
) )

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