1
mirror of https://github.com/revanced/revanced-patcher synced 2025-09-10 05:30:49 +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
127 changed files with 1819 additions and 12347 deletions

9
.gitattributes vendored
View File

@@ -1,9 +0,0 @@
#
# https://help.github.com/articles/dealing-with-line-endings/
#
# Linux start script should use lf
/gradlew text eol=lf
# These are Windows script files and should use crlf
*.bat text eol=crlf

View File

@@ -1,72 +0,0 @@
name: 🐞 Bug report
description: Report a very clearly broken issue.
title: 'bug: <title>'
labels: [bug]
body:
- type: markdown
attributes:
value: |
# ReVanced bug report
Important to note that your issue may have already been reported before. Please check for existing issues [here](https://github.com/revanced/revanced-patcher/labels/bug).
- type: dropdown
attributes:
label: Type
options:
- Crash
- Cosmetic
- Other
validations:
required: true
- type: textarea
attributes:
label: Bug description
description: How did you find the bug? Any additional details that might help?
validations:
required: true
- type: textarea
attributes:
label: Steps to reproduce
description: Add the steps to reproduce this bug including your environment.
placeholder: Step 1. Download some files. Step 2. ...
validations:
required: true
- type: textarea
attributes:
label: Relevant log output
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
render: shell
validations:
required: true
- type: textarea
attributes:
label: Screenshots or videos
description: Add screenshots or videos that show the bug here.
placeholder: Drag and drop the screenshots/videos into this box.
validations:
required: false
- type: textarea
attributes:
label: Solution
description: If applicable, add a possible solution.
validations:
required: false
- type: textarea
attributes:
label: Additional context
description: Add additional context here.
validations:
required: false
- type: checkboxes
id: acknowledgements
attributes:
label: Acknowledgements
description: Your issue will be closed if you haven't done these steps.
options:
- label: I have searched the existing issues and this is a new and no duplicate or related to another open issue.
required: true
- label: I have written a short but informative title.
required: true
- label: I filled out all of the requested information in this issue properly.
required: true

View File

@@ -1,8 +0,0 @@
blank_issues_enabled: false
contact_links:
- name: 📃 Documentation
url: https://github.com/revanced/revanced-documentation/
about: Don't know how or where to start? Check out our documentation!
- name: 🗨 Discussions
url: https://github.com/revanced/revanced-suggestions/discussions
about: Got something you think should change or be added? Search for or start a new discussion!

View File

@@ -1,58 +0,0 @@
name: ⭐ Feature request
description: Create a detailed feature request.
title: 'feat: <title>'
labels: [feature-request]
body:
- type: markdown
attributes:
value: |
# ReVanced feature request
Do not submit requests for patches here. Please submit them [here](https://github.com/orgs/revanced/discussions/categories/patches) instead.
Important to note that your feature request may have already been made before. Please check for existing feature requests [here](https://github.com/revanced/revanced-patcher/labels/feature-request).
- type: dropdown
attributes:
label: Type
options:
- Functionality
- Cosmetic
- Other
validations:
required: true
- type: textarea
attributes:
label: Issue
description: What is the current problem. Why does it require a feature request?
validations:
required: true
- type: textarea
attributes:
label: Feature
description: Describe your feature in detail. How does it solve the issue?
validations:
required: true
- type: textarea
attributes:
label: Motivation
description: Why should your feature should be considered?
validations:
required: true
- type: textarea
attributes:
label: Additional context
description: Add additional context here.
validations:
required: false
- type: checkboxes
id: acknowledgements
attributes:
label: Acknowledgements
description: Your issue will be closed if you haven't done these steps.
options:
- label: I have searched the existing issues and this is a new and no duplicate or related to another open issue.
required: true
- label: I have written a short but informative title.
required: true
- label: I filled out all of the requested information in this issue properly.
required: true

2
.github/config.yml vendored
View File

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

View File

@@ -1,25 +0,0 @@
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,7 +1,5 @@
name: Release
on:
workflow_dispatch:
push:
branches:
- main
@@ -10,36 +8,34 @@ on:
branches:
- main
- dev
jobs:
release:
name: Release
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v2
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: Cache
uses: actions/cache@v3
- name: Setup JDK
uses: actions/setup-java@v2
with:
path: |
${{ runner.home }}/.gradle/caches
${{ runner.home }}/.gradle/wrapper
.gradle
build
node_modules
key: ${{ runner.os }}-gradle-npm-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties', 'package-lock.json') }}
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 clean --no-daemon
run: ./gradlew build
- name: Setup semantic-release
run: npm install
run: npm install -g semantic-release @semantic-release/git @semantic-release/changelog gradle-semantic-release-plugin -D
- name: Release
env:
GITHUB_TOKEN: ${{ secrets.REPOSITORY_PUSH_ACCESS }}
run: npm exec semantic-release
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npx semantic-release

7
.gitignore vendored
View File

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

8
.idea/.gitignore generated vendored Normal file
View File

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

10
.idea/codeStyles/Project.xml generated Normal file
View File

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

5
.idea/codeStyles/codeStyleConfig.xml generated Normal file
View File

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

7
.idea/discord.xml generated Normal file
View File

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

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>

10
.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,10 @@
<?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 Normal file
View File

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

@@ -20,18 +20,6 @@
]
}
],
[
"@saithodev/semantic-release-backmerge",
{
backmergeBranches: [{"from": "main", "to": "dev"}],
clearWorkspace: true
}
],
[
"@semantic-release/github",
{
successComment: false
}
]
"@semantic-release/github"
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1 @@
# 💉 ReVanced Patcher
ReVanced Patcher used to patch Android applications.
# Patcher

View File

@@ -1,42 +0,0 @@
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

View File

@@ -1,18 +0,0 @@
plugins {
kotlin("jvm")
`maven-publish`
}
group = "app.revanced"
dependencies {
implementation("io.github.reandroid:ARSCLib:1.1.7")
}
java {
withSourcesJar()
}
kotlin {
jvmToolchain(11)
}

View File

@@ -1,72 +0,0 @@
package app.revanced.arsc
/**
* An exception thrown when there is an error with APK resources.
*
* @param message The exception message.
* @param throwable The corresponding [Throwable].
*/
sealed class ApkResourceException(message: String, throwable: Throwable? = null) : Exception(message, throwable) {
/**
* An exception when locking resources.
*
* @param message The exception message.
* @param throwable The corresponding [Throwable].
*/
class Locked(message: String, throwable: Throwable? = null) : ApkResourceException(message, throwable)
/**
* An exception when writing resources.
*
* @param message The exception message.
* @param throwable The corresponding [Throwable].
*/
class Write(message: String, throwable: Throwable? = null) : ApkResourceException(message, throwable)
/**
* An exception when reading resources.
*
* @param message The exception message.
* @param throwable The corresponding [Throwable].
*/
class Read(message: String, throwable: Throwable? = null) : ApkResourceException(message, throwable)
/**
* An exception when decoding resources.
*
* @param message The exception message.
* @param throwable The corresponding [Throwable].
*/
class Decode(message: String, throwable: Throwable? = null) : ApkResourceException(message, throwable)
/**
* An exception when encoding resources.
*
* @param message The exception message.
* @param throwable The corresponding [Throwable].
*/
class Encode(message: String, throwable: Throwable? = null) : ApkResourceException(message, throwable)
/**
* An exception thrown when a reference could not be resolved.
*
* @param reference The invalid reference.
* @param throwable The corresponding [Throwable].
*/
class InvalidReference(reference: String, throwable: Throwable? = null) :
ApkResourceException("Failed to resolve: $reference", throwable) {
/**
* An exception thrown when a reference could not be resolved.
*
* @param type The type of the reference.
* @param name The name of the reference.
* @param throwable The corresponding [Throwable].
*/
constructor(type: String, name: String, throwable: Throwable? = null) : this("@$type/$name", throwable)
}
/**
* An exception thrown when the Apk file not have a resource table, but was expected to have one.
*/
class MissingResourceTable : ApkResourceException("Apk does not have a resource table.")
}

View File

@@ -1,28 +0,0 @@
@file:Suppress("MemberVisibilityCanBePrivate")
package app.revanced.arsc.archive
import app.revanced.arsc.resource.ResourceContainer
import com.reandroid.apk.ApkModule
import com.reandroid.apk.DexFileInputSource
import com.reandroid.archive.InputSource
import java.io.File
import java.io.Flushable
/**
* A class for reading/writing files in an [ApkModule].
*
* @param module The [ApkModule] to operate on.
*/
class Archive(internal val module: ApkModule) : Flushable {
val mainPackageResources = ResourceContainer(this, module.tableBlock)
fun save(output: File) {
flush()
module.writeApk(output)
}
fun readDexFiles(): MutableList<DexFileInputSource> = module.listDexFiles()
fun write(inputSource: InputSource) = module.apkArchive.add(inputSource) // Overwrites existing files.
fun read(name: String): InputSource? = module.apkArchive.getInputSource(name)
override fun flush() = mainPackageResources.flush()
}

View File

@@ -1,7 +0,0 @@
package app.revanced.arsc.logging
interface Logger {
fun error(msg: String)
fun warn(msg: String)
fun info(msg: String)
fun trace(msg: String)
}

View File

@@ -1,166 +0,0 @@
package app.revanced.arsc.resource
import app.revanced.arsc.ApkResourceException
import com.reandroid.arsc.coder.EncodeResult
import com.reandroid.arsc.coder.ValueDecoder
import com.reandroid.arsc.value.Entry
import com.reandroid.arsc.value.ValueType
import com.reandroid.arsc.value.array.ArrayBag
import com.reandroid.arsc.value.array.ArrayBagItem
import com.reandroid.arsc.value.plurals.PluralsBag
import com.reandroid.arsc.value.plurals.PluralsBagItem
import com.reandroid.arsc.value.plurals.PluralsQuantity
import com.reandroid.arsc.value.style.StyleBag
import com.reandroid.arsc.value.style.StyleBagItem
/**
* A resource value.
*/
sealed class Resource {
internal abstract fun write(entry: Entry, resources: ResourceContainer)
}
internal val Resource.isComplex get() = when (this) {
is Scalar -> false
is Complex -> true
}
/**
* A simple resource.
*/
open class Scalar internal constructor(private val valueType: ValueType, private val value: Int) : Resource() {
protected open fun data(resources: ResourceContainer) = value
override fun write(entry: Entry, resources: ResourceContainer) {
entry.setValueAsRaw(valueType, data(resources))
}
internal open fun toArrayItem(resources: ResourceContainer) = ArrayBagItem.create(valueType, data(resources))
internal open fun toStyleItem(resources: ResourceContainer) = StyleBagItem.create(valueType, data(resources))
}
/**
* A marker class for complex resources.
*/
sealed class Complex : Resource()
private fun encoded(encodeResult: EncodeResult?) = encodeResult?.let { Scalar(it.valueType, it.value) }
?: throw ApkResourceException.Encode("Failed to encode value")
/**
* Encode a color.
*
* @param hex The hex value of the color.
* @return The encoded [Resource].
*/
fun color(hex: String) = encoded(ValueDecoder.encodeColor(hex))
/**
* Encode a dimension or fraction.
*
* @param value The dimension value such as 24dp.
* @return The encoded [Resource].
*/
fun dimension(value: String) = encoded(ValueDecoder.encodeDimensionOrFraction(value))
/**
* Encode a boolean resource.
*
* @param value The boolean.
* @return The encoded [Resource].
*/
fun boolean(value: Boolean) = Scalar(ValueType.INT_BOOLEAN, if (value) -Int.MAX_VALUE else 0)
/**
* Encode a float.
*
* @param n The number to encode.
* @return The encoded [Resource].
*/
fun float(n: Float) = Scalar(ValueType.FLOAT, n.toBits())
/**
* Create an integer [Resource].
*
* @param n The number to encode.
* @return The integer [Resource].
*/
fun integer(n: Int) = Scalar(ValueType.INT_DEC, n)
/**
* Create a reference [Resource].
*
* @param resourceId The target resource.
* @return The reference resource.
*/
fun reference(resourceId: Int) = Scalar(ValueType.REFERENCE, resourceId)
/**
* Resolve and create a reference [Resource].
*
* @see reference
* @param ref The reference string to resolve.
* @param resourceTable The resource table to resolve the reference with.
* @return The reference resource.
*/
fun reference(resourceTable: ResourceTable, ref: String) = reference(resourceTable.resolve(ref))
/**
* An array [Resource].
*
* @param elements The elements of the array.
*/
class Array(private val elements: Collection<Scalar>) : Complex() {
override fun write(entry: Entry, resources: ResourceContainer) {
ArrayBag.create(entry).addAll(elements.map { it.toArrayItem(resources) })
}
}
/**
* A style resource.
*
* @param elements The attributes to override.
* @param parent A reference to the parent style.
*/
class Style(private val elements: Map<String, Scalar>, private val parent: String? = null) : Complex() {
override fun write(entry: Entry, resources: ResourceContainer) {
val resTable = resources.resourceTable
val style = StyleBag.create(entry)
parent?.let {
style.parentId = resTable.resolve(parent)
}
style.putAll(
elements.asIterable().associate {
StyleBag.resolve(resTable.encodeMaterials, it.key) to it.value.toStyleItem(resources)
})
}
}
/**
* A quantity string [Resource].
*
* @param elements A map of the quantity to the corresponding string.
*/
class Plurals(private val elements: Map<String, String>) : Complex() {
override fun write(entry: Entry, resources: ResourceContainer) {
val plurals = PluralsBag.create(entry)
plurals.putAll(elements.asIterable().associate { (k, v) ->
PluralsQuantity.value(k) to PluralsBagItem.string(resources.getOrCreateString(v))
})
}
}
/**
* A string [Resource].
*
* @param value The string value.
*/
class StringResource(val value: String) : Scalar(ValueType.STRING, 0) {
private fun tableString(resources: ResourceContainer) = resources.getOrCreateString(value)
override fun data(resources: ResourceContainer) = tableString(resources).index
override fun toArrayItem(resources: ResourceContainer) = ArrayBagItem.string(tableString(resources))
override fun toStyleItem(resources: ResourceContainer) = StyleBagItem.string(tableString(resources))
}

View File

@@ -1,167 +0,0 @@
package app.revanced.arsc.resource
import app.revanced.arsc.ApkResourceException
import app.revanced.arsc.archive.Archive
import com.reandroid.apk.xmlencoder.EncodeUtil
import com.reandroid.arsc.chunk.TableBlock
import com.reandroid.arsc.chunk.xml.ResXmlDocument
import com.reandroid.arsc.value.Entry
import com.reandroid.arsc.value.ResConfig
import java.io.Closeable
import java.io.File
import java.io.Flushable
class ResourceContainer(private val archive: Archive, internal val tableBlock: TableBlock) : Flushable {
private val packageBlock = tableBlock.pickOne() // Pick the main package block.
internal lateinit var resourceTable: ResourceTable // TODO: Set this.
private val lockedResourceFileNames = mutableSetOf<String>()
private fun lock(resourceFile: ResourceFile) {
if (resourceFile.name in lockedResourceFileNames) {
throw ApkResourceException.Locked("Resource file ${resourceFile.name} is already locked.")
}
lockedResourceFileNames.add(resourceFile.name)
}
private fun unlock(resourceFile: ResourceFile) {
lockedResourceFileNames.remove(resourceFile.name)
}
fun <T : ResourceFile> openResource(name: String): ResourceFileEditor<T> {
val inputSource = archive.read(name)
?: throw ApkResourceException.Read("Resource file $name not found.")
val resourceFile = when {
ResXmlDocument.isResXmlBlock(inputSource.openStream()) -> {
val xmlDocument = archive.module
.loadResXmlDocument(inputSource)
.decodeToXml(resourceTable.entryStore, packageBlock.id)
ResourceFile.XmlResourceFile(name, xmlDocument)
}
else -> {
val bytes = inputSource.openStream().use { it.readAllBytes() }
ResourceFile.BinaryResourceFile(name, bytes)
}
}
try {
@Suppress("UNCHECKED_CAST")
return ResourceFileEditor(resourceFile as T).also {
lockedResourceFileNames.add(name)
}
} catch (e: ClassCastException) {
throw ApkResourceException.Decode("Resource file $name is not ${resourceFile::class}.", e)
}
}
inner class ResourceFileEditor<T : ResourceFile> internal constructor(
private val resourceFile: T,
) : Closeable {
fun use(block: (T) -> Unit) = block(resourceFile)
override fun close() {
lockedResourceFileNames.remove(resourceFile.name)
}
}
override fun flush() {
TODO("Not yet implemented")
}
/**
* Open a resource file, creating it if the file does not exist.
*
* @param path The resource file path.
* @return The corresponding [ResourceFiles],
*/
fun openFile(path: String) = ResourceFiles(createHandle(path), archive)
private fun getPackageBlock() = packageBlock ?: throw ApkResourceException.MissingResourceTable
internal fun getOrCreateString(value: String) =
tableBlock?.stringPool?.getOrCreate(value) ?: throw ApkResourceException.MissingResourceTable
private fun Entry.set(resource: Resource) {
val existingEntryNameReference = specReference
// Sets this.specReference if the entry is not yet initialized.
// Sets this.specReference to 0 if the resource type of the existing entry changes.
ensureComplex(resource.isComplex)
if (existingEntryNameReference != 0) {
// Preserve the entry name by restoring the previous spec block reference (if present).
specReference = existingEntryNameReference
}
resource.write(this, this@ResourceContainer)
resourceTable.registerChanged(this)
}
/**
* Retrieve an [Entry] from the resource table.
*
* @param type The resource type.
* @param name The resource name.
* @param qualifiers The variant to use.
*/
private fun getEntry(type: String, name: String, qualifiers: String?): Entry? {
val resourceId = try {
resourceTable.resolve("@$type/$name")
} catch (_: ApkResourceException.InvalidReference) {
return null
}
val config = ResConfig.parse(qualifiers)
return tableBlock?.resolveReference(resourceId)?.singleOrNull { it.resConfig == config }
}
/**
* Create a [ResourceFiles.Handle] that can be used to open a [ResourceFiles].
* This may involve looking it up in the resource table to find the actual location in the archive.
*
* @param path The path of the resource.
*/
private fun createHandle(path: String): ResourceFiles.Handle {
if (path.startsWith("res/values")) throw ApkResourceException.Decode("Decoding the resource table as a file is not supported")
var onClose = {}
var archivePath = path
if (tableBlock != null && path.startsWith("res/") && path.count { it == '/' } == 2) {
val file = File(path)
val qualifiers = EncodeUtil.getQualifiersFromResFile(file)
val type = EncodeUtil.getTypeNameFromResFile(file)
val name = file.nameWithoutExtension
// The resource file names that the app developers used may have been minified, so we have to resolve it with the resource table.
// Example: res/drawable-hdpi/icon.png -> res/4a.png
getEntry(type, name, qualifiers)?.resValue?.valueAsString?.let {
archivePath = it
} ?: run {
// An entry for this specific resource file was not found in the resource table, so we have to register it after we save.
onClose = { setResource(type, name, StringResource(archivePath), qualifiers) }
}
}
return ResourceFiles.Handle(path, archivePath, onClose)
}
fun setResource(type: String, entryName: String, resource: Resource, qualifiers: String? = null) =
getPackageBlock().getOrCreate(qualifiers, type, entryName).also { it.set(resource) }.resourceId
fun setResources(type: String, resources: Map<String, Resource>, configuration: String? = null) {
getPackageBlock().getOrCreateSpecTypePair(type).getOrCreateTypeBlock(configuration).apply {
resources.forEach { (entryName, resource) -> getOrCreateEntry(entryName).set(resource) }
}
}
override fun flush() {
packageBlock?.name = archive
}
}

View File

@@ -1,91 +0,0 @@
package app.revanced.arsc.resource
import app.revanced.arsc.ApkResourceException
import app.revanced.arsc.archive.Archive
import com.reandroid.archive.InputSource
import com.reandroid.xml.XMLDocument
import com.reandroid.xml.XMLException
import java.io.*
abstract class ResourceFile(val name: String) {
internal var realName: String? = null
class XmlResourceFile(name: String, val document: XMLDocument) : ResourceFile(name)
class BinaryResourceFile(name: String, var bytes: ByteArray) : ResourceFile(name)
}
class ResourceFiles private constructor(
) : Closeable {
/**
* Instantiate a [ResourceFiles].
*
* @param handle The [Handle] associated with this file.
* @param archive The [Archive] that the file resides in.
*/
internal constructor(handle: Handle, archive: Archive) : this(
handle,
archive,
try {
archive.read(handle.archivePath)
} catch (e: XMLException) {
throw ApkResourceException.Decode("Failed to decode XML while reading ${handle.virtualPath}", e)
} catch (e: IOException) {
throw ApkResourceException.Decode("Could not read ${handle.virtualPath}", e)
}
)
companion object {
const val DEFAULT_BUFFER_SIZE = 1024
}
var contents = readResult?.data ?: ByteArray(0)
set(value) {
pendingWrite = true
field = value
}
val exists = readResult != null
override fun toString() = handle.virtualPath
override fun close() {
if (pendingWrite) {
val path = handle.archivePath
if (isXmlResource) archive.writeXml(
path,
try {
XMLDocument.load(inputStream())
} catch (e: XMLException) {
throw ApkResourceException.Encode("Failed to parse XML while writing ${handle.virtualPath}", e)
}
) else archive.writeRaw(path, contents)
}
handle.onClose()
archive.unlock(this)
}
fun inputStream(): InputStream = ByteArrayInputStream(contents)
fun outputStream(bufferSize: Int = DEFAULT_BUFFER_SIZE): OutputStream =
object : ByteArrayOutputStream(bufferSize) {
override fun close() {
this@ResourceFiles.contents = if (buf.size > count) buf.copyOf(count) else buf
super.close()
}
}
/**
* @param virtualPath The resource file path. Example: /res/drawable-hdpi/icon.png.
* @param archivePath The actual file path in the archive. Example: res/4a.png.
* @param onClose An action to perform when the file associated with this handle is closed
*/
internal data class Handle(val virtualPath: String, val archivePath: String, val onClose: () -> Unit)
}

View File

@@ -1,100 +0,0 @@
package app.revanced.arsc.resource
import app.revanced.arsc.ApkResourceException
import com.reandroid.apk.xmlencoder.EncodeException
import com.reandroid.apk.xmlencoder.EncodeMaterials
import com.reandroid.arsc.util.FrameworkTable
import com.reandroid.arsc.value.Entry
import com.reandroid.common.TableEntryStore
/**
* A high-level API for resolving resources in the resource table, which spans the entire ApkBundle.
*/
class ResourceTable(base: ResourceContainer, all: Sequence<ResourceContainer>) {
private val packageName = base.tableBlock!!.name
/**
* A [TableEntryStore] used to decode XML.
*/
internal val entryStore = TableEntryStore()
/**
* The [EncodeMaterials] to use for resolving resources and encoding XML.
*/
internal val encodeMaterials: EncodeMaterials = object : EncodeMaterials() {
/*
Our implementation is more efficient because it does not have to loop through every single entry group
when the resource id cannot be found in the TableIdentifier, which does not update when you create a new resource.
It also looks at the entire table instead of just the current package.
*/
override fun resolveLocalResourceId(type: String, name: String) = resolveLocal(type, name)
}
/**
* The resource mappings which are generated when the ApkBundle is created.
*/
private val tableIdentifier = encodeMaterials.tableIdentifier
/**
* A table of all the resources that have been changed or added.
*/
private val modifiedResources = HashMap<String, HashMap<String, Int>>()
/**
* Resolve a resource id for the specified resource.
* Cannot resolve resources from the android framework.
*
* @param type The type of the resource.
* @param name The name of the resource.
* @return The id of the resource.
*/
fun resolveLocal(type: String, name: String) =
modifiedResources[type]?.get(name)
?: tableIdentifier.get(packageName, type, name)?.resourceId
?: throw ApkResourceException.InvalidReference(
type,
name
)
/**
* Resolve a resource id for the specified resource.
*
* @param reference The resource reference string.
* @return The id of the resource.
*/
fun resolve(reference: String) = try {
encodeMaterials.resolveReference(reference)
} catch (e: EncodeException) {
throw ApkResourceException.InvalidReference(reference, e)
}
/**
* Notify the [ResourceTable] that an [Entry] has been created or modified.
*/
internal fun registerChanged(entry: Entry) {
modifiedResources.getOrPut(entry.typeName, ::HashMap)[entry.name] = entry.resourceId
}
init {
all.forEach {
it.tableBlock?.let { table ->
entryStore.add(table)
tableIdentifier.load(table)
}
it.resourceTable = this
}
base.also {
encodeMaterials.currentPackage = it.tableBlock
it.tableBlock!!.frameWorks.forEach { fw ->
if (fw is FrameworkTable) {
entryStore.add(fw)
encodeMaterials.addFramework(fw)
}
}
}
}
}

View File

@@ -1,56 +0,0 @@
package app.revanced.arsc.xml
import app.revanced.arsc.resource.ResourceContainer
import app.revanced.arsc.resource.boolean
import com.reandroid.apk.xmlencoder.EncodeException
import com.reandroid.apk.xmlencoder.XMLEncodeSource
import com.reandroid.arsc.chunk.xml.ResXmlDocument
import com.reandroid.xml.XMLDocument
import com.reandroid.xml.XMLElement
import com.reandroid.xml.source.XMLDocumentSource
/**
* Archive input source to lazily encode an [XMLDocument] after it has been modified.
*
* @param name The file name of this input source.
* @param document The [XMLDocument] to encode.
* @param resources The [ResourceContainer] to use for encoding.
*/
internal class LazyXMLEncodeSource(
name: String,
val document: XMLDocument,
private val resources: ResourceContainer
) : XMLEncodeSource(resources.resourceTable.encodeMaterials, XMLDocumentSource(name, document)) {
private var encoded = false
override fun getResXmlBlock(): ResXmlDocument {
if (encoded) return super.getResXmlBlock()
XMLEncodeSource(resources.resourceTable.encodeMaterials, XMLDocumentSource(name, document))
fun XMLElement.registerIds() {
listAttributes().forEach { attr ->
if (!attr.value.startsWith("@+id/")) return@forEach
val name = attr.value.split('/').last()
resources.setResource("id", name, boolean(false))
attr.value = "@id/$name"
}
listChildElements().forEach { it.registerIds() }
}
// Handle all @+id/id_name references in the document.
document.documentElement.registerIds()
encoded = true
// This will call XMLEncodeSource.getResXmlBlock(),
// which will encode the document if it has not already been encoded.
try {
return super.getResXmlBlock()
} catch (e: EncodeException) {
throw EncodeException("Failed to encode $name", e)
}
}
}

View File

@@ -1,3 +1,70 @@
plugins {
kotlin("jvm") version "1.8.20" apply false
kotlin("jvm") version "1.6.20"
java
`maven-publish`
}
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"))
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")
}
}
}
java {
withSourcesJar()
withJavadocJar()
}
val isGitHubCI = System.getenv("GITHUB_ACTOR") != null
publishing {
repositories {
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 {
register<MavenPublication>("gpr") {
from(components["java"])
}
}
}

View File

@@ -1,4 +1,2 @@
org.gradle.parallel=true
org.gradle.caching=true
kotlin.code.style = official
version = 11.0.4
version = 1.0.0-dev.10

Binary file not shown.

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