DexPatcher / dexpatcher-gradle

Modify Android applications at source-level in Android Studio
https://dexpatcher.github.io/
GNU General Public License v3.0
84 stars 17 forks source link

Invalid character for resource #21

Closed renaudcerrato closed 5 years ago

renaudcerrato commented 5 years ago

Patching a 3rd party APK fails because of some "invalid" characters found in resource names. For example :

res/drawable-v21/$avd_show_password__2.xml

I've read the whole XDA post, and I understand that's an aapt limitation, but it's still not clear to me what's the official recommended workaround. I'm not interested in patching those resources (if any at all).

Any recommendation?

Lanchon commented 5 years ago

yes. what version of the gradle plugin are you using?

renaudcerrato commented 5 years ago

I'm using the 2.0.0-alpha4 along with the Android Gradle plugin 3.3.2. I'm so excited about that tool, and I'd really like to give it a try 😏

Lanchon commented 5 years ago

as you've read, this is a limitation of AAPT. i really can't tell you much about the reason behind it all, i'm not too familiar. but apktool ran into the same issue, and their solution (as always have been for similar aapt limitations) is to bundle their own patched aapt2 that sidesteps the issue.

the android gradle plugin used to invoke the aapt1/2 binary that users installed as part of the android sdk. but this caused issues for them because it forced loose coupling between their gradle plugin and aapt. so to be able to upgrade them in lockstep, current versions of the android gradle plugin download the aapt binary they were designed to work with from google's maven repo, expand it into some temp dir, and run it form there.

i'm sure the android gradle plugin must provide a way to override the aapt2 version to use, but so far i haven't been able to find it. if you happen into some info about this, please share it.

anyway, my plan is to use this mechanism to direct google's plugin to use the aapt2 version patched by the apktool project. this should solve your issue and others too.

this is one of 2 showstopper issues preventing the my plugin to move form alpha to beta stage. (the other issue is not so much an issue but an enhancement: i want to get rid of the dependency on my own dexpatcher-gradle-tools local clone.)

Lanchon commented 5 years ago

as a workaround for you, you can try this:

instead of patching the apk directly, try patching an apklib. take a look at the apklib sample where there are 2 projects: one builds the apklib and the other consumes it. you can use a similar setup, except that you make the second project consume a copy of the apklib directly (place it in the dir you are placing the apk now) instead of consuming a reference to the first project. you get the apklib from the output of the first project. with this set up, try manually removing the offending files from the apklib. i've heard many times this produces a working apk anyway.

Lanchon commented 5 years ago

you can also try building using aapt v1 (requires android gradle plugin 3.2.x). dubious, but it might work.

also... MAYBE the android gradle plugin uses aapt v1 from the sdk instead of downloading it... MAYBE. in that case, you can take the patched aapt v1 from apktool and replace the one in the sdk so that the plugin will pick it up (yes, a mess).

sorry, these are all untested workarounds. i don't really have a lot of time for this for now.

Lanchon commented 5 years ago

i suggest:

before going deep into this issue, first check that the app you want to mod is not hardened with anti-tampering.

first try simply resigning the app. some apps will query their own signature and fail to work (or work incorrectly) if the result is unexpected. AFAIK, a resigned app will always work unless it implements anti-tampering.

next, try decoding and rebuilding with apktool. then sign and test. if it doesn't work, again, this is probably some anti-tampering at work.

please report your progress

renaudcerrato commented 5 years ago

Thanks for such details. Will definitely try to workaround it following your recommendations and will post my results asap (I already consumed most of the weekly time I dedicated to play with it). Dexpatcher reminds me the amazing Nokix tool, back from the early 2000's, used to patch Nokia DCT3 firmwares ☺️ Amazing job.

Lanchon commented 5 years ago

:) thanks!

Lanchon commented 5 years ago

SOLUTION (for dexpatcher-gradle 2.0.0-alpha4)

i didn't test any of this, but it should work. if it doesn't, point to a nonexistent file from android.aapt2FromMavenOverride to check that the android gradle plugin is picking up the config.

please report!

renaudcerrato commented 5 years ago

Using the Android Gradle plugin 3.2.x, the build is still using the downloaded aapt2 (using the --legacy switch) :

> java.util.concurrent.ExecutionException: com.android.builder.internal.aapt.v2.Aapt2Exception: Android resource compilation failed
  Output:  /home/renaud/Workspace/mexdium/app/build/intermediates/dexpatcher/decoded-app/res/values/public.xml:1724: error: resource 'drawable/$avd_hide_password__0' has invalid entry name '$avd_hide_password__0'. Invalid character '$avd_hide_password__0'.
  /home/renaud/Workspace/mexdium/app/build/intermediates/dexpatcher/decoded-app/res/values/public.xml:1725: error: resource 'drawable/$avd_hide_password__1' has invalid entry name '$avd_hide_password__1'. Invalid character '$avd_hide_password__1'.
  /home/renaud/Workspace/mexdium/app/build/intermediates/dexpatcher/decoded-app/res/values/public.xml:1726: error: resource 'drawable/$avd_hide_password__2' has invalid entry name '$avd_hide_password__2'. Invalid character '$avd_hide_password__2'.
  /home/renaud/Workspace/mexdium/app/build/intermediates/dexpatcher/decoded-app/res/values/public.xml:1727: error: resource 'drawable/$avd_show_password__0' has invalid entry name '$avd_show_password__0'. Invalid character '$avd_show_password__0'.
  /home/renaud/Workspace/mexdium/app/build/intermediates/dexpatcher/decoded-app/res/values/public.xml:1728: error: resource 'drawable/$avd_show_password__1' has invalid entry name '$avd_show_password__1'. Invalid character '$avd_show_password__1'.
  /home/renaud/Workspace/mexdium/app/build/intermediates/dexpatcher/decoded-app/res/values/public.xml:1729: error: resource 'drawable/$avd_show_password__2' has invalid entry name '$avd_show_password__2'. Invalid character '$avd_show_password__2'.

  Command: /home/renaud/.gradle/caches/transforms-2/files-2.1/77b9bd2d91c219867f78451fe2a10816/aapt2-3.2.1-4818971-linux/aapt2 compile --legacy \
          -o \
          /home/renaud/Workspace/mexdium/app/build/intermediates/dexpatcher/resource-id-mappings/debug \
          /home/renaud/Workspace/mexdium/app/build/intermediates/dexpatcher/decoded-app/res/values/public.xml

Unfortunately, using 3.3.2 along with the latest aapt2 from apktool (2.4.0), the gradle property android.aapt2FromMavenOverride raises a warning, but still fails :

Executing tasks: [:app:assembleDebug]

> Configure project :app
WARNING: The option setting 'android.aapt2FromMavenOverride=aapt2/linux/aapt2' is experimental and unsupported.

> Task :app:decodeApk UP-TO-DATE
> Task :app:provideDecodedApp

> Task :app:sourceAppInfo
minSdkVersion: '21'
targetSdkVersion: '28'
versionCode: '***'
versionName: ***

> Task :app:dedexAppClasses UP-TO-DATE
> Task :app:packExtraAppResources UP-TO-DATE
> Task :app:packAppComponents UP-TO-DATE
> Task :app:preBuild UP-TO-DATE
> Task :app:preDebugBuild UP-TO-DATE
> Task :app:compileDebugAidl NO-SOURCE
> Task :app:compileDebugRenderscript UP-TO-DATE
> Task :app:checkDebugManifest UP-TO-DATE
> Task :app:generateDebugBuildConfig UP-TO-DATE
> Task :app:prepareLintJar UP-TO-DATE
> Task :app:generateDebugSources UP-TO-DATE
> Task :app:javaPreCompileDebug
> Task :app:mainApkListPersistenceDebug UP-TO-DATE
> Task :app:generateDebugResValues
> Task :app:generateDebugResources
/home/renaud/Workspace/mexdium/app/build/intermediates/dexpatcher/decoded-app/res/values/public.xml:1724: error: resource 'drawable/$avd_hide_password__0' has invalid entry name '$avd_hide_password__0'. Invalid character '$avd_hide_password__0'.
/home/renaud/Workspace/mexdium/app/build/intermediates/dexpatcher/decoded-app/res/values/public.xml:1725: error: resource 'drawable/$avd_hide_password__1' has invalid entry name '$avd_hide_password__1'. Invalid character '$avd_hide_password__1'.
/home/renaud/Workspace/mexdium/app/build/intermediates/dexpatcher/decoded-app/res/values/public.xml:1726: error: resource 'drawable/$avd_hide_password__2' has invalid entry name '$avd_hide_password__2'. Invalid character '$avd_hide_password__2'.
/home/renaud/Workspace/mexdium/app/build/intermediates/dexpatcher/decoded-app/res/values/public.xml:1727: error: resource 'drawable/$avd_show_password__0' has invalid entry name '$avd_show_password__0'. Invalid character '$avd_show_password__0'.
/home/renaud/Workspace/mexdium/app/build/intermediates/dexpatcher/decoded-app/res/values/public.xml:1728: error: resource 'drawable/$avd_show_password__1' has invalid entry name '$avd_show_password__1'. Invalid character '$avd_show_password__1'.
/home/renaud/Workspace/mexdium/app/build/intermediates/dexpatcher/decoded-app/res/values/public.xml:1729: error: resource 'drawable/$avd_show_password__2' has invalid entry name '$avd_show_password__2'. Invalid character '$avd_show_password__2'.

> Task :app:processIdMappingsDebug

> Task :app:mergeDebugResources FAILED
/home/renaud/.gradle/caches/transforms-2/files-2.1/31e31bcf0cc227f192f699c127644bf0/res/drawable/$avd_hide_password__0.xml: Error: '$' is not a valid file-based resource name character: File-based resource names must contain only lowercase a-z, 0-9, or underscore

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:mergeDebugResources'.
> /home/renaud/.gradle/caches/transforms-2/files-2.1/31e31bcf0cc227f192f699c127644bf0/res/drawable/$avd_hide_password__0.xml: Error: '$' is not a valid file-based resource name character: File-based resource names must contain only lowercase a-z, 0-9, or underscore

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

Deprecated Gradle features were used in this build, making it incompatible with Gradle 6.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/5.1.1/userguide/command_line_interface.html#sec:command_line_warnings

BUILD FAILED in 1s
16 actionable tasks: 6 executed, 10 up-to-date

I'm sure he's picking the configuration, since pointing to an non-existing file instead of app/aapt2/linux/aapt2 makes the build fails:

ERROR: Custom AAPT2 location does not point to an AAPT2 executable: aapt2/linux/foo

Using an empty (executable) aapt2 file, the build also fails:

Execution failed for task ':app:processIdMappingsDebug'.
> java.util.concurrent.ExecutionException: com.android.builder.internal.aapt.v2.Aapt2InternalException: AAPT2 linux Daemon #0: Daemon startup failed
  This should not happen under normal circumstances, please file an issue if it does.

Decompiling/building the APK using apktool is working flawlessly, thus I'm sure I'm using the right aapt2, I can't see why it wouldn't works using the override :-/

➜ md5sum aapt2 && file aapt2   
b46bf054721fe58b108e492b6f2bc7c5  aapt2
aapt2: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, for GNU/Linux 2.6.24, stripped
renaudcerrato commented 5 years ago

Looking at the stacktrace, it seems that the exception is not thrown by aapt2 but here and here instead :

* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:mergeDebugResources'.
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:95)
        at org.gradle.api.internal.tasks.execution.ResolveTaskOutputCachingStateExecuter.execute(ResolveTaskOutputCachingStateExecuter.java:91)
        at org.gradle.api.internal.tasks.execution.ResolveBuildCacheKeyExecuter.execute(ResolveBuildCacheKeyExecuter.java:79)
        at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:57)
        at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:119)
        at org.gradle.api.internal.tasks.execution.ResolvePreviousStateExecuter.execute(ResolvePreviousStateExecuter.java:43)
        at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:93)
        at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:45)
        at org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute(ResolveTaskArtifactStateTaskExecuter.java:94)
        at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:56)
        at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:55)
        at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
        at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:67)
        at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
        at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:49)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:315)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:305)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:175)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:101)
        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)
        at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:49)
        at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:43)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:355)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:343)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:336)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:322)
        at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker$1.execute(DefaultPlanExecutor.java:134)
        at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker$1.execute(DefaultPlanExecutor.java:129)
        at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:202)
        at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:193)
        at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:129)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
        at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
        at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
Caused by: com.android.build.gradle.tasks.ResourceException: /home/renaud/.gradle/caches/transforms-2/files-2.1/31e31bcf0cc227f192f699c127644bf0/res/drawable/$avd_hide_password__0.xml: Error: '$' is not a valid file-based resource name character: File-based resource names must contain only lowercase a-z, 0-9, or underscore
        at com.android.build.gradle.tasks.MergeResources.doFullTaskAction(MergeResources.java:271)
        at com.android.build.gradle.internal.tasks.IncrementalTask.taskAction(IncrementalTask.java:106)
        at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:73)
        at org.gradle.api.internal.project.taskfactory.IncrementalTaskAction.doExecute(IncrementalTaskAction.java:47)
        at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:41)
        at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:28)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$2.run(ExecuteActionsTaskExecuter.java:284)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:301)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:293)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:175)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:273)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:258)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.access$200(ExecuteActionsTaskExecuter.java:67)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.execute(ExecuteActionsTaskExecuter.java:145)
        at org.gradle.internal.execution.impl.steps.ExecuteStep.execute(ExecuteStep.java:49)
        at org.gradle.internal.execution.impl.steps.CancelExecutionStep.execute(CancelExecutionStep.java:34)
        at org.gradle.internal.execution.impl.steps.TimeoutStep.executeWithoutTimeout(TimeoutStep.java:69)
        at org.gradle.internal.execution.impl.steps.TimeoutStep.execute(TimeoutStep.java:49)
        at org.gradle.internal.execution.impl.steps.CatchExceptionStep.execute(CatchExceptionStep.java:33)
        at org.gradle.internal.execution.impl.steps.CreateOutputsStep.execute(CreateOutputsStep.java:50)
        at org.gradle.internal.execution.impl.steps.SnapshotOutputStep.execute(SnapshotOutputStep.java:43)
        at org.gradle.internal.execution.impl.steps.SnapshotOutputStep.execute(SnapshotOutputStep.java:29)
        at org.gradle.internal.execution.impl.steps.CacheStep.executeWithoutCache(CacheStep.java:134)
        at org.gradle.internal.execution.impl.steps.CacheStep.lambda$execute$3(CacheStep.java:83)
        at org.gradle.internal.execution.impl.steps.CacheStep.execute(CacheStep.java:82)
        at org.gradle.internal.execution.impl.steps.CacheStep.execute(CacheStep.java:36)
        at org.gradle.internal.execution.impl.steps.PrepareCachingStep.execute(PrepareCachingStep.java:33)
        at org.gradle.internal.execution.impl.steps.StoreSnapshotsStep.execute(StoreSnapshotsStep.java:38)
        at org.gradle.internal.execution.impl.steps.StoreSnapshotsStep.execute(StoreSnapshotsStep.java:23)
        at org.gradle.internal.execution.impl.steps.SkipUpToDateStep.executeBecause(SkipUpToDateStep.java:96)
        at org.gradle.internal.execution.impl.steps.SkipUpToDateStep.lambda$execute$0(SkipUpToDateStep.java:89)
        at org.gradle.internal.execution.impl.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:52)
        at org.gradle.internal.execution.impl.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:36)
        at org.gradle.internal.execution.impl.DefaultWorkExecutor.execute(DefaultWorkExecutor.java:34)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:91)
        ... 33 more
Caused by: /home/renaud/.gradle/caches/transforms-2/files-2.1/31e31bcf0cc227f192f699c127644bf0/res/drawable/$avd_hide_password__0.xml: Error: '$' is not a valid file-based resource name character: File-based resource names must contain only lowercase a-z, 0-9, or underscore
        at com.android.ide.common.resources.MergingException.throwIfNonEmpty(MergingException.java:152)
        at com.android.ide.common.resources.DataSet.loadFromFiles(DataSet.java:256)
        at com.android.ide.common.resources.ResourceSet.loadFromFiles(ResourceSet.java:55)
        at com.android.build.gradle.tasks.MergeResources.doFullTaskAction(MergeResources.java:242)
        ... 69 more
Lanchon commented 5 years ago

thanks! nice digging around.

Using the Android Gradle plugin 3.2.x, the build is still using the downloaded aapt2

most likely, 3.2.x doesn't know about the override.

Unfortunately, using 3.3.2 [...] still fails

Task :app:mergeDebugResources FAILED

Looking at the stacktrace, it seems that the exception is not thrown by aapt2

the resources go though many stages in the process pipeline in dexpatcher, which is more complex than apktool. any one stage could check for filename validity. so we now know that the resource merger checks... tough luck.

possibilities:

after merger, resources get to aapt2.

btw, processing here didn't get to the point that aapt2 is invoked, so we don't know if the override trick works. dexpatcher uses incremental resource compilation and a separate resource linking step, and i don't know how apktool works or whether the patched aapt2 they provide.

anyway, for now you can still try this workaround: https://github.com/DexPatcher/dexpatcher-gradle/issues/21#issuecomment-496026218

Lanchon commented 5 years ago

~you know, the more i dig around this issue, the more i suspect that these /res/drawable-v21/$avd_(show|hide)_password__<n>.xml resources are a bug of some tool, and are never reference by the dex code and can simply be deleted.~

renaudcerrato commented 5 years ago

Mmm... Interesting thought. Will try the apklib workaround and also deleting them. Will keep you posted, but can't wait for 2.0.0-beta πŸ˜‰

Lanchon commented 5 years ago

i spent a long time planning for the move to per-tool gradle configurations to download the required tools at build time instead of relying on a local clone of dexpatcher-gradle-tools. the move involved adding new repo types to gradle, since the tools are published as github and bitbucket release artifacts. everything was coming into place, but unfortunately i came across this bug:

https://github.com/gradle/gradle/issues/5322

both gradle and github have bugs that precludes them from working together and no side is fixing their code. the alternative (regular download tasks) is ugly and potentially inefficient. so i decided to scrap all the work and keep the dexpatcher-gradle-tools repo.

:(

Lanchon commented 5 years ago

FYI, i discuss your specific case here: https://github.com/DexPatcher/dexpatcher-gradle/issues/22

Lanchon commented 5 years ago

SUCCESS!!! :-)

you need this gradle.properties:

android.disableResourceValidation=true
android.aapt2FromMavenOverride=aapt2/<platform>/<aapt2-file>

reference: https://github.com/DexPatcher/dexpatcher-gradle/issues/21#issuecomment-496038252

renaudcerrato commented 5 years ago

OMG! I assume you tested it already? Will try at home this weekend! Congratulations!

Lanchon commented 5 years ago

I assume you tested it already?

yes i did :)

renaudcerrato commented 5 years ago

Almost there:

* What went wrong:
Execution failed for task ':app:mergeDebugResources'.
> java.util.concurrent.ExecutionException: com.android.builder.internal.aapt.v2.Aapt2Exception: Android resource compilation failed
  /home/renaud/.gradle/caches/transforms-2/files-2.1/31e31bcf0cc227f192f699c127644bf0/res/values/styles.xml:4490:5-60: AAPT: error: invalid value for type 'style'. Expected a reference.

Looking at the incriminated file, there's indeed a suspicious invalid style:

...
    <item type="style" name="APKTOOL_DUMMY_9d">false</item>
</resources>

Looks like an apk tool issue anyway.

ttoommbb commented 5 years ago

same error. mark first.

Lanchon commented 5 years ago

Looks like an apk tool issue anyway.

yes, definitely. many obfuscation tools choke on malformed data that android never checks because maybe the resource is never referenced.

Apktool can't determine the type of the resource, so it can't reliably create a fake Style for these resources. Manual intervention to recreate the styles and/or remove them is the only solution.

i made the whole .apklib thingy precisely as a way to manually intervene problematic stuff. you can generate an apklib (which in the dxp 2.x branch is basically just the zipped output of apktool so you can create it yourself or use my plugin) and mod it. how to do this "manual intervention to recreate the styles and/or remove them" is beyond this project and should be taken to apktool. sorry about that :(

renaudcerrato commented 5 years ago

Yup. Thanks for the follow up. I guess you can close that issue! Great job!

Lanchon commented 5 years ago

UPDATE: solution here