Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalid character for resource #21

Closed
renaudcerrato opened this issue May 26, 2019 · 24 comments
Closed

Invalid character for resource #21

renaudcerrato opened this issue May 26, 2019 · 24 comments

Comments

@renaudcerrato
Copy link

renaudcerrato commented May 26, 2019

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
Copy link
Member

Lanchon commented May 26, 2019

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

@renaudcerrato
Copy link
Author

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
Copy link
Member

Lanchon commented May 26, 2019

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
Copy link
Member

Lanchon commented May 26, 2019

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
Copy link
Member

Lanchon commented May 26, 2019

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
Copy link
Member

Lanchon commented May 26, 2019

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
Copy link
Author

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
Copy link
Member

Lanchon commented May 26, 2019

:) thanks!

@Lanchon
Copy link
Member

Lanchon commented May 26, 2019

SOLUTION (for dexpatcher-gradle 2.0.0-alpha4)

  • download latest apktool
  • extract aapt2 64-bit for your platform from apktool.jar/prebuilt/<platform>
  • remove the _64 part from the filename
  • place it in an aapt2/<platform> directory you create in your dexpatcher project (possibly not your root gradle project)
  • create a gradle.properties file in your dexpatcher project
  • add a entry to it like this:
    android.aapt2FromMavenOverride=aapt2/<platform>/<aapt2-file>

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
Copy link
Author

renaudcerrato commented May 27, 2019

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
Copy link
Author

renaudcerrato commented May 27, 2019

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
Copy link
Member

Lanchon commented May 28, 2019

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:

  • rewrite/patch the resource merger myself. but i don't really want to do this.
  • forward the invalid files to the output of the merger (precluding processing on those files).
  • rename incoming and outgoing merger files to quote invalid characters.
    (eg: temporarily replace $ with __dexpatcher_dollar__ in filenames during merger.)
  • rename decode resources and rename then back just before aapt2 to avoid problems in other stages before merger.

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:
#21 (comment)

@Lanchon
Copy link
Member

Lanchon commented May 28, 2019

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
Copy link
Author

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
Copy link
Member

Lanchon commented May 30, 2019

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:

gradle/gradle#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
Copy link
Member

Lanchon commented May 30, 2019

FYI, i discuss your specific case here: #22

@Lanchon
Copy link
Member

Lanchon commented May 30, 2019

SUCCESS!!! :-)

you need this gradle.properties:

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

reference: #21 (comment)

@renaudcerrato
Copy link
Author

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

@Lanchon
Copy link
Member

Lanchon commented May 30, 2019

I assume you tested it already?

yes i did :)

@renaudcerrato
Copy link
Author

renaudcerrato commented Jun 2, 2019

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
Copy link

ttoommbb commented Jun 3, 2019

same error. mark first.

@Lanchon
Copy link
Member

Lanchon commented Jun 4, 2019

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
Copy link
Author

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

@Lanchon
Copy link
Member

Lanchon commented Jun 27, 2019

UPDATE: solution here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants