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

Compare commits

...

157 Commits

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

### Bug Fixes

* qualifying `Element` with wrong package ([4d74de4](4d74de4061))
2022-05-07 19:37:18 +00:00
oSumAtrIX
4d74de4061 fix: qualifying Element with wrong package
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-05-07 21:36:05 +02:00
oSumAtrIX
4fbee7d255 Merge remote-tracking branch 'origin/dev' into dev 2022-05-07 21:25:37 +02:00
oSumAtrIX
fd9f639605 chore: bump java-version for action setup-java
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-05-07 21:25:18 +02:00
semantic-release-bot
9084ccc2a2 chore(release): 1.0.0-dev.9 [skip ci]
# [1.0.0-dev.9](https://github.com/revanced/revanced-patcher/compare/v1.0.0-dev.8...v1.0.0-dev.9) (2022-05-07)

### Bug Fixes

* `compareSignatureToMethod` not matching correctly in case opcodes are null ([5ae5e98](5ae5e98f1f))
* `ConcurrentModificationException` while iterating through `proxies` and modifying it ([bfeeaf4](bfeeaf4435))
* `PackageMetadata` ([305a817](305a81793a))
* `replaceWith` not replacing classes with used class proxies ([f0f3403](f0f34031dd))
* adding existing classes to the patchers cache ([4281546](4281546f69))
* always return PatchResultSuccess on patch success ([866b03a](866b03af21))
* applying no patches throwing error ([f88c118](f88c11820d))
* applyPatches not returning successful patches ([8b70bb4](8b70bb4290))
* Classes not being written properly because of array shifting ([1471956](147195647c))
* failing tests temporarily ([66b08f8](66b08f8b3a))
* fix classes having multiple instances of fields ([b711b80](b711b8001e))
* fix classes having multiple method instances ([12c10d8](12c10d8c64))
* Fixed writer & signature resolver, improved tests & speed, minor refactoring ([bb42fa3](bb42fa3c6f))
* fuzzy resolver warning params were turned around ([d49df10](d49df10a3c))
* incorrect pattern offset ([03700ff](03700ffa51))
* make `methodMetadata` nullable in `MethodSignatureMetadata` ([864e38c](864e38c069))
* make warnings nullable instead of lateinit ([04b49b8](04b49b8b66))
* match to correct signature method parameters ([c49071a](c49071aff7))
* MethodSignature#resolved throwing an exception ([82b1e66](82b1e66d54))
* Move proxy package out of cache package ([6bc4e7e](6bc4e7eab7))
* null check causing an exception ([560c485](560c485ab0))
* Patcher not writing resolved methods ([d15240d](d15240d033))
* reaching all constructors not possible ([37fa994](37fa9949ec))
* remove leftover debug code ([4458141](4458141d6d))
* return mutable set of classes ([84bc7e0](84bc7e0dc7))
* returning failure on success ([3b68d5c](3b68d5c65e))
* Search method map for existing class proxy ([d5e694c](d5e694c306))
* string signature in `SignatureResolver` ([ac36d19](ac36d19693))
* Suppress unused for addFiles ([a0d6d46](a0d6d46217))
* throwing in case the opcode patterns do not match ([f72dd68](f72dd68ec5))
* use Array instead of Iterable for methodParameters ([312235b](312235b194))
* write all classes ([6ad51aa](6ad51aad9a))

### Code Refactoring

* bump multidexlib2 to 2.5.2.r2 ([32e6458](32e645850d))
* Change all references from Array to Iterable ([264989f](264989f488))

### Features

* add `MethodWalker` ([659e108](659e1087c9))
* add `p` naming scheme to smali compiler ([38556d6](38556d61ab))
* add extensions for cloning methods ([df7503b](df7503b47b))
* add findClass method with className ([78235d1](78235d1abe))
* Add first tests ([6767c8f](6767c8fbc1))
* add fuzzy resolver ([a492808](a492808021))
* add immutableMethod ([eed1cfd](eed1cfda7b))
* add inline smali compiler ([dbafe2a](dbafe2ab37))
* add missing test for fields ([4022b8b](4022b8b847))
* add or extension for AccessFlags ([aec5eeb](aec5eeb597))
* Add patch metadata ([8544fc4](8544fc4cbc)), closes [ReVancedTeam/revanced-patches#1](https://github.com/ReVancedTeam/revanced-patches/issues/1)
* Add warnings for Fuzzy resolver ([643a14e](643a14e664))
* allow classes to be overwritten in addFiles and resolve signatures when applyPatches is called ([5f71a34](5f71a342ac))
* Allow unknown opcodes using `null` ([f4a47d4](f4a47d4dc8))
* Finish first patcher test ([a9e4e8a](a9e4e8ac32))
* Improve `SignatureResolver` ([88a6a27](88a6a27302))
* migrate to dexlib ([be51f42](be51f42710))
* Minor refactor and return proxy, if class has been proxied already ([2d3c611](2d3c61113d))
* properly manage `ClassProxy` & add `ProxyBackedClassList` ([2319787](23197879b2))
* remaining mutable `EncodedValue` classes ([7d38bb0](7d38bb0baa))
* string signature ([#22](https://github.com/revanced/revanced-patcher/issues/22)) ([c245edb](c245edb0c5))

### Performance Improvements

* depend on `androlib` instead of `ApkDecoder` ([e5c054a](e5c054ac2f))
* do not resolve empty signatures list ([1f7bf3a](1f7bf3ac6c))
* lazy-ify all mutable clones ([05e4400](05e44007d8))
* optimize indexOf call away ([f8e978a](f8e978af88))
* use Set instead of List since there are no dupes ([6221387](622138736d))
* use String List and compare instead of any lambda ([aed4fd9](aed4fd9a3c))

### Reverts

* AccessFlag extensions not working with IDE ([e161f7f](e161f7fea4))
* previous commits check for dupes in dexFile, not cache ([433914f](433914feda))

### BREAKING CHANGES

* arrayOf has to be changed to listOf.
* Method signature of Patcher#save() was changed to comply with the changes of multidexlib2.
* Removed usage of ASM library
2022-05-07 03:19:37 +00:00
oSumAtrIX
83a8a48176 Merge pull request #16 from revanced/dalvik-patcher
feat: Dalvik patcher
2022-05-07 05:17:23 +02:00
oSumAtrIX
66b08f8b3a fix: failing tests temporarily
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-05-07 05:13:53 +02:00
oSumAtrIX
e286ba5090 Merge remote-tracking branch 'origin/dalvik-patcher' into dalvik-patcher 2022-05-07 05:07:35 +02:00
oSumAtrIX
e5c054ac2f perf: depend on androlib instead of ApkDecoder
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-05-07 05:07:27 +02:00
oSumAtrIX
cb0741d05f Merge pull request #30 from j4k0xb/dalvik-patcher
Add `p` naming scheme to smali compiler
2022-05-07 02:34:05 +02:00
j4k0xb
38556d61ab feat: add p naming scheme to smali compiler 2022-05-07 02:22:18 +02:00
oSumAtrIX
ce8021b482 Merge pull request #29 from autergame/dalvik-patcher
Replace ReVancedTeam with revanced in build.gradle.kts
2022-05-07 01:22:14 +02:00
autergame
243dba7751 Replace ReVancedTeam with revanced in build.gradle.kts 2022-05-06 20:17:10 -03:00
oSumAtrIX
698f759979 Merge pull request #28 from ReVancedTeam/resource-patcher
add: resource patcher
2022-05-04 23:59:04 +02:00
oSumAtrIX
1701da3dde add: resource patcher
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-05-04 23:46:04 +02:00
oSumAtrIX
37fa9949ec fix: reaching all constructors not possible
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-04-27 03:13:45 +02:00
oSumAtrIX
ac36d19693 fix: string signature in SignatureResolver
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-04-20 02:45:50 +02:00
oSumAtrIX
c245edb0c5 feat: string signature (#22)
* feat: string signature

Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>

* fix: signature in test

Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>

* fix: make string signature optional

Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>

* fix: use of `compareOpcodes` when comparing string signatures

Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>

* add: `PackageMetadata` for signatures

Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-04-19 21:51:50 +02:00
oSumAtrIX
1f7bf3ac6c perf: do not resolve empty signatures list
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-04-19 20:17:56 +02:00
oSumAtrIX
bfeeaf4435 fix: ConcurrentModificationException while iterating through proxies and modifying it
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-04-19 20:07:31 +02:00
oSumAtrIX
748d0abad0 refactor: resolve signatures automatically
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-04-19 19:54:59 +02:00
oSumAtrIX
569238ab76 add: applyProxies method
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-04-19 19:47:35 +02:00
oSumAtrIX
23197879b2 feat: properly manage ClassProxy & add ProxyBackedClassList
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-04-18 21:37:57 +02:00
oSumAtrIX
305a81793a fix: PackageMetadata
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-04-18 18:41:46 +02:00
oSumAtrIX
33f9211f98 add: PackageMetadata for signatures
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-04-18 18:24:56 +02:00
oSumAtrIX
864e38c069 fix: make methodMetadata nullable in MethodSignatureMetadata
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-04-18 03:43:08 +02:00
oSumAtrIX
659e1087c9 feat: add MethodWalker
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-04-17 18:43:54 +02:00
Lucaskyy
03700ffa51 fix: incorrect pattern offset 2022-04-16 21:38:06 +02:00
Lucaskyy
ae06d826e8 docs: fix improper docs for fuzzy resolver Warning 2022-04-15 10:38:24 +02:00
oSumAtrIX
5ca5188fc2 refactor: better naming for resolver warning parameters
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-04-15 08:51:56 +02:00
oSumAtrIX
f88c11820d fix: applying no patches throwing error
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-04-15 06:03:08 +02:00
oSumAtrIX
93e81ff047 refact: better parameter names for Warning
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-04-15 04:59:10 +02:00
Lucaskyy
d49df10a3c fix: fuzzy resolver warning params were turned around 2022-04-14 20:51:48 +02:00
Lucaskyy
04b49b8b66 fix: make warnings nullable instead of lateinit 2022-04-14 19:26:43 +02:00
Lucaskyy
5ddc63f979 refactor: remove all parameter names 2022-04-14 19:11:55 +02:00
Lucaskyy
82b1e66d54 fix: MethodSignature#resolved throwing an exception 2022-04-14 19:11:38 +02:00
Lucaskyy
fd630cd429 test: Add tests for unknown opcodes 2022-04-14 18:37:43 +02:00
Lucaskyy
f4a47d4dc8 feat: Allow unknown opcodes using null
This is the same as `??` in IDA signatures.
2022-04-14 18:29:37 +02:00
Lucaskyy
3bfc24fc16 chore: remove todo 2022-04-14 18:23:26 +02:00
Lucaskyy
25bba2c1d8 refactor: remove all @Suppression's 2022-04-14 16:45:16 +02:00
Lucaskyy
4dea27e831 refactor: format code 2022-04-14 16:44:02 +02:00
Lucaskyy
a0d6d46217 fix: Suppress unused for addFiles 2022-04-14 16:42:51 +02:00
Lucaskyy
643a14e664 feat: Add warnings for Fuzzy resolver 2022-04-14 16:42:16 +02:00
Lucaskyy
355e6d82cc docs: fix wrong wording 2022-04-14 12:33:31 +02:00
Lucaskyy
df7503b47b feat: add extensions for cloning methods 2022-04-14 12:31:38 +02:00
Lucaskyy
a01dded092 test: fix outdated test 2022-04-14 12:02:40 +02:00
Lucaskyy
9ae95174e6 refactor: replace asInstructions with toInstruction to follow proper naming scheme 2022-04-14 12:00:50 +02:00
Lucaskyy
e161f7fea4 revert: AccessFlag extensions not working with IDE 2022-04-14 11:59:23 +02:00
Lucaskyy
200e3c9fdb refactor: replace Array with Iterable 2022-04-14 11:53:08 +02:00
oSumAtrIX
f0f34031dd fix: replaceWith not replacing classes with used class proxies
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-04-14 11:00:25 +02:00
oSumAtrIX
560c485ab0 fix: null check causing an exception
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-04-14 10:44:15 +02:00
oSumAtrIX
cc5a414692 add: throw on getting result of MethodSignature if null
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-04-14 09:44:32 +02:00
oSumAtrIX
c2a334eb3f refact: include each signature in its corresponding patch
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-04-14 08:48:05 +02:00
Lucaskyy
1b2fbbca26 refactor: rename method to resolverMethod 2022-04-13 21:04:26 +02:00
Lucaskyy
4458141d6d fix: remove leftover debug code 2022-04-13 20:26:43 +02:00
Lucaskyy
8544fc4cbc feat: Add patch metadata
Fixes ReVancedTeam/revanced-patches#1
2022-04-13 20:25:51 +02:00
Lucaskyy
a492808021 feat: add fuzzy resolver
fixed docs for MethodSignature & added tests for fuzzy resolver
2022-04-13 20:17:31 +02:00
Lucaskyy
0204eee79e refactor: migrate signature schema changes to Patcher
also updated Extensions, for good measure.
2022-04-13 19:42:50 +02:00
oSumAtrIX
4022b8b847 feat: add missing test for fields
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-04-13 02:59:06 +02:00
oSumAtrIX
8daf877fac style: reformat code
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-04-13 02:47:53 +02:00
oSumAtrIX
7d38bb0baa feat: remaining mutable EncodedValue classes 2022-04-13 00:19:09 +02:00
Lucaskyy
5f71a342ac feat: allow classes to be overwritten in addFiles and resolve signatures when applyPatches is called 2022-04-12 19:11:07 +02:00
Lucaskyy
866b03af21 fix: always return PatchResultSuccess on patch success 2022-04-11 17:34:43 +02:00
Lucaskyy
4c1a42b216 add: optional callback for CLI 2022-04-11 17:27:12 +02:00
Lucaskyy
264989f488 refactor: Change all references from Array to Iterable
BREAKING CHANGE: arrayOf has to be changed to listOf.
2022-04-11 16:29:53 +02:00
oSumAtrIX
4281546f69 fix: adding existing classes to the patchers cache 2022-04-11 03:52:04 +02:00
Lucaskyy
af4f2396c7 chore: update kotlin, don't shade deps, publish to maven local, make deps api instead of implementation 2022-04-10 00:52:32 +02:00
Lucaskyy
147195647c fix: Classes not being written properly because of array shifting
We now use a MutableList to replace it at the proper index, and use a ListBackedSet, so we don't copy List's to Set's for no reason.
This was a very bad issue. The array was shifted every time we removed the original class, the fact we even got a "working" dex file surprises me. Thankfully, this issue is now solved, and we lived happily after.
2022-04-09 23:41:54 +02:00
Lucaskyy
433914feda revert: previous commits check for dupes in dexFile, not cache
This reverts commit aed4fd9a3c.
This reverts commit 622138736d.
2022-04-09 22:46:24 +02:00
Lucaskyy
622138736d perf: use Set instead of List since there are no dupes 2022-04-09 22:31:32 +02:00
Lucaskyy
aed4fd9a3c perf: use String List and compare instead of any lambda 2022-04-09 22:04:00 +02:00
Lucaskyy
32e645850d refactor: bump multidexlib2 to 2.5.2.r2
BREAKING CHANGE: Method signature of Patcher#save() was changed to comply with the changes of multidexlib2.
2022-04-09 20:33:22 +02:00
Lucaskyy
e45fc02aae ci: Fix Unauthorized error 2022-04-09 19:38:21 +02:00
Lucaskyy
e0d29cf450 refactor: bump multidexlib2, dexlib2 and smali 2022-04-09 18:20:12 +02:00
oSumAtrIX
2b888e381c add: addFiles method to merge additional dex containers 2022-04-09 04:51:31 +02:00
oSumAtrIX
f72dd68ec5 fix: throwing in case the opcode patterns do not match 2022-04-09 04:50:38 +02:00
Lucaskyy
3b68d5c65e fix: returning failure on success
oh wow, that's an oopsie
2022-04-09 00:03:21 +02:00
Lucaskyy
eed1cfda7b feat: add immutableMethod
added docs
2022-04-08 23:51:31 +02:00
Lucaskyy
8b70bb4290 fix: applyPatches not returning successful patches 2022-04-08 23:50:26 +02:00
Lucaskyy
dbda641d0c chore: format code 2022-04-08 23:28:32 +02:00
oSumAtrIX
5ae5e98f1f fix: compareSignatureToMethod not matching correctly in case opcodes are null 2022-04-08 23:25:44 +02:00
Lucaskyy
1ba40ab1cb refactor: make method a property 2022-04-08 23:15:40 +02:00
Lucaskyy
e9c119ebb1 refactor: cleanup SignatureResolver.kt 2022-04-08 22:59:20 +02:00
Lucaskyy
1bd6d1d5b8 test: fix test with previous changes 2022-04-08 22:59:03 +02:00
Lucaskyy
4e7378bd79 refactor: rename resolveAndGetMethod to method 2022-04-08 22:58:39 +02:00
Lucaskyy
28ed4793e3 refactor: cleanup Patcher.kt 2022-04-08 22:56:24 +02:00
Lucaskyy
312235b194 fix: use Array instead of Iterable for methodParameters 2022-04-08 22:55:40 +02:00
Lucaskyy
6ab21e5891 chore: move replace extension method to Extensions.kt 2022-04-08 22:55:12 +02:00
Lucaskyy
db8d1150c3 docs: fixup 2022-04-08 22:54:23 +02:00
Lucaskyy
8f778f38fe chore: publish jar with dependencies 2022-04-08 22:49:37 +02:00
oSumAtrIX
88a6a27302 feat: Improve SignatureResolver 2022-04-08 18:19:48 +02:00
oSumAtrIX
a9e4e8ac32 feat: Finish first patcher test 2022-04-06 23:10:52 +02:00
oSumAtrIX
d5e694c306 fix: Search method map for existing class proxy 2022-04-06 23:09:58 +02:00
oSumAtrIX
dde0a22642 add: MutableMethodImplementation.addInstructions extension 2022-04-06 23:09:16 +02:00
oSumAtrIX
9a67aa3ff4 add: TODO for mutable encoded value clones 2022-04-06 23:08:31 +02:00
oSumAtrIX
e69708f21e refactor: lazy initialize implementation field for mutable methods 2022-04-06 19:37:29 +02:00
oSumAtrIX
c49071aff7 fix: match to correct signature method parameters 2022-04-06 19:36:44 +02:00
oSumAtrIX
d15240d033 fix: Patcher not writing resolved methods 2022-04-06 19:36:02 +02:00
oSumAtrIX
6767c8fbc1 feat: Add first tests 2022-04-06 02:15:40 +02:00
oSumAtrIX
4543b36616 refactor: Improve SignatureResolver 2022-04-06 01:25:45 +02:00
oSumAtrIX
ec6d462ade refactor: Use String instead of CharSequence for method parameter signature 2022-04-06 01:25:10 +02:00
oSumAtrIX
84bc7e0dc7 fix: return mutable set of classes 2022-04-06 01:23:53 +02:00
oSumAtrIX
6ad51aad9a fix: write all classes 2022-04-05 04:45:43 +02:00
oSumAtrIX
b711b8001e fix: fix classes having multiple instances of fields 2022-04-05 03:54:16 +02:00
oSumAtrIX
12c10d8c64 fix: fix classes having multiple method instances 2022-04-05 03:52:00 +02:00
Lucaskyy
05e44007d8 perf: lazy-ify all mutable clones 2022-04-03 23:52:36 +02:00
Lucaskyy
dbafe2ab37 feat: add inline smali compiler 2022-04-03 23:51:01 +02:00
Lucaskyy
45a885dbde test: use findClass with className & cleanup 2022-03-31 23:22:57 +02:00
Lucaskyy
78235d1abe feat: add findClass method with className 2022-03-31 23:22:14 +02:00
Lucaskyy
aec5eeb597 feat: add or extension for AccessFlags 2022-03-31 22:46:46 +02:00
Lucaskyy
d98c9eeb30 style: reformat code 2022-03-31 22:46:12 +02:00
Lucaskyy
f8e978af88 perf: optimize indexOf call away 2022-03-31 22:45:22 +02:00
oSumAtrIX
86cb053566 docs: Document important parts of the code 2022-03-31 19:25:46 +02:00
oSumAtrIX
c1ccb70de4 refactor: Replacing original classes with mutated ones 2022-03-31 18:56:36 +02:00
oSumAtrIX
bb42fa3c6f fix: Fixed writer & signature resolver, improved tests & speed, minor refactoring 2022-03-31 18:37:35 +02:00
oSumAtrIX
2d3c61113d feat: Minor refactor and return proxy, if class has been proxied already 2022-03-30 19:15:00 +02:00
oSumAtrIX
6bc4e7eab7 fix: Move proxy package out of cache package 2022-03-30 15:12:47 +02:00
oSumAtrIX
be51f42710 feat: migrate to dexlib
BREAKING CHANGE: Removed usage of ASM library
2022-03-30 15:10:18 +02:00
semantic-release-bot
fa0412985c chore(release): 1.0.0-dev.8 [skip ci]
# [1.0.0-dev.8](https://github.com/ReVancedTeam/revanced-patcher/compare/v1.0.0-dev.7...v1.0.0-dev.8) (2022-03-24)

### Performance Improvements

* check type instead of class ([47eb493](47eb493f54))
2022-03-24 22:38:45 +00:00
Lucaskyy
0048788dd0 Merge remote-tracking branch 'origin/dev' into dev 2022-03-24 23:37:34 +01:00
Lucaskyy
47eb493f54 perf: check type instead of class
this is way better, thank you oSumAtrIX!
2022-03-24 23:37:28 +01:00
semantic-release-bot
6b1337e4fc chore(release): 1.0.0-dev.7 [skip ci]
# [1.0.0-dev.7](https://github.com/ReVancedTeam/revanced-patcher/compare/v1.0.0-dev.6...v1.0.0-dev.7) (2022-03-24)

### Bug Fixes

* **MethodResolver:** fix cd57a8c9a0 ([1af31b2](1af31b2aa3))
2022-03-24 22:31:58 +00:00
Lucaskyy
f4589db3a9 test: fix assert message 2022-03-24 23:31:01 +01:00
Lucaskyy
1af31b2aa3 fix(MethodResolver): fix cd57a8c9a0 2022-03-24 23:29:32 +01:00
semantic-release-bot
14f7667156 chore(release): 1.0.0-dev.6 [skip ci]
# [1.0.0-dev.6](https://github.com/ReVancedTeam/revanced-patcher/compare/v1.0.0-dev.5...v1.0.0-dev.6) (2022-03-24)

### Bug Fixes

* **MethodResolver:** strip labels nodes so opcode patterns match ([cd57a8c](cd57a8c9a0))
2022-03-24 21:49:47 +00:00
Lucaskyy
cd57a8c9a0 fix(MethodResolver): strip labels nodes so opcode patterns match
this commit is also a fix for 8d1bb5f3d9 because it corrupted the stack by completely removing the nodes
2022-03-24 22:48:34 +01:00
Lucaskyy
0d3beb353d Merge remote-tracking branch 'origin/dev' into dev 2022-03-24 21:38:22 +01:00
Lucaskyy
ddef338631 refactor: log as trace instead of debug
so there's less spam in console
2022-03-24 21:38:13 +01:00
semantic-release-bot
fc4b673087 chore(release): 1.0.0-dev.5 [skip ci]
# [1.0.0-dev.5](https://github.com/ReVancedTeam/revanced-patcher/compare/v1.0.0-dev.4...v1.0.0-dev.5) (2022-03-24)

### Bug Fixes

* **MethodResolver:** strip labels and line numbers so opcode patterns match ([8d1bb5f](8d1bb5f3d9))
2022-03-24 20:30:54 +00:00
Lucaskyy
8d1bb5f3d9 fix(MethodResolver): strip labels and line numbers so opcode patterns match 2022-03-24 21:27:44 +01:00
Lucaskyy
c8a017a4c0 refactor: only compute maxs and use existing stack frames 2022-03-24 19:45:13 +01:00
semantic-release-bot
51fb59a43c chore(release): 1.0.0-dev.4 [skip ci]
# [1.0.0-dev.4](https://github.com/ReVancedTeam/revanced-patcher/compare/v1.0.0-dev.3...v1.0.0-dev.4) (2022-03-23)

### Bug Fixes

* give ClassWriter a ClassReader for symtable ([e8f6973](e8f6973938))
2022-03-23 22:02:18 +00:00
Lucaskyy
a78715133c Merge remote-tracking branch 'origin/dev' into dev 2022-03-23 23:01:20 +01:00
Lucaskyy
e8f6973938 fix: give ClassWriter a ClassReader for symtable
removed SafeClassWriter as it was unused
2022-03-23 23:01:13 +01:00
semantic-release-bot
3cb1e01587 chore(release): 1.0.0-dev.3 [skip ci]
# [1.0.0-dev.3](https://github.com/ReVancedTeam/revanced-patcher/compare/v1.0.0-dev.2...v1.0.0-dev.3) (2022-03-23)

### Features

* add SafeClassWriter ([ca6b94d](ca6b94d943))
2022-03-23 21:34:05 +00:00
Lucaskyy
cb4ee207e1 Merge remote-tracking branch 'origin/dev' into dev 2022-03-23 22:32:58 +01:00
Lucaskyy
ca6b94d943 feat: add SafeClassWriter
the standard ClassWriter implementation uses the ClassLoader to find a common superclass. this won't work for us since we are not loading the JAR into the classpath. using this SafeClassWriter should fix that issue.
2022-03-23 22:32:50 +01:00
semantic-release-bot
6cdb6887d4 chore(release): 1.0.0-dev.2 [skip ci]
# [1.0.0-dev.2](https://github.com/ReVancedTeam/revanced-patcher/compare/v1.0.0-dev.1...v1.0.0-dev.2) (2022-03-23)

### Bug Fixes

* set marklimit to Integer.MAX_VALUE ([ab6453c](ab6453ca8a))
2022-03-23 21:10:02 +00:00
Lucaskyy
ab6453ca8a fix: set marklimit to Integer.MAX_VALUE 2022-03-23 22:08:51 +01:00
semantic-release-bot
e8182c17ad chore(release): 1.0.0-dev.1 [skip ci]
# 1.0.0-dev.1 (2022-03-23)

### Bug Fixes

* avoid ignoring test resources (fixes [#1](https://github.com/ReVancedTeam/revanced-patcher/issues/1)) ([d5a3c76](d5a3c76389))
* current must be calculated after increment ([5f12bab](5f12bab5df))
* **gradle:** publish source and javadocs ([87bbde5](87bbde5e06))
* **Io:** fix finding classes by name ([460d62a](460d62a24c))
* **Io:** JAR loading and saving ([#8](https://github.com/ReVancedTeam/revanced-patcher/issues/8)) ([4d98cbc](4d98cbc9e8))
* nullable signature members ([#10](https://github.com/ReVancedTeam/revanced-patcher/issues/10)) ([8db8893](8db8893ab1))
* Patch should have access to the Cache ([6c0f082](6c0f0823c9))
* remove broken code ([0e72a6e](0e72a6e85f))
* set index for insertAt to 0 by default ([1769132](1769132a9e))
* workflow on dev branch ([7e67daf](7e67daf878))

### Code Refactoring

* convert Patch to abstract class ([23e897a](23e897a7a9))
* Optimize Signature class ([#11](https://github.com/ReVancedTeam/revanced-patcher/issues/11)) ([49beec9](49beec9fc6))
* Rename `net.revanced` to `app.revanced` ([3ab42a9](3ab42a932c))

### Features

* Add `findParentMethod` utility method ([#4](https://github.com/ReVancedTeam/revanced-patcher/issues/4)) ([00c6ab7](00c6ab7faf))

### BREAKING CHANGES

* Array<Int> was changed to IntArray. This breaks existing patches.
* Package name was changed from "net.revanced" to "app.revanced"
* Method signature of execute() was changed to include the cache, this will break existing implementations of the Patch class.
* Patch class is now an abstract class. You must implement it. You can use anonymous implements, like done in the tests.
2022-03-23 19:01:41 +00:00
Lucaskyy
49beec9fc6 refactor: Optimize Signature class (#11)
BREAKING CHANGE: Array<Int> was changed to IntArray. This breaks existing patches.
2022-03-23 20:00:35 +01:00
Lucaskyy
3ab42a932c refactor: Rename net.revanced to app.revanced
BREAKING CHANGE: Package name was changed from "net.revanced" to "app.revanced"
2022-03-23 19:56:37 +01:00
oSumAtrIX
4d98cbc9e8 fix(Io): JAR loading and saving (#8)
* refactor: Complete rewrite of `Io`

* style: format code

* style: rewrite todos

* fix: use lateinit instead of nonnull assert for zipEntry

* fix: use lateinit instead of nonnull assert for jarEntry & reuse zipEntry

* docs: add docs to `Patcher`

* test: match output of patcher

* chore: add todo to `Io` for removing non-class files

Co-authored-by: Sculas <contact@sculas.xyz>
2022-03-23 19:56:35 +01:00
Lucaskyy
87bbde5e06 fix(gradle): publish source and javadocs 2022-03-23 19:56:34 +01:00
oSumAtrIX
8db8893ab1 fix: nullable signature members (#10)
This commit will allow "partial" signatures, basically we will be allowed to exclude members to match for the signature
2022-03-23 19:56:33 +01:00
oSumAtrIX
00c6ab7faf feat: Add findParentMethod utility method (#4)
* feat: Add `findParentMethod` utitly method

* refactor: add `resolveMethod` to `MethodResolver`

added some assertions and some tests

Co-authored-by: Lucaskyy <contact@sculas.xyz>
2022-03-23 19:56:31 +01:00
Bleuzen
460d62a24c fix(Io): fix finding classes by name 2022-03-23 19:55:40 +01:00
Lucaskyy
89e4b9f762 chore: push IntelliJ project files 2022-03-23 19:55:39 +01:00
Lucaskyy
a8fd7c00c3 refactor: target java 8 instead of java 17 2022-03-23 19:55:38 +01:00
Lucaskyy
1769132a9e fix: set index for insertAt to 0 by default 2022-03-23 19:55:37 +01:00
Lucaskyy
6c0f0823c9 fix: Patch should have access to the Cache
BREAKING CHANGE: Method signature of execute() was changed to include the cache, this will break existing implementations of the Patch class.
2022-03-23 19:55:35 +01:00
Lucaskyy
23e897a7a9 refactor: convert Patch to abstract class
BREAKING CHANGE: Patch class is now an abstract class. You must implement it. You can use anonymous implements, like done in the tests.
2022-03-23 19:55:34 +01:00
Lucaskyy
7e67daf878 fix: workflow on dev branch 2022-03-20 20:42:55 +01:00
Lucaskyy
593c83f29f style: remove tab 2022-03-20 20:39:47 +01:00
Sculas
72e123dd01 Merge pull request #3 from ReVancedTeam/ci-semantic-release
ci: add semantic-release
2022-03-20 20:34:31 +01:00
she11sh0cked
599a401ed9 ci: add gradle-semantic-release-plugin and remove the github release assets 2022-03-20 19:32:20 +01:00
she11sh0cked
3f8500b059 ci: add semantic-release 2022-03-20 19:03:05 +01:00
71 changed files with 2746 additions and 556 deletions

41
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,41 @@
name: Release
on:
push:
branches:
- main
- dev
pull_request:
branches:
- main
- dev
jobs:
release:
name: Release
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Setup JDK
uses: actions/setup-java@v2
with:
java-version: '17'
distribution: 'adopt'
cache: gradle
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: "lts/*"
- name: Make gradlew executable
run: chmod +x gradlew
- name: Build with Gradle
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./gradlew build
- name: Setup semantic-release
run: npm install -g semantic-release @semantic-release/git @semantic-release/changelog gradle-semantic-release-plugin -D
- name: Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npx semantic-release

15
.idea/git_toolbox_prj.xml generated Normal file
View File

@@ -0,0 +1,15 @@
<?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

@@ -0,0 +1,6 @@
<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>

6
.idea/vcs.xml generated
View File

@@ -1,5 +1,11 @@
<?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>

25
.releaserc Normal file
View File

@@ -0,0 +1,25 @@
{
"branches": [
"main",
{
"name": "dev",
"prerelease": true
}
],
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
"gradle-semantic-release-plugin",
[
"@semantic-release/git",
{
"assets": [
"CHANGELOG.md",
"gradle.properties"
]
}
],
"@semantic-release/github"
]
}

183
CHANGELOG.md Normal file
View File

@@ -0,0 +1,183 @@
# [1.0.0-dev.10](https://github.com/revanced/revanced-patcher/compare/v1.0.0-dev.9...v1.0.0-dev.10) (2022-05-07)
### Bug Fixes
* qualifying `Element` with wrong package ([4d74de4](https://github.com/revanced/revanced-patcher/commit/4d74de4061f26c0d7c17fabd849051b429d86033))
# [1.0.0-dev.9](https://github.com/revanced/revanced-patcher/compare/v1.0.0-dev.8...v1.0.0-dev.9) (2022-05-07)
### Bug Fixes
* `compareSignatureToMethod` not matching correctly in case opcodes are null ([5ae5e98](https://github.com/revanced/revanced-patcher/commit/5ae5e98f1f8e174d800bcc75723e1ed965d66196))
* `ConcurrentModificationException` while iterating through `proxies` and modifying it ([bfeeaf4](https://github.com/revanced/revanced-patcher/commit/bfeeaf443549c9a43279d83a0628c061a382beb9))
* `PackageMetadata` ([305a817](https://github.com/revanced/revanced-patcher/commit/305a81793a9a04fe4e8969f2d3b591b0f01e3b63))
* `replaceWith` not replacing classes with used class proxies ([f0f3403](https://github.com/revanced/revanced-patcher/commit/f0f34031dd4e618223f016f7c427d7c93ab8456a))
* adding existing classes to the patchers cache ([4281546](https://github.com/revanced/revanced-patcher/commit/4281546f69225ee90ec4c003f4313df41edf71a6))
* always return PatchResultSuccess on patch success ([866b03a](https://github.com/revanced/revanced-patcher/commit/866b03af217ad97dd2755bfdc0ffe5bcf723c949))
* applying no patches throwing error ([f88c118](https://github.com/revanced/revanced-patcher/commit/f88c11820dbdc0d1d52a49c9bcdb4f7caa9eb6eb))
* applyPatches not returning successful patches ([8b70bb4](https://github.com/revanced/revanced-patcher/commit/8b70bb42909434a5e59315502f6d54d7c7691f18))
* Classes not being written properly because of array shifting ([1471956](https://github.com/revanced/revanced-patcher/commit/147195647c3990ab78ba95e4b3000650e718b713))
* failing tests temporarily ([66b08f8](https://github.com/revanced/revanced-patcher/commit/66b08f8b3a8f31844c7e7bab4df4243521d4a431))
* fix classes having multiple instances of fields ([b711b80](https://github.com/revanced/revanced-patcher/commit/b711b8001e4845857fa6cc71b107f1c553b31e80))
* fix classes having multiple method instances ([12c10d8](https://github.com/revanced/revanced-patcher/commit/12c10d8c64422c4534c23467e367707e3b953f82))
* Fixed writer & signature resolver, improved tests & speed, minor refactoring ([bb42fa3](https://github.com/revanced/revanced-patcher/commit/bb42fa3c6f59b78a7223fc70edbe598ec181ee37))
* fuzzy resolver warning params were turned around ([d49df10](https://github.com/revanced/revanced-patcher/commit/d49df10a3ca6b472ce4a32d10cfe787ca243d47b))
* incorrect pattern offset ([03700ff](https://github.com/revanced/revanced-patcher/commit/03700ffa519e5f20b1a0d0ffe68f3fb504351ee5))
* make `methodMetadata` nullable in `MethodSignatureMetadata` ([864e38c](https://github.com/revanced/revanced-patcher/commit/864e38c06906a9e29271fe383d51a8ec6594a46c))
* make warnings nullable instead of lateinit ([04b49b8](https://github.com/revanced/revanced-patcher/commit/04b49b8b664e45e64e9561eca3353ffdeda91187))
* match to correct signature method parameters ([c49071a](https://github.com/revanced/revanced-patcher/commit/c49071aff78245f27c98a4760b361c30aa6340bc))
* MethodSignature#resolved throwing an exception ([82b1e66](https://github.com/revanced/revanced-patcher/commit/82b1e66d54bed1e4c335e0515b7ff3ec901fa6f8))
* Move proxy package out of cache package ([6bc4e7e](https://github.com/revanced/revanced-patcher/commit/6bc4e7eab742f5796f3041332c70495e3f993c9b))
* null check causing an exception ([560c485](https://github.com/revanced/revanced-patcher/commit/560c485ab08b08a213b58704b11b1e2f5f625080))
* Patcher not writing resolved methods ([d15240d](https://github.com/revanced/revanced-patcher/commit/d15240d0330a63c4b568fc5de3de861b8046cba4))
* reaching all constructors not possible ([37fa994](https://github.com/revanced/revanced-patcher/commit/37fa9949ec84ffd277f32b1cd554e92be41d35e4))
* remove leftover debug code ([4458141](https://github.com/revanced/revanced-patcher/commit/4458141d6d2e1b015c0d70a6e65e6c32a3cf17dc))
* return mutable set of classes ([84bc7e0](https://github.com/revanced/revanced-patcher/commit/84bc7e0dc76f0732613383accb803f2c52da98ac))
* returning failure on success ([3b68d5c](https://github.com/revanced/revanced-patcher/commit/3b68d5c65ec3082d1aa48525b4ee2a4163895a3b))
* Search method map for existing class proxy ([d5e694c](https://github.com/revanced/revanced-patcher/commit/d5e694c306a47f47b8d1078b5c9f8a742445cf7e))
* string signature in `SignatureResolver` ([ac36d19](https://github.com/revanced/revanced-patcher/commit/ac36d19693390db8f404ed30963aefb2fb7519e0))
* Suppress unused for addFiles ([a0d6d46](https://github.com/revanced/revanced-patcher/commit/a0d6d462170552929039d71eafa813fdfde215cb))
* throwing in case the opcode patterns do not match ([f72dd68](https://github.com/revanced/revanced-patcher/commit/f72dd68ec575ee0926ee668911ebb6f85b75f7d1))
* use Array instead of Iterable for methodParameters ([312235b](https://github.com/revanced/revanced-patcher/commit/312235b194cac01ddc3f03ecff32c7de4e48c29c))
* write all classes ([6ad51aa](https://github.com/revanced/revanced-patcher/commit/6ad51aad9a94d8dd5afb5e270138ef7161ccfb07))
### Code Refactoring
* bump multidexlib2 to 2.5.2.r2 ([32e6458](https://github.com/revanced/revanced-patcher/commit/32e645850d4cc74aa708984da03ae1606e696d20))
* Change all references from Array to Iterable ([264989f](https://github.com/revanced/revanced-patcher/commit/264989f48804ed637469436acf8165ac4b7be383))
### Features
* add `MethodWalker` ([659e108](https://github.com/revanced/revanced-patcher/commit/659e1087c9e7a33e04cd7eb728c01ed946335810))
* add `p` naming scheme to smali compiler ([38556d6](https://github.com/revanced/revanced-patcher/commit/38556d61ab192dfa84083d935ee3e9eee5450d06))
* add extensions for cloning methods ([df7503b](https://github.com/revanced/revanced-patcher/commit/df7503b47b1e2162d6ab666f8586c633c314016f))
* add findClass method with className ([78235d1](https://github.com/revanced/revanced-patcher/commit/78235d1abe267e6aaa086662ad69af7132b8ff74))
* Add first tests ([6767c8f](https://github.com/revanced/revanced-patcher/commit/6767c8fbc15ea18a61db53e1472483632077f62a))
* add fuzzy resolver ([a492808](https://github.com/revanced/revanced-patcher/commit/a4928080217451017a99cf158fd5cc9d650a5a9e))
* add immutableMethod ([eed1cfd](https://github.com/revanced/revanced-patcher/commit/eed1cfda7b89f03f4c61ac4401707e1a12e6efb3))
* add inline smali compiler ([dbafe2a](https://github.com/revanced/revanced-patcher/commit/dbafe2ab37b25480f3e218d94ced5af2e56cba68))
* add missing test for fields ([4022b8b](https://github.com/revanced/revanced-patcher/commit/4022b8b847e8767ace0da3f98ad72ab61a4c242b))
* add or extension for AccessFlags ([aec5eeb](https://github.com/revanced/revanced-patcher/commit/aec5eeb597f0e9968b43efa228c96e83175e031c))
* Add patch metadata ([8544fc4](https://github.com/revanced/revanced-patcher/commit/8544fc4cbcb5d7c1ac0f6fcae52882a00d2bacf5)), closes [ReVancedTeam/revanced-patches#1](https://github.com/ReVancedTeam/revanced-patches/issues/1)
* Add warnings for Fuzzy resolver ([643a14e](https://github.com/revanced/revanced-patcher/commit/643a14e664c7ff86580da683eaff9c486884ee2c))
* allow classes to be overwritten in addFiles and resolve signatures when applyPatches is called ([5f71a34](https://github.com/revanced/revanced-patcher/commit/5f71a342ac9c6aa64a4983156f595ae0832c30e8))
* Allow unknown opcodes using `null` ([f4a47d4](https://github.com/revanced/revanced-patcher/commit/f4a47d4dc893bb511ca2087a1a63bfc35888663f))
* Finish first patcher test ([a9e4e8a](https://github.com/revanced/revanced-patcher/commit/a9e4e8ac3203bdd62abcd1e366f08a2269919571))
* Improve `SignatureResolver` ([88a6a27](https://github.com/revanced/revanced-patcher/commit/88a6a2730296883e191543c2666f39f24c05d74d))
* migrate to dexlib ([be51f42](https://github.com/revanced/revanced-patcher/commit/be51f42710c1489ef4405700e56ffecee5e6552f))
* Minor refactor and return proxy, if class has been proxied already ([2d3c611](https://github.com/revanced/revanced-patcher/commit/2d3c61113dc9b76c43e93928ba11026fe0ad444e))
* properly manage `ClassProxy` & add `ProxyBackedClassList` ([2319787](https://github.com/revanced/revanced-patcher/commit/23197879b20906aac7563e5f8107305edd7ccb1b))
* remaining mutable `EncodedValue` classes ([7d38bb0](https://github.com/revanced/revanced-patcher/commit/7d38bb0baaeabade6a9e64d97e2dd6c20edd153f))
* string signature ([#22](https://github.com/revanced/revanced-patcher/issues/22)) ([c245edb](https://github.com/revanced/revanced-patcher/commit/c245edb0c5317c1bb884ea315a1a04b720f20dd5))
### Performance Improvements
* depend on `androlib` instead of `ApkDecoder` ([e5c054a](https://github.com/revanced/revanced-patcher/commit/e5c054ac2f68b00ac123a45ed56b9f150332a82d))
* do not resolve empty signatures list ([1f7bf3a](https://github.com/revanced/revanced-patcher/commit/1f7bf3ac6c77a71abd687f2ff6f7306a40654a1b))
* lazy-ify all mutable clones ([05e4400](https://github.com/revanced/revanced-patcher/commit/05e44007d81399791aa1bab1eead66b7ff662043))
* optimize indexOf call away ([f8e978a](https://github.com/revanced/revanced-patcher/commit/f8e978af888255d9c104a8275be1d9b091af3f96))
* use Set instead of List since there are no dupes ([6221387](https://github.com/revanced/revanced-patcher/commit/622138736dca6c0161171330801b7b5666594ec7))
* use String List and compare instead of any lambda ([aed4fd9](https://github.com/revanced/revanced-patcher/commit/aed4fd9a3c9e7f96c1e2c54b831c3fe7d3d720a2))
### Reverts
* AccessFlag extensions not working with IDE ([e161f7f](https://github.com/revanced/revanced-patcher/commit/e161f7fea449883b7ac0fb436ed4f7f2ff78af62))
* previous commits check for dupes in dexFile, not cache ([433914f](https://github.com/revanced/revanced-patcher/commit/433914feda3066102a073d6b3bc457d0fae87911))
### BREAKING CHANGES
* arrayOf has to be changed to listOf.
* Method signature of Patcher#save() was changed to comply with the changes of multidexlib2.
* Removed usage of ASM library
# [1.0.0-dev.8](https://github.com/ReVancedTeam/revanced-patcher/compare/v1.0.0-dev.7...v1.0.0-dev.8) (2022-03-24)
### Performance Improvements
* check type instead of class ([47eb493](https://github.com/ReVancedTeam/revanced-patcher/commit/47eb493f5425dc27a4d6e79e6b02a36ef760e8da))
# [1.0.0-dev.7](https://github.com/ReVancedTeam/revanced-patcher/compare/v1.0.0-dev.6...v1.0.0-dev.7) (2022-03-24)
### Bug Fixes
* **MethodResolver:** fix cd57a8c9a0db7e3ae5ad0bca202e5955930319ab ([1af31b2](https://github.com/ReVancedTeam/revanced-patcher/commit/1af31b2aa3772a7473c04d27bf835c8eae13438d))
# [1.0.0-dev.6](https://github.com/ReVancedTeam/revanced-patcher/compare/v1.0.0-dev.5...v1.0.0-dev.6) (2022-03-24)
### Bug Fixes
* **MethodResolver:** strip labels nodes so opcode patterns match ([cd57a8c](https://github.com/ReVancedTeam/revanced-patcher/commit/cd57a8c9a0db7e3ae5ad0bca202e5955930319ab))
# [1.0.0-dev.5](https://github.com/ReVancedTeam/revanced-patcher/compare/v1.0.0-dev.4...v1.0.0-dev.5) (2022-03-24)
### Bug Fixes
* **MethodResolver:** strip labels and line numbers so opcode patterns match ([8d1bb5f](https://github.com/ReVancedTeam/revanced-patcher/commit/8d1bb5f3d9da544cf6e3e3848bfcc56327cde810))
# [1.0.0-dev.4](https://github.com/ReVancedTeam/revanced-patcher/compare/v1.0.0-dev.3...v1.0.0-dev.4) (2022-03-23)
### Bug Fixes
* give ClassWriter a ClassReader for symtable ([e8f6973](https://github.com/ReVancedTeam/revanced-patcher/commit/e8f6973938c70002f04a86f329aa5b134f6ef649))
# [1.0.0-dev.3](https://github.com/ReVancedTeam/revanced-patcher/compare/v1.0.0-dev.2...v1.0.0-dev.3) (2022-03-23)
### Features
* add SafeClassWriter ([ca6b94d](https://github.com/ReVancedTeam/revanced-patcher/commit/ca6b94d943b7067aae87a4e282cfb323811c0462))
# [1.0.0-dev.2](https://github.com/ReVancedTeam/revanced-patcher/compare/v1.0.0-dev.1...v1.0.0-dev.2) (2022-03-23)
### Bug Fixes
* set marklimit to Integer.MAX_VALUE ([ab6453c](https://github.com/ReVancedTeam/revanced-patcher/commit/ab6453ca8a02af70da4468c1a63c68dde4d392ef))
# 1.0.0-dev.1 (2022-03-23)
### Bug Fixes
* avoid ignoring test resources (fixes [#1](https://github.com/ReVancedTeam/revanced-patcher/issues/1)) ([d5a3c76](https://github.com/ReVancedTeam/revanced-patcher/commit/d5a3c76389ba902c22ddc8b7ba1a110b7ff852df))
* current must be calculated after increment ([5f12bab](https://github.com/ReVancedTeam/revanced-patcher/commit/5f12bab5df97fbe6e2e62c1bf2814a2e682ab4f3))
* **gradle:** publish source and javadocs ([87bbde5](https://github.com/ReVancedTeam/revanced-patcher/commit/87bbde5e06d038d8f6ddaac391e1db397f5a5590))
* **Io:** fix finding classes by name ([460d62a](https://github.com/ReVancedTeam/revanced-patcher/commit/460d62a24c4cad05691c4b269c2faeda47fee3b7))
* **Io:** JAR loading and saving ([#8](https://github.com/ReVancedTeam/revanced-patcher/issues/8)) ([4d98cbc](https://github.com/ReVancedTeam/revanced-patcher/commit/4d98cbc9e8fe1e39b3d9d4185b3c5b4882093af6))
* nullable signature members ([#10](https://github.com/ReVancedTeam/revanced-patcher/issues/10)) ([8db8893](https://github.com/ReVancedTeam/revanced-patcher/commit/8db8893ab1bda55f11cc75db55c7c1a38f1d1b16))
* Patch should have access to the Cache ([6c0f082](https://github.com/ReVancedTeam/revanced-patcher/commit/6c0f0823c91dc643dd80205b1e840e59827bee06))
* remove broken code ([0e72a6e](https://github.com/ReVancedTeam/revanced-patcher/commit/0e72a6e85ff9a6035510680fc5e33ab0cd14144f))
* set index for insertAt to 0 by default ([1769132](https://github.com/ReVancedTeam/revanced-patcher/commit/1769132a9e29cf3a0c5ae0917209c83c138c0216))
* workflow on dev branch ([7e67daf](https://github.com/ReVancedTeam/revanced-patcher/commit/7e67daf8789c534bed0091a3975776eb95039acc))
### Code Refactoring
* convert Patch to abstract class ([23e897a](https://github.com/ReVancedTeam/revanced-patcher/commit/23e897a7a9125f4ac4266263e7dd94fe63a0bfa1))
* Optimize Signature class ([#11](https://github.com/ReVancedTeam/revanced-patcher/issues/11)) ([49beec9](https://github.com/ReVancedTeam/revanced-patcher/commit/49beec9fc6eee6ccf52a6185761a200a6ed2b16e))
* Rename `net.revanced` to `app.revanced` ([3ab42a9](https://github.com/ReVancedTeam/revanced-patcher/commit/3ab42a932c8d5027d554106dfe8e1299ebc1ac7f))
### Features
* Add `findParentMethod` utility method ([#4](https://github.com/ReVancedTeam/revanced-patcher/issues/4)) ([00c6ab7](https://github.com/ReVancedTeam/revanced-patcher/commit/00c6ab7fafe2a59dec0052cc5b7d1d16939076b2))
### BREAKING CHANGES
* Array<Int> was changed to IntArray. This breaks existing patches.
* Package name was changed from "net.revanced" to "app.revanced"
* Method signature of execute() was changed to include the cache, this will break existing implementations of the Patch class.
* Patch class is now an abstract class. You must implement it. You can use anonymous implements, like done in the tests.

View File

@@ -1,41 +1,65 @@
plugins {
kotlin("jvm") version "1.6.10"
kotlin("jvm") version "1.6.20"
java
`maven-publish`
}
group = "net.revanced"
group = "app.revanced"
repositories {
mavenCentral()
maven {
url = uri("https://maven.pkg.github.com/revanced/multidexlib2")
credentials {
// DO NOT set these variables in the project's gradle.properties.
// Instead, you should set them in:
// Windows: %homepath%\.gradle\gradle.properties
// Linux: ~/.gradle/gradle.properties
username = project.findProperty("gpr.user") as String? ?: System.getenv("GITHUB_ACTOR") // DO NOT CHANGE!
password = project.findProperty("gpr.key") as String? ?: System.getenv("GITHUB_TOKEN") // DO NOT CHANGE!
}
}
}
dependencies {
implementation(kotlin("stdlib"))
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("io.github.microutils:kotlin-logging:2.1.21")
testImplementation("ch.qos.logback:logback-classic:1.2.11") // use your own logger!
api("org.apktool:apktool-lib:2.6.1")
api("app.revanced:multidexlib2:2.5.2.r2")
api("org.smali:smali:2.5.2")
testImplementation(kotlin("test"))
}
tasks.test {
useJUnitPlatform()
testLogging {
events("PASSED", "SKIPPED", "FAILED")
tasks {
test {
useJUnitPlatform()
testLogging {
events("PASSED", "SKIPPED", "FAILED")
}
}
}
java {
withSourcesJar()
withJavadocJar()
}
val isGitHubCI = System.getenv("GITHUB_ACTOR") != null
publishing {
repositories {
maven {
name = "GitHubPackages"
url = uri("https://maven.pkg.github.com/ReVancedTeam/revanced-patcher")
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-patcher")
credentials {
username = System.getenv("GITHUB_ACTOR")
password = System.getenv("GITHUB_TOKEN")
}
}
} else {
mavenLocal()
}
}
publications {
@@ -43,4 +67,4 @@ publishing {
from(components["java"])
}
}
}
}

View File

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

View File

@@ -0,0 +1,209 @@
package app.revanced.patcher
import app.revanced.patcher.data.PatcherData
import app.revanced.patcher.data.base.Data
import app.revanced.patcher.data.implementation.findIndexed
import app.revanced.patcher.patch.base.Patch
import app.revanced.patcher.patch.implementation.BytecodePatch
import app.revanced.patcher.patch.implementation.ResourcePatch
import app.revanced.patcher.patch.implementation.metadata.PatchMetadata
import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess
import app.revanced.patcher.signature.MethodSignature
import app.revanced.patcher.signature.resolver.SignatureResolver
import app.revanced.patcher.util.ListBackedSet
import brut.androlib.Androlib
import brut.androlib.meta.UsesFramework
import brut.directory.ExtFile
import lanchon.multidexlib2.BasicDexFileNamer
import lanchon.multidexlib2.DexIO
import lanchon.multidexlib2.MultiDexIO
import org.jf.dexlib2.Opcodes
import org.jf.dexlib2.iface.ClassDef
import org.jf.dexlib2.iface.DexFile
import org.jf.dexlib2.writer.io.MemoryDataStore
import java.io.File
val NAMER = BasicDexFileNamer()
/**
* The ReVanced Patcher.
* @param inputFile The input file (usually an apk file).
* @param resourceCacheDirectory Directory to cache resources.
* @param patchResources Weather to use the resource patcher. Resources will still need to be decoded.
*/
class Patcher(
inputFile: File,
// TODO: maybe a file system in memory is better. Could cause high memory usage.
private val resourceCacheDirectory: String,
private val patchResources: Boolean = false
) {
val packageVersion: String
val packageName: String
private val usesFramework: UsesFramework
private val patcherData: PatcherData
private val opcodes: Opcodes
private var signaturesResolved = false
private val androlib = Androlib()
init {
val extFileInput = ExtFile(inputFile)
val resourceTable = androlib.getResTable(extFileInput, true)
val outDir = File(resourceCacheDirectory)
if (outDir.exists()) outDir.deleteRecursively()
outDir.mkdir()
// 1. decode resources to cache directory
androlib.decodeManifestWithResources(extFileInput, outDir, resourceTable)
androlib.decodeResourcesFull(extFileInput, outDir, resourceTable)
// 2. read framework ids from the resource table
usesFramework = UsesFramework()
usesFramework.ids = resourceTable.listFramePackages().map { it.id }.sorted()
// 3. read package info
packageName = resourceTable.packageOriginal
packageVersion = resourceTable.versionInfo.versionName
// read dex files
val dexFile = MultiDexIO.readDexFile(true, inputFile, NAMER, null, null)
opcodes = dexFile.opcodes
// save to patcher data
patcherData = PatcherData(dexFile.classes.toMutableList(), resourceCacheDirectory)
}
/**
* 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.
*/
fun addFiles(
files: Iterable<File>,
allowedOverwrites: Iterable<String> = emptyList(),
throwOnDuplicates: Boolean = false
) {
for (file in files) {
val dexFile = MultiDexIO.readDexFile(true, file, NAMER, null, null)
for (classDef in dexFile.classes) {
val e = patcherData.bytecodeData.classes.internalClasses.findIndexed { it.type == classDef.type }
if (e != null) {
if (throwOnDuplicates) {
throw Exception("Class ${classDef.type} has already been added to the patcher.")
}
val (_, idx) = e
if (allowedOverwrites.contains(classDef.type)) {
patcherData.bytecodeData.classes.internalClasses[idx] = classDef
}
continue
}
patcherData.bytecodeData.classes.internalClasses.add(classDef)
}
}
}
/**
* Save the patched dex file.
*/
fun save(): Map<String, MemoryDataStore> {
val newDexFile = object : DexFile {
override fun getClasses(): Set<ClassDef> {
patcherData.bytecodeData.classes.applyProxies()
return ListBackedSet(patcherData.bytecodeData.classes.internalClasses)
}
override fun getOpcodes(): Opcodes {
return this@Patcher.opcodes
}
}
// build modified resources
if (patchResources) {
val extDir = ExtFile(resourceCacheDirectory)
androlib.buildResources(extDir, usesFramework)
}
// write dex modified files
val output = mutableMapOf<String, MemoryDataStore>()
MultiDexIO.writeDexFile(
true, -1, // core count
output, NAMER, newDexFile,
DexIO.DEFAULT_MAX_DEX_POOL_SIZE,
null
)
return output
}
/**
* Add a patch to the patcher.
* @param patches The patches to add.
*/
fun addPatches(patches: Iterable<Patch<Data>>) {
patcherData.patches.addAll(patches)
}
/**
* Resolves all signatures.
*/
fun resolveSignatures(): List<MethodSignature> {
val signatures = buildList {
for (patch in patcherData.patches) {
if (patch !is BytecodePatch) continue
this.addAll(patch.signatures)
}
}
if (signatures.isEmpty()) {
return emptyList()
}
SignatureResolver(patcherData.bytecodeData.classes.internalClasses, signatures).resolve(patcherData)
signaturesResolved = true
return signatures
}
/**
* Apply patches loaded into the patcher.
* @param stopOnError If true, the patches will stop on the first error.
* @return A map of [PatchResultSuccess]. If the [Patch] was successfully applied,
* [PatchResultSuccess] will always be returned to the wrapping Result object.
* If the [Patch] failed to apply, an Exception will always be returned to the wrapping Result object.
*/
fun applyPatches(
stopOnError: Boolean = false,
callback: (String) -> Unit = {}
): Map<PatchMetadata, Result<PatchResultSuccess>> {
if (!signaturesResolved) {
resolveSignatures()
}
return buildMap {
for (patch in patcherData.patches) {
val resourcePatch = patch is ResourcePatch
if (!patchResources && resourcePatch) continue
callback(patch.metadata.shortName)
val result: Result<PatchResultSuccess> = try {
val data = if (resourcePatch) {
patcherData.resourceData
} else {
patcherData.bytecodeData
}
val pr = patch.execute(data)
if (pr.isSuccess()) {
Result.success(pr.success()!!)
} else {
Result.failure(Exception(pr.error()?.errorMessage() ?: "Unknown error"))
}
} catch (e: Exception) {
Result.failure(e)
}
this[patch.metadata] = result
if (result.isFailure && stopOnError) break
}
}
}
}

View File

@@ -0,0 +1,18 @@
package app.revanced.patcher.data
import app.revanced.patcher.data.base.Data
import app.revanced.patcher.data.implementation.BytecodeData
import app.revanced.patcher.data.implementation.ResourceData
import app.revanced.patcher.patch.base.Patch
import org.jf.dexlib2.iface.ClassDef
import java.io.File
internal data class PatcherData(
val internalClasses: MutableList<ClassDef>,
val resourceCacheDirectory: String
) {
internal val patches = mutableListOf<Patch<Data>>()
internal val bytecodeData = BytecodeData(patches, internalClasses)
internal val resourceData = ResourceData(File(resourceCacheDirectory))
}

View File

@@ -0,0 +1,9 @@
package app.revanced.patcher.data.base
import app.revanced.patcher.data.implementation.BytecodeData
import app.revanced.patcher.data.implementation.ResourceData
/**
* Constraint interface for [BytecodeData] and [ResourceData]
*/
interface Data

View File

@@ -0,0 +1,87 @@
package app.revanced.patcher.data.implementation
import app.revanced.patcher.data.base.Data
import app.revanced.patcher.methodWalker.MethodWalker
import app.revanced.patcher.patch.base.Patch
import app.revanced.patcher.patch.implementation.BytecodePatch
import app.revanced.patcher.proxy.ClassProxy
import app.revanced.patcher.signature.SignatureResolverResult
import app.revanced.patcher.util.ProxyBackedClassList
import org.jf.dexlib2.iface.ClassDef
import org.jf.dexlib2.iface.Method
class BytecodeData(
// FIXME: ugly solution due to design.
// It does not make sense for a BytecodeData instance to have access to the patches
private val patches: List<Patch<Data>>,
internalClasses: MutableList<ClassDef>
) : Data {
val classes = ProxyBackedClassList(internalClasses)
/**
* Find a class by a given class name
* @return A proxy for the first class that matches the class name
*/
fun findClass(className: String) = findClass { it.type.contains(className) }
/**
* Find a class by a given predicate
* @return A proxy for the first class that matches the predicate
*/
fun findClass(predicate: (ClassDef) -> Boolean): ClassProxy? {
// if we already proxied the class matching the predicate...
for (patch in patches) {
if (patch !is BytecodePatch) continue
for (signature in patch.signatures) {
val result = signature.result
result ?: continue
if (predicate(result.definingClassProxy.immutableClass)) return result.definingClassProxy // ...then return that proxy
}
}
// else resolve the class to a proxy and return it, if the predicate is matching a class
return classes.find(predicate)?.let {
proxy(it)
}
}
}
class MethodMap : LinkedHashMap<String, SignatureResolverResult>() {
override fun get(key: String): SignatureResolverResult {
return super.get(key) ?: throw MethodNotFoundException("Method $key was not found in the method cache")
}
}
internal class MethodNotFoundException(s: String) : Exception(s)
internal inline fun <reified T> Iterable<T>.find(predicate: (T) -> Boolean): T? {
for (element in this) {
if (predicate(element)) {
return element
}
}
return null
}
fun BytecodeData.toMethodWalker(startMethod: Method): MethodWalker {
return MethodWalker(this, startMethod)
}
internal inline fun <T> Iterable<T>.findIndexed(predicate: (T) -> Boolean): Pair<T, Int>? {
for ((index, element) in this.withIndex()) {
if (predicate(element)) {
return element to index
}
}
return null
}
fun BytecodeData.proxy(classDef: ClassDef): ClassProxy {
var proxy = this.classes.proxies.find { it.immutableClass.type == classDef.type }
if (proxy == null) {
proxy = ClassProxy(classDef)
this.classes.proxies.add(proxy)
}
return proxy
}

View File

@@ -0,0 +1,49 @@
package app.revanced.patcher.data.implementation
import app.revanced.patcher.data.base.Data
import org.w3c.dom.Document
import java.io.Closeable
import java.io.File
import javax.xml.XMLConstants
import javax.xml.parsers.DocumentBuilderFactory
import javax.xml.transform.TransformerFactory
import javax.xml.transform.dom.DOMSource
import javax.xml.transform.stream.StreamResult
class ResourceData(private val resourceCacheDirectory: File) : Data {
private fun resolve(path: String) = resourceCacheDirectory.resolve(path)
fun forEach(action: (File) -> Unit) = resourceCacheDirectory.walkTopDown().forEach(action)
fun reader(path: String) = resolve(path).reader()
fun writer(path: String) = resolve(path).writer()
fun replace(path: String, oldValue: String, newValue: String, oldValueIsRegex: Boolean = false) {
// TODO: buffer this somehow
val content = resolve(path).readText()
if (oldValueIsRegex) {
content.replace(Regex(oldValue), newValue)
return
}
}
fun getXmlEditor(path: String) = DomFileEditor(resolve(path))
}
class DomFileEditor internal constructor(private val domFile: File) : Closeable {
val file: Document
init {
val factory = DocumentBuilderFactory.newInstance()
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true)
val builder = factory.newDocumentBuilder()
// this will expectedly throw
file = builder.parse(domFile)
file.normalize()
}
override fun close() = TransformerFactory.newInstance().newTransformer()
.transform(DOMSource(file), StreamResult(domFile.outputStream()))
}

View File

@@ -0,0 +1,81 @@
package app.revanced.patcher.extensions
import app.revanced.patcher.proxy.mutableTypes.MutableMethod.Companion.toMutable
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.builder.BuilderInstruction
import org.jf.dexlib2.builder.MutableMethodImplementation
import org.jf.dexlib2.iface.Method
import org.jf.dexlib2.iface.reference.MethodReference
import org.jf.dexlib2.immutable.ImmutableMethod
import org.jf.dexlib2.immutable.ImmutableMethodImplementation
import org.jf.dexlib2.util.MethodUtil
infix fun AccessFlags.or(other: AccessFlags) = this.value or other.value
infix fun Int.or(other: AccessFlags) = this or other.value
fun MutableMethodImplementation.addInstructions(index: Int, instructions: List<BuilderInstruction>) {
for (i in instructions.lastIndex downTo 0) {
this.addInstruction(index, instructions[i])
}
}
/**
* Clones the method.
* @param registerCount This parameter allows you to change the register count of the method.
* This may be a positive or negative number.
* @return The **immutable** cloned method. Call [toMutable] or [cloneMutable] to get a **mutable** copy.
*/
internal fun Method.clone(
registerCount: Int = 0,
): ImmutableMethod {
val clonedImplementation = implementation?.let {
ImmutableMethodImplementation(
it.registerCount + registerCount,
it.instructions,
it.tryBlocks,
it.debugItems,
)
}
return ImmutableMethod(
returnType,
name,
parameters,
returnType,
accessFlags,
annotations,
hiddenApiRestrictions,
clonedImplementation
)
}
/**
* Clones the method.
* @param registerCount This parameter allows you to change the register count of the method.
* This may be a positive or negative number.
* @return The **mutable** cloned method. Call [clone] to get an **immutable** copy.
*/
internal fun Method.cloneMutable(
registerCount: Int = 0,
) = clone(registerCount).toMutable()
internal fun Method.softCompareTo(
otherMethod: MethodReference
): Boolean {
if (MethodUtil.isConstructor(this) && !parametersEqual(this.parameterTypes, otherMethod.parameterTypes))
return false
return this.name == otherMethod.name
}
// FIXME: also check the order of parameters as different order equals different method overload
internal fun parametersEqual(
parameters1: Iterable<CharSequence>,
parameters2: Iterable<CharSequence>
): Boolean {
return parameters1.count() == parameters2.count() && parameters1.all { parameter ->
parameters2.any {
it.startsWith(
parameter
)
}
}
}

View File

@@ -0,0 +1,55 @@
package app.revanced.patcher.methodWalker
import app.revanced.patcher.data.implementation.BytecodeData
import app.revanced.patcher.data.implementation.MethodNotFoundException
import app.revanced.patcher.extensions.softCompareTo
import app.revanced.patcher.proxy.mutableTypes.MutableMethod
import org.jf.dexlib2.Format
import org.jf.dexlib2.iface.Method
import org.jf.dexlib2.iface.instruction.formats.Instruction35c
import org.jf.dexlib2.iface.reference.MethodReference
import org.jf.dexlib2.util.Preconditions
/**
* Find a method from another method via instruction offsets.
* @param bytecodeData The bytecodeData to use when resolving the next method reference.
* @param currentMethod The method to start from.
*/
class MethodWalker internal constructor(
private val bytecodeData: BytecodeData,
private var currentMethod: Method
) {
/**
* Get the method which was walked last.
* It is possible to cast this method to a [MutableMethod], if the method has been walked mutably.
*/
fun getMethod(): Method {
return currentMethod
}
/**
* Walk to a method defined at the offset in the instruction list of the current method.
* @param offset The offset of the instruction. This instruction must be of format 35c.
* @param walkMutable If this is true, the class of the method will be resolved mutably.
* The current method will be mutable.
*/
fun walk(offset: Int, walkMutable: Boolean = false): MethodWalker {
currentMethod.implementation?.instructions?.let { instructions ->
val instruction = instructions.elementAt(offset)
Preconditions.checkFormat(instruction.opcode, Format.Format35c)
val newMethod = (instruction as Instruction35c).reference as MethodReference
val proxy = bytecodeData.findClass(newMethod.definingClass)!!
val methods = if (walkMutable) proxy.resolve().methods else proxy.immutableClass.methods
currentMethod = methods.first { it ->
return@first it.softCompareTo(newMethod)
}
return this
}
throw MethodNotFoundException("This method can not be walked at offset $offset inside the method ${currentMethod.name}")
}
}

View File

@@ -0,0 +1,22 @@
package app.revanced.patcher.patch.base
import app.revanced.patcher.data.base.Data
import app.revanced.patcher.patch.implementation.BytecodePatch
import app.revanced.patcher.patch.implementation.ResourcePatch
import app.revanced.patcher.patch.implementation.metadata.PatchMetadata
import app.revanced.patcher.patch.implementation.misc.PatchResult
/**
* A ReVanced patch.
* Can either be a [ResourcePatch] or a [BytecodePatch]
*/
abstract class Patch<out T : Data>(
open val metadata: PatchMetadata
) {
/**
* The main function of the [Patch] which the patcher will call.
*/
abstract fun execute(data: @UnsafeVariance T): PatchResult // FIXME: remove the UnsafeVariance annotation
}

View File

@@ -0,0 +1,16 @@
package app.revanced.patcher.patch.implementation
import app.revanced.patcher.data.implementation.BytecodeData
import app.revanced.patcher.patch.base.Patch
import app.revanced.patcher.patch.implementation.metadata.PatchMetadata
import app.revanced.patcher.signature.MethodSignature
/**
* Bytecode patch for the Patcher.
* @param metadata [PatchMetadata] for the patch.
* @param signatures A list of [MethodSignature] this patch relies on.
*/
abstract class BytecodePatch(
override val metadata: PatchMetadata,
val signatures: Iterable<MethodSignature>
) : Patch<BytecodeData>(metadata)

View File

@@ -0,0 +1,13 @@
package app.revanced.patcher.patch.implementation
import app.revanced.patcher.data.implementation.ResourceData
import app.revanced.patcher.patch.base.Patch
import app.revanced.patcher.patch.implementation.metadata.PatchMetadata
/**
* Resource patch for the Patcher.
* @param metadata [PatchMetadata] for the patch.
*/
abstract class ResourcePatch(
override val metadata: PatchMetadata
) : Patch<ResourceData>(metadata)

View File

@@ -0,0 +1,29 @@
package app.revanced.patcher.patch.implementation.metadata
import app.revanced.patcher.patch.base.Patch
/**
* Metadata about a [Patch].
* @param shortName A suggestive short name for the [Patch].
* @param name A suggestive name for the [Patch].
* @param description A description for the [Patch].
* @param compatiblePackages A list of packages this [Patch] is compatible with.
* @param version The version of the [Patch].
*/
data class PatchMetadata(
val shortName: String,
val name: String,
val description: String,
val compatiblePackages: Iterable<PackageMetadata>,
val version: String,
)
/**
* Metadata about a package.
* @param name The package name.
* @param versions Compatible versions of the package.
*/
data class PackageMetadata(
val name: String,
val versions: Iterable<String>
)

View File

@@ -1,4 +1,4 @@
package net.revanced.patcher.patch
package app.revanced.patcher.patch.implementation.misc
interface PatchResult {
fun error(): PatchResultError? {

View File

@@ -0,0 +1,41 @@
package app.revanced.patcher.proxy
import app.revanced.patcher.proxy.mutableTypes.MutableClass
import org.jf.dexlib2.iface.ClassDef
/**
* A proxy class for a [ClassDef].
*
* A class proxy simply holds a reference to the original class
* and allocates a mutable clone for the original class if needed.
* @param immutableClass The class to proxy
*/
class ClassProxy(
val immutableClass: ClassDef,
) {
internal var proxyUsed = false
internal lateinit var mutatedClass: MutableClass
init {
// in the instance, that a [MutableClass] is being proxied,
// do not create an additional clone and reuse the [MutableClass] instance
if (immutableClass is MutableClass) {
mutatedClass = immutableClass
proxyUsed = true
}
}
/**
* Allocates and returns a mutable clone of the original class.
* A patch should always use the original immutable class reference
* to avoid unnecessary allocations for the mutable class.
* @return A mutable clone of the original class.
*/
fun resolve(): MutableClass {
if (!proxyUsed) {
proxyUsed = true
mutatedClass = MutableClass(immutableClass)
}
return mutatedClass
}
}

View File

@@ -0,0 +1,29 @@
package app.revanced.patcher.proxy.mutableTypes
import app.revanced.patcher.proxy.mutableTypes.MutableAnnotationElement.Companion.toMutable
import org.jf.dexlib2.base.BaseAnnotation
import org.jf.dexlib2.iface.Annotation
class MutableAnnotation(annotation: Annotation) : BaseAnnotation() {
private val visibility = annotation.visibility
private val type = annotation.type
private val _elements by lazy { annotation.elements.map { element -> element.toMutable() }.toMutableSet() }
override fun getType(): String {
return type
}
override fun getElements(): MutableSet<MutableAnnotationElement> {
return _elements
}
override fun getVisibility(): Int {
return visibility
}
companion object {
fun Annotation.toMutable(): MutableAnnotation {
return MutableAnnotation(this)
}
}
}

View File

@@ -0,0 +1,34 @@
package app.revanced.patcher.proxy.mutableTypes
import app.revanced.patcher.proxy.mutableTypes.encodedValue.MutableEncodedValue
import app.revanced.patcher.proxy.mutableTypes.encodedValue.MutableEncodedValue.Companion.toMutable
import org.jf.dexlib2.base.BaseAnnotationElement
import org.jf.dexlib2.iface.AnnotationElement
import org.jf.dexlib2.iface.value.EncodedValue
class MutableAnnotationElement(annotationElement: AnnotationElement) : BaseAnnotationElement() {
private var name = annotationElement.name
private var value = annotationElement.value.toMutable()
fun setName(name: String) {
this.name = name
}
fun setValue(value: MutableEncodedValue) {
this.value = value
}
override fun getName(): String {
return name
}
override fun getValue(): EncodedValue {
return value
}
companion object {
fun AnnotationElement.toMutable(): MutableAnnotationElement {
return MutableAnnotationElement(this)
}
}
}

View File

@@ -0,0 +1,103 @@
package app.revanced.patcher.proxy.mutableTypes
import app.revanced.patcher.proxy.mutableTypes.MutableAnnotation.Companion.toMutable
import app.revanced.patcher.proxy.mutableTypes.MutableField.Companion.toMutable
import app.revanced.patcher.proxy.mutableTypes.MutableMethod.Companion.toMutable
import com.google.common.collect.Iterables
import org.jf.dexlib2.base.reference.BaseTypeReference
import org.jf.dexlib2.iface.ClassDef
import org.jf.dexlib2.util.FieldUtil
import org.jf.dexlib2.util.MethodUtil
class MutableClass(classDef: ClassDef) : ClassDef, BaseTypeReference() {
// Class
private var type = classDef.type
private var sourceFile = classDef.sourceFile
private var accessFlags = classDef.accessFlags
private var superclass = classDef.superclass
private val _interfaces by lazy { classDef.interfaces.toMutableList() }
private val _annotations by lazy {
classDef.annotations.map { annotation -> annotation.toMutable() }.toMutableSet()
}
// Methods
private val _methods by lazy { classDef.methods.map { method -> method.toMutable() }.toMutableSet() }
private val _directMethods by lazy { Iterables.filter(_methods, MethodUtil.METHOD_IS_DIRECT).toMutableSet() }
private val _virtualMethods by lazy { Iterables.filter(_methods, MethodUtil.METHOD_IS_VIRTUAL).toMutableSet() }
// Fields
private val _fields by lazy { classDef.fields.map { field -> field.toMutable() }.toMutableSet() }
private val _staticFields by lazy { Iterables.filter(_fields, FieldUtil.FIELD_IS_STATIC).toMutableSet() }
private val _instanceFields by lazy { Iterables.filter(_fields, FieldUtil.FIELD_IS_INSTANCE).toMutableSet() }
fun setType(type: String) {
this.type = type
}
fun setSourceFile(sourceFile: String?) {
this.sourceFile = sourceFile
}
fun setAccessFlags(accessFlags: Int) {
this.accessFlags = accessFlags
}
fun setSuperClass(superclass: String?) {
this.superclass = superclass
}
override fun getType(): String {
return type
}
override fun getAccessFlags(): Int {
return accessFlags
}
override fun getSourceFile(): String? {
return sourceFile
}
override fun getSuperclass(): String? {
return superclass
}
override fun getInterfaces(): MutableList<String> {
return _interfaces
}
override fun getAnnotations(): MutableSet<MutableAnnotation> {
return _annotations
}
override fun getStaticFields(): MutableSet<MutableField> {
return _staticFields
}
override fun getInstanceFields(): MutableSet<MutableField> {
return _instanceFields
}
override fun getFields(): MutableSet<MutableField> {
return _fields
}
override fun getDirectMethods(): MutableSet<MutableMethod> {
return _directMethods
}
override fun getVirtualMethods(): MutableSet<MutableMethod> {
return _virtualMethods
}
override fun getMethods(): MutableSet<MutableMethod> {
return _methods
}
companion object {
fun ClassDef.toMutable(): MutableClass {
return MutableClass(this)
}
}
}

View File

@@ -0,0 +1,73 @@
package app.revanced.patcher.proxy.mutableTypes
import app.revanced.patcher.proxy.mutableTypes.MutableAnnotation.Companion.toMutable
import app.revanced.patcher.proxy.mutableTypes.encodedValue.MutableEncodedValue
import app.revanced.patcher.proxy.mutableTypes.encodedValue.MutableEncodedValue.Companion.toMutable
import org.jf.dexlib2.HiddenApiRestriction
import org.jf.dexlib2.base.reference.BaseFieldReference
import org.jf.dexlib2.iface.Field
class MutableField(field: Field) : Field, BaseFieldReference() {
private var definingClass = field.definingClass
private var name = field.name
private var type = field.type
private var accessFlags = field.accessFlags
private var initialValue = field.initialValue?.toMutable()
private val _annotations by lazy { field.annotations.map { annotation -> annotation.toMutable() }.toMutableSet() }
private val _hiddenApiRestrictions by lazy { field.hiddenApiRestrictions }
fun setDefiningClass(definingClass: String) {
this.definingClass = definingClass
}
fun setName(name: String) {
this.name = name
}
fun setType(type: String) {
this.type = type
}
fun setAccessFlags(accessFlags: Int) {
this.accessFlags = accessFlags
}
fun setInitialValue(initialValue: MutableEncodedValue?) {
this.initialValue = initialValue
}
override fun getDefiningClass(): String {
return this.definingClass
}
override fun getName(): String {
return this.name
}
override fun getType(): String {
return this.type
}
override fun getAnnotations(): MutableSet<MutableAnnotation> {
return this._annotations
}
override fun getAccessFlags(): Int {
return this.accessFlags
}
override fun getHiddenApiRestrictions(): MutableSet<HiddenApiRestriction> {
return this._hiddenApiRestrictions
}
override fun getInitialValue(): MutableEncodedValue? {
return this.initialValue
}
companion object {
fun Field.toMutable(): MutableField {
return MutableField(this)
}
}
}

View File

@@ -0,0 +1,64 @@
package app.revanced.patcher.proxy.mutableTypes
import app.revanced.patcher.proxy.mutableTypes.MutableAnnotation.Companion.toMutable
import app.revanced.patcher.proxy.mutableTypes.MutableMethodParameter.Companion.toMutable
import org.jf.dexlib2.HiddenApiRestriction
import org.jf.dexlib2.base.reference.BaseMethodReference
import org.jf.dexlib2.builder.MutableMethodImplementation
import org.jf.dexlib2.iface.Method
class MutableMethod(method: Method) : Method, BaseMethodReference() {
private var definingClass = method.definingClass
private var name = method.name
private var accessFlags = method.accessFlags
private var returnType = method.returnType
// Create own mutable MethodImplementation (due to not being able to change members like register count)
private val _implementation by lazy { method.implementation?.let { MutableMethodImplementation(it) } }
private val _annotations by lazy { method.annotations.map { annotation -> annotation.toMutable() }.toMutableSet() }
private val _parameters by lazy { method.parameters.map { parameter -> parameter.toMutable() }.toMutableList() }
private val _parameterTypes by lazy { method.parameterTypes.toMutableList() }
private val _hiddenApiRestrictions by lazy { method.hiddenApiRestrictions }
override fun getDefiningClass(): String {
return definingClass
}
override fun getName(): String {
return name
}
override fun getParameterTypes(): MutableList<CharSequence> {
return _parameterTypes
}
override fun getReturnType(): String {
return returnType
}
override fun getAnnotations(): MutableSet<MutableAnnotation> {
return _annotations
}
override fun getAccessFlags(): Int {
return accessFlags
}
override fun getHiddenApiRestrictions(): MutableSet<HiddenApiRestriction> {
return _hiddenApiRestrictions
}
override fun getParameters(): MutableList<MutableMethodParameter> {
return _parameters
}
override fun getImplementation(): MutableMethodImplementation? {
return _implementation
}
companion object {
fun Method.toMutable(): MutableMethod {
return MutableMethod(this)
}
}
}

View File

@@ -0,0 +1,37 @@
package app.revanced.patcher.proxy.mutableTypes
import app.revanced.patcher.proxy.mutableTypes.MutableAnnotation.Companion.toMutable
import org.jf.dexlib2.base.BaseMethodParameter
import org.jf.dexlib2.iface.MethodParameter
// TODO: finish overriding all members if necessary
class MutableMethodParameter(parameter: MethodParameter) : MethodParameter, BaseMethodParameter() {
private var type = parameter.type
private var name = parameter.name
private var signature = parameter.signature
private val _annotations by lazy {
parameter.annotations.map { annotation -> annotation.toMutable() }.toMutableSet()
}
override fun getType(): String {
return type
}
override fun getName(): String? {
return name
}
override fun getSignature(): String? {
return signature
}
override fun getAnnotations(): MutableSet<MutableAnnotation> {
return _annotations
}
companion object {
fun MethodParameter.toMutable(): MutableMethodParameter {
return MutableMethodParameter(this)
}
}
}

View File

@@ -0,0 +1,33 @@
package app.revanced.patcher.proxy.mutableTypes.encodedValue
import app.revanced.patcher.proxy.mutableTypes.MutableAnnotationElement.Companion.toMutable
import org.jf.dexlib2.base.value.BaseAnnotationEncodedValue
import org.jf.dexlib2.iface.AnnotationElement
import org.jf.dexlib2.iface.value.AnnotationEncodedValue
class MutableAnnotationEncodedValue(annotationEncodedValue: AnnotationEncodedValue) : BaseAnnotationEncodedValue(),
MutableEncodedValue {
private var type = annotationEncodedValue.type
private val _elements by lazy {
annotationEncodedValue.elements.map { annotationElement -> annotationElement.toMutable() }.toMutableSet()
}
override fun getType(): String {
return this.type
}
fun setType(type: String) {
this.type = type
}
override fun getElements(): MutableSet<out AnnotationElement> {
return _elements
}
companion object {
fun AnnotationEncodedValue.toMutable(): MutableAnnotationEncodedValue {
return MutableAnnotationEncodedValue(this)
}
}
}

View File

@@ -0,0 +1,22 @@
package app.revanced.patcher.proxy.mutableTypes.encodedValue
import app.revanced.patcher.proxy.mutableTypes.encodedValue.MutableEncodedValue.Companion.toMutable
import org.jf.dexlib2.base.value.BaseArrayEncodedValue
import org.jf.dexlib2.iface.value.ArrayEncodedValue
import org.jf.dexlib2.iface.value.EncodedValue
class MutableArrayEncodedValue(arrayEncodedValue: ArrayEncodedValue) : BaseArrayEncodedValue(), MutableEncodedValue {
private val _value by lazy {
arrayEncodedValue.value.map { encodedValue -> encodedValue.toMutable() }.toMutableList()
}
override fun getValue(): MutableList<out EncodedValue> {
return _value
}
companion object {
fun ArrayEncodedValue.toMutable(): MutableArrayEncodedValue {
return MutableArrayEncodedValue(this)
}
}
}

View File

@@ -0,0 +1,23 @@
package app.revanced.patcher.proxy.mutableTypes.encodedValue
import org.jf.dexlib2.base.value.BaseBooleanEncodedValue
import org.jf.dexlib2.iface.value.BooleanEncodedValue
class MutableBooleanEncodedValue(booleanEncodedValue: BooleanEncodedValue) : BaseBooleanEncodedValue(),
MutableEncodedValue {
private var value = booleanEncodedValue.value
override fun getValue(): Boolean {
return this.value
}
fun setValue(value: Boolean) {
this.value = value
}
companion object {
fun BooleanEncodedValue.toMutable(): MutableBooleanEncodedValue {
return MutableBooleanEncodedValue(this)
}
}
}

View File

@@ -0,0 +1,22 @@
package app.revanced.patcher.proxy.mutableTypes.encodedValue
import org.jf.dexlib2.base.value.BaseByteEncodedValue
import org.jf.dexlib2.iface.value.ByteEncodedValue
class MutableByteEncodedValue(byteEncodedValue: ByteEncodedValue) : BaseByteEncodedValue(), MutableEncodedValue {
private var value = byteEncodedValue.value
override fun getValue(): Byte {
return this.value
}
fun setValue(value: Byte) {
this.value = value
}
companion object {
fun ByteEncodedValue.toMutable(): MutableByteEncodedValue {
return MutableByteEncodedValue(this)
}
}
}

View File

@@ -0,0 +1,22 @@
package app.revanced.patcher.proxy.mutableTypes.encodedValue
import org.jf.dexlib2.base.value.BaseCharEncodedValue
import org.jf.dexlib2.iface.value.CharEncodedValue
class MutableCharEncodedValue(charEncodedValue: CharEncodedValue) : BaseCharEncodedValue(), MutableEncodedValue {
private var value = charEncodedValue.value
override fun getValue(): Char {
return this.value
}
fun setValue(value: Char) {
this.value = value
}
companion object {
fun CharEncodedValue.toMutable(): MutableCharEncodedValue {
return MutableCharEncodedValue(this)
}
}
}

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