1
mirror of https://github.com/revanced/revanced-patcher synced 2025-09-06 16:38:50 +02:00

Compare commits

...

92 Commits

Author SHA1 Message Date
semantic-release-bot
d4f08d7bff chore(release): 8.0.0 [skip ci]
# [8.0.0](https://github.com/revanced/revanced-patcher/compare/v7.1.1...v8.0.0) (2023-05-13)

* feat!: add `classDef` parameter to `MethodFingerprint` (#175) ([a205220](a2052202b2)), closes [#175](https://github.com/revanced/revanced-patcher/issues/175)

### BREAKING CHANGES

* This changes the signature of the `customFingerprint` function.
2023-05-13 23:58:31 +00:00
oSumAtrIX
ca9fe322eb chore: merge branch dev to main (#174) 2023-05-14 01:57:34 +02:00
Jim Man
239ea0bcaa refactor: simplify loading patches (#172) 2023-05-14 01:55:26 +02:00
semantic-release-bot
7f02b8df48 chore(release): 8.0.0-dev.1 [skip ci]
# [8.0.0-dev.1](https://github.com/revanced/revanced-patcher/compare/v7.1.1...v8.0.0-dev.1) (2023-05-10)

* feat!: add `classDef` parameter to `MethodFingerprint` (#175) ([a205220](a2052202b2)), closes [#175](https://github.com/revanced/revanced-patcher/issues/175)

### BREAKING CHANGES

* This changes the signature of the `customFingerprint` function.
2023-05-10 23:38:38 +00:00
badawoll
a2052202b2 feat!: add classDef parameter to MethodFingerprint (#175)
BREAKING CHANGE: This changes the signature of the `customFingerprint` function.
2023-05-11 01:37:17 +02:00
oSumAtrIX
223cea7021 build: use Java SDK 17 for building 2023-05-09 08:16:15 +02:00
semantic-release-bot
ac9337f694 chore(release): 7.1.1 [skip ci]
## [7.1.1](https://github.com/revanced/revanced-patcher/compare/v7.1.0...v7.1.1) (2023-05-07)

### Bug Fixes

* remove `count` instead of `count + 1` instructions with `removeInstructions` ([#167](https://github.com/revanced/revanced-patcher/issues/167)) ([98f8eed](98f8eedecd))
2023-05-07 23:06:19 +00:00
oSumAtrIX
549651d04a chore: merge branch dev to main (#171) 2023-05-08 01:05:17 +02:00
semantic-release-bot
966bbd902e chore(release): 7.1.1-dev.1 [skip ci]
## [7.1.1-dev.1](https://github.com/revanced/revanced-patcher/compare/v7.1.0...v7.1.1-dev.1) (2023-05-07)

### Bug Fixes

* remove `count` instead of `count + 1` instructions with `removeInstructions` ([#167](https://github.com/revanced/revanced-patcher/issues/167)) ([98f8eed](98f8eedecd))
2023-05-07 23:04:09 +00:00
oSumAtrIX
81e6f8784e docs: fix heading 2023-05-08 01:03:11 +02:00
oSumAtrIX
9c53877888 build: downgrade to JDK version 11
This is to properly support Android
2023-05-08 01:03:11 +02:00
rstular
98f8eedecd fix: remove count instead of count + 1 instructions with removeInstructions (#167)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>

BREAKING-CHANGE: This alters the behaviour of the function. Instead of removing `count + 1` instructions, this now removes `count` instructions.
2023-05-08 01:03:09 +02:00
semantic-release-bot
4ed429d25c chore(release): 7.1.0 [skip ci]
# [7.1.0](https://github.com/revanced/revanced-patcher/compare/v7.0.0...v7.1.0) (2023-05-05)

### Features

* add appreciation message for new contributors ([d674362](d67436271d))
* add overload to get instruction as type ([49c173d](49c173dc14))
2023-05-05 23:06:29 +00:00
oSumAtrIX
119d05f469 chore: merge branch dev to main (#161) 2023-05-06 01:05:01 +02:00
semantic-release-bot
2432fde6bf chore(release): 7.1.0-dev.2 [skip ci]
# [7.1.0-dev.2](https://github.com/revanced/revanced-patcher/compare/v7.1.0-dev.1...v7.1.0-dev.2) (2023-05-05)

### Features

* add overload to get instruction as type ([49c173d](49c173dc14))
2023-05-05 21:38:29 +00:00
oSumAtrIX
49c173dc14 feat: add overload to get instruction as type 2023-05-05 23:36:30 +02:00
oSumAtrIX
d83e9372bb chore: update gradle and dependencies 2023-04-30 05:27:22 +02:00
semantic-release-bot
7e8cd3bede chore(release): 7.1.0-dev.1 [skip ci]
# [7.1.0-dev.1](https://github.com/revanced/revanced-patcher/compare/v7.0.0...v7.1.0-dev.1) (2023-04-30)

### Features

* add appreciation message for new contributors ([d674362](d67436271d))
2023-04-30 01:16:45 +00:00
oSumAtrIX
d67436271d feat: add appreciation message for new contributors 2023-04-30 03:15:12 +02:00
oSumAtrIX
aa07f35f06 chore: bump dependencies 2023-04-03 03:04:05 +02:00
oSumAtrIX
77e0536838 build: update Kotlin to 1.8.10 2023-03-31 17:19:40 +02:00
oSumAtrIX
a49e78234b chore: remove project files
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2023-03-02 19:23:41 +01:00
semantic-release-bot
a3ae825e48 chore(release): 7.0.0 [skip ci]
# [7.0.0](https://github.com/revanced/revanced-patcher/compare/v6.4.3...v7.0.0) (2023-02-26)

* feat!: merge integrations only when necessary ([6e24a85](6e24a85eab))

### BREAKING CHANGES

* `Patcher.addFiles` is now renamed to `Patcher.addIntegrations`

Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2023-02-26 23:42:48 +00:00
oSumAtrIX
146c8504ed chore: merge branch dev to main (#159) 2023-02-27 00:41:27 +01:00
semantic-release-bot
2eb125ad69 chore(release): 7.0.0-dev.1 [skip ci]
# [7.0.0-dev.1](https://github.com/revanced/revanced-patcher/compare/v6.4.3...v7.0.0-dev.1) (2023-02-26)

* feat!: merge integrations only when necessary ([6e24a85](6e24a85eab))

### BREAKING CHANGES

* `Patcher.addFiles` is now renamed to `Patcher.addIntegrations`

Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2023-02-26 23:24:38 +00:00
oSumAtrIX
6e24a85eab feat!: merge integrations only when necessary
BREAKING CHANGE: `Patcher.addFiles` is now renamed to `Patcher.addIntegrations`

Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2023-02-27 00:23:27 +01:00
oSumAtrIX
e4c3e9ffc5 refactor: remove unnecessary annotations
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2023-02-26 23:18:35 +01:00
Javier Flores
4c1778a62f chore: update gradle wrapper to 8.0.1 (#160) 2023-02-26 03:46:33 +01:00
oSumAtrIX
d99261cdbb ci: fix backmerge direction
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2023-02-22 16:39:50 +01:00
oSumAtrIX
ac1c0f2773 ci: add backmerge target branch
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2023-02-22 06:45:16 +01:00
oSumAtrIX
eddd4ec7ac ci: use new semantic-release-backmerge option
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2023-02-18 21:55:40 +01:00
Palm
07a2829c65 ci: update actions (#158) 2023-02-13 22:29:20 +01:00
semantic-release-bot
3d77e299d9 chore(release): 6.4.3 [skip ci]
## [6.4.3](https://github.com/revanced/revanced-patcher/compare/v6.4.2...v6.4.3) (2023-02-10)

### Bug Fixes

* check `CONST_STRING_JUMP` instructions for matching string ([058d292](058d292ad5))
2023-02-10 04:28:15 +00:00
oSumAtrIX
f1336f89e4 chore: merge branch dev to main (#156) 2023-02-10 05:26:43 +01:00
semantic-release-bot
0502f84c20 chore(release): 6.4.3-dev.1 [skip ci]
## [6.4.3-dev.1](https://github.com/revanced/revanced-patcher/compare/v6.4.2...v6.4.3-dev.1) (2023-02-10)

### Bug Fixes

* check `CONST_STRING_JUMP` instructions for matching string ([058d292](058d292ad5))
2023-02-10 04:20:46 +00:00
oSumAtrIX
058d292ad5 fix: check CONST_STRING_JUMP instructions for matching string
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2023-02-10 05:18:38 +01:00
oSumAtrIX
1029d56a52 refactor: remove dead code
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2023-02-10 05:17:36 +01:00
oSumAtrIX
709b5a0fec chore: fix typo
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2023-02-10 05:16:00 +01:00
semantic-release-bot
e1accc5041 chore(release): 6.4.2 [skip ci]
## [6.4.2](https://github.com/revanced/revanced-patcher/compare/v6.4.1...v6.4.2) (2023-01-17)

### Bug Fixes

* resolve failing builds ([a263fdf](a263fdfd41))
2023-01-17 23:29:34 +00:00
oSumAtrIX
6dbbf2e03e chore: merge branch dev to main (#153) 2023-01-18 00:14:38 +01:00
semantic-release-bot
16557eeab0 chore(release): 6.4.2-dev.1 [skip ci]
## [6.4.2-dev.1](https://github.com/revanced/revanced-patcher/compare/v6.4.1...v6.4.2-dev.1) (2023-01-17)

### Bug Fixes

* resolve failing builds ([a263fdf](a263fdfd41))
2023-01-17 23:09:26 +00:00
oSumAtrIX
6bca3e2bb5 build: update dependencies 2023-01-17 23:57:19 +01:00
oSumAtrIX
a263fdfd41 fix: resolve failing builds
This updates dependencies, because the previous ones were missing or outdated.
2023-01-17 01:32:11 +01:00
semantic-release-bot
e4b4bacae8 chore(release): 6.4.1 [skip ci]
## [6.4.1](https://github.com/revanced/revanced-patcher/compare/v6.4.0...v6.4.1) (2023-01-15)

### Bug Fixes

* update dependency `app.revanced:multidexlib2` ([#150](https://github.com/revanced/revanced-patcher/issues/150)) ([dd7dd38](dd7dd38357))
2023-01-15 05:13:48 +00:00
semantic-release-bot
cbc97af155 chore(release): 6.4.1 [skip ci]
## [6.4.1](https://github.com/revanced/revanced-patcher/compare/v6.4.0...v6.4.1) (2023-01-15)

### Bug Fixes

* update dependency `app.revanced:multidexlib2` ([#150](https://github.com/revanced/revanced-patcher/issues/150)) ([dd7dd38](dd7dd38357))
2023-01-15 04:32:33 +00:00
oSumAtrIX
d5533788e2 chore: merge branch dev to main (#152) 2023-01-15 05:31:12 +01:00
oSumAtrIX
5a4ea5cd7d ci: add missing PAT in step Release 2023-01-15 05:29:50 +01:00
oSumAtrIX
70f3c8b38c chore: merge branch dev to main (#151) 2023-01-15 05:24:25 +01:00
semantic-release-bot
6b410a0eea chore(release): 6.4.1-dev.1 [skip ci]
## [6.4.1-dev.1](https://github.com/revanced/revanced-patcher/compare/v6.4.0...v6.4.1-dev.1) (2023-01-15)

### Bug Fixes

* update dependency `app.revanced:multidexlib2` ([#150](https://github.com/revanced/revanced-patcher/issues/150)) ([dd7dd38](dd7dd38357))
2023-01-15 03:07:43 +00:00
oSumAtrIX
73a013d75b ci: use PAT in step Release 2023-01-15 04:06:45 +01:00
oSumAtrIX
7159f3db4c ci: downgrade semantic release and plugins to v19 2023-01-15 04:06:45 +01:00
oSumAtrIX
7d5ecf095c ci: give jobs names 2023-01-15 04:06:44 +01:00
oSumAtrIX
fa015a424d refactor: fix formatting 2023-01-15 04:06:44 +01:00
oSumAtrIX
dd7dd38357 fix: update dependency app.revanced:multidexlib2 (#150)
This commit addresses https://github.com/revanced/multidexlib2/issues/2.
2023-01-15 04:06:43 +01:00
semantic-release-bot
22356f2d26 chore(release): 6.4.0 [skip ci]
# [6.4.0](https://github.com/revanced/revanced-patcher/compare/v6.3.2...v6.4.0) (2023-01-02)

### Features

* add missing setter to `MutableMethod` ([8f3ecc3](8f3ecc318c))
* do not fix methods or methods in class merger ([4102f43](4102f43b8a))
* fix method and field access when merging classes ([5c09ef7](5c09ef7837))
* make `aaptPath` nullable ([#146](https://github.com/revanced/revanced-patcher/issues/146)) ([9f0a09a](9f0a09a756))
2023-01-02 08:07:08 +00:00
oSumAtrIX
66701f6076 chore: merge branch dev to main (#147) 2023-01-02 09:05:19 +01:00
semantic-release-bot
6a6ded084e chore(release): 6.4.0-dev.2 [skip ci]
# [6.4.0-dev.2](https://github.com/revanced/revanced-patcher/compare/v6.4.0-dev.1...v6.4.0-dev.2) (2023-01-02)

### Features

* add missing setter to `MutableMethod` ([8f3ecc3](8f3ecc318c))
* do not fix methods or methods in class merger ([4102f43](4102f43b8a))
* fix method and field access when merging classes ([5c09ef7](5c09ef7837))
2023-01-02 07:58:55 +00:00
oSumAtrIX
5887c69bde refactor: move merging classes code to own class (#149) 2023-01-02 08:58:05 +01:00
oSumAtrIX
4102f43b8a feat: do not fix methods or methods in class merger 2023-01-02 08:50:08 +01:00
oSumAtrIX
5c09ef7837 feat: fix method and field access when merging classes 2023-01-02 07:57:50 +01:00
oSumAtrIX
3e0bf8c863 refactor: move merging classes code to own class 2023-01-02 07:57:48 +01:00
oSumAtrIX
8f3ecc318c feat: add missing setter to MutableMethod 2023-01-02 07:09:58 +01:00
oSumAtrIX
365da96e2b build: do not comment on successful releases 2022-12-31 21:12:03 +01:00
oSumAtrIX
cd68ec4803 ci: do not escape in environment variable MESSAGE 2022-12-29 19:07:31 +01:00
semantic-release-bot
35265e029c chore(release): 6.4.0-dev.1 [skip ci]
# [6.4.0-dev.1](https://github.com/revanced/revanced-patcher/compare/v6.3.2...v6.4.0-dev.1) (2022-12-20)

### Features

* make `aaptPath` nullable ([#146](https://github.com/revanced/revanced-patcher/issues/146)) ([9f0a09a](9f0a09a756))
2022-12-20 19:05:47 +00:00
Canny
9f0a09a756 feat: make aaptPath nullable (#146) 2022-12-20 20:04:15 +01:00
semantic-release-bot
e802141df5 chore(release): 6.3.2 [skip ci]
## [6.3.2](https://github.com/revanced/revanced-patcher/compare/v6.3.1...v6.3.2) (2022-12-18)

### Bug Fixes

* check if fingerprint string is substring of any string references ([c5de9e2](c5de9e2988))
* print full exception when patch fails ([7cf79e6](7cf79e68e0))
2022-12-18 21:11:48 +00:00
oSumAtrIX
abebc0862c chore: merge branch dev to main (#144) 2022-12-18 22:10:56 +01:00
semantic-release-bot
96ef150e89 chore(release): 6.3.2-dev.1 [skip ci]
## [6.3.2-dev.1](https://github.com/revanced/revanced-patcher/compare/v6.3.1...v6.3.2-dev.1) (2022-12-18)

### Bug Fixes

* check if fingerprint string is substring of any string references ([c5de9e2](c5de9e2988))
* print full exception when patch fails ([7cf79e6](7cf79e68e0))
2022-12-18 21:08:40 +00:00
oSumAtrIX
c5de9e2988 fix: check if fingerprint string is substring of any string references 2022-12-18 22:05:05 +01:00
semantic-release-bot
c391ca648b chore(release): 6.3.2-dev.1 [skip ci]
## [6.3.2-dev.1](https://github.com/revanced/revanced-patcher/compare/v6.3.1...v6.3.2-dev.1) (2022-12-17)

### Bug Fixes

* print full exception when patch fails ([27a8401](27a8401d81))
2022-12-18 09:02:48 +01:00
oSumAtrIX
7cf79e68e0 fix: print full exception when patch fails 2022-12-18 09:02:48 +01:00
oSumAtrIX
f07db3c214 chore: merge branch dev to main (#143) 2022-12-15 21:44:59 +01:00
oSumAtrIX
88bb3a8845 ci: do not release on build commit type 2022-12-15 19:47:31 +01:00
oSumAtrIX
b9e6bd6775 chore: merge branch dev to main (#141) 2022-12-15 19:36:43 +01:00
oSumAtrIX
cd1b72e078 ci: remove unnecessary step 2022-12-15 01:08:00 +01:00
oSumAtrIX
6b889557ab ci: stash before rebasing 2022-12-15 01:07:48 +01:00
oSumAtrIX
4b1be8c647 ci: only back-merge from main branch to dev 2022-12-15 01:04:16 +01:00
oSumAtrIX
73c893c6e7 chore: merge branch dev to main (#140)
chore: merge branch `dev` to `main`
2022-12-14 00:13:25 +01:00
oSumAtrIX
75b36823b8 ci: back-merge releases back into dev branch 2022-12-14 00:02:52 +01:00
semantic-release-bot
d2d93cd075 chore(release): 6.3.1 [skip ci]
## [6.3.1](https://github.com/revanced/revanced-patcher/compare/v6.3.0...v6.3.1) (2022-12-13)

### Bug Fixes

* publicize types when merging files if necessary ([#137](https://github.com/revanced/revanced-patcher/issues/137)) ([9ec720e](9ec720e983))
2022-12-13 22:52:11 +00:00
oSumAtrIX
26b8621ac8 chore: merge branch dev to main (#139) 2022-12-13 23:50:28 +01:00
semantic-release-bot
f365a41741 chore(release): 6.3.1-dev.1 [skip ci]
## [6.3.1-dev.1](https://github.com/revanced/revanced-patcher/compare/v6.3.0...v6.3.1-dev.1) (2022-12-13)

### Bug Fixes

* publicize types when merging files if necessary ([#137](https://github.com/revanced/revanced-patcher/issues/137)) ([9ec720e](9ec720e983))
2022-12-13 22:39:34 +00:00
oSumAtrIX
9ec720e983 fix: publicize types when merging files if necessary (#137) 2022-12-13 23:36:47 +01:00
oSumAtrIX
0f432b3fdd ci: escape backticks in message environment variable 2022-12-13 23:36:47 +01:00
oSumAtrIX
96cd5618dd ci: open pull requests to merge dev to main (#131) 2022-12-13 23:36:47 +01:00
oSumAtrIX
c2a5a55e67 refactor: remove unnecessary test 2022-12-11 03:01:41 +01:00
oSumAtrIX
6c5de8b414 ci: refactor release workflow 2022-12-11 03:01:40 +01:00
semantic-release-bot
ea773cfa56 chore(release): 6.3.0 [skip ci]
# [6.3.0](https://github.com/revanced/revanced-patcher/compare/v6.2.0...v6.3.0) (2022-12-02)

### Features

* sort patches in lexicographical order ([a306561](a306561b55)), closes [#125](https://github.com/revanced/revanced-patcher/issues/125)
2022-12-02 02:32:49 +00:00
oSumAtrIX
a306561b55 feat: sort patches in lexicographical order
Closes #125
2022-12-02 03:31:25 +01:00
semantic-release-bot
b6dcd88495 chore(release): 6.2.0 [skip ci]
# [6.2.0](https://github.com/revanced/revanced-patcher/compare/v6.1.1...v6.2.0) (2022-12-02)

### Features

* merge classes on addition ([#127](https://github.com/revanced/revanced-patcher/issues/127)) ([a925650](a925650044))
2022-12-02 01:33:08 +00:00
oSumAtrIX
a925650044 feat: merge classes on addition (#127) 2022-12-02 02:31:47 +01:00
40 changed files with 7255 additions and 254 deletions

2
.github/config.yml vendored Normal file
View File

@@ -0,0 +1,2 @@
firstPRMergeComment: >
Thank you for contributing to ReVanced. Join us on [Discord](https://revanced.app/discord) if you want to receive a contributor role.

25
.github/workflows/pull_request.yml vendored Normal file
View File

@@ -0,0 +1,25 @@
name: PR to main
on:
push:
branches:
- dev
workflow_dispatch:
env:
MESSAGE: merge branch `${{ github.head_ref || github.ref_name }}` to `main`
jobs:
pull-request:
name: Open pull request
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Open pull request
uses: repo-sync/pull-request@v2
with:
destination_branch: 'main'
pr_title: 'chore: ${{ env.MESSAGE }}'
pr_body: 'This pull request will ${{ env.MESSAGE }}.'
pr_draft: true

View File

@@ -1,4 +1,5 @@
name: Release
on:
workflow_dispatch:
push:
@@ -9,6 +10,7 @@ on:
branches:
- main
- dev
jobs:
release:
name: Release
@@ -17,24 +19,24 @@ jobs:
- name: Checkout
uses: actions/checkout@v3
with:
# Make sure the release step uses its own credentials:
# https://github.com/cycjimmy/semantic-release-action#private-packages
persist-credentials: false
fetch-depth: 0
- name: Setup JDK
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
distribution: 'zulu'
cache: gradle
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: "lts/*"
- name: Build with Gradle
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./gradlew build
node-version: "18"
cache: 'npm'
- name: Setup semantic-release
run: npm install -g semantic-release @semantic-release/git @semantic-release/changelog gradle-semantic-release-plugin -D
run: npm install
- name: Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npx semantic-release
GITHUB_TOKEN: ${{ secrets.REPOSITORY_PUSH_ACCESS }}
run: npm exec semantic-release

7
.gitignore vendored
View File

@@ -74,6 +74,7 @@ cmake-build-*/
# IntelliJ
out/
.idea/
# mpeltonen/sbt-idea plugin
.idea_modules/
@@ -115,3 +116,9 @@ gradle-app.setting
# Avoid ignoring test resources
!src/test/resources/*
# Dependency directories
node_modules/
# Gradle props, to avoid sharing the gpr key
gradle.properties

9
.idea/.gitignore generated vendored
View File

@@ -1,9 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
/kotlinc.xml

View File

@@ -1,10 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<JetCodeStyleSettings>
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings>
<codeStyleSettings language="kotlin">
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</codeStyleSettings>
</code_scheme>
</component>

View File

@@ -1,5 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

7
.idea/discord.xml generated
View File

@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DiscordProjectSettings">
<option name="show" value="PROJECT_FILES" />
<option name="description" value="" />
</component>
</project>

View File

@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GitToolBoxProjectSettings">
<option name="commitMessageIssueKeyValidationOverride">
<BoolValueOverride>
<option name="enabled" value="true" />
</BoolValueOverride>
</option>
<option name="commitMessageValidationEnabledOverride">
<BoolValueOverride>
<option name="enabled" value="true" />
</BoolValueOverride>
</option>
</component>
</project>

View File

@@ -1,6 +0,0 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="UnusedSymbol" enabled="false" level="WARNING" enabled_by_default="false" />
</profile>
</component>

10
.idea/misc.xml generated
View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="FrameworkDetectionExcludesConfiguration">
<file type="web" url="file://$PROJECT_DIR$" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="azul-17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

12
.idea/vcs.xml generated
View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CommitMessageInspectionProfile">
<profile version="1.0">
<inspection_tool class="CommitFormat" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="CommitNamingConvention" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</component>
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@@ -7,11 +7,7 @@
}
],
"plugins": [
["@semantic-release/commit-analyzer", {
"releaseRules": [
{"type": "build", "release": "patch"}
]
}],
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
"gradle-semantic-release-plugin",
@@ -24,6 +20,18 @@
]
}
],
"@semantic-release/github"
[
"@saithodev/semantic-release-backmerge",
{
backmergeBranches: [{"from": "main", "to": "dev"}],
clearWorkspace: true
}
],
[
"@semantic-release/github",
{
successComment: false
}
]
]
}

View File

@@ -1,3 +1,209 @@
# [8.0.0](https://github.com/revanced/revanced-patcher/compare/v7.1.1...v8.0.0) (2023-05-13)
* feat!: add `classDef` parameter to `MethodFingerprint` (#175) ([a205220](https://github.com/revanced/revanced-patcher/commit/a2052202b23037150df6aadc47f6e91efcd481cf)), closes [#175](https://github.com/revanced/revanced-patcher/issues/175)
### BREAKING CHANGES
* This changes the signature of the `customFingerprint` function.
# [8.0.0-dev.1](https://github.com/revanced/revanced-patcher/compare/v7.1.1...v8.0.0-dev.1) (2023-05-10)
* feat!: add `classDef` parameter to `MethodFingerprint` (#175) ([a205220](https://github.com/revanced/revanced-patcher/commit/a2052202b23037150df6aadc47f6e91efcd481cf)), closes [#175](https://github.com/revanced/revanced-patcher/issues/175)
### BREAKING CHANGES
* This changes the signature of the `customFingerprint` function.
## [7.1.1](https://github.com/revanced/revanced-patcher/compare/v7.1.0...v7.1.1) (2023-05-07)
### Bug Fixes
* remove `count` instead of `count + 1` instructions with `removeInstructions` ([#167](https://github.com/revanced/revanced-patcher/issues/167)) ([98f8eed](https://github.com/revanced/revanced-patcher/commit/98f8eedecd72b0afe6a0f099a3641a1cc6be2698))
## [7.1.1-dev.1](https://github.com/revanced/revanced-patcher/compare/v7.1.0...v7.1.1-dev.1) (2023-05-07)
### Bug Fixes
* remove `count` instead of `count + 1` instructions with `removeInstructions` ([#167](https://github.com/revanced/revanced-patcher/issues/167)) ([98f8eed](https://github.com/revanced/revanced-patcher/commit/98f8eedecd72b0afe6a0f099a3641a1cc6be2698))
# [7.1.0](https://github.com/revanced/revanced-patcher/compare/v7.0.0...v7.1.0) (2023-05-05)
### Features
* add appreciation message for new contributors ([d674362](https://github.com/revanced/revanced-patcher/commit/d67436271ddca9ccfe008272c1ca82c6123ae7ee))
* add overload to get instruction as type ([49c173d](https://github.com/revanced/revanced-patcher/commit/49c173dc14137ddd198a611e9882dc71300831ee))
# [7.1.0-dev.2](https://github.com/revanced/revanced-patcher/compare/v7.1.0-dev.1...v7.1.0-dev.2) (2023-05-05)
### Features
* add overload to get instruction as type ([49c173d](https://github.com/revanced/revanced-patcher/commit/49c173dc14137ddd198a611e9882dc71300831ee))
# [7.1.0-dev.1](https://github.com/revanced/revanced-patcher/compare/v7.0.0...v7.1.0-dev.1) (2023-04-30)
### Features
* add appreciation message for new contributors ([d674362](https://github.com/revanced/revanced-patcher/commit/d67436271ddca9ccfe008272c1ca82c6123ae7ee))
# [7.0.0](https://github.com/revanced/revanced-patcher/compare/v6.4.3...v7.0.0) (2023-02-26)
* feat!: merge integrations only when necessary ([6e24a85](https://github.com/revanced/revanced-patcher/commit/6e24a85eabd1e7a1484fad229d5ba55c3ba1f1b4))
### BREAKING CHANGES
* `Patcher.addFiles` is now renamed to `Patcher.addIntegrations`
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
# [7.0.0-dev.1](https://github.com/revanced/revanced-patcher/compare/v6.4.3...v7.0.0-dev.1) (2023-02-26)
* feat!: merge integrations only when necessary ([6e24a85](https://github.com/revanced/revanced-patcher/commit/6e24a85eabd1e7a1484fad229d5ba55c3ba1f1b4))
### BREAKING CHANGES
* `Patcher.addFiles` is now renamed to `Patcher.addIntegrations`
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
## [6.4.3](https://github.com/revanced/revanced-patcher/compare/v6.4.2...v6.4.3) (2023-02-10)
### Bug Fixes
* check `CONST_STRING_JUMP` instructions for matching string ([058d292](https://github.com/revanced/revanced-patcher/commit/058d292ad5e297f4c652ff543c13e77a39f7fb1b))
## [6.4.3-dev.1](https://github.com/revanced/revanced-patcher/compare/v6.4.2...v6.4.3-dev.1) (2023-02-10)
### Bug Fixes
* check `CONST_STRING_JUMP` instructions for matching string ([058d292](https://github.com/revanced/revanced-patcher/commit/058d292ad5e297f4c652ff543c13e77a39f7fb1b))
## [6.4.2](https://github.com/revanced/revanced-patcher/compare/v6.4.1...v6.4.2) (2023-01-17)
### Bug Fixes
* resolve failing builds ([a263fdf](https://github.com/revanced/revanced-patcher/commit/a263fdfd413fc05098e28d4800e36ce7d313085b))
## [6.4.2-dev.1](https://github.com/revanced/revanced-patcher/compare/v6.4.1...v6.4.2-dev.1) (2023-01-17)
### Bug Fixes
* resolve failing builds ([a263fdf](https://github.com/revanced/revanced-patcher/commit/a263fdfd413fc05098e28d4800e36ce7d313085b))
## [6.4.1](https://github.com/revanced/revanced-patcher/compare/v6.4.0...v6.4.1) (2023-01-15)
### Bug Fixes
* update dependency `app.revanced:multidexlib2` ([#150](https://github.com/revanced/revanced-patcher/issues/150)) ([dd7dd38](https://github.com/revanced/revanced-patcher/commit/dd7dd383577dcfc95e97f77b446a89b41b589dc0))
## [6.4.1](https://github.com/revanced/revanced-patcher/compare/v6.4.0...v6.4.1) (2023-01-15)
### Bug Fixes
* update dependency `app.revanced:multidexlib2` ([#150](https://github.com/revanced/revanced-patcher/issues/150)) ([dd7dd38](https://github.com/revanced/revanced-patcher/commit/dd7dd383577dcfc95e97f77b446a89b41b589dc0))
## [6.4.1-dev.1](https://github.com/revanced/revanced-patcher/compare/v6.4.0...v6.4.1-dev.1) (2023-01-15)
### Bug Fixes
* update dependency `app.revanced:multidexlib2` ([#150](https://github.com/revanced/revanced-patcher/issues/150)) ([dd7dd38](https://github.com/revanced/revanced-patcher/commit/dd7dd383577dcfc95e97f77b446a89b41b589dc0))
# [6.4.0](https://github.com/revanced/revanced-patcher/compare/v6.3.2...v6.4.0) (2023-01-02)
### Features
* add missing setter to `MutableMethod` ([8f3ecc3](https://github.com/revanced/revanced-patcher/commit/8f3ecc318c39f0270aff53efdee7a1c8d82af421))
* do not fix methods or methods in class merger ([4102f43](https://github.com/revanced/revanced-patcher/commit/4102f43b8a9473fd0ee96c5d4fb8f6e9b4e30e70))
* fix method and field access when merging classes ([5c09ef7](https://github.com/revanced/revanced-patcher/commit/5c09ef7837f9b731e137b66c19da77f63c007595))
* make `aaptPath` nullable ([#146](https://github.com/revanced/revanced-patcher/issues/146)) ([9f0a09a](https://github.com/revanced/revanced-patcher/commit/9f0a09a7569fd5dd78afa27cb66a73d1662edc69))
# [6.4.0-dev.2](https://github.com/revanced/revanced-patcher/compare/v6.4.0-dev.1...v6.4.0-dev.2) (2023-01-02)
### Features
* add missing setter to `MutableMethod` ([8f3ecc3](https://github.com/revanced/revanced-patcher/commit/8f3ecc318c39f0270aff53efdee7a1c8d82af421))
* do not fix methods or methods in class merger ([4102f43](https://github.com/revanced/revanced-patcher/commit/4102f43b8a9473fd0ee96c5d4fb8f6e9b4e30e70))
* fix method and field access when merging classes ([5c09ef7](https://github.com/revanced/revanced-patcher/commit/5c09ef7837f9b731e137b66c19da77f63c007595))
# [6.4.0-dev.1](https://github.com/revanced/revanced-patcher/compare/v6.3.2...v6.4.0-dev.1) (2022-12-20)
### Features
* make `aaptPath` nullable ([#146](https://github.com/revanced/revanced-patcher/issues/146)) ([9f0a09a](https://github.com/revanced/revanced-patcher/commit/9f0a09a7569fd5dd78afa27cb66a73d1662edc69))
## [6.3.2](https://github.com/revanced/revanced-patcher/compare/v6.3.1...v6.3.2) (2022-12-18)
### Bug Fixes
* check if fingerprint string is substring of any string references ([c5de9e2](https://github.com/revanced/revanced-patcher/commit/c5de9e29889dffd18b31e62a892881cc48e8b607))
* print full exception when patch fails ([7cf79e6](https://github.com/revanced/revanced-patcher/commit/7cf79e68e0e9dfd9faddee33139b127b71882d3e))
## [6.3.2-dev.1](https://github.com/revanced/revanced-patcher/compare/v6.3.1...v6.3.2-dev.1) (2022-12-18)
### Bug Fixes
* check if fingerprint string is substring of any string references ([c5de9e2](https://github.com/revanced/revanced-patcher/commit/c5de9e29889dffd18b31e62a892881cc48e8b607))
* print full exception when patch fails ([7cf79e6](https://github.com/revanced/revanced-patcher/commit/7cf79e68e0e9dfd9faddee33139b127b71882d3e))
## [6.3.2-dev.1](https://github.com/revanced/revanced-patcher/compare/v6.3.1...v6.3.2-dev.1) (2022-12-17)
### Bug Fixes
* print full exception when patch fails ([27a8401](https://github.com/revanced/revanced-patcher/commit/27a8401d81e078e0303f7ddcb0ac6f342f8e4def))
## [6.3.1](https://github.com/revanced/revanced-patcher/compare/v6.3.0...v6.3.1) (2022-12-13)
### Bug Fixes
* publicize types when merging files if necessary ([#137](https://github.com/revanced/revanced-patcher/issues/137)) ([9ec720e](https://github.com/revanced/revanced-patcher/commit/9ec720e983785d8b1dde330cc0e0e0f914c1803c))
## [6.3.1-dev.1](https://github.com/revanced/revanced-patcher/compare/v6.3.0...v6.3.1-dev.1) (2022-12-13)
### Bug Fixes
* publicize types when merging files if necessary ([#137](https://github.com/revanced/revanced-patcher/issues/137)) ([9ec720e](https://github.com/revanced/revanced-patcher/commit/9ec720e983785d8b1dde330cc0e0e0f914c1803c))
# [6.3.0](https://github.com/revanced/revanced-patcher/compare/v6.2.0...v6.3.0) (2022-12-02)
### Features
* sort patches in lexicographical order ([a306561](https://github.com/revanced/revanced-patcher/commit/a306561b55ac848792046378f582a036f7ffab03)), closes [#125](https://github.com/revanced/revanced-patcher/issues/125)
# [6.2.0](https://github.com/revanced/revanced-patcher/compare/v6.1.1...v6.2.0) (2022-12-02)
### Features
* merge classes on addition ([#127](https://github.com/revanced/revanced-patcher/issues/127)) ([a925650](https://github.com/revanced/revanced-patcher/commit/a9256500440f9b4117f1b8813ba0097dafee4ebb))
## [6.1.1](https://github.com/revanced/revanced-patcher/compare/v6.1.0...v6.1.1) (2022-11-25)

View File

@@ -1,2 +1,3 @@
# Patcher
Patcher framework used in the ReVanced project.
# 💉 ReVanced Patcher
ReVanced Patcher used to patch Android applications.

View File

@@ -1,6 +1,5 @@
plugins {
kotlin("jvm") version "1.7.0"
java
kotlin("jvm") version "1.8.10"
`maven-publish`
}
@@ -22,12 +21,12 @@ repositories {
dependencies {
implementation("xpp3:xpp3:1.1.4c")
implementation("org.smali:smali:2.5.2")
implementation("app.revanced:multidexlib2:2.5.2.r2")
implementation("org.apktool:apktool-lib:2.8.1-SNAPSHOT")
implementation("app.revanced:smali:2.5.3-a3836654")
implementation("app.revanced:multidexlib2:2.5.3-a3836654")
implementation("app.revanced:apktool-lib:2.7.0")
implementation(kotlin("reflect"))
testImplementation(kotlin("test"))
implementation("org.jetbrains.kotlin:kotlin-reflect:1.8.20-RC")
testImplementation("org.jetbrains.kotlin:kotlin-test:1.8.20-RC")
}
tasks {
@@ -46,6 +45,10 @@ java {
withSourcesJar()
}
kotlin {
jvmToolchain(11)
}
publishing {
repositories {
if (System.getenv("GITHUB_ACTOR") != null)

View File

@@ -1,2 +1,2 @@
kotlin.code.style = official
version = 6.1.1
version = 8.0.0

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

6580
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

9
package.json Normal file
View File

@@ -0,0 +1,9 @@
{
"devDependencies": {
"@saithodev/semantic-release-backmerge": "^3.1.0",
"@semantic-release/changelog": "^6.0.2",
"@semantic-release/git": "^10.0.1",
"gradle-semantic-release-plugin": "^1.7.6",
"semantic-release": "^20.1.0"
}
}

View File

@@ -1,9 +1,9 @@
package app.revanced.patcher
import app.revanced.patcher.data.Context
import app.revanced.patcher.data.findIndexed
import app.revanced.patcher.extensions.PatchExtensions.dependencies
import app.revanced.patcher.extensions.PatchExtensions.patchName
import app.revanced.patcher.extensions.PatchExtensions.requiresIntegrations
import app.revanced.patcher.extensions.nullOutputStream
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.patch.*
@@ -27,7 +27,7 @@ import org.jf.dexlib2.writer.io.MemoryDataStore
import java.io.File
import java.nio.file.Files
private val NAMER = BasicDexFileNamer()
internal val NAMER = BasicDexFileNamer()
/**
* The ReVanced Patcher.
@@ -37,6 +37,7 @@ class Patcher(private val options: PatcherOptions) {
private val logger = options.logger
private val opcodes: Opcodes
private var resourceDecodingMode = ResourceDecodingMode.MANIFEST_ONLY
private var mergeIntegrations = false
val context: PatcherContext
companion object {
@@ -63,42 +64,19 @@ class Patcher(private val options: PatcherOptions) {
}
/**
* Add additional dex file container to the patcher.
* @param files The dex file containers to add to the patcher.
* @param allowedOverwrites A list of class types that are allowed to be overwritten.
* @param throwOnDuplicates If this is set to true, the patcher will throw an exception if a duplicate class has been found.
* Add integrations to be merged by the patcher.
* The integrations will only be merged, if necessary.
*
* @param integrations The integrations, must be dex files or dex file container such as ZIP, APK or DEX files.
* @param callback The callback for [integrations] which are being added.
*/
fun addFiles(
files: List<File>,
allowedOverwrites: Iterable<String> = emptyList(),
throwOnDuplicates: Boolean = false,
fun addIntegrations(
integrations: List<File>,
callback: (File) -> Unit
) {
for (file in files) {
var modified = false
for (classDef in MultiDexIO.readDexFile(true, file, NAMER, null, null).classes) {
val type = classDef.type
val existingClass = context.bytecodeContext.classes.classes.findIndexed { it.type == type }
if (existingClass == null) {
if (throwOnDuplicates) throw Exception("Class $type has already been added to the patcher")
logger.trace("Merging $type")
context.bytecodeContext.classes.classes.add(classDef)
modified = true
continue
}
if (!allowedOverwrites.contains(type)) continue
logger.trace("Overwriting $type")
val index = existingClass.second
context.bytecodeContext.classes.classes[index] = classDef
modified = true
}
if (modified) callback(file)
context.integrations.apply integrations@{
add(integrations)
this@integrations.callback = callback
}
}
@@ -154,6 +132,7 @@ class Patcher(private val options: PatcherOptions) {
cacheDirectory.close()
}
}
else -> logger.info("Not compiling resources because resource patching is not required")
}
@@ -186,18 +165,29 @@ class Patcher(private val options: PatcherOptions) {
*/
fun addPatches(patches: Iterable<Class<out Patch<Context>>>) {
/**
* Fill the cache with the instances of the [Patch]es for later use.
* Note: Dependencies of the [Patch] will be cached as well.
* Returns true if at least one patches or its dependencies matches the given predicate.
*/
fun Class<out Patch<Context>>.isResource() {
this.also {
if (!ResourcePatch::class.java.isAssignableFrom(it)) return@also
// set the mode to decode all resources before running the patches
fun Class<out Patch<Context>>.anyRecursively(predicate: (Class<out Patch<Context>>) -> Boolean): Boolean =
predicate(this) || dependencies?.any { it.java.anyRecursively(predicate) } == true
// Determine if resource patching is required.
for (patch in patches) {
if (patch.anyRecursively { ResourcePatch::class.java.isAssignableFrom(it) }) {
resourceDecodingMode = ResourceDecodingMode.FULL
}.dependencies?.forEach { it.java.isResource() }
break
}
}
context.patches.addAll(patches.onEach(Class<out Patch<Context>>::isResource))
// Determine if merging integrations is required.
for (patch in patches) {
if (patch.anyRecursively { it.requiresIntegrations }) {
mergeIntegrations = true
break
}
}
context.patches.addAll(patches)
}
/**
@@ -240,6 +230,7 @@ class Patcher(private val options: PatcherOptions) {
}
}
ResourceDecodingMode.MANIFEST_ONLY -> {
logger.info("Decoding AndroidManifest.xml only, because resources are not needed")
@@ -310,9 +301,10 @@ class Patcher(private val options: PatcherOptions) {
val result = executePatch(dependency, executedPatches)
if (result.isSuccess()) return@forEach
val error = result.error()!!
val errorMessage = error.cause ?: error.message
return PatchResultError("'$patchName' depends on '${dependency.patchName}' but the following error was raised: $errorMessage")
return PatchResultError(
"'$patchName' depends on '${dependency.patchName}' but the following error was raised: " +
result.error()!!.let { it.cause?.stackTraceToString() ?: it.message }
)
}
val isResourcePatch = ResourcePatch::class.java.isAssignableFrom(patchClass)
@@ -344,6 +336,8 @@ class Patcher(private val options: PatcherOptions) {
}
return sequence {
if (mergeIntegrations) context.integrations.merge(logger)
// prevent from decoding the manifest twice if it is not needed
if (resourceDecodingMode == ResourceDecodingMode.FULL) decodeResources(ResourceDecodingMode.FULL)

View File

@@ -1,10 +1,9 @@
package app.revanced.patcher
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.data.Context
import app.revanced.patcher.data.PackageMetadata
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.data.*
import app.revanced.patcher.logging.Logger
import app.revanced.patcher.patch.Patch
import app.revanced.patcher.util.ClassMerger.merge
import org.jf.dexlib2.iface.ClassDef
import java.io.File
@@ -14,6 +13,52 @@ data class PatcherContext(
) {
val packageMetadata = PackageMetadata()
internal val patches = mutableListOf<Class<out Patch<Context>>>()
internal val integrations = Integrations(this)
internal val bytecodeContext = BytecodeContext(classes)
internal val resourceContext = ResourceContext(resourceCacheDirectory)
internal class Integrations(val context: PatcherContext) {
var callback: ((File) -> Unit)? = null
private val integrations: MutableList<File> = mutableListOf()
fun add(integrations: List<File>) = this@Integrations.integrations.addAll(integrations)
/**
* Merge integrations.
* @param logger A logger.
*/
fun merge(logger: Logger) {
with(context.bytecodeContext.classes) {
for (integrations in integrations) {
callback?.let { it(integrations) }
for (classDef in lanchon.multidexlib2.MultiDexIO.readDexFile(
true,
integrations,
NAMER,
null,
null
).classes) {
val type = classDef.type
val result = classes.findIndexed { it.type == type }
if (result == null) {
logger.trace("Merging type $type")
classes.add(classDef)
continue
}
val (existingClass, existingClassIndex) = result
logger.trace("Type $type exists. Adding missing methods and fields.")
existingClass.merge(classDef, context, logger).let { mergedClass ->
if (mergedClass !== existingClass) // referential equality check
classes[existingClassIndex] = mergedClass
}
}
}
}
}
}
}

View File

@@ -15,7 +15,7 @@ import java.io.File
data class PatcherOptions(
internal val inputFile: File,
internal val resourceCacheDirectory: String,
internal val aaptPath: String = "",
internal val aaptPath: String? = null,
internal val frameworkFolderLocation: String? = null,
internal val logger: Logger = NopLogger
)

View File

@@ -7,8 +7,6 @@ import app.revanced.patcher.patch.Patch
* @param compatiblePackages A list of packages a [Patch] is compatible with.
*/
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class Compatibility(
val compatiblePackages: Array<Package>,
)
@@ -19,8 +17,6 @@ annotation class Compatibility(
* @param versions The versions of the package the [Patch] is compatible with.
*/
@Target()
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class Package(
val name: String,
val versions: Array<String> = [],

View File

@@ -7,8 +7,6 @@ import app.revanced.patcher.patch.Patch
* @param name A suggestive name for the [Patch].
*/
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class Name(
val name: String,
)
@@ -18,8 +16,6 @@ annotation class Name(
* @param description A description for the [Patch].
*/
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class Description(
val description: String,
)
@@ -30,8 +26,6 @@ annotation class Description(
* @param version The version of a [Patch].
*/
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class Version(
val version: String,
)

View File

@@ -54,17 +54,6 @@ class BytecodeContext internal constructor(classes: MutableList<ClassDef>) : Con
}
return proxy
}
private companion object {
inline fun <reified T> Iterable<T>.find(predicate: (T) -> Boolean): T? {
for (element in this) {
if (predicate(element)) {
return element
}
}
return null
}
}
}
/**

View File

@@ -8,6 +8,7 @@ import app.revanced.patcher.patch.OptionsContainer
import app.revanced.patcher.patch.Patch
import app.revanced.patcher.patch.PatchOptions
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.RequiresIntegrations
import kotlin.reflect.KClass
import kotlin.reflect.KVisibility
import kotlin.reflect.full.companionObject
@@ -58,6 +59,9 @@ object PatchExtensions {
val Class<out Patch<Context>>.compatiblePackages
get() = findAnnotationRecursively(Compatibility::class)?.compatiblePackages
internal val Class<out Patch<Context>>.requiresIntegrations
get() = findAnnotationRecursively(RequiresIntegrations::class) != null
val Class<out Patch<Context>>.options: PatchOptions?
get() = kotlin.companionObject?.let { cl ->
if (cl.visibility != KVisibility.PUBLIC) return null

View File

@@ -39,7 +39,7 @@ fun MutableMethodImplementation.replaceInstructions(index: Int, instructions: Li
}
fun MutableMethodImplementation.removeInstructions(index: Int, count: Int) {
for (i in count downTo 0) {
for (i in count - 1 downTo 0) {
this.removeInstruction(index + i)
}
}
@@ -101,12 +101,20 @@ fun MutableMethod.removeInstruction(index: Int) = this.implementation!!.removeIn
fun MutableMethod.label(index: Int) = this.implementation!!.newLabelForIndex(index)
/**
* Get the instruction at given index in the method's implementation.
* Get an instruction at the given index in the method's implementation.
* @param index The index to get the instruction at.
* @return The instruction.
*/
fun MutableMethod.instruction(index: Int): BuilderInstruction = this.implementation!!.instructions[index]
/**
* Get an instruction at the given index in the method's implementation.
* @param index The index to get the instruction at.
* @param T The type of instruction to return.
* @return The instruction.
*/
fun <T> MutableMethod.instruction(index: Int): T = instruction(index) as T
/**
* Add smali instructions to the method.
* @param index The index to insert the instructions at.
@@ -227,21 +235,4 @@ internal fun parametersEqual(
internal val nullOutputStream = object : OutputStream() {
override fun write(b: Int) {}
}
/**
* Should be used to parse a list of parameters represented by their first letter,
* or in the case of arrays prefixed with an unspecified amount of '[' character.
*/
internal fun String.parseParameters(): List<String> {
val parameters = mutableListOf<String>()
var parameter = ""
for (char in this.toCharArray()) {
parameter += char
if (char == '[') continue
parameters.add(parameter)
parameter = ""
}
return parameters
}

View File

@@ -7,7 +7,6 @@ import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
* @param threshold if [threshold] or more of the opcodes do not match, skip.
*/
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
annotation class FuzzyPatternScanMethod(
val threshold: Int = 1
)

View File

@@ -31,7 +31,7 @@ abstract class MethodFingerprint(
internal val parameters: Iterable<String>? = null,
internal val opcodes: Iterable<Opcode?>? = null,
internal val strings: Iterable<String>? = null,
internal val customFingerprint: ((methodDef: Method) -> Boolean)? = null
internal val customFingerprint: ((methodDef: Method, classDef: ClassDef) -> Boolean)? = null
) : Fingerprint {
/**
* The result of the [MethodFingerprint] the [Method].
@@ -94,7 +94,7 @@ abstract class MethodFingerprint(
) return false
@Suppress("UNNECESSARY_NOT_NULL_ASSERTION")
if (methodFingerprint.customFingerprint != null && !methodFingerprint.customFingerprint!!(method))
if (methodFingerprint.customFingerprint != null && !methodFingerprint.customFingerprint!!(method, forClass))
return false
val stringsScanResult: StringsScanResult? =
@@ -106,10 +106,13 @@ abstract class MethodFingerprint(
val stringsList = methodFingerprint.strings.toMutableList()
implementation.instructions.forEachIndexed { instructionIndex, instruction ->
if (instruction.opcode.ordinal != Opcode.CONST_STRING.ordinal) return@forEachIndexed
if (
instruction.opcode != Opcode.CONST_STRING &&
instruction.opcode != Opcode.CONST_STRING_JUMBO
) return@forEachIndexed
val string = ((instruction as ReferenceInstruction).reference as StringReference).string
val index = stringsList.indexOfFirst { it == string }
val index = stringsList.indexOfFirst(string::contains)
if (index == -1) return@forEachIndexed
add(
@@ -244,7 +247,7 @@ data class MethodFingerprintResult(
* The result of scanning strings on the [MethodFingerprint].
* @param matches The list of strings that were matched.
*/
data class StringsScanResult(val matches: List<StringMatch>){
data class StringsScanResult(val matches: List<StringMatch>) {
/**
* Represents a match for a string at an index.
* @param string The string that was matched.

View File

@@ -5,20 +5,23 @@ import app.revanced.patcher.patch.Patch
import kotlin.reflect.KClass
/**
* Annotation to mark a Class as a patch.
* Annotation to mark a class as a patch.
* @param include If false, the patch should be treated as optional by default.
*/
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class Patch(val include: Boolean = true)
/**
* Annotation for dependencies of [Patch]es .
* Annotation for dependencies of [Patch]es.
*/
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class DependsOn(
val dependencies: Array<KClass<out Patch<Context>>> = []
)
)
/**
* Annotation to mark [Patch]es which depend on integrations.
*/
@Target(AnnotationTarget.CLASS)
annotation class RequiresIntegrations // required because integrations are decoupled from patches

View File

@@ -0,0 +1,214 @@
package app.revanced.patcher.util
import app.revanced.patcher.PatcherContext
import app.revanced.patcher.extensions.or
import app.revanced.patcher.logging.Logger
import app.revanced.patcher.util.ClassMerger.Utils.asMutableClass
import app.revanced.patcher.util.ClassMerger.Utils.filterAny
import app.revanced.patcher.util.ClassMerger.Utils.filterNotAny
import app.revanced.patcher.util.ClassMerger.Utils.isPublic
import app.revanced.patcher.util.ClassMerger.Utils.toPublic
import app.revanced.patcher.util.TypeUtil.traverseClassHierarchy
import app.revanced.patcher.util.proxy.mutableTypes.MutableClass
import app.revanced.patcher.util.proxy.mutableTypes.MutableClass.Companion.toMutable
import app.revanced.patcher.util.proxy.mutableTypes.MutableField
import app.revanced.patcher.util.proxy.mutableTypes.MutableField.Companion.toMutable
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.iface.ClassDef
import org.jf.dexlib2.util.MethodUtil
import kotlin.reflect.KFunction2
/**
* Experimental class to merge a [ClassDef] with another.
* Note: This will not consider method implementations or if the class is missing a superclass or interfaces.
*/
internal object ClassMerger {
/**
* Merge a class with [otherClass].
*
* @param otherClass The class to merge with
* @param context The context to traverse the class hierarchy in.
* @param logger A logger.
*/
fun ClassDef.merge(otherClass: ClassDef, context: PatcherContext, logger: Logger? = null) = this
//.fixFieldAccess(otherClass, logger)
//.fixMethodAccess(otherClass, logger)
.addMissingFields(otherClass, logger)
.addMissingMethods(otherClass, logger)
.publicize(otherClass, context, logger)
/**
* Add methods which are missing but existing in [fromClass].
*
* @param fromClass The class to add missing methods from.
* @param logger A logger.
*/
private fun ClassDef.addMissingMethods(fromClass: ClassDef, logger: Logger? = null): ClassDef {
val missingMethods = fromClass.methods.let { fromMethods ->
methods.filterNot { method ->
fromMethods.any { fromMethod ->
MethodUtil.methodSignaturesMatch(fromMethod, method)
}
}
}
if (missingMethods.isEmpty()) return this
logger?.trace("Found ${missingMethods.size} missing methods")
return asMutableClass().apply {
methods.addAll(missingMethods.map { it.toMutable() })
}
}
/**
* Add fields which are missing but existing in [fromClass].
*
* @param fromClass The class to add missing fields from.
* @param logger A logger.
*/
private fun ClassDef.addMissingFields(fromClass: ClassDef, logger: Logger? = null): ClassDef {
val missingFields = fields.filterNotAny(fromClass.fields) { field, fromField ->
fromField.name == field.name
}
if (missingFields.isEmpty()) return this
logger?.trace("Found ${missingFields.size} missing fields")
return asMutableClass().apply {
fields.addAll(missingFields.map { it.toMutable() })
}
}
/**
* Make a class and its super class public recursively.
* @param reference The class to check the [AccessFlags] of.
* @param context The context to traverse the class hierarchy in.
* @param logger A logger.
*/
private fun ClassDef.publicize(reference: ClassDef, context: PatcherContext, logger: Logger? = null) =
if (reference.accessFlags.isPublic() && !accessFlags.isPublic())
this.asMutableClass().apply {
context.bytecodeContext.traverseClassHierarchy(this) {
if (accessFlags.isPublic()) return@traverseClassHierarchy
logger?.trace("Publicizing ${this.type}")
accessFlags = accessFlags.toPublic()
}
}
else this
/**
* Publicize fields if they are public in [reference].
*
* @param reference The class to check the [AccessFlags] of the fields in.
* @param logger A logger.
*/
private fun ClassDef.fixFieldAccess(reference: ClassDef, logger: Logger? = null): ClassDef {
val brokenFields = fields.filterAny(reference.fields) { field, referenceField ->
if (field.name != referenceField.name) return@filterAny false
referenceField.accessFlags.isPublic() && !field.accessFlags.isPublic()
}
if (brokenFields.isEmpty()) return this
logger?.trace("Found ${brokenFields.size} broken fields")
/**
* Make a field public.
*/
fun MutableField.publicize() {
accessFlags = accessFlags.toPublic()
}
return asMutableClass().apply {
fields.filter { brokenFields.contains(it) }.forEach(MutableField::publicize)
}
}
/**
* Publicize methods if they are public in [reference].
*
* @param reference The class to check the [AccessFlags] of the methods in.
* @param logger A logger.
*/
private fun ClassDef.fixMethodAccess(reference: ClassDef, logger: Logger? = null): ClassDef {
val brokenMethods = methods.filterAny(reference.methods) { method, referenceMethod ->
if (!MethodUtil.methodSignaturesMatch(method, referenceMethod)) return@filterAny false
referenceMethod.accessFlags.isPublic() && !method.accessFlags.isPublic()
}
if (brokenMethods.isEmpty()) return this
logger?.trace("Found ${brokenMethods.size} methods")
/**
* Make a method public.
*/
fun MutableMethod.publicize() {
accessFlags = accessFlags.toPublic()
}
return asMutableClass().apply {
methods.filter { brokenMethods.contains(it) }.forEach(MutableMethod::publicize)
}
}
private object Utils {
fun ClassDef.asMutableClass() = if (this is MutableClass) this else this.toMutable()
/**
* Check if the [AccessFlags.PUBLIC] flag is set.
*
* @return True, if the flag is set.
*/
fun Int.isPublic() = AccessFlags.PUBLIC.isSet(this)
/**
* Make [AccessFlags] public.
*
* @return The new [AccessFlags].
*/
fun Int.toPublic() = this.or(AccessFlags.PUBLIC).and(AccessFlags.PRIVATE.value.inv())
/**
* Filter [this] on [needles] matching the given [predicate].
*
* @param this The hay to filter for [needles].
* @param needles The needles to filter [this] with.
* @param predicate The filter.
* @return The [this] filtered on [needles] matching the given [predicate].
*/
fun <HayType, NeedleType> Iterable<HayType>.filterAny(
needles: Iterable<NeedleType>, predicate: (HayType, NeedleType) -> Boolean
) = Iterable<HayType>::filter.any(this, needles, predicate)
/**
* Filter [this] on [needles] not matching the given [predicate].
*
* @param this The hay to filter for [needles].
* @param needles The needles to filter [this] with.
* @param predicate The filter.
* @return The [this] filtered on [needles] not matching the given [predicate].
*/
fun <HayType, NeedleType> Iterable<HayType>.filterNotAny(
needles: Iterable<NeedleType>, predicate: (HayType, NeedleType) -> Boolean
) = Iterable<HayType>::filterNot.any(this, needles, predicate)
fun <HayType, NeedleType> KFunction2<Iterable<HayType>, (HayType) -> Boolean, List<HayType>>.any(
haystack: Iterable<HayType>,
needles: Iterable<NeedleType>,
predicate: (HayType, NeedleType) -> Boolean
) = this(haystack) { hay ->
needles.any { needle ->
predicate(hay, needle)
}
}
}
}

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