Skip to content

[FEAT] XAPK Support - Support Resource Decompilation in XAPK | @null in XML Resources When Decompiling XAPK Base APK #3806

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

Open
sipsuru opened this issue Feb 14, 2025 · 17 comments

Comments

@sipsuru
Copy link

sipsuru commented Feb 14, 2025

Information

  1. Apktool Version (apktool -version) - 2.11.0 | 2.11.0-7-f5c226b5-SNAPSHOT
  2. Operating System (Mac, Linux, Windows) - Windows
  3. APK From? (Playstore, ROM, Other) - Other [ApkCombo / ApkPure - XAPK]
  4. Java Version (java --version) - 23.0.1 | 2024-10-15

ADB Stacktrace/Logcat

adb: failed to finalize session
Failure [INSTALL_PARSE_FAILED_MANIFEST_MALFORMED: Failed parse during installPackageLI: /data/app/vmdl1887994749.tmp/base.apk (at Binary XML file line #645): <meta-data> requires an android:value or android:resource attribute]

Steps to Reproduce

  1. Download xapk and extract apks inside.
  2. Decompile wp.wattpad.apk with apktool d wp.wattpad.apk
  3. Delete original wp.wattpad.apk
  4. Recompile without modifications with apktool b -o wp.wattpad.apk
  5. Sign all apks (in current directory) with: sign.py
  6. [Tried with & without this step]; Align all apks (in current directory) with: align.py
  7. Install all apks with adb install-multiple app1.apk app2.apk ... OR
    Create a zip folder containing all the apks, icon.png, manifest.json

Frameworks

Not from a framework

APK

https://apkcombo.app/wattpad/wp.wattpad/download/phone-10.95.0-apk

Questions to ask before submission

  1. Have you tried apktool d, apktool b without changing anything? - Yes
  2. If you are trying to install a modified apk, did you resign it? - Yes
  3. Are you using the latest apktool version? - Yes

Update: I don't get any error (or warning) when decompiling or recompiling. So I've included adb's logcat here.

Additional Information

Not a issue with the original xapk itself. I could successfully install the original xapk (and with adb too).

When the wp.wattpad.apk (base apk) is decompiled, it contains a lot of @null values, like

<meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@null"/>
<service android:foregroundServiceType="shortService" android:icon="@null" android:name="wp.wattpad.migration.MigrationService"/>

and in many more. (This's from AndroidManifest.xml)

There're apks for multiple resolutions: config.hdpi.apk, config.ldpi.apk, config.mdpi.apk, config.tvdpi.apk, config.xhdpi.apk, config.xxhdpi.apk, config.xxhdpi.apk, so could it be that apktool replaces original resources with @null as they're not available in the base apk?

Furthermore, the target Android version seemed to be 15, which's more interesting.

@fastman92
Copy link

fastman92 commented Feb 15, 2025

I'm trying it on 'Opera browser beta' with the same problem.

Problem is the following:

base.apk has AndroidManifest.xml and resources.arsc

Let's see AndroidManifest.xml in Android Studio (Analyze APK option):
<meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@ref/0x7f080413" /

Let's see base.apk's resources.arsc.
It contains ID 0x7f080413, however no name is defined. It's also not defined for any DPI resolution.

Image

This symbol is available for xxhdpi resolution in another APK package (split_config.xxhdpi.apk):

Image

It has got a name drawable/notification_smali

Solution:
Allow res/values/public.xml to contain names of symbols that are not defined. Currently it would say the following if symbol in public.xml is declared, but its definition cannot be found for any DPI:
W: R:\tmp\decompiledBase\res\values\public.xml:19946: error: no definition for declared symbol 'com.opera.browser.beta:drawable/notification_small'.

Currently this is not allowed.

For decompilation, add the possibility to specify more APK packages from which resource IDs will be derived.
Add an option like this:
-additional_apks "R:\tmp\unpackedAPKs\split_config.xxhdpi.apk:R:\unpackedAPKs\R:\tmp\unpackedAPKs\ssplit_config.xxxhdpi.apk:R:\tmp\unpackedAPKs\split_mintegral_ads.apk"

resources.arsc to be loaded from these additional APK packages and IDs to be put inside of res/values/public.xml properly. AndroidManifest.xml should be decompiled then.

Thanks for this great project by the way.

@sipsuru sipsuru changed the title [BUG] XAPK Base apk Invalid Decompile | @null as value in xml | Android 15 Target SDK [BUG] XAPK Base APK - Invalid Resource Decompilation | @null in XML Resources | Android 15 Target SDK Feb 17, 2025
@iBotPeaches
Copy link
Owner

Yes this is a challenge Apktool has not yet handled. Apktool frameworks handle this somewhat well, but that goes under assumption that pkgId is different for loading for all. As you can tell in your split setups - they all share the private package id (0x7f) but have chunks of their own resources.

This has bubbled up in a few times in some applications that have similar behavior without being a split - say this ticket where Twitter has 7f-7g - #2514

Or this one - #3364

Its just a bit difficult to identify the fix here between quite a few things.

  1. Does apktool just ignore resources from another split? Can it? How does aapt handle it?
  2. Does apktool unsplit an apk?
  3. Does apktool just call out to apkeditor for a merge, then handle an apk? https://github.com/REAndroid/APKEditor?tab=readme-ov-file#3--merge
  4. Just because apktool could reach out and identify the location of an unknown resource - is that all we need?

@sipsuru
Copy link
Author

sipsuru commented Mar 13, 2025

Short-Term Solution

  1. Option to Ignore Missing Resources from Split APKs

    • It’d be best if Apktool added an option to ignore missing resources when dealing with split APKs. Right now, Apktool runs into issues when resources are missing from the base APK but are present in other split APKs. Adding a flag to ignore these missing resources would allow Apktool to continue processing without errors, even if the resources are absent.
    • This would help users who encounter issues with split APKs, especially when the missing resources aren't critical. It’d be a quick workaround and make Apktool more flexible in handling these scenarios.
  2. Documentation Update

    • It’d also be helpful to update the documentation to make it clear how to handle split APKs. Users could either merge the APKs with a tool like APKEditor before decompiling or use the new "ignore missing resources" option in Apktool to proceed without hitting errors.
    • A clear explanation in the docs would guide users, preventing confusion and making the tool more approachable for split APK cases.

Long-Term Vision

  1. Automatically Fetch Missing Resources
    • In the long run, it’d be great if Apktool could automatically detect and pull missing resources from the split APKs. Instead of relying on third-party tools or manual merging, Apktool could handle this process internally, either by fetching the resources or notifying the user when they need to merge the APKs.
    • This would make Apktool more efficient and capable of dealing with modern APKs that are often split into multiple parts. It’d improve the overall user experience by reducing the manual work involved.

Summary

  • Short-Term: Adding an option to ignore missing resources and updating the documentation to recommend either merging APKs or using the new flag would provide an immediate fix for split APKs.
  • Long-Term: Developing the ability to automatically handle missing resources would make Apktool a more robust and fully-featured tool for modern APK formats.

I guess, this approach would help Apktool support split APKs more effectively while reducing the complexity for users

@fastman92
Copy link

Make it load resource IDs from multiple APK files.

Initially APK tool has been designed to work with only one APK file. This approach is no longer valid, most importantly for resources.

At least the resource IDs should be loaded from (primary APK file + several other APK files).
Then the rest of decompilation process should follow.


Solution:
Allow res/values/public.xml to contain names of symbols that are not defined. Currently it would say the following if symbol in public.xml is declared, but its definition cannot be found for any DPI:
W: R:\tmp\decompiledBase\res\values\public.xml:19946: error: no definition for declared symbol 'com.opera.browser.beta:drawable/notification_small'.

Currently this is not allowed.

For decompilation, add the possibility to specify more APK packages from which resource IDs will be derived.
Add an option like this:
-additional_apks "R:\tmp\unpackedAPKs\split_config.xxhdpi.apk:R:\unpackedAPKs\R:\tmp\unpackedAPKs\ssplit_config.xxxhdpi.apk:R:\tmp\unpackedAPKs\split_mintegral_ads.apk"

resources.arsc to be loaded from these additional APK packages and IDs to be put inside of res/values/public.xml properly. AndroidManifest.xml should be decompiled later.

@iBotPeaches, how about implementing it in this way? This doesn't sound that hard to do, although it can take few hours possibly.

@iBotPeaches
Copy link
Owner

I mean if you feel you can implement that in a few hours - go for it. That feels like 20-30 hours of work for me.

@fastman92
Copy link

I can possibly think about implementing it soon, can do a pull request then. I'm using your tool in my project (fastman92 APK modifier) that handles standalone/split APK files (APK/APKM/APKS/XAPK), so I can see some challenges that come with it. You have made a great tool overall.

Image

Today I've been working on handling the problem of decompilation of DEX files from 'assets' directory and compilation by APKtool. It doesn't work properly in APKtool. have designed a workaround in my tool for this, so that additional DEX files can be compiled properly and put into correct location into APK file (back into assets). This is something that I would like to see fixed in APKtool. I could possibly add a pull request for this.

I haven't worked with source code of APK tool yet, so my time estimate may be a bit off. For me the time to implement it might be longer because I don't have such a good understanding of APK tool's source code as you do (may need some to learn few things how it works). Anyway, I'll see what I can do. May add a pull request later.

@sipsuru sipsuru changed the title [BUG] XAPK Base APK - Invalid Resource Decompilation | @null in XML Resources | Android 15 Target SDK [FEAT] XAPK Support - Support Resource Decompilation in XAPK | @null in XML Resources When Decompiling XAPK Base APK Mar 20, 2025
@fastman92
Copy link

What I've discovered while my tool, dummy mode in APK tool can handle split APKs properly.
This will create empty entries that begin with "APKTOOL_DUMMY_". @null is completely wrong, when there was an actual reference to resource.

So now my tool can convert any bundle to standalone APK, managed to implement a tricky move of resources between base APK and other APK files including their names. This was quite a lot of work, but I did it finally.

I recommend everyone to use the following setting: -resm dummy
For bundles with more than one APK it's absolutely necessary.

@walisinghe-college
Copy link

@fastman92

So now my tool can convert any bundle to standalone APK, managed to implement a tricky move of resources between base APK and other APK files, including their names. This was quite a lot of work, but I did it finally.

That was (merging the bundles into a single apk file), already an option!? -- With APKEditor, so why YOUR TOOL is specific for this case, and you didn't have to implement a tricky move for that? (Correct me if I missed something please)

I recommend everyone to use the following setting: -resm dummy
For bundles with more than one APK it's absolutely necessary.

That's not the point there;

  • Here, I don't have a good understanding about -resm dummy option though.

When you have that option, I guess you cannot get a working app recompiled (I guess -- There is a great chance I'm missing here -- Correct me if so)

And, let's take if it does somehow replace dummy resource locations with actual ones on recompilation, but, does it decompile the actual resources as well or skip them?

If this option doesn't do these (reallocate actual files, and decompile all the resources), in dummy mode, this's not a solution at all!? Cause for example, the Wattpad XAPK, has only config.xxhdpi.apk and the base apk (wp.wattpad.apk), so how can we edit resources then?

Again, I really don't know about the -resm dummy flag. So I could be completely wrong. Kindly correct me.

@fastman92
Copy link

fastman92 commented Mar 29, 2025

Right. APK editor allows to merge the bundle into a single APK file. I'm building my own tool that also does it and many other things like renaming the package including everything that's related to package name.
My tool works by editing APK tool's decompiled directories and merges them together in the end (if converting to APK). It relies heavily on APK tool, so I've had to learn quite a lot about the structure of APK tool's directory.

Let's explain the thing about resources now.

resources.arsc contains a list of IDs and their values for several different configurations (default, :
the possible value can be one of the following for drawable:

  • path to png file
  • path to 9.png file
  • path to XML file
  • reference to another resource
    - empty / unset
  • color

Here it can be seen:

Anyway, what matters it can be empty. For bundles (using split APKs) it's possible that there will be a resource ID declared, where all configurations have an unset value in certain APK file.

Let's take a look at this:

Image

There exists a resource ID 0x7f080378 in this base APK, but its value is not set for any configuration (default, sw600dp, television...). It's empty.

APK tool, when decompiling this base APK will consider it a missing resource (empty value in all configurations). With "dummy" mode it will properly create an entry for this in the following files:
public.xml, to specify ID: <public type="drawable" name="APKTOOL_DUMMY_7f080378" id="0x7f080378" />
drawable.xml, to specify the value for "default" configuration: <item type="drawable" name="APKTOOL_DUMMY_7f080378" />
You can see, it's an empty value here.

The APK can be recompiled this way properly.

Now in other file like config.xxhdpi.apk things look a bit differently,
for the same resource ID 0x7f080378:

Image

As it can be seen, for this ID there's a value for at least one config specified. APK tool will not create a dummy element for this. It will extract the file to "{decompiledDir}\res\drawable-xxhdpi".

There will be two things:
in public.xml, the line to specify ID:

The definition for xxhdpi config. In this case the PNG file will be created:
{decompiledDir}\res\drawable-xxhdpi\ic_notification.png

"so how can we edit resources then?" Resource IDs are common, but the definitions for certain configs may be in any of split APK files.

You edit resources in APK packages, where they reside. Can refer to resource IDs that may have their definitions in other APK files (must have empty dummy entry for at least one config in such a case in file such as drawables.xml so that APK tool does not abort the compilation and does not tell "public symbol not defined").

I had to think quite a bit about this problem as I'm developing my tool.
My tool, when converting to standalone APK performs an exchange of symbol names between base and other APK files automatically. Also, exchanging the symbol names between symbol names between base and other APK files, when still leaving a bundle, not converting to standalone APK.

@sipsuru
Copy link
Author

sipsuru commented Apr 1, 2025

@fastman92

when converting to standalone, APK performs an exchange of symbol names between base and other APK files automatically

Ah, I see, that approach seems feasible. Therefore, perhaps you could integrate this feature; once implemented in your tool, it would offer increased efficiency?

@fastman92
Copy link

@fastman92

when converting to standalone, APK performs an exchange of symbol names between base and other APK files automatically

Ah, I see, that approach seems feasible. Therefore, perhaps you could integrate this feature; once implemented in your tool, it would offer increased efficiency?

I want to do this. I still need to understand the problem fully in order to make this functionality work flawlessly.

@sipsuru
Copy link
Author

sipsuru commented Apr 2, 2025

I want to do this. I still need to understand the problem fully in order to make this functionality work flawlessly.

Looking forward for it

@fastman92
Copy link

fastman92 commented Apr 4, 2025

I want to do this. I still need to understand the problem fully in order to make this functionality work flawlessly.

Looking forward for it

Done.

Download the newest version of "fastman92 APK modifier" https://gtaforums.com/topic/979211-fastman92-apk-modifier/

Load bundle (APK/APKS/APKM/XAPK/directory)

Image

Check the option "Only fix resources, don't add APK modifier's code".

Click Save button. You can save as a bundle or standalone APK.

Image

Look for modified files in tmp directory, where you have extracted APK modifier.

You might want to copy these files to another location. They are being deleted, when APK modifier is being shut down. These files are better in a way, also modified to allow a compilation in cases, where APK tool's code would fail to compile resources (also fixing the problem of private resources).

So, what's important to know about split APKs: make sure to decompile them with "-resm dummy" option in APKtool. This way APKtool won't output @null in place of actual references, but it will create empty entries that can be referenced properly.

@walisinghe-college
Copy link

@fastman92

Done.
Download the newest version of "fastman92 APK modifier" https://gtaforums.com/topic/979211-fastman92-apk-modifier/

Oh my... I was thinking that you were going to contribute back to this project when you said you could do it and @iBotPeaches said "go for it". 😯

And it's not opensource?

Anyway, I personally appreciate the work you've done! Should checkout.

@fastman92
Copy link

fastman92 commented Apr 4, 2025

@fastman92

Done.
Download the newest version of "fastman92 APK modifier" https://gtaforums.com/topic/979211-fastman92-apk-modifier/

Oh my... I was thinking that you were going to contribute back to this project when you said you could do it and @iBotPeaches said "go for it". 😯

And it's not opensource?

Anyway, I personally appreciate the work you've done! Should checkout.

I may add some improvements to APKtool later. I have never worked with APKtool's source code though, so it can take me some time to figure out what I can do with this.
I have initially thought APKtool would need an improval to handle @null values in case of split APKs. This turned out to be not needed. The problem of @null can be addressed by "-resm dummy". Decompilation without "-resm dummy", with @null values doesn't make much sense.

APKtool's is focused on decompilation and recompilation of a single APK file and it works quite well for this task (although there are some problems with this, noticeable in case of certain APKs). Now my project is focused on working with packages or bundles (multiple APKs), possibly adding some good changes automatically (like AndUnpr directory to be used instead of Android, solves Android 10+ problem of limited access to /sdcard/Android, these changes can be disabled in GUI) and their recompilation, possibly conversion to standalone APK.
You can also rename the bundle/package and it does many changes that might be required automatically to accomplish the change. There are many other features. Maybe I can extend it to provide an easier way to work multiple APKs for someone who wants to edit files. At the moment it can help in the way that it can exchange resource proper symbol names (thus replacing APKTOOL_DUMMY_ to real name if found) between different packages.
I can also see some ways in which APKtool could be improved. At the moment my focus was on my own project.

@walisinghe-college
Copy link

I have never worked with APKtool's source code though, so it can take me some time to figure out what I can do with this.

Ah, I see.

Now my project is focused on working with packages or bundles (multiple APKs), possibly adding some good changes automatically (like AndUnpr directory to be used instead of Android, solves Android 10+ problem of limited access to /sdcard/Android, these changes can be disabled in GUI) and their recompilation, possibly conversion to standalone APK.

Impressive, indeed.

I can also see some ways in which APKtool could be improved. At the moment my focus was on my own project.

Ah, right.

@fastman92
Copy link

fastman92 commented Apr 4, 2025

I have never worked with APKtool's source code though, so it can take me some time to figure out what I can do with this.

Ah, I see.

Now my project is focused on working with packages or bundles (multiple APKs), possibly adding some good changes automatically (like AndUnpr directory to be used instead of Android, solves Android 10+ problem of limited access to /sdcard/Android, these changes can be disabled in GUI) and their recompilation, possibly conversion to standalone APK.

Impressive, indeed.

I can also see some ways in which APKtool could be improved. At the moment my focus was on my own project.

Ah, right.

Thanks for the reply. I'd recommend my project to anyone who wants to modify an application to provide an easy access to files (/sdcard/AndUnpr instead of /sdcard/Android, people who want to modify game files). My project works with multiple packages, it offers many features, makes lots of changes. Note that it depends on APKtool to decompile and compile each single APK. That being said, APKtool is an important project to handle a single APK.

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

4 participants