Compare commits

...

94 Commits

Author SHA1 Message Date
semantic-release-bot
96e7aed843 chore(release): 1.0.0-dev.9 [skip ci]
# [1.0.0-dev.9](https://github.com/revanced/revanced-patches/compare/v1.0.0-dev.8...v1.0.0-dev.9) (2022-05-13)

### Bug Fixes

* clean after building ([96f76b2](96f76b2eb5))
2022-05-13 18:11:26 +00:00
Sculas
96f76b2eb5 fix: clean after building 2022-05-13 20:10:09 +02:00
semantic-release-bot
f25c8d2cd1 chore(release): 1.0.0-dev.8 [skip ci]
# [1.0.0-dev.8](https://github.com/revanced/revanced-patches/compare/v1.0.0-dev.7...v1.0.0-dev.8) (2022-05-13)

### Bug Fixes

* publish releases ([fa3f6e2](fa3f6e2f33))
2022-05-13 18:07:43 +00:00
Sculas
fa3f6e2f33 fix: publish releases 2022-05-13 20:06:34 +02:00
semantic-release-bot
c2aa3b8365 chore(release): 1.0.0-dev.7 [skip ci]
# [1.0.0-dev.7](https://github.com/revanced/revanced-patches/compare/v1.0.0-dev.6...v1.0.0-dev.7) (2022-05-07)

### Bug Fixes

* use the latest version of patcher dependency ([e09f25c](e09f25cb75))
2022-05-07 19:43:22 +00:00
oSumAtrIX
e09f25cb75 fix: use the latest version of patcher dependency
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-05-07 21:42:18 +02:00
oSumAtrIX
0207d08c17 chore: bump project JDK to JDK 17
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-05-07 21:37:05 +02:00
oSumAtrIX
ae1127c02d Merge remote-tracking branch 'origin/dev' into dev 2022-05-07 21:26:40 +02:00
oSumAtrIX
e49fb3c969 chore: bump java-version for action setup-java
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-05-07 21:26:33 +02:00
semantic-release-bot
80462bbe1c chore(release): 1.0.0-dev.6 [skip ci]
# [1.0.0-dev.6](https://github.com/revanced/revanced-patches/compare/v1.0.0-dev.5...v1.0.0-dev.6) (2022-05-07)

### Bug Fixes

* update patches ([e6f3b3c](e6f3b3cd21))
2022-05-07 16:10:49 +00:00
oSumAtrIX
8043396ee4 Merge pull request #13 from revanced/patch-update
Update YouTube patches to `17.17.34`
2022-05-07 18:09:26 +02:00
oSumAtrIX
70bfd792bf Merge branch 'dev' into patch-update 2022-05-07 18:01:39 +02:00
oSumAtrIX
e6f3b3cd21 fix: update patches
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-05-07 17:50:22 +02:00
semantic-release-bot
364155f683 chore(release): 1.0.0-dev.5 [skip ci]
# [1.0.0-dev.5](https://github.com/revanced/revanced-patches/compare/v1.0.0-dev.4...v1.0.0-dev.5) (2022-05-07)

### Bug Fixes

* `enable-seekbar-tapping` patch ([af4d514](af4d514038))
* `Index` in wrong package ([0a57a1d](0a57a1d1c1))
* `minimized-playback` & `old-quality-layout` wrong opcodes ([c36c5f8](c36c5f80b4))
* `minimized-playback` patch ([cc558b3](cc558b35e9))
* `SignatureChecker` not handling nullable field `methodMetadata` ([c2e0e91](c2e0e918d0))
* accidentally removed code in refactor ([affd51d](affd51d2c1))
* add missing `trimIndent()` to string literals ([046d1f0](046d1f05f7))
* add missing opcode for `create-button-method` ([c3f5eec](c3f5eec804))
* attempt on all patches ([9e49e71](9e49e71364))
* breaking changes of the patcher ([acdb444](acdb44477c))
* breaking patcher changes ([923b0d9](923b0d9a01))
* disable `hide-suggestions-patch` patch until fixed ([fb4dc1d](fb4dc1dcfc))
* incorrect endIndex (fixed in Patcher) ([54196e7](54196e70ab))
* modified opcode for `show-video-ads-constructor` ([5cb333d](5cb333d769))
* multiple bugs in patches ([f4d25ae](f4d25aeea2))
* name for `IntegrationsPatch` ([2d1c3ee](2d1c3ee109))
* print instruction index of warning ([a63db11](a63db11046))
* remove `HideSuggestionsPatch` from `Index` ([0c16b51](0c16b51e93))
* signature checker with changes of patcher ([34449ab](34449abe41))
* tests failing ([51aeebe](51aeebe1e8))
* update `HomeAdsPatch` ([529fa1e](529fa1edff))
* version in package metadata of music ([c6dae56](c6dae56521))
* **VideoAds:** remove `istore1` opcode ([ba1103a](ba1103aca3))
* wrong access flag in signature for `Create button patch` ([2f2a0ff](2f2a0ff5e3))
* wrong opcode for `create-button-method` ([067d530](067d530901))
* wrong opcode pattern for `create-button-method` ([42253f0](42253f016a))
* wrong opcode pattern for `enable-seekbar-tapping-signature` ([38d77be](38d77be08b))
* wrong opcode pattern for signature in `Hide suggestions patch` ([51c45c6](51c45c636f))
* wrong patches in `upgrade-tab-remover` ([08b4294](08b4294f5e))
* wrong signature for `hide-reels-signature` ([9987679](9987679f66))
* wrong signatures for patch `Old Quality Layout Patch` ([d29329f](d29329fb32))
* wrong versions of patches ([89dcb56](89dcb56a9f))

### Features

* `hide-shorts-button` patch ([d6d6438](d6d6438110))
* `tastebuilder-remover` for music ([51a061f](51a061fe2d))
* Add (WIP) Signature Checker ([38761e8](38761e8e26))
* add home ads patch ([024ecb2](024ecb2fb0))
* added `codecs-unlock` patch ([5114ae1](5114ae1a2a))
* display metadata for each signature in `SignatureChecker` ([8b5d316](8b5d316ad3))
* get required register dynamically ([f65199c](f65199c028))
* integrations patch ([61554ce](61554ce809))
* migrate to dalvik patches ([d01658c](d01658c840))
* Patches for YouTube Music ([385c278](385c278e05))
* remove obsolete patch `Hide suggestions patch` ([9cb59b4](9cb59b44e3))
2022-05-07 03:36:21 +00:00
oSumAtrIX
24245b8d53 Merge pull request #2 from revanced/dalvik-patches
feat: migrate to Dalvik patches
2022-05-07 05:34:16 +02:00
oSumAtrIX
51aeebe1e8 fix: tests failing
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-05-07 05:31:29 +02:00
oSumAtrIX
6f72b84a32 Merge pull request #12 from autergame/dalvik-patches
Replace ReVancedTeam with revanced in build.gradle.kts
2022-05-07 05:23:42 +02:00
oSumAtrIX
2ea7ccdf43 Migrate to new organization 2022-05-07 01:23:58 +02:00
autergame
2aa5c2d611 Replace ReVancedTeam with revanced in build.gradle.kts 2022-05-06 20:22:28 -03:00
oSumAtrIX
34f6dcfc63 Merge pull request #11 from Iamlooker/dalvik-patches
fix: build broken by 5cf23a7
2022-05-06 16:50:58 +02:00
LooKeR
a182ff5bdb Fix build broken by 5cf23a7 2022-05-06 13:39:29 +05:30
oSumAtrIX
8242fde8f1 Merge pull request #8 from ReVancedTeam/migrate-to-resource-patcher
add: resource patcher
2022-05-04 23:57:59 +02:00
oSumAtrIX
923b0d9a01 fix: breaking patcher changes
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-05-04 23:52:50 +02:00
oSumAtrIX
98ce25d50f add: resource patcher
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-05-04 23:50:45 +02:00
oSumAtrIX
5cf23a72d2 Merge pull request #7 from ReVancedTeam/music-patches
feat: `YouTube Music` patches
2022-04-28 23:38:03 +02:00
epicsampler
7193575eee refactor: YouTube Music patches 2022-04-28 23:30:31 +02:00
epicsampler
51a061fe2d feat: tastebuilder-remover for music 2022-04-28 15:47:08 +00:00
epicsampler
c6dae56521 fix: version in package metadata of music 2022-04-28 15:02:57 +00:00
oSumAtrIX
08b4294f5e fix: wrong patches in upgrade-tab-remover
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-04-27 03:06:52 +02:00
epicsampler
5114ae1a2a feat: added codecs-unlock patch 2022-04-26 21:44:02 +00:00
oSumAtrIX
385c278e05 feat: Patches for YouTube Music
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-04-26 23:10:36 +02:00
oSumAtrIX
529fa1edff fix: update HomeAdsPatch
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-04-21 19:44:44 +02:00
oSumAtrIX
a80fc38b60 Merge pull request #4 from j4k0xb/dalvik-patches
feat: `hide-shorts-button` patch
2022-04-19 18:17:03 +02:00
j4k0xb
d6d6438110 feat: hide-shorts-button patch 2022-04-19 17:51:45 +02:00
oSumAtrIX
acdb44477c fix: breaking changes of the patcher 2022-04-18 18:41:26 +02:00
oSumAtrIX
1a3fed3b65 Merge remote-tracking branch 'origin/dalvik-patches' into dalvik-patches 2022-04-18 18:01:33 +02:00
oSumAtrIX
5877714361 refactor: remove .trimIndent() from each MethodSignatureMetadata description 2022-04-18 18:01:23 +02:00
oSumAtrIX
57f506dbfd add: HomePromoPatch (#3)
* add: `HomePromoPatch`

* fix: `HomePromoPatch` using the last signature in loop
2022-04-18 18:00:10 +02:00
oSumAtrIX
c2e0e918d0 fix: SignatureChecker not handling nullable field methodMetadata 2022-04-18 17:16:28 +02:00
oSumAtrIX
8b5d316ad3 feat: display metadata for each signature in SignatureChecker 2022-04-17 18:46:27 +02:00
oSumAtrIX
2d1c3ee109 fix: name for IntegrationsPatch 2022-04-17 18:45:38 +02:00
baiorett
89d5b08d85 Merge remote-tracking branch 'origin/dalvik-patches' into dalvik-patches 2022-04-16 23:52:08 +03:00
baiorett
024ecb2fb0 feat: add home ads patch 2022-04-16 23:46:40 +03:00
Lucaskyy
54196e70ab fix: incorrect endIndex (fixed in Patcher) 2022-04-16 21:42:02 +02:00
Lucaskyy
b67dec3294 revert: "fix: wrong signature for hide-reels-signature"
This reverts commit 22d8791ac6.
2022-04-15 21:32:17 +02:00
Lucaskyy
22d8791ac6 fix: wrong signature for hide-reels-signature 2022-04-15 11:55:58 +02:00
Lucaskyy
34449abe41 fix: signature checker with changes of patcher 2022-04-15 11:55:35 +02:00
oSumAtrIX
42253f016a fix: wrong opcode pattern for create-button-method 2022-04-15 06:31:15 +02:00
oSumAtrIX
89dcb56a9f fix: wrong versions of patches 2022-04-15 05:28:30 +02:00
oSumAtrIX
0c16b51e93 fix: remove HideSuggestionsPatch from Index 2022-04-15 04:58:11 +02:00
oSumAtrIX
d29329fb32 fix: wrong signatures for patch Old Quality Layout Patch 2022-04-15 04:57:51 +02:00
oSumAtrIX
9cb59b44e3 feat: remove obsolete patch Hide suggestions patch 2022-04-15 04:56:58 +02:00
oSumAtrIX
9987679f66 fix: wrong signature for hide-reels-signature 2022-04-15 04:56:17 +02:00
oSumAtrIX
38d77be08b fix: wrong opcode pattern for enable-seekbar-tapping-signature 2022-04-15 04:53:34 +02:00
oSumAtrIX
f65199c028 feat: get required register dynamically 2022-04-14 22:59:26 +02:00
Lucaskyy
a63db11046 fix: print instruction index of warning 2022-04-14 21:48:46 +02:00
Lucaskyy
78d1c97aa1 refactor: finalize Signature Checker 2022-04-14 21:47:43 +02:00
Lucaskyy
affd51d2c1 fix: accidentally removed code in refactor 2022-04-14 20:07:01 +02:00
Lucaskyy
067d530901 fix: wrong opcode for create-button-method
Added in latest(?) version of the app.
2022-04-14 20:00:45 +02:00
Lucaskyy
c46c150629 refactor: print surrounding opcodes of a warning 2022-04-14 19:58:55 +02:00
Lucaskyy
5cb333d769 fix: modified opcode for show-video-ads-constructor
Modified in latest(?) version of the app.
2022-04-14 19:58:24 +02:00
Lucaskyy
c3f5eec804 fix: add missing opcode for create-button-method
Added in latest(?) version of the app.
2022-04-14 19:57:00 +02:00
Lucaskyy
38761e8e26 feat: Add (WIP) Signature Checker 2022-04-14 19:19:43 +02:00
Lucaskyy
a55fa685f6 chore: upgrade Kotlin & add test library 2022-04-14 19:19:26 +02:00
Lucaskyy
c36c5f80b4 fix: minimized-playback & old-quality-layout wrong opcodes 2022-04-14 19:18:34 +02:00
Lucaskyy
9fa44443fa chore: clarify order of writing in EnableSeekbarTappingPatch.kt 2022-04-14 18:47:26 +02:00
Lucaskyy
858468dc1d refactor: remove all parameter names
also fixed some warnings.
2022-04-14 18:45:34 +02:00
Lucaskyy
dcc825088c Merge remote-tracking branch 'origin/dalvik-patches' into dalvik-patches 2022-04-14 12:13:38 +02:00
Lucaskyy
f073388b9a refactor: make patches compatible with breaking changes of the patcher
also commented HideSuggestionsPatch.kt so warnings suppressed
2022-04-14 12:11:24 +02:00
Lucaskyy
97e1b65900 refactor: replace Array with List 2022-04-14 11:58:25 +02:00
oSumAtrIX
046d1f05f7 fix: add missing trimIndent() to string literals
Co-authored-by: Sculas <contact@sculas.xyz>
2022-04-14 11:50:15 +02:00
oSumAtrIX
51c45c636f fix: wrong opcode pattern for signature in Hide suggestions patch 2022-04-14 11:01:25 +02:00
oSumAtrIX
2f2a0ff5e3 fix: wrong access flag in signature for Create button patch 2022-04-14 11:01:04 +02:00
oSumAtrIX
0a57a1d1c1 fix: Index in wrong package 2022-04-14 10:39:15 +02:00
oSumAtrIX
dc59fe1b22 refactor: make patches compatible with breaking changes of the patcher 2022-04-14 10:17:53 +02:00
oSumAtrIX
73a47dc3f6 refact: include each signature in its corresponding patch 2022-04-14 08:49:11 +02:00
Lucaskyy
d474d669e6 refactor: start migrating some signatures to Kotlin 2022-04-13 21:47:09 +02:00
Lucaskyy
ecacfd72e8 refactor: make patches compatible with the newest patcher 2022-04-13 21:25:50 +02:00
oSumAtrIX
fb4dc1dcfc fix: disable hide-suggestions-patch patch until fixed 2022-04-13 05:18:51 +02:00
oSumAtrIX
af4d514038 fix: enable-seekbar-tapping patch 2022-04-13 05:18:12 +02:00
oSumAtrIX
cc558b35e9 fix: minimized-playback patch 2022-04-13 00:16:20 +02:00
oSumAtrIX
ab234789cc refact: use kebab-case for VideoAds patch 2022-04-12 21:10:11 +02:00
oSumAtrIX
61554ce809 feat: integrations patch 2022-04-12 20:59:06 +02:00
Lucaskyy
65c6794a7c Merge remote-tracking branch 'origin/dalvik-patches' into dalvik-patches 2022-04-11 16:41:44 +02:00
Lucaskyy
051e80cc2b refactor: make patches compatible with the newest patcher 2022-04-11 16:41:29 +02:00
oSumAtrIX
f4d25aeea2 fix: multiple bugs in patches 2022-04-10 05:13:20 +02:00
Lucaskyy
95be597eab chore: publish and get from maven local 2022-04-10 00:51:24 +02:00
oSumAtrIX
9e49e71364 fix: attempt on all patches 2022-04-09 22:59:51 +02:00
oSumAtrIX
d01658c840 feat: migrate to dalvik patches 2022-04-07 22:41:55 +02:00
Lucaskyy
ba1103aca3 fix(VideoAds): remove istore1 opcode 2022-03-24 22:02:45 +01:00
semantic-release-bot
85236c57b8 chore(release): 1.0.0-dev.4 [skip ci]
# [1.0.0-dev.4](https://github.com/ReVancedTeam/revanced-patches/compare/v1.0.0-dev.3...v1.0.0-dev.4) (2022-03-22)

### Features

* use supplier instead of KClass ([bf2b2ae](bf2b2ae791))
* use supplier instead of KClass ([790c84a](790c84a00e))

### BREAKING CHANGES

* signature of patches was changed
* signature of patches was changed
2022-03-22 21:26:34 +00:00
Lucaskyy
bf2b2ae791 feat: use supplier instead of KClass
BREAKING CHANGE: signature of patches was changed
2022-03-22 22:24:56 +01:00
Lucaskyy
9e1dac57e7 Merge remote-tracking branch 'origin/dev' into dev
# Conflicts:
#	src/main/kotlin/app/revanced/patches/Index.kt
2022-03-22 22:23:57 +01:00
Lucaskyy
790c84a00e feat: use supplier instead of KClass
BREAKING CHANGE: signature of patches was changed
2022-03-22 22:22:46 +01:00
33 changed files with 3795 additions and 305 deletions

View File

@@ -20,7 +20,7 @@ jobs:
- name: Setup JDK
uses: actions/setup-java@v2
with:
java-version: '8'
java-version: '17'
distribution: 'adopt'
cache: gradle
- name: Setup Node.js
@@ -32,7 +32,7 @@ jobs:
- name: Build with Gradle
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./gradlew build
run: ./gradlew build clean
- name: Setup semantic-release
run: npm install -g semantic-release @semantic-release/git @semantic-release/changelog gradle-semantic-release-plugin -D
- name: Release

5
.gitignore vendored
View File

@@ -111,4 +111,7 @@ gradle-app.setting
.gradletasknamecache
# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898
# gradle/wrapper/gradle-wrapper.properties
# gradle/wrapper/gradle-wrapper.properties
# Potentially copyrighted test APK
*.apk

2
.idea/misc.xml generated
View File

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

View File

@@ -20,6 +20,15 @@
]
}
],
"@semantic-release/github"
[
"@semantic-release/github",
{
"assets": [
{
"path": "build/libs/*.jar"
}
]
}
]
]
}

View File

@@ -1,3 +1,98 @@
# [1.0.0-dev.9](https://github.com/revanced/revanced-patches/compare/v1.0.0-dev.8...v1.0.0-dev.9) (2022-05-13)
### Bug Fixes
* clean after building ([a2df3fb](https://github.com/revanced/revanced-patches/commit/a2df3fbc9761b07f3010542fa8684ade00e4dc91))
# [1.0.0-dev.8](https://github.com/revanced/revanced-patches/compare/v1.0.0-dev.7...v1.0.0-dev.8) (2022-05-13)
### Bug Fixes
* publish releases ([83916f9](https://github.com/revanced/revanced-patches/commit/83916f96d27989dcbb35c0ba6ef326a16b470501))
# [1.0.0-dev.7](https://github.com/revanced/revanced-patches/compare/v1.0.0-dev.6...v1.0.0-dev.7) (2022-05-07)
### Bug Fixes
* use the latest version of patcher dependency ([fe4a439](https://github.com/revanced/revanced-patches/commit/fe4a439cb2bc5e385ae13e8e155f25bb15e74633))
# [1.0.0-dev.6](https://github.com/revanced/revanced-patches/compare/v1.0.0-dev.5...v1.0.0-dev.6) (2022-05-07)
### Bug Fixes
* update patches ([91b8ec8](https://github.com/revanced/revanced-patches/commit/91b8ec81f33417798546c32db708fe09ada3930c))
# [1.0.0-dev.5](https://github.com/revanced/revanced-patches/compare/v1.0.0-dev.4...v1.0.0-dev.5) (2022-05-07)
### Bug Fixes
* `enable-seekbar-tapping` patch ([52fd726](https://github.com/revanced/revanced-patches/commit/52fd726d9b0d2efbd0f9742fc84ad01ccdcff168))
* `Index` in wrong package ([2f9360f](https://github.com/revanced/revanced-patches/commit/2f9360f57cc8415564534fbbd8bd5e2a83a1b629))
* `minimized-playback` & `old-quality-layout` wrong opcodes ([b45d175](https://github.com/revanced/revanced-patches/commit/b45d175c6f1ece6da894ab16128c2644d262c9c7))
* `minimized-playback` patch ([55677a4](https://github.com/revanced/revanced-patches/commit/55677a44ff965c0b92c3f1d771bd68c12c142ad4))
* `SignatureChecker` not handling nullable field `methodMetadata` ([17bcf78](https://github.com/revanced/revanced-patches/commit/17bcf786a85ccf1f7d9f5a66a044a3c26def09bb))
* accidentally removed code in refactor ([0077e26](https://github.com/revanced/revanced-patches/commit/0077e26d23cc112b671a41614a55348fac2c88ca))
* add missing `trimIndent()` to string literals ([76d3c71](https://github.com/revanced/revanced-patches/commit/76d3c71b67edebd79f2cdb1bb28e4d2969d72223))
* add missing opcode for `create-button-method` ([0a398ef](https://github.com/revanced/revanced-patches/commit/0a398ef364f91a0dd9608df1a036a2515476ccf2))
* attempt on all patches ([3395d69](https://github.com/revanced/revanced-patches/commit/3395d69747103a4bdf314297aa0bfa6ef6a0fc36))
* breaking changes of the patcher ([1a49bbd](https://github.com/revanced/revanced-patches/commit/1a49bbdbc4ff6f427934259536218e161908b449))
* breaking patcher changes ([581d1b0](https://github.com/revanced/revanced-patches/commit/581d1b0ca7d15adcdb1ab6116ef035acfe701757))
* disable `hide-suggestions-patch` patch until fixed ([99099ea](https://github.com/revanced/revanced-patches/commit/99099ea0bc12f5f25896967db642442df69d0c4f))
* incorrect endIndex (fixed in Patcher) ([424788e](https://github.com/revanced/revanced-patches/commit/424788edd777110cdaff97500556d18628f33385))
* modified opcode for `show-video-ads-constructor` ([a0dcea3](https://github.com/revanced/revanced-patches/commit/a0dcea3a13f68cae449dfaf445b542e339c83ff0))
* multiple bugs in patches ([e37201d](https://github.com/revanced/revanced-patches/commit/e37201d0ceef474696857a0d8845950c888194d0))
* name for `IntegrationsPatch` ([e46ef02](https://github.com/revanced/revanced-patches/commit/e46ef02302825d62b57912b2747a25f858036bb7))
* print instruction index of warning ([9e29aee](https://github.com/revanced/revanced-patches/commit/9e29aeeeff222412f6c45cf7e4879f8ec53ca6ee))
* remove `HideSuggestionsPatch` from `Index` ([f32e474](https://github.com/revanced/revanced-patches/commit/f32e4747b512c675b807ff5eebfd0b8e66173fba))
* signature checker with changes of patcher ([e82459d](https://github.com/revanced/revanced-patches/commit/e82459d37759e1a5a860d3e7fcdf69d95b06858e))
* tests failing ([102793f](https://github.com/revanced/revanced-patches/commit/102793f24f8bf7c7fd254968b29d65da7b2b962f))
* update `HomeAdsPatch` ([62f1801](https://github.com/revanced/revanced-patches/commit/62f1801e9cbee53c0be3413c245161bd941e4aec))
* version in package metadata of music ([b299205](https://github.com/revanced/revanced-patches/commit/b299205aa7cde82f1f55fc598de3ff8d80b8bcb0))
* **VideoAds:** remove `istore1` opcode ([dc4ec57](https://github.com/revanced/revanced-patches/commit/dc4ec574414c5df959efa0ca8f1cd39a812fedf8))
* wrong access flag in signature for `Create button patch` ([9fbb89d](https://github.com/revanced/revanced-patches/commit/9fbb89d05336a256a0759eea6095e073946c45e5))
* wrong opcode for `create-button-method` ([3214650](https://github.com/revanced/revanced-patches/commit/32146506f139aebc44cd5faffb7706b8b9c21c3d))
* wrong opcode pattern for `create-button-method` ([f4d8a85](https://github.com/revanced/revanced-patches/commit/f4d8a8525bc64b90748b21979d463977a21dcd85))
* wrong opcode pattern for `enable-seekbar-tapping-signature` ([1d83395](https://github.com/revanced/revanced-patches/commit/1d833957ed3e01188770c85e3d84e483419bd797))
* wrong opcode pattern for signature in `Hide suggestions patch` ([535aee0](https://github.com/revanced/revanced-patches/commit/535aee08408b990c80f5966c13fa84666a8b35d0))
* wrong patches in `upgrade-tab-remover` ([5182290](https://github.com/revanced/revanced-patches/commit/518229031ceca049ad790f7b77b19405d39f0ce1))
* wrong signature for `hide-reels-signature` ([2d9ff2a](https://github.com/revanced/revanced-patches/commit/2d9ff2af0a991d7721f3741187716a3b08bb4029))
* wrong signatures for patch `Old Quality Layout Patch` ([823e503](https://github.com/revanced/revanced-patches/commit/823e503d84037bdf27b09f17e63383f963c76854))
* wrong versions of patches ([a112b22](https://github.com/revanced/revanced-patches/commit/a112b22ce6e685204caab6f95f511e26ef95806b))
### Features
* `hide-shorts-button` patch ([88352ee](https://github.com/revanced/revanced-patches/commit/88352ee6ecd23faa4a7fd9f7495e67fa1d3e33bd))
* `tastebuilder-remover` for music ([a6aeca3](https://github.com/revanced/revanced-patches/commit/a6aeca31bd80b8c4a8acd071e22faca6e136bdb0))
* Add (WIP) Signature Checker ([ae4c7b2](https://github.com/revanced/revanced-patches/commit/ae4c7b29f211c461de460f97f3a8656e795adafb))
* add home ads patch ([36cddd1](https://github.com/revanced/revanced-patches/commit/36cddd1488683e19e2b927e34c80a4f0f3cace35))
* added `codecs-unlock` patch ([e5fd7ce](https://github.com/revanced/revanced-patches/commit/e5fd7cece94b1ff5342178f59b29576db806e0f6))
* display metadata for each signature in `SignatureChecker` ([736a71f](https://github.com/revanced/revanced-patches/commit/736a71fac21a32dbb1eef9c3a9f0d3005e7d9ca0))
* get required register dynamically ([0924ca2](https://github.com/revanced/revanced-patches/commit/0924ca2ad30ae865dcc0fd484cb0da517e827352))
* integrations patch ([19c0b0d](https://github.com/revanced/revanced-patches/commit/19c0b0d194bb97c7248ea7a9b081176961653b9d))
* migrate to dalvik patches ([e088c67](https://github.com/revanced/revanced-patches/commit/e088c671081bcf75586ccc1c4bdbed9366e93874))
* Patches for YouTube Music ([b60c9d3](https://github.com/revanced/revanced-patches/commit/b60c9d33b611bb4d5b55bb419652bc14b0309792))
* remove obsolete patch `Hide suggestions patch` ([e65c6f2](https://github.com/revanced/revanced-patches/commit/e65c6f240ed23a54271d20a90fc57ec65cafc02d))
# [1.0.0-dev.4](https://github.com/ReVancedTeam/revanced-patches/compare/v1.0.0-dev.3...v1.0.0-dev.4) (2022-03-22)
### Features
* use supplier instead of KClass ([08af6e5](https://github.com/ReVancedTeam/revanced-patches/commit/08af6e54af79ef9ef4fb3372a348ce9b6fba4d20))
* use supplier instead of KClass ([91aa019](https://github.com/ReVancedTeam/revanced-patches/commit/91aa019f8d3d87fbf7affeb7abc2b02ba87af5c3))
### BREAKING CHANGES
* signature of patches was changed
* signature of patches was changed
# [1.0.0-dev.3](https://github.com/ReVancedTeam/revanced-patches/compare/v1.0.0-dev.2...v1.0.0-dev.3) (2022-03-21)

View File

@@ -1,5 +1,5 @@
plugins {
kotlin("jvm") version "1.6.10"
kotlin("jvm") version "1.6.20"
java
`maven-publish`
}
@@ -8,8 +8,9 @@ group = "app.revanced"
repositories {
mavenCentral()
mavenLocal()
maven {
url = uri("https://maven.pkg.github.com/ReVancedTeam/revanced-patcher") // note the "r"!
url = uri("https://maven.pkg.github.com/revanced/revanced-patcher") // note the "r"!
credentials {
// DO NOT set these variables in the project's gradle.properties.
// Instead, you should set them in:
@@ -22,14 +23,10 @@ repositories {
}
dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib:1.6.10")
implementation(kotlin("stdlib"))
testImplementation(kotlin("test"))
implementation("org.ow2.asm:asm:9.2")
implementation("org.ow2.asm:asm-util:9.2")
implementation("org.ow2.asm:asm-tree:9.2")
implementation("org.ow2.asm:asm-commons:9.2")
implementation("app.revanced:revanced-patcher:1.+") // use latest version.
implementation("app.revanced:revanced-patcher:1.+")
}
java {
@@ -37,15 +34,21 @@ java {
withJavadocJar()
}
val isGitHubCI = System.getenv("GITHUB_ACTOR") != null
publishing {
repositories {
maven {
name = "GitHubPackages"
url = uri("https://maven.pkg.github.com/ReVancedTeam/revanced-patches") // note the "s"!
credentials {
username = System.getenv("GITHUB_ACTOR")
password = System.getenv("GITHUB_TOKEN")
if (isGitHubCI) {
maven {
name = "GitHubPackages"
url = uri("https://maven.pkg.github.com/revanced/revanced-patches") // note the "s"!
credentials {
username = System.getenv("GITHUB_ACTOR")
password = System.getenv("GITHUB_TOKEN")
}
}
} else {
mavenLocal()
}
}
publications {
@@ -53,4 +56,4 @@ publishing {
from(components["java"])
}
}
}
}

View File

@@ -1,2 +1,2 @@
kotlin.code.style = official
version = 1.0.0-dev.3
version = 1.0.0-dev.9

View File

@@ -0,0 +1,14 @@
package app.revanced.extensions
import app.revanced.patcher.smali.toInstruction
import org.jf.dexlib2.builder.MutableMethodImplementation
internal fun MutableMethodImplementation.injectHideCall(
index: Int,
register: Int
) {
this.addInstruction(
index,
"invoke-static { v$register }, Lfi/razerman/youtube/XAdRemover;->HideView(Landroid/view/View;)V".toInstruction()
)
}

View File

@@ -1,13 +1,21 @@
package app.revanced.patches
import app.revanced.patcher.patch.Patch
import app.revanced.patches.ad.VideoAds
import app.revanced.patches.interaction.EnableSeekbarTapping
import app.revanced.patches.layout.*
import kotlin.reflect.KClass
import app.revanced.patcher.data.base.Data
import app.revanced.patcher.patch.base.Patch
import app.revanced.patches.music.audio.CodecsUnlockPatch
import app.revanced.patches.music.audio.EnableAudioOnlyPatch
import app.revanced.patches.music.layout.RemoveTasteBuilderPatch
import app.revanced.patches.music.layout.RemoveUpgradeTabPatch
import app.revanced.patches.music.premium.BackgroundPlayPatch
import app.revanced.patches.youtube.ad.HomePromoPatch
import app.revanced.patches.youtube.ad.VideoAdsPatch
import app.revanced.patches.youtube.interaction.EnableSeekbarTappingPatch
import app.revanced.patches.youtube.layout.*
import app.revanced.patches.youtube.misc.FixLocaleConfigErrorPatch
import app.revanced.patches.youtube.misc.IntegrationsPatch
/**
* Index contains all the patches and should be imported when using this library.
* Index contains all the patches.
*/
@Suppress("Unused")
object Index {
@@ -15,13 +23,22 @@ object Index {
* Array of patches.
* New patches should be added to the array.
*/
val patches: Array<KClass<out Patch>> = arrayOf(
VideoAds::class,
MinimizedPlayback::class,
CreateButtonRemover::class,
HideReels::class,
HideSuggestions::class,
OldQualityLayout::class,
EnableSeekbarTapping::class
val patches: List<() -> Patch<Data>> = listOf(
::IntegrationsPatch,
::FixLocaleConfigErrorPatch,
//::HomeAdsPatch,
::VideoAdsPatch,
::HomePromoPatch,
::MinimizedPlaybackPatch,
::CreateButtonRemoverPatch,
::ShortsButtonRemoverPatch,
::HideReelsPatch,
::OldQualityLayoutPatch,
::EnableSeekbarTappingPatch,
::EnableAudioOnlyPatch,
::RemoveUpgradeTabPatch,
::RemoveTasteBuilderPatch,
::BackgroundPlayPatch,
::CodecsUnlockPatch
)
}
}

View File

@@ -1,41 +0,0 @@
package app.revanced.patches.ad
import app.revanced.patcher.cache.Cache
import app.revanced.patcher.patch.Patch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.signature.Signature
import app.revanced.patcher.writer.ASMWriter.insertAt
import org.objectweb.asm.Opcodes
import org.objectweb.asm.Type
import org.objectweb.asm.tree.MethodInsnNode
import org.objectweb.asm.tree.VarInsnNode
class VideoAds : Patch("VideoAds") {
override fun execute(cache: Cache): PatchResult {
val showVideoAdsMethodData = cache.methods["show-video-ads"].findParentMethod(
Signature(
"method",
Type.VOID_TYPE,
Opcodes.ACC_PUBLIC or Opcodes.ACC_FINAL,
arrayOf(Type.BOOLEAN_TYPE),
null
)
) ?: return PatchResultError("Could not find required method to patch")
showVideoAdsMethodData.method.instructions.insertAt(
0,
VarInsnNode(Opcodes.ISTORE, 1),
MethodInsnNode(
Opcodes.INVOKESTATIC,
"fi/vanced/libraries/youtube/whitelisting/Whitelist",
"shouldShowAds",
Type.getMethodDescriptor(Type.BOOLEAN_TYPE)
)
)
return PatchResultSuccess()
}
}

View File

@@ -1,49 +0,0 @@
package app.revanced.patches.interaction
import app.revanced.patcher.cache.Cache
import app.revanced.patcher.patch.Patch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.writer.ASMWriter.insertAt
import org.objectweb.asm.Opcodes
import org.objectweb.asm.tree.*
class EnableSeekbarTapping : Patch("enable-seekbar-tapping") {
override fun execute(cache: Cache): PatchResult {
val patchData = cache.methods["enable-seekbar-tapping"]
val methodOPatchData = cache.methods["enable-seekbar-tapping-method-o"]
val methodPPatchData = cache.methods["enable-seekbar-tapping-method-p"]
val elseLabel = LabelNode()
patchData.method.instructions.insertAt(
patchData.scanData.endIndex,
InsnNode(Opcodes.ACONST_NULL),
MethodInsnNode(
Opcodes.INVOKESTATIC,
"fi/razerman/youtube/preferences/BooleanPreferences",
"isTapSeekingEnabled",
"()Z"
),
JumpInsnNode(Opcodes.IFEQ, elseLabel),
VarInsnNode(Opcodes.ALOAD, 0),
VarInsnNode(Opcodes.ILOAD, 6),
MethodInsnNode(
Opcodes.INVOKEVIRTUAL,
methodOPatchData.declaringClass.name,
methodOPatchData.method.name,
"(I)V"
),
VarInsnNode(Opcodes.ALOAD, 0),
VarInsnNode(Opcodes.ILOAD, 6),
MethodInsnNode(
Opcodes.INVOKEVIRTUAL,
methodPPatchData.declaringClass.name,
methodPPatchData.method.name,
"(I)V"
),
elseLabel
)
return PatchResultSuccess()
}
}

View File

@@ -1,32 +0,0 @@
package app.revanced.patches.layout
import app.revanced.patcher.cache.Cache
import app.revanced.patcher.patch.Patch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.writer.ASMWriter.insertAt
import org.objectweb.asm.Opcodes
import org.objectweb.asm.tree.MethodInsnNode
import org.objectweb.asm.tree.VarInsnNode
class CreateButtonRemover : Patch("create-button-remover") {
override fun execute(cache: Cache): PatchResult {
val patchData = cache.methods["create-button-patch"]
patchData.method.instructions.insertAt(
patchData.scanData.endIndex - 1,
VarInsnNode(
Opcodes.ALOAD,
6
),
MethodInsnNode(
Opcodes.INVOKESTATIC,
"fi/razerman/youtube/XAdRemover",
"hideCreateButton",
"(Landroid/view/View;)V"
)
)
return PatchResultSuccess()
}
}

View File

@@ -1,29 +0,0 @@
package app.revanced.patches.layout
import app.revanced.patcher.cache.Cache
import app.revanced.patcher.patch.Patch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.writer.ASMWriter.insertAt
import org.objectweb.asm.Opcodes
import org.objectweb.asm.tree.MethodInsnNode
import org.objectweb.asm.tree.VarInsnNode
class HideReels : Patch("hide-reels") {
override fun execute(cache: Cache): PatchResult {
val patchData = cache.methods["hide-reel-patch"]
patchData.method.instructions.insertAt(
patchData.scanData.endIndex + 1,
VarInsnNode(Opcodes.ALOAD, 18),
MethodInsnNode(
Opcodes.INVOKESTATIC,
"fi/razerman/youtube/XAdRemover",
"HideReels",
"(Landroid/view/View;)V"
)
)
return PatchResultSuccess()
}
}

View File

@@ -1,52 +0,0 @@
package app.revanced.patches.layout
import app.revanced.patcher.cache.Cache
import app.revanced.patcher.patch.Patch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.signature.Signature
import app.revanced.patcher.writer.ASMWriter.insertAt
import org.objectweb.asm.Opcodes
import org.objectweb.asm.Type
import org.objectweb.asm.tree.MethodInsnNode
import org.objectweb.asm.tree.VarInsnNode
class HideSuggestions : Patch("hide-suggestions") {
override fun execute(cache: Cache): PatchResult {
val method = cache.methods["hide-suggestions-patch"].findParentMethod(
Signature(
"hide-suggestions-method",
Type.VOID_TYPE,
Opcodes.ACC_PUBLIC or Opcodes.ACC_FINAL,
arrayOf(Type.BOOLEAN_TYPE),
arrayOf(
Opcodes.ALOAD,
Opcodes.ILOAD,
Opcodes.PUTFIELD,
Opcodes.ALOAD,
Opcodes.GETFIELD
)
)
) ?: return PatchResultError("Parent method hide-suggestions-method has not been found")
method.method.instructions.insertAt(
0,
VarInsnNode(Opcodes.ILOAD, 1),
MethodInsnNode(
Opcodes.INVOKESTATIC,
"java/lang/Boolean",
"valueOf",
"(Z)Ljava/lang/Boolean"
),
MethodInsnNode(
Opcodes.INVOKESTATIC,
"fi/razerman/youtube/XAdRemover",
"HideReels",
"(Landroid/view/View;)V"
)
)
return PatchResultSuccess()
}
}

View File

@@ -1,13 +0,0 @@
package app.revanced.patches.layout
import app.revanced.patcher.cache.Cache
import app.revanced.patcher.patch.Patch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
class MinimizedPlayback : Patch("minimized-playback") {
override fun execute(cache: Cache): PatchResult {
cache.methods["minimized-playback-manager"].method.instructions.clear()
return PatchResultSuccess()
}
}

View File

@@ -1,52 +0,0 @@
package app.revanced.patches.layout
import app.revanced.patcher.cache.Cache
import app.revanced.patcher.patch.Patch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.signature.Signature
import app.revanced.patcher.util.ExtraTypes
import app.revanced.patcher.writer.ASMWriter.insertAt
import org.objectweb.asm.Opcodes
import org.objectweb.asm.tree.JumpInsnNode
import org.objectweb.asm.tree.MethodInsnNode
import org.objectweb.asm.tree.VarInsnNode
class OldQualityLayout : Patch("old-quality-restore") {
override fun execute(cache: Cache): PatchResult {
val method = cache.methods["old-quality-patch"].findParentMethod(
Signature(
"old-quality-patch-method",
ExtraTypes.Any,
Opcodes.ACC_PUBLIC or Opcodes.ACC_FINAL,
arrayOf(),
arrayOf(
Opcodes.ALOAD,
Opcodes.GETFIELD,
Opcodes.ISTORE,
Opcodes.ICONST_3,
Opcodes.ISTORE
)
)
) ?: return PatchResultError("Parent method old-quality-patch-method has not been found")
method.method.instructions.insertAt(
0,
MethodInsnNode(
Opcodes.INVOKESTATIC,
"fi/razerman/youtube/XGlobals",
"useOldStyleQualitySettings",
"()Z"
),
VarInsnNode(Opcodes.ISTORE, 1),
VarInsnNode(Opcodes.ILOAD, 1),
JumpInsnNode(
Opcodes.IFNE,
(method.method.instructions[method.scanData.endIndex + 3] as JumpInsnNode).label
),
)
return PatchResultSuccess()
}
}

View File

@@ -0,0 +1,157 @@
package app.revanced.patches.music.audio
import app.revanced.patcher.data.implementation.BytecodeData
import app.revanced.patcher.data.implementation.toMethodWalker
import app.revanced.patcher.extensions.or
import app.revanced.patcher.patch.implementation.BytecodePatch
import app.revanced.patcher.patch.implementation.metadata.PackageMetadata
import app.revanced.patcher.patch.implementation.metadata.PatchMetadata
import app.revanced.patcher.patch.implementation.misc.PatchResult
import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess
import app.revanced.patcher.signature.MethodMetadata
import app.revanced.patcher.signature.MethodSignature
import app.revanced.patcher.signature.MethodSignatureMetadata
import app.revanced.patcher.signature.PatternScanMethod
import app.revanced.patcher.smali.toInstruction
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
private val packageMetadata = listOf(
PackageMetadata(
"com.google.android.apps.youtube.music",
listOf("5.03.50")
)
)
private val patchMetadata = PatchMetadata(
"codecs-unlock",
"Audio codecs unlock patch",
"Enables more audio codecs. Usually results in better audio quality but may depend on song and device.",
packageMetadata,
"0.0.1"
)
class CodecsUnlockPatch : BytecodePatch(
patchMetadata,
listOf(
MethodSignature(
MethodSignatureMetadata(
"codec-lock-method",
MethodMetadata(
"Labwj;",
"a",
),
PatternScanMethod.Fuzzy(2),// FIXME: Test this threshold and find the best value.
packageMetadata,
"Required signature for ${patchMetadata.name}. Discovered in version 5.03.50.",
"0.0.1"
),
"L",
AccessFlags.PUBLIC or AccessFlags.STATIC,
listOf("L", "L", "L", "L"),
listOf(
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_DIRECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IF_NEZ,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IF_NEZ,
Opcode.SGET,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IF_NEZ,
Opcode.SGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
Opcode.INVOKE_INTERFACE,
Opcode.INVOKE_DIRECT,
Opcode.RETURN_OBJECT
)
),
MethodSignature(
MethodSignatureMetadata(
"all-codecs-reference-method",
MethodMetadata(
"Laari;",
"b",
),
PatternScanMethod.Fuzzy(2),// FIXME: Test this threshold and find the best value.
packageMetadata,
"Required signature for ${patchMetadata.name}. Discovered in version 5.03.50.",
"0.0.1"
),
"J",
AccessFlags.PUBLIC or AccessFlags.FINAL,
listOf("L"),
listOf(
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT,
Opcode.CONST_4,
Opcode.IF_EQZ,
Opcode.IGET_BOOLEAN,
Opcode.IF_NEZ,
Opcode.IGET_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.IPUT_BOOLEAN,
Opcode.IGET_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.GOTO,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT,
Opcode.IF_NEZ,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT,
Opcode.IF_EQZ,
Opcode.IGET_BOOLEAN,
Opcode.IF_NEZ,
Opcode.IGET_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.IPUT_BOOLEAN,
Opcode.IGET_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.GOTO,
Opcode.MOVE_EXCEPTION,
Opcode.INVOKE_SUPER,
Opcode.MOVE_RESULT_WIDE,
Opcode.RETURN_WIDE
),
listOf("itag")
)
)
) {
override fun execute(data: BytecodeData): PatchResult {
var result = signatures.first().result!!
val implementation = result.method.implementation!!
val instructionIndex = result.scanData.startIndex
result = signatures.last().result!!
val codecMethod = data
.toMethodWalker(result.immutableMethod)
.walk(result.scanData.startIndex)
.getMethod()
implementation.replaceInstruction(
instructionIndex,
"invoke-static {}, ${codecMethod.definingClass}->${codecMethod.name}()Ljava/util/Set;".toInstruction()
)
return PatchResultSuccess()
}
}

View File

@@ -0,0 +1,133 @@
package app.revanced.patches.music.audio
import app.revanced.patcher.data.implementation.BytecodeData
import app.revanced.patcher.extensions.or
import app.revanced.patcher.patch.implementation.BytecodePatch
import app.revanced.patcher.patch.implementation.metadata.PackageMetadata
import app.revanced.patcher.patch.implementation.metadata.PatchMetadata
import app.revanced.patcher.patch.implementation.misc.PatchResult
import app.revanced.patcher.patch.implementation.misc.PatchResultError
import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess
import app.revanced.patcher.signature.MethodMetadata
import app.revanced.patcher.signature.MethodSignature
import app.revanced.patcher.signature.MethodSignatureMetadata
import app.revanced.patcher.signature.PatternScanMethod
import app.revanced.patcher.smali.toInstruction
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
private val compatiblePackages = listOf(
PackageMetadata(
"com.google.android.apps.youtube.music",
listOf("5.03.50")
)
)
class EnableAudioOnlyPatch : BytecodePatch(
PatchMetadata(
"audio-only-playback-patch",
"Audio Only Mode Patch",
"Add the option to play music without video.",
compatiblePackages,
"0.0.1"
),
listOf(
MethodSignature(
MethodSignatureMetadata(
"audio-only-method-signature",
MethodMetadata("Lgmd;", "c"),
PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value.
compatiblePackages,
"Signature for the method required to be patched.",
"0.0.1"
),
"V",
AccessFlags.PUBLIC or AccessFlags.FINAL,
listOf("L", "Z"),
listOf(
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IF_EQ,
Opcode.CONST_4,
Opcode.GOTO,
Opcode.NOP,
Opcode.IGET_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT,
Opcode.IF_EQZ,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
Opcode.IF_EQZ,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
Opcode.IF_EQZ,
Opcode.IF_EQZ,
Opcode.INVOKE_INTERFACE,
Opcode.INVOKE_INTERFACE,
Opcode.GOTO,
Opcode.RETURN_VOID
)
)
)
) {
override fun execute(data: BytecodeData): PatchResult {
val result = signatures.first().result!!.findParentMethod(
MethodSignature(
MethodSignatureMetadata(
"audio-only-enabler-method",
MethodMetadata("Lgmd;", "d"),
PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value.
compatiblePackages,
"Signature for the method required to be patched.",
"0.0.1"
),
"Z",
AccessFlags.PUBLIC or AccessFlags.FINAL,
listOf(),
listOf(
Opcode.IGET_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IGET_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
Opcode.IF_NEZ,
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.GOTO,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.RETURN
)
)
) ?: return PatchResultError("Required method for ${metadata.shortName} not found.")
val implementation = result.method.implementation!!
implementation.replaceInstruction(
implementation.instructions.count() - 1,
"const/4 v0, 0x1".toInstruction()
)
implementation.addInstruction(
"return v0".toInstruction()
)
return PatchResultSuccess()
}
}

View File

@@ -0,0 +1,94 @@
package app.revanced.patches.music.layout
import app.revanced.patcher.data.implementation.BytecodeData
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.or
import app.revanced.patcher.patch.implementation.BytecodePatch
import app.revanced.patcher.patch.implementation.metadata.PackageMetadata
import app.revanced.patcher.patch.implementation.metadata.PatchMetadata
import app.revanced.patcher.patch.implementation.misc.PatchResult
import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess
import app.revanced.patcher.signature.MethodMetadata
import app.revanced.patcher.signature.MethodSignature
import app.revanced.patcher.signature.MethodSignatureMetadata
import app.revanced.patcher.signature.PatternScanMethod
import app.revanced.patcher.smali.toInstructions
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.formats.Instruction22c
private val compatiblePackages = listOf(
PackageMetadata(
"com.google.android.apps.youtube.music",
listOf("5.03.50")
)
)
class RemoveTasteBuilderPatch : BytecodePatch(
PatchMetadata(
"tasteBuilder-remover",
"Remove TasteBuilder Patch",
"Removes the \"Tell us which artists you like\" card from the Home screen. The same functionality can be triggered from the settings anyway.",
compatiblePackages,
"0.0.1"
),
listOf(
MethodSignature(
MethodSignatureMetadata(
"taste-builder-constructor",
MethodMetadata("Lkyu;", "<init>"),
PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value.
compatiblePackages,
"Required signature for this patch.",
"0.0.1"
),
"V",
AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
listOf("L", "L", "L", "L"),
listOf(
Opcode.INVOKE_DIRECT,
Opcode.INVOKE_VIRTUAL,
Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT,
Opcode.IPUT_OBJECT,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CONST,
Opcode.CONST_4,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.CONST,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
Opcode.IPUT_OBJECT,
Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT,
Opcode.IPUT_OBJECT
)
)
)
) {
override fun execute(data: BytecodeData): PatchResult {
val result = signatures.first().result!!
val implementation = result.method.implementation!!
val insertIndex = result.scanData.endIndex - 8
val register = (implementation.instructions[insertIndex] as Instruction22c).registerA
val instructionList =
"""
const/16 v1, 0x8
invoke-virtual {v${register}, v1}, Landroid/view/View;->setVisibility(I)V
""".trimIndent().toInstructions().toMutableList()
implementation.addInstructions(
insertIndex,
instructionList
)
return PatchResultSuccess()
}
}

View File

@@ -0,0 +1,151 @@
package app.revanced.patches.music.layout
import app.revanced.patcher.data.implementation.BytecodeData
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.or
import app.revanced.patcher.patch.implementation.BytecodePatch
import app.revanced.patcher.patch.implementation.metadata.PackageMetadata
import app.revanced.patcher.patch.implementation.metadata.PatchMetadata
import app.revanced.patcher.patch.implementation.misc.PatchResult
import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess
import app.revanced.patcher.signature.MethodMetadata
import app.revanced.patcher.signature.MethodSignature
import app.revanced.patcher.signature.MethodSignatureMetadata
import app.revanced.patcher.signature.PatternScanMethod
import app.revanced.patcher.smali.toInstructions
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.builder.instruction.BuilderInstruction22t
import org.jf.dexlib2.iface.instruction.formats.Instruction22c
import org.jf.dexlib2.iface.instruction.formats.Instruction35c
private val compatiblePackages = listOf(
PackageMetadata(
"com.google.android.apps.youtube.music",
listOf("5.03.50")
)
)
class RemoveUpgradeTabPatch : BytecodePatch(
PatchMetadata(
"upgrade-tab-remover",
"Remove Upgrade Tab Patch",
"Remove the upgrade tab from t he pivot bar in YouTube music.",
compatiblePackages,
"0.0.1"
),
listOf(
MethodSignature(
MethodSignatureMetadata(
"pivot-bar-constructor",
MethodMetadata("Lhfu;", "<init2>"), // unknown
PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value.
compatiblePackages,
"Required signature for this patch.",
"0.0.1"
),
"V",
AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
listOf("L", "Z"),
listOf(
Opcode.INVOKE_DIRECT,
Opcode.CONST_4,
Opcode.IPUT_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.IPUT_BOOLEAN,
Opcode.IGET_OBJECT,
Opcode.IF_NEZ,
Opcode.GOTO,
Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT,
Opcode.IGET_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT,
Opcode.IF_EQZ,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
Opcode.IGET,
Opcode.CONST,
Opcode.IF_NE,
Opcode.IGET_OBJECT,
Opcode.CHECK_CAST,
Opcode.GOTO,
Opcode.SGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT,
Opcode.IF_EQZ,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
Opcode.IGET,
Opcode.CONST,
Opcode.IF_NE,
Opcode.IGET_OBJECT,
Opcode.CHECK_CAST,
Opcode.INVOKE_INTERFACE,
Opcode.GOTO,
Opcode.NOP,
Opcode.IPUT_OBJECT,
Opcode.RETURN_VOID
)
)
)
) {
override fun execute(data: BytecodeData): PatchResult {
val result = signatures.first().result!!
val implementation = result.method.implementation!!
val pivotBarElementFieldRef =
(implementation.instructions[result.scanData.endIndex - 1] as Instruction22c).reference
val register = (implementation.instructions.first() as Instruction35c).registerC
// first compile all the needed instructions
val instructionList =
"""
invoke-interface { v0 }, Ljava/util/List;->size()I
move-result v1
const/4 v2, 0x3
invoke-interface {v0, v2}, Ljava/util/List;->remove(I)Ljava/lang/Object;
iput-object v0, v$register, $pivotBarElementFieldRef
""".trimIndent().toInstructions().toMutableList()
// replace the instruction to retain the label at given index
implementation.replaceInstruction(
result.scanData.endIndex - 1,
instructionList[0] // invoke-interface
)
// do not forget to remove this instruction since we added it already
instructionList.removeFirst()
val exitInstruction = instructionList.last() // iput-object
implementation.addInstruction(
result.scanData.endIndex,
exitInstruction
)
// do not forget to remove this instruction since we added it already
instructionList.removeLast()
// add the necessary if statement to remove the upgrade tab button in case it exists
instructionList.add(
2, // if-le
BuilderInstruction22t(
Opcode.IF_LE,
1, 2,
implementation.newLabelForIndex(result.scanData.endIndex)
)
)
implementation.addInstructions(
result.scanData.endIndex,
instructionList
)
return PatchResultSuccess()
}
}

View File

@@ -0,0 +1,92 @@
package app.revanced.patches.music.premium
import app.revanced.patcher.data.implementation.BytecodeData
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.or
import app.revanced.patcher.patch.implementation.BytecodePatch
import app.revanced.patcher.patch.implementation.metadata.PackageMetadata
import app.revanced.patcher.patch.implementation.metadata.PatchMetadata
import app.revanced.patcher.patch.implementation.misc.PatchResult
import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess
import app.revanced.patcher.signature.MethodMetadata
import app.revanced.patcher.signature.MethodSignature
import app.revanced.patcher.signature.MethodSignatureMetadata
import app.revanced.patcher.signature.PatternScanMethod
import app.revanced.patcher.smali.toInstructions
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
private val compatiblePackages = listOf(
PackageMetadata(
"com.google.android.apps.youtube.music",
listOf("5.03.50")
)
)
class BackgroundPlayPatch : BytecodePatch(
PatchMetadata(
"background-play",
"Enable Background Playback Patch",
"Enable playing music in the background.",
compatiblePackages,
"0.0.1"
),
listOf(
MethodSignature(
MethodSignatureMetadata(
"background-playback-disabler-method",
MethodMetadata("Lafgf;", "e"),
PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value.
compatiblePackages,
"Signature for the method required to be patched.",
"0.0.1"
),
"Z",
AccessFlags.PUBLIC or AccessFlags.STATIC,
listOf("L"),
listOf(
Opcode.CONST_4,
Opcode.IF_EQZ,
Opcode.IGET,
Opcode.AND_INT_LIT16,
Opcode.IF_EQZ,
Opcode.IGET_OBJECT,
Opcode.IF_NEZ,
Opcode.SGET_OBJECT,
Opcode.IGET,
Opcode.CONST,
Opcode.IF_NE,
Opcode.IGET_OBJECT,
Opcode.IF_NEZ,
Opcode.SGET_OBJECT,
Opcode.IGET,
Opcode.IF_NE,
Opcode.IGET_OBJECT,
Opcode.CHECK_CAST,
Opcode.GOTO,
Opcode.SGET_OBJECT,
Opcode.GOTO,
Opcode.CONST_4,
Opcode.IF_EQZ,
Opcode.IGET_BOOLEAN,
Opcode.IF_EQZ,
Opcode.CONST_4,
Opcode.RETURN,
Opcode.RETURN,
Opcode.RETURN
)
)
)
) {
override fun execute(data: BytecodeData): PatchResult {
signatures.first().result!!.method.implementation!!.addInstructions(
0,
"""
const/4 v0, 0x1
return v0
""".trimIndent().toInstructions()
)
return PatchResultSuccess()
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,188 @@
package app.revanced.patches.youtube.ad
import app.revanced.extensions.injectHideCall
import app.revanced.patcher.data.implementation.BytecodeData
import app.revanced.patcher.data.implementation.toMethodWalker
import app.revanced.patcher.extensions.or
import app.revanced.patcher.patch.implementation.BytecodePatch
import app.revanced.patcher.patch.implementation.metadata.PackageMetadata
import app.revanced.patcher.patch.implementation.metadata.PatchMetadata
import app.revanced.patcher.patch.implementation.misc.PatchResult
import app.revanced.patcher.patch.implementation.misc.PatchResultError
import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess
import app.revanced.patcher.proxy.mutableTypes.MutableMethod
import app.revanced.patcher.signature.MethodMetadata
import app.revanced.patcher.signature.MethodSignature
import app.revanced.patcher.signature.MethodSignatureMetadata
import app.revanced.patcher.signature.PatternScanMethod
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.formats.Instruction11x
private val compatiblePackages = listOf(
PackageMetadata(
"com.google.android.youtube",
listOf("17.03.38", "17.14.35", "17.17.34")
)
)
private val patchMetadata = PatchMetadata(
"home-promo-ads",
"Home Promo Ads Patch",
"Patch to remove promoted ads in YouTube",
compatiblePackages,
"0.0.1"
)
private val signatureDescription = "Required signature for ${patchMetadata.name}. Discovered in version 17.03.38."
class HomePromoPatch : BytecodePatch(
patchMetadata,
listOf(
MethodSignature(
MethodSignatureMetadata(
"promoted-discovery-app-parent-method",
MethodMetadata(
"Ljre;",
"lP",
),
PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value.
compatiblePackages,
signatureDescription,
"0.0.1"
),
"V",
AccessFlags.PUBLIC or AccessFlags.FINAL or AccessFlags.BRIDGE or AccessFlags.SYNTHETIC,
listOf("L", "L"),
listOf(
Opcode.INVOKE_DIRECT,
Opcode.IGET_BOOLEAN,
Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.IF_NEZ,
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.IF_NEZ,
Opcode.SGET_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IGET_OBJECT,
Opcode.IF_NEZ,
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT,
Opcode.NEW_ARRAY,
Opcode.IPUT_OBJECT,
Opcode.CONST_4,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT,
Opcode.IF_GE,
Opcode.IGET_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
Opcode.APUT_OBJECT,
Opcode.ADD_INT_LIT8,
Opcode.GOTO
)
),
MethodSignature(
MethodSignatureMetadata(
"promoted-discovery-action-parent-method",
MethodMetadata(
"Ljqv;",
"lP",
),
PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value.
compatiblePackages,
signatureDescription,
"0.0.1"
),
"V",
AccessFlags.PUBLIC or AccessFlags.FINAL or AccessFlags.BRIDGE or AccessFlags.SYNTHETIC,
listOf("L", "L"),
listOf(
Opcode.MOVE_OBJECT_FROM16,
Opcode.MOVE_OBJECT_FROM16,
Opcode.MOVE_OBJECT_FROM16,
Opcode.CHECK_CAST,
Opcode.INVOKE_VIRTUAL_RANGE,
Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT,
Opcode.IGET_BOOLEAN,
Opcode.CONST_4,
Opcode.XOR_INT_2ADDR,
Opcode.IGET_BOOLEAN,
Opcode.INVOKE_DIRECT,
Opcode.IGET_BOOLEAN,
Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.IF_NEZ,
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.IF_NEZ,
Opcode.SGET_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IGET_OBJECT,
Opcode.CONST_4,
Opcode.IF_NEZ,
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT
)
)
)
) {
override fun execute(data: BytecodeData): PatchResult {
for (signature in signatures) {
val result = signature.result!!
val methodMetadata = MethodMetadata(signature.metadata.methodMetadata!!.definingClass, "d")
val requiredMethod = result.findParentMethod(
MethodSignature(
MethodSignatureMetadata(
"promoted-discovery-action-method",
methodMetadata,
PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value.
compatiblePackages,
signatureDescription,
"0.0.1"
),
"V",
AccessFlags.PRIVATE or AccessFlags.FINAL,
listOf("Z", "Z"),
null
)
)
?: return PatchResultError("Required parent method ${methodMetadata.name} could not be found in ${methodMetadata.definingClass}")
val toBePatchedInvokeOffset =
requiredMethod.immutableMethod.implementation!!.instructions.indexOfFirst { it.opcode == Opcode.INVOKE_DIRECT }
val toBePatchedMethod = data
.toMethodWalker(requiredMethod.immutableMethod)
.walk(toBePatchedInvokeOffset, true)
.getMethod() as MutableMethod
val implementation = toBePatchedMethod.implementation!!
val invokeVirtualOffset = implementation.instructions.indexOfFirst { it.opcode == Opcode.INVOKE_VIRTUAL }
val moveResultInstruction = implementation.instructions[invokeVirtualOffset + 1]
if (moveResultInstruction.opcode != Opcode.MOVE_RESULT_OBJECT)
return PatchResultError("The toBePatchedInvokeOffset offset was wrong in ${metadata.name}")
val register = (moveResultInstruction as Instruction11x).registerA
implementation.injectHideCall(invokeVirtualOffset + 2, register)
}
return PatchResultSuccess()
}
}

View File

@@ -0,0 +1,112 @@
package app.revanced.patches.youtube.ad
import app.revanced.patcher.data.implementation.BytecodeData
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.or
import app.revanced.patcher.patch.implementation.BytecodePatch
import app.revanced.patcher.patch.implementation.metadata.PackageMetadata
import app.revanced.patcher.patch.implementation.metadata.PatchMetadata
import app.revanced.patcher.patch.implementation.misc.PatchResult
import app.revanced.patcher.patch.implementation.misc.PatchResultError
import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess
import app.revanced.patcher.signature.MethodMetadata
import app.revanced.patcher.signature.MethodSignature
import app.revanced.patcher.signature.MethodSignatureMetadata
import app.revanced.patcher.signature.PatternScanMethod
import app.revanced.patcher.smali.toInstructions
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
private val packageMetadata = listOf(
PackageMetadata(
"com.google.android.youtube",
listOf("17.14.35", "17.17.34")
)
)
private val patchMetadata = PatchMetadata(
"video-ads",
"YouTube Video Ads Patch",
"Patch to remove ads in the YouTube video player.",
packageMetadata,
"0.0.1"
)
class VideoAdsPatch : BytecodePatch(
patchMetadata,
listOf(
MethodSignature(
MethodSignatureMetadata(
"show-video-ads-constructor",
MethodMetadata(
"Laadb",
"<init>",
),
PatternScanMethod.Fuzzy(2),// FIXME: Test this threshold and find the best value.
packageMetadata,
"Required signature for ${patchMetadata.name}. Discovered in version 17.14.35.",
"0.0.1"
),
"V",
AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
listOf("L", "L", "L"),
listOf(
Opcode.INVOKE_DIRECT,
Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT,
Opcode.IPUT_OBJECT,
Opcode.NEW_INSTANCE,
null, // either CONST_4 or CONST_16
Opcode.INVOKE_DIRECT,
Opcode.IPUT_OBJECT,
Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT,
Opcode.IPUT_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.CONST_4,
Opcode.IPUT_BOOLEAN,
Opcode.RETURN_VOID
)
)
)
) {
override fun execute(data: BytecodeData): PatchResult {
var result = signatures.first().result!!
val responsibleMethodSignature = MethodSignature(
MethodSignatureMetadata(
"show-video-ads-method",
MethodMetadata(
"zai",
null // unknown
),
PatternScanMethod.Direct(),
packageMetadata,
"Signature to find the method, which is responsible for showing the video ads. Discovered in version 17.14.35",
"0.0.1"
),
"V",
AccessFlags.PUBLIC or AccessFlags.FINAL,
listOf("Z"),
null
)
result = result.findParentMethod(
responsibleMethodSignature
) ?: return PatchResultError(
"Could not find parent method with signature ${responsibleMethodSignature.metadata.name}"
)
// Override the parameter by calling shouldShowAds and setting the parameter to the result
result.method.implementation!!.addInstructions(
0,
"""
invoke-static { }, Lfi/vanced/libraries/youtube/whitelisting/Whitelist;->shouldShowAds()Z
move-result v1
""".trimIndent().toInstructions()
)
return PatchResultSuccess()
}
}

View File

@@ -0,0 +1,186 @@
package app.revanced.patches.youtube.interaction
import app.revanced.patcher.data.implementation.BytecodeData
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.or
import app.revanced.patcher.patch.implementation.BytecodePatch
import app.revanced.patcher.patch.implementation.metadata.PackageMetadata
import app.revanced.patcher.patch.implementation.metadata.PatchMetadata
import app.revanced.patcher.patch.implementation.misc.PatchResult
import app.revanced.patcher.patch.implementation.misc.PatchResultError
import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess
import app.revanced.patcher.signature.MethodMetadata
import app.revanced.patcher.signature.MethodSignature
import app.revanced.patcher.signature.MethodSignatureMetadata
import app.revanced.patcher.signature.PatternScanMethod
import app.revanced.patcher.smali.toInstructions
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.builder.instruction.BuilderInstruction21t
import org.jf.dexlib2.iface.Method
import org.jf.dexlib2.iface.instruction.formats.Instruction11n
import org.jf.dexlib2.iface.instruction.formats.Instruction35c
private val compatiblePackages = listOf(
PackageMetadata(
"com.google.android.youtube",
listOf("17.17.34")
)
)
class EnableSeekbarTappingPatch : BytecodePatch(
PatchMetadata(
"seekbar-tapping",
"Enable seekbar tapping patch",
"Enable tapping on the seekbar of the YouTube player.",
compatiblePackages,
"0.0.1"
),
listOf(
MethodSignature(
MethodSignatureMetadata(
"enable-seekbar-tapping-parent-signature",
MethodMetadata("Lzhj;", "J"), // unknown
PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value.
compatiblePackages,
"Signature for a parent method, which is needed to find the actual method required to be patched.",
"0.0.1"
),
"L",
AccessFlags.PUBLIC or AccessFlags.FINAL,
listOf(),
listOf(
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CONST_4,
Opcode.NEW_ARRAY,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_WIDE,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CONST_4,
Opcode.APUT_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_WIDE,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CONST_4,
Opcode.APUT_OBJECT,
Opcode.CONST,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.RETURN_OBJECT
)
),
MethodSignature(
MethodSignatureMetadata(
"enable-seekbar-tapping-signature",
MethodMetadata("Lfao;", "onTouchEvent"), // unknown
PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value.
compatiblePackages,
"Signature for the method required to be patched.",
"0.0.1"
),
"Z",
AccessFlags.PUBLIC or AccessFlags.FINAL,
listOf("L"),
listOf(
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_WIDE,
Opcode.IGET,
Opcode.IGET_OBJECT,
Opcode.IGET,
Opcode.DIV_INT_2ADDR,
Opcode.ADD_INT,
Opcode.SUB_INT_2ADDR,
Opcode.INT_TO_FLOAT,
Opcode.CMPG_FLOAT,
Opcode.IF_GTZ,
Opcode.INT_TO_FLOAT,
Opcode.CMPG_FLOAT,
Opcode.IF_GTZ,
Opcode.CONST_4,
Opcode.INVOKE_INTERFACE,
Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT,
Opcode.IPUT_OBJECT,
Opcode.INVOKE_VIRTUAL
)
)
)
) {
override fun execute(data: BytecodeData): PatchResult {
var result = signatures.first().result!!
val tapSeekMethods = mutableMapOf<String, Method>()
// find the methods which tap the seekbar
for (it in result.definingClassProxy.immutableClass.methods) {
if (it.implementation == null) continue
val instructions = it.implementation!!.instructions
// here we make sure we actually find the method because it has more then 7 instructions
if (instructions.count() < 7) continue
// we know that the 7th instruction has the opcode CONST_4
val instruction = instructions.elementAt(6)
if (instruction.opcode != Opcode.CONST_4) continue
// the literal for this instruction has to be either 1 or 2
val literal = (instruction as Instruction11n).narrowLiteral
// method founds
if (literal == 1) tapSeekMethods["P"] = it
if (literal == 2) tapSeekMethods["O"] = it
}
// replace map because we dont need the upper one anymore
result = signatures.last().result!!
val implementation = result.method.implementation!!
// if tap-seeking is enabled, do not invoke the two methods below
val pMethod = tapSeekMethods["P"]!!
val oMethod = tapSeekMethods["O"]!!
// get the required register
val instruction = implementation.instructions[result.scanData.endIndex]
if (instruction.opcode != Opcode.INVOKE_VIRTUAL)
return PatchResultError("Could not find the correct register")
val register = (instruction as Instruction35c).registerC
// the instructions are written in reverse order.
implementation.addInstructions(
result.scanData.endIndex + 1,
"""
invoke-virtual { v$register, v2 }, ${oMethod.definingClass}->${oMethod.name}(I)V
invoke-virtual { v$register, v2 }, ${pMethod.definingClass}->${pMethod.name}(I)V
""".trimIndent().toInstructions()
)
// if tap-seeking is disabled, do not invoke the two methods above by jumping to the else label
val elseLabel = implementation.newLabelForIndex(result.scanData.endIndex + 1)
implementation.addInstruction(
result.scanData.endIndex + 1,
BuilderInstruction21t(Opcode.IF_EQZ, 0, elseLabel)
)
implementation.addInstructions(
result.scanData.endIndex + 1,
"""
invoke-static { }, Lfi/razerman/youtube/preferences/BooleanPreferences;->isTapSeekingEnabled()Z
move-result v0
""".trimIndent().toInstructions()
)
return PatchResultSuccess()
}
}

View File

@@ -0,0 +1,102 @@
package app.revanced.patches.youtube.layout
import app.revanced.patcher.data.implementation.BytecodeData
import app.revanced.patcher.extensions.or
import app.revanced.patcher.patch.implementation.BytecodePatch
import app.revanced.patcher.patch.implementation.metadata.PackageMetadata
import app.revanced.patcher.patch.implementation.metadata.PatchMetadata
import app.revanced.patcher.patch.implementation.misc.PatchResult
import app.revanced.patcher.patch.implementation.misc.PatchResultError
import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess
import app.revanced.patcher.signature.MethodMetadata
import app.revanced.patcher.signature.MethodSignature
import app.revanced.patcher.signature.MethodSignatureMetadata
import app.revanced.patcher.signature.PatternScanMethod
import app.revanced.patcher.smali.toInstruction
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.formats.Instruction35c
private val compatiblePackages = listOf(
PackageMetadata(
"com.google.android.youtube",
listOf("17.14.35", "17.17.34")
)
)
class CreateButtonRemoverPatch : BytecodePatch(
PatchMetadata(
"create-button",
"Create button patch",
"Disable the create button.",
compatiblePackages,
"0.0.1"
),
listOf(
MethodSignature(
MethodSignatureMetadata(
"create-button-method",
MethodMetadata("Lkne", "z"), // unknown
PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value.
compatiblePackages,
"Signature for the method required to be patched.",
"0.0.1"
),
"V",
AccessFlags.PUBLIC or AccessFlags.FINAL,
listOf("Z"),
listOf(
Opcode.IGET,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IF_NEZ,
Opcode.SGET_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT,
Opcode.IGET_OBJECT,
Opcode.IF_NEZ,
Opcode.SGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.IF_NEZ,
Opcode.SGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.NEW_INSTANCE,
Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT,
Opcode.CONST,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.MOVE_OBJECT,
Opcode.MOVE_OBJECT,
Opcode.INVOKE_DIRECT_RANGE,
Opcode.CONST_4,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
)
)
)
) {
override fun execute(data: BytecodeData): PatchResult {
val result = signatures.first().result!!
// Get the required register which holds the view object we need to pass to the method hideCreateButton
val implementation = result.method.implementation!!
val instruction = implementation.instructions[result.scanData.endIndex + 1]
if (instruction.opcode != Opcode.INVOKE_STATIC)
return PatchResultError("Could not find the correct register")
val register = (instruction as Instruction35c).registerC
// Hide the button view via proxy by passing it to the hideCreateButton method
implementation.addInstruction(
result.scanData.endIndex + 1,
"invoke-static { v$register }, Lfi/razerman/youtube/XAdRemover;->hideCreateButton(Landroid/view/View;)V".toInstruction()
)
return PatchResultSuccess()
}
}

View File

@@ -0,0 +1,115 @@
package app.revanced.patches.youtube.layout
import app.revanced.patcher.data.implementation.BytecodeData
import app.revanced.patcher.extensions.or
import app.revanced.patcher.patch.implementation.BytecodePatch
import app.revanced.patcher.patch.implementation.metadata.PackageMetadata
import app.revanced.patcher.patch.implementation.metadata.PatchMetadata
import app.revanced.patcher.patch.implementation.misc.PatchResult
import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess
import app.revanced.patcher.signature.MethodMetadata
import app.revanced.patcher.signature.MethodSignature
import app.revanced.patcher.signature.MethodSignatureMetadata
import app.revanced.patcher.signature.PatternScanMethod
import app.revanced.patcher.smali.toInstruction
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
private val compatiblePackages = listOf(
PackageMetadata(
"com.google.android.youtube",
listOf("17.17.34")
)
)
class HideReelsPatch : BytecodePatch(
PatchMetadata(
"hide-reels",
"Hide reels patch",
"Hide reels on the page.",
compatiblePackages,
"0.0.1"
),
listOf(
MethodSignature(
MethodSignatureMetadata(
"hide-reels-signature",
MethodMetadata("Ljvy", "<init>"), // unknown
PatternScanMethod.Fuzzy(3), // FIXME: Test this threshold and find the best value.
compatiblePackages,
"Signature for the method required to be patched.",
"0.0.1"
),
"V",
AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
listOf(
"L",
"L",
"L",
"L",
"L",
"L",
"L",
"L",
"L",
"L",
"L",
"[B",
"[B",
"[B",
"[B",
"[B",
"[B"
),
listOf(
Opcode.MOVE_OBJECT,
Opcode.MOVE_OBJECT,
Opcode.INVOKE_DIRECT,
Opcode.MOVE_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.MOVE_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.MOVE_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.MOVE_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.MOVE_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.MOVE_OBJECT_FROM16,
Opcode.IPUT_OBJECT,
Opcode.MOVE_OBJECT_FROM16,
Opcode.IPUT_OBJECT,
Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT,
Opcode.IPUT_OBJECT,
Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT,
Opcode.IPUT_OBJECT,
Opcode.MOVE_OBJECT_FROM16,
Opcode.IPUT_OBJECT,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CONST,
Opcode.CONST_4,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IPUT_OBJECT
)
)
)
) {
override fun execute(data: BytecodeData): PatchResult {
val result = signatures.first().result!!
val implementation = result.method.implementation!!
// HideReel will hide the reel view before it is being used,
// so we pass the view to the HideReel method
implementation.addInstruction(
result.scanData.endIndex,
"invoke-static { v2 }, Lfi/razerman/youtube/XAdRemover;->HideReel(Landroid/view/View;)V".toInstruction()
)
return PatchResultSuccess()
}
}

View File

@@ -0,0 +1,89 @@
package app.revanced.patches.youtube.layout
import app.revanced.patcher.data.implementation.BytecodeData
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.or
import app.revanced.patcher.patch.implementation.BytecodePatch
import app.revanced.patcher.patch.implementation.metadata.PackageMetadata
import app.revanced.patcher.patch.implementation.metadata.PatchMetadata
import app.revanced.patcher.patch.implementation.misc.PatchResult
import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess
import app.revanced.patcher.signature.MethodMetadata
import app.revanced.patcher.signature.MethodSignature
import app.revanced.patcher.signature.MethodSignatureMetadata
import app.revanced.patcher.signature.PatternScanMethod
import app.revanced.patcher.smali.toInstructions
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
private val compatiblePackages = listOf(
PackageMetadata(
"com.google.android.youtube",
listOf("17.14.35", "17.17.34")
)
)
class MinimizedPlaybackPatch : BytecodePatch(
PatchMetadata(
"minimized-playback",
"Minimized Playback Patch",
"Enable minimized and background playback.",
compatiblePackages,
"0.0.1"
),
listOf(
MethodSignature(
MethodSignatureMetadata(
"minimized-playback-manager",
MethodMetadata("Lype", "j"), // unknown
PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value.
compatiblePackages,
"Signature for the method required to be patched.",
"0.0.1"
),
"Z",
AccessFlags.PUBLIC or AccessFlags.STATIC,
listOf("L"),
listOf(
Opcode.CONST_4,
Opcode.IF_EQZ,
Opcode.IGET,
Opcode.AND_INT_LIT16,
Opcode.IF_EQZ,
Opcode.IGET_OBJECT,
Opcode.IF_NEZ,
Opcode.SGET_OBJECT,
Opcode.IGET,
Opcode.CONST,
Opcode.IF_NE,
Opcode.IGET_OBJECT,
Opcode.IF_NEZ,
Opcode.SGET_OBJECT,
Opcode.IGET,
Opcode.IF_NE,
Opcode.IGET_OBJECT,
Opcode.CHECK_CAST,
Opcode.GOTO,
Opcode.SGET_OBJECT,
Opcode.GOTO,
Opcode.CONST_4,
Opcode.IF_EQZ,
Opcode.IGET_BOOLEAN,
Opcode.IF_EQZ
)
)
)
) {
override fun execute(data: BytecodeData): PatchResult {
// Instead of removing all instructions like Vanced,
// we return the method at the beginning instead
signatures.first().result!!.method.implementation!!.addInstructions(
0,
"""
const/4 v0, 0x1
return v0
""".trimIndent().toInstructions()
)
return PatchResultSuccess()
}
}

View File

@@ -0,0 +1,127 @@
package app.revanced.patches.youtube.layout
import app.revanced.patcher.data.implementation.BytecodeData
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.or
import app.revanced.patcher.patch.implementation.BytecodePatch
import app.revanced.patcher.patch.implementation.metadata.PackageMetadata
import app.revanced.patcher.patch.implementation.metadata.PatchMetadata
import app.revanced.patcher.patch.implementation.misc.PatchResult
import app.revanced.patcher.patch.implementation.misc.PatchResultError
import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess
import app.revanced.patcher.signature.MethodMetadata
import app.revanced.patcher.signature.MethodSignature
import app.revanced.patcher.signature.MethodSignatureMetadata
import app.revanced.patcher.signature.PatternScanMethod
import app.revanced.patcher.smali.toInstructions
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.builder.instruction.BuilderInstruction21t
private val compatiblePackages = listOf(
PackageMetadata(
"com.google.android.youtube",
listOf("17.17.34")
)
)
class OldQualityLayoutPatch : BytecodePatch(
PatchMetadata(
"old-quality-layout",
"Old Quality Layout Patch",
"Enable the original quality flyout menu",
compatiblePackages,
"0.0.1"
),
listOf(
MethodSignature(
MethodSignatureMetadata(
"old-quality-parent-method-signature",
MethodMetadata("Libh", "<init>"), // unknown
PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value.
compatiblePackages,
"Signature to find a parent method required by the Old Quality Layout patch.",
"0.0.1"
),
"V",
AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
listOf("L", "L", "L", "L", "L", "L", "L"),
listOf(
Opcode.INVOKE_DIRECT,
Opcode.IPUT_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.SGET_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.SGET_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IGET_OBJECT,
Opcode.IF_NEZ,
Opcode.SGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.IF_NEZ,
Opcode.SGET_OBJECT,
Opcode.IGET_BOOLEAN,
Opcode.CONST_4,
Opcode.CONST_4,
Opcode.CONST_4,
)
)
)
) {
override fun execute(data: BytecodeData): PatchResult {
var result = signatures.first().result!!
result = result.findParentMethod(
MethodSignature(
MethodSignatureMetadata(
"old-quality-method-signature",
MethodMetadata("Libh", null), // unknown
PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value.
compatiblePackages,
"Signature to find the method required by the Old Quality Layout patch",
"0.0.1"
),
"L",
AccessFlags.FINAL or AccessFlags.PRIVATE,
listOf("Z"),
listOf(
Opcode.CONST_4,
Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT,
Opcode.GOTO,
Opcode.IGET_OBJECT,
)
)
) ?: return PatchResultError("Method old-quality-patch-method has not been found")
val implementation = result.method.implementation!!
// if useOldStyleQualitySettings == true, jump over all instructions
val jmpInstruction =
BuilderInstruction21t(
Opcode.IF_NEZ,
0,
implementation.instructions[result.scanData.endIndex].location.labels.first()
)
implementation.addInstruction(5, jmpInstruction)
implementation.addInstructions(
0,
"""
invoke-static { }, Lfi/razerman/youtube/XGlobals;->useOldStyleQualitySettings()Z
move-result v0
""".trimIndent().toInstructions()
)
return PatchResultSuccess()
}
}

View File

@@ -0,0 +1,135 @@
package app.revanced.patches.youtube.layout
import app.revanced.patcher.data.implementation.BytecodeData
import app.revanced.patcher.extensions.or
import app.revanced.patcher.patch.implementation.BytecodePatch
import app.revanced.patcher.patch.implementation.metadata.PackageMetadata
import app.revanced.patcher.patch.implementation.metadata.PatchMetadata
import app.revanced.patcher.patch.implementation.misc.PatchResult
import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess
import app.revanced.patcher.signature.MethodMetadata
import app.revanced.patcher.signature.MethodSignature
import app.revanced.patcher.signature.MethodSignatureMetadata
import app.revanced.patcher.signature.PatternScanMethod
import app.revanced.patcher.smali.toInstruction
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.formats.Instruction11x
private val compatiblePackages = listOf(
PackageMetadata(
"com.google.android.youtube",
listOf("17.14.35", "17.17.34")
)
)
class ShortsButtonRemoverPatch : BytecodePatch(
PatchMetadata(
"shorts-button",
"Shorts button patch",
"Hide the shorts button.",
compatiblePackages,
"0.0.1"
),
listOf(
MethodSignature(
MethodSignatureMetadata(
"pivotbar-buttons-method-tabenum",
MethodMetadata("Lkne", "z"), // unknown
PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value.
compatiblePackages,
"Signature for the pivotbar method that creates all button views.",
"0.0.1"
),
"V",
AccessFlags.PUBLIC or AccessFlags.FINAL,
listOf("Z"),
listOf(
Opcode.CHECK_CAST,
Opcode.IGET_OBJECT,
Opcode.IF_NEZ,
Opcode.SGET_OBJECT,
Opcode.IGET,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IF_NEZ,
Opcode.SGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IGET_OBJECT,
Opcode.CHECK_CAST,
Opcode.IGET_OBJECT,
Opcode.IF_NEZ,
Opcode.SGET_OBJECT,
Opcode.IGET,
Opcode.INVOKE_STATIC, // SomeEnum.fromValue(tabOrdinal)
Opcode.MOVE_RESULT_OBJECT
)
),
MethodSignature(
MethodSignatureMetadata(
"pivotbar-buttons-method-view",
MethodMetadata("Lkne", "z"), // unknown
PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value.
compatiblePackages,
"Signature for the pivotbar method that creates all button views.",
"0.0.1"
),
"V",
AccessFlags.PUBLIC or AccessFlags.FINAL,
listOf("Z"),
listOf(
Opcode.NEW_INSTANCE, // new StateListDrawable()
Opcode.INVOKE_DIRECT,
Opcode.NEW_ARRAY,
Opcode.CONST,
Opcode.CONST_16,
Opcode.APUT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.SGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_OBJECT,
Opcode.MOVE_OBJECT,
Opcode.MOVE,
Opcode.MOVE_OBJECT,
Opcode.INVOKE_VIRTUAL_RANGE, // pivotBar.getView(drawable, tabName, z, i, map, akebVar, optional)
Opcode.MOVE_RESULT_OBJECT,
)
),
)
) {
override fun execute(data: BytecodeData): PatchResult {
val result1 = signatures.first().result!!
val implementation1 = result1.method.implementation!!
val moveEnumInstruction = implementation1.instructions[result1.scanData.endIndex]
val enumRegister = (moveEnumInstruction as Instruction11x).registerA
val result2 = signatures.last().result!!
val implementation2 = result2.method.implementation!!
val moveViewInstruction = implementation2.instructions[result2.scanData.endIndex]
val viewRegister = (moveViewInstruction as Instruction11x).registerA
// Save the tab enum in XGlobals to avoid smali/register workarounds
implementation1.addInstruction(
result1.scanData.endIndex + 1,
"sput-object v$enumRegister, Lfi/razerman/youtube/XGlobals;->lastPivotTab:Ljava/lang/Enum;".toInstruction()
)
// Hide the button view via proxy by passing it to the hideShortsButton method
// It only hides it if the last tab name is "TAB_SHORTS"
implementation2.addInstruction(
result2.scanData.endIndex + 2,
"invoke-static { v$viewRegister }, Lfi/razerman/youtube/XAdRemover;->hideShortsButton(Landroid/view/View;)V".toInstruction()
)
return PatchResultSuccess()
}
}

View File

@@ -0,0 +1,46 @@
package app.revanced.patches.youtube.misc
import app.revanced.patcher.data.implementation.ResourceData
import app.revanced.patcher.patch.implementation.ResourcePatch
import app.revanced.patcher.patch.implementation.metadata.PackageMetadata
import app.revanced.patcher.patch.implementation.metadata.PatchMetadata
import app.revanced.patcher.patch.implementation.misc.PatchResult
import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess
import org.w3c.dom.Element
private val compatiblePackages = listOf(
PackageMetadata(
"com.google.android.youtube",
listOf("17.14.35", "17.17.34")
)
)
class FixLocaleConfigErrorPatch : ResourcePatch(
PatchMetadata(
"locale-config-fix",
"Manifest attribute fix patch",
"Fix an error when building the resources by patching the manifest file.",
compatiblePackages,
"0.0.1"
),
) {
override fun execute(data: ResourceData): PatchResult {
// create an xml editor instance
val editor = data.getXmlEditor("AndroidManifest.xml")
// edit the application nodes attribute...
val applicationNode = editor
.file
.getElementsByTagName("application")
.item(0) as Element
// by replacing the attributes name
val attribute = "android:localeConfig"
applicationNode.setAttribute("localeConfig", applicationNode.getAttribute(attribute))
applicationNode.removeAttribute("android:localeConfig")
// close & save the modified file
editor.close()
return PatchResultSuccess()
}
}

View File

@@ -0,0 +1,125 @@
package app.revanced.patches.youtube.misc
import app.revanced.patcher.data.implementation.BytecodeData
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.or
import app.revanced.patcher.patch.implementation.BytecodePatch
import app.revanced.patcher.patch.implementation.metadata.PackageMetadata
import app.revanced.patcher.patch.implementation.metadata.PatchMetadata
import app.revanced.patcher.patch.implementation.misc.PatchResult
import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess
import app.revanced.patcher.proxy.mutableTypes.MutableMethod.Companion.toMutable
import app.revanced.patcher.signature.MethodMetadata
import app.revanced.patcher.signature.MethodSignature
import app.revanced.patcher.signature.MethodSignatureMetadata
import app.revanced.patcher.signature.PatternScanMethod
import app.revanced.patcher.smali.toInstructions
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.immutable.ImmutableMethod
import org.jf.dexlib2.immutable.ImmutableMethodImplementation
private val compatiblePackages = listOf(
PackageMetadata(
"com.google.android.youtube",
listOf("17.03.38", "17.14.35", "17.17.34")
)
)
class IntegrationsPatch : BytecodePatch(
PatchMetadata(
"integrations",
"Inject Integrations Patch",
"Applies mandatory patches to implement the ReVanced integrations into the application.",
compatiblePackages,
"0.0.1"
),
listOf(
MethodSignature(
MethodSignatureMetadata(
"integrations-patch",
MethodMetadata("Lacnx", "onCreate"),
PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value.
compatiblePackages,
"Inject the integrations into the application with the method of this signature",
"0.0.1"
),
"V",
AccessFlags.PUBLIC.value,
listOf(),
listOf(
Opcode.SGET_OBJECT,
Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT,
Opcode.IGET_OBJECT,
Opcode.CONST_STRING,
Opcode.IF_NEZ,
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.MOVE_OBJECT,
Opcode.CHECK_CAST,
Opcode.MOVE_OBJECT,
Opcode.CHECK_CAST,
Opcode.CONST_4,
Opcode.CONST_STRING,
Opcode.INVOKE_INTERFACE_RANGE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.SPUT_OBJECT,
Opcode.SGET_OBJECT,
Opcode.INVOKE_STATIC,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IGET_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
Opcode.INVOKE_VIRTUAL,
Opcode.INVOKE_SUPER,
Opcode.INVOKE_VIRTUAL
)
)
)
) {
override fun execute(data: BytecodeData): PatchResult {
val result = signatures.first().result!!
val implementation = result.method.implementation!!
val count = implementation.registerCount - 1
implementation.addInstructions(
result.scanData.endIndex + 1,
"""
invoke-static {v$count}, Lpl/jakubweg/StringRef;->setContext(Landroid/content/Context;)V
sput-object v$count, Lapp/revanced/integrations/Globals;->context:Landroid/content/Context;
""".trimIndent().toInstructions()
)
val classDef = result.definingClassProxy.resolve()
classDef.methods.add(
ImmutableMethod(
classDef.type,
"getAppContext",
null,
"Landroid/content/Context;",
AccessFlags.PUBLIC or AccessFlags.STATIC,
null,
null,
ImmutableMethodImplementation(
1,
"""
invoke-static { }, Lapp/revanced/integrations/Globals;->getAppContext()Landroid/content/Context;
move-result-object v0
return-object v0
""".trimIndent().toInstructions(),
null,
null
)
).toMutable()
)
return PatchResultSuccess()
}
}

View File

@@ -0,0 +1,59 @@
package app.revanced.patches
import app.revanced.patcher.Patcher
import app.revanced.patcher.signature.MethodMetadata
import app.revanced.patcher.signature.MethodSignature
import app.revanced.patcher.signature.PatternScanMethod
import org.jf.dexlib2.iface.Method
import org.junit.Test
import java.io.File
internal class SignatureChecker {
@Test
fun checkSignatures() {
return
// FIXME: instead of having this as a test, it should be turned into a task which can be ran manually
val file = File("stock.apk")
if (!file.exists()) {
throw IllegalStateException("Missing $file! To run this test, please place stock.apk here: ${file.absolutePath}")
}
val patcher = Patcher(file, "signatureCheckerCache", false)
patcher.addPatches(Index.patches.map { it() })
val unresolved = mutableListOf<MethodSignature>()
for (signature in patcher.resolveSignatures()) {
if (!signature.resolved) {
unresolved.add(signature)
continue
}
val patternScanMethod = signature.metadata.patternScanMethod
if (patternScanMethod is PatternScanMethod.Fuzzy) {
val warnings = patternScanMethod.warnings!!
val method = signature.result!!.method
val methodFromMetadata =
if (signature.metadata.methodMetadata != null) signature.metadata.methodMetadata!! else MethodMetadata(
null,
null
)
println("Signature: ${signature.metadata.name}.\nMethod: ${methodFromMetadata.definingClass}->${methodFromMetadata.name} (Signature matches: ${method.definingClass}->${method.toStr()})\nWarnings: ${warnings.count()}")
for (warning in warnings) {
println("${warning.instructionIndex} / ${warning.patternIndex}: ${warning.wrongOpcode} (expected: ${warning.correctOpcode})")
}
println("=".repeat(20))
}
}
if (unresolved.isNotEmpty()) {
val base = Exception("${unresolved.size} signatures were not resolved.")
for (signature in unresolved) {
base.addSuppressed(Exception("Signature ${signature.metadata.name} was not resolved!"))
}
throw base
}
}
private fun Method.toStr(): String {
return "${this.name}(${this.parameterTypes.joinToString("")})${this.returnType}"
}
}