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

[BUG] Several resources are missing (skipped) #3778

Closed
andrewille opened this issue Jan 23, 2025 · 9 comments · Fixed by #3799 or #3807
Closed

[BUG] Several resources are missing (skipped) #3778

andrewille opened this issue Jan 23, 2025 · 9 comments · Fixed by #3799 or #3807
Assignees
Milestone

Comments

@andrewille
Copy link

Information

  1. Apktool Version (apktool -version) - 2.11.0
  2. Operating System (Mac, Linux, Windows) - Linux
  3. APK From? (Playstore, ROM, Other) - Playstore
  4. Java Version (java --version) - openjdk 17.0.13 2024-10-15

Issue details

While decoding the resources on latest WhatsApp, APKTool is skipping several resources (such as strings) which makes the app unusable. I can load the original .apk file into jadx and it shows all strings without problems. However, APKTool can't. The new WhatsApp seems to contain unordered entries in the resource chunks which seems to require seeking backwards in the resources.arsc file. I think it is likely that this is the same issue here. See skylot/jadx#2343

Stacktrace/Logcat

I: Using Apktool 2.11.0 on WhatsApp.apk with 8 threads
I: Copying raw classes.dex file...
I: Copying raw classes2.dex file...
I: Copying raw classes3.dex file...
I: Copying raw classes4.dex file...
I: Copying raw classes5.dex file...
I: Copying raw classes6.dex file...
I: Copying raw classes7.dex file...
I: Loading resource table...
W: End of chunk hit. Skipping remaining entries (15) in type: bool
W: End of chunk hit. Skipping remaining entries (1334) in type: color
W: End of chunk hit. Skipping remaining entries (2232) in type: color
W: End of chunk hit. Skipping remaining entries (1865) in type: color
W: End of chunk hit. Skipping remaining entries (3984) in type: dimen
W: End of chunk hit. Skipping remaining entries (3170) in type: dimen
W: End of chunk hit. Skipping remaining entries (3170) in type: dimen
W: End of chunk hit. Skipping remaining entries (3170) in type: dimen
W: End of chunk hit. Skipping remaining entries (1027) in type: dimen
W: End of chunk hit. Skipping remaining entries (3185) in type: dimen
W: End of chunk hit. Skipping remaining entries (1434) in type: dimen
W: End of chunk hit. Skipping remaining entries (1158) in type: dimen
W: End of chunk hit. Skipping remaining entries (1012) in type: dimen
W: End of chunk hit. Skipping remaining entries (1751) in type: dimen
W: End of chunk hit. Skipping remaining entries (1816) in type: dimen
W: End of chunk hit. Skipping remaining entries (1815) in type: dimen
W: End of chunk hit. Skipping remaining entries (1333) in type: dimen
W: End of chunk hit. Skipping remaining entries (1814) in type: dimen
W: End of chunk hit. Skipping remaining entries (1803) in type: dimen
W: End of chunk hit. Skipping remaining entries (38) in type: integer
W: End of chunk hit. Skipping remaining entries (4) in type: integer
W: End of chunk hit. Skipping remaining entries (2302) in type: string
W: End of chunk hit. Skipping remaining entries (2) in type: string
W: End of chunk hit. Skipping remaining entries (53) in type: string
W: End of chunk hit. Skipping remaining entries (82) in type: string
W: End of chunk hit. Skipping remaining entries (55) in type: string
W: End of chunk hit. Skipping remaining entries (33) in type: string
W: End of chunk hit. Skipping remaining entries (34) in type: string
W: End of chunk hit. Skipping remaining entries (91) in type: string
W: End of chunk hit. Skipping remaining entries (73) in type: string
W: End of chunk hit. Skipping remaining entries (82) in type: string
W: End of chunk hit. Skipping remaining entries (84) in type: string
W: End of chunk hit. Skipping remaining entries (85) in type: string
W: End of chunk hit. Skipping remaining entries (52) in type: string
W: End of chunk hit. Skipping remaining entries (73) in type: string
W: End of chunk hit. Skipping remaining entries (57) in type: string
W: End of chunk hit. Skipping remaining entries (87) in type: string
W: End of chunk hit. Skipping remaining entries (85) in type: string
W: End of chunk hit. Skipping remaining entries (53) in type: string
W: End of chunk hit. Skipping remaining entries (82) in type: string
W: End of chunk hit. Skipping remaining entries (56) in type: string
W: End of chunk hit. Skipping remaining entries (55) in type: string
W: End of chunk hit. Skipping remaining entries (82) in type: string
W: End of chunk hit. Skipping remaining entries (82) in type: string
W: End of chunk hit. Skipping remaining entries (55) in type: string
W: End of chunk hit. Skipping remaining entries (57) in type: string
W: End of chunk hit. Skipping remaining entries (83) in type: string
W: End of chunk hit. Skipping remaining entries (73) in type: string
W: End of chunk hit. Skipping remaining entries (52) in type: string
W: End of chunk hit. Skipping remaining entries (52) in type: string
W: End of chunk hit. Skipping remaining entries (56) in type: string
W: End of chunk hit. Skipping remaining entries (35) in type: string
W: End of chunk hit. Skipping remaining entries (73) in type: string
W: End of chunk hit. Skipping remaining entries (56) in type: string
W: End of chunk hit. Skipping remaining entries (54) in type: string
W: End of chunk hit. Skipping remaining entries (84) in type: string
W: End of chunk hit. Skipping remaining entries (83) in type: string
W: End of chunk hit. Skipping remaining entries (55) in type: string
W: End of chunk hit. Skipping remaining entries (56) in type: string
W: End of chunk hit. Skipping remaining entries (56) in type: string
W: End of chunk hit. Skipping remaining entries (73) in type: string
W: End of chunk hit. Skipping remaining entries (57) in type: string
W: End of chunk hit. Skipping remaining entries (57) in type: string
W: End of chunk hit. Skipping remaining entries (54) in type: string
W: End of chunk hit. Skipping remaining entries (73) in type: string
W: End of chunk hit. Skipping remaining entries (41) in type: string
W: End of chunk hit. Skipping remaining entries (83) in type: string
W: End of chunk hit. Skipping remaining entries (85) in type: string
W: End of chunk hit. Skipping remaining entries (73) in type: string
W: End of chunk hit. Skipping remaining entries (88) in type: string
W: End of chunk hit. Skipping remaining entries (83) in type: string
W: End of chunk hit. Skipping remaining entries (55) in type: string
W: End of chunk hit. Skipping remaining entries (55) in type: string
W: End of chunk hit. Skipping remaining entries (54) in type: string
W: End of chunk hit. Skipping remaining entries (83) in type: string
W: End of chunk hit. Skipping remaining entries (85) in type: string
W: End of chunk hit. Skipping remaining entries (83) in type: string
W: End of chunk hit. Skipping remaining entries (82) in type: string
W: End of chunk hit. Skipping remaining entries (53) in type: string
W: End of chunk hit. Skipping remaining entries (73) in type: string
W: End of chunk hit. Skipping remaining entries (57) in type: string
W: End of chunk hit. Skipping remaining entries (85) in type: string
W: End of chunk hit. Skipping remaining entries (27) in type: string
W: End of chunk hit. Skipping remaining entries (84) in type: string
W: End of chunk hit. Skipping remaining entries (73) in type: string
W: End of chunk hit. Skipping remaining entries (140) in type: string
W: End of chunk hit. Skipping remaining entries (27) in type: string
W: End of chunk hit. Skipping remaining entries (54) in type: string
W: End of chunk hit. Skipping remaining entries (26) in type: string
W: End of chunk hit. Skipping remaining entries (88) in type: string
W: End of chunk hit. Skipping remaining entries (85) in type: string
W: End of chunk hit. Skipping remaining entries (73) in type: string
I: Decoding file-resources...
I: Loading resource table from file: /home/andre/.local/share/apktool/framework/1.apk
I: Decoding values */* XMLs...
I: Decoding AndroidManifest.xml with resources...
I: Regular manifest package...
I: Copying original files...
I: Copying assets...
I: Copying kotlin...
I: Copying META-INF/services...
I: Copying unknown files...
Decoding process was successful

Steps to Reproduce

  1. apktool d base.apk -o ./WhatsApp --no-src
  2. apktool b ./WhatsApp --use-aapt2
  3. install and run the output .apk
  4. app name is missing (in launcher) and it will crash on opening due to missing string resources

APK

Choose arm64-v8a variant here and extract base.apk: APKMirror

@iBotPeaches
Copy link
Owner

Well thats interesting. Thanks for the jadx research. Thankfully during a previous fix we already have the infrastructure to jump around the stream.

I'll take this.

@iBotPeaches
Copy link
Owner

Had some time this morning - made some good progress, but broke basically all the tests. Still results in this application skipping a ton of resources, but best I believe so far - that is correct.

#3799

I: Using Apktool 2.11.0 on base.apk with 8 threads
I: Baksmaling classes.dex...
I: Baksmaling classes2.dex...
I: Baksmaling classes3.dex...
I: Baksmaling classes4.dex...
I: Baksmaling classes5.dex...
I: Baksmaling classes6.dex...
I: Baksmaling classes7.dex...
I: Loading resource table...
W: End of chunk hit. Skipping remaining entries (13) in type: bool
W: End of chunk hit. Skipping remaining entries (334) in type: color
W: End of chunk hit. Skipping remaining entries (1851) in type: color
W: End of chunk hit. Skipping remaining entries (38) in type: dimen
W: End of chunk hit. Skipping remaining entries (3170) in type: dimen
W: End of chunk hit. Skipping remaining entries (3170) in type: dimen
W: End of chunk hit. Skipping remaining entries (3170) in type: dimen
W: End of chunk hit. Skipping remaining entries (1751) in type: dimen
W: End of chunk hit. Skipping remaining entries (1816) in type: dimen
W: End of chunk hit. Skipping remaining entries (1815) in type: dimen
W: End of chunk hit. Skipping remaining entries (488) in type: dimen
W: End of chunk hit. Skipping remaining entries (1801) in type: dimen
W: End of chunk hit. Skipping remaining entries (1801) in type: dimen
W: End of chunk hit. Skipping remaining entries (3) in type: integer
W: End of chunk hit. Skipping remaining entries (1) in type: string
W: End of chunk hit. Skipping remaining entries (27) in type: string
W: End of chunk hit. Skipping remaining entries (27) in type: string
W: End of chunk hit. Skipping remaining entries (27) in type: string
I: Decoding file-resources...

@iBotPeaches
Copy link
Owner

Okay, PR up and should be fixed once merged.

➜  3778 apktool d base.apk -f                                                                                                
I: Using Apktool 2.11.0 on base.apk with 8 threads
I: Baksmaling classes.dex...
I: Baksmaling classes2.dex...
I: Baksmaling classes3.dex...
I: Baksmaling classes4.dex...
I: Baksmaling classes5.dex...
I: Baksmaling classes7.dex...
I: Baksmaling classes6.dex...
I: Loading resource table...
W: End of chunk hit. Skipping remaining entries (13) in type: bool
W: End of chunk hit. Skipping remaining entries (334) in type: color
W: End of chunk hit. Skipping remaining entries (1851) in type: color
W: End of chunk hit. Skipping remaining entries (38) in type: dimen
W: End of chunk hit. Skipping remaining entries (3170) in type: dimen
W: End of chunk hit. Skipping remaining entries (3170) in type: dimen
W: End of chunk hit. Skipping remaining entries (3170) in type: dimen
W: End of chunk hit. Skipping remaining entries (1751) in type: dimen
W: End of chunk hit. Skipping remaining entries (1816) in type: dimen
W: End of chunk hit. Skipping remaining entries (1815) in type: dimen
W: End of chunk hit. Skipping remaining entries (488) in type: dimen
W: End of chunk hit. Skipping remaining entries (1801) in type: dimen
W: End of chunk hit. Skipping remaining entries (1801) in type: dimen
W: End of chunk hit. Skipping remaining entries (3) in type: integer
W: End of chunk hit. Skipping remaining entries (1) in type: string
W: End of chunk hit. Skipping remaining entries (27) in type: string
W: End of chunk hit. Skipping remaining entries (27) in type: string
W: End of chunk hit. Skipping remaining entries (27) in type: string
I: Decoding file-resources...
I: Loading resource table from file: /home/ibotpeaches/.local/share/apktool/framework/1.apk
I: Decoding values */* XMLs...
I: Decoding AndroidManifest.xml with resources...
I: Regular manifest package...
I: Copying original files...
I: Copying assets...
I: Copying unknown files...
➜  3778 

@iBotPeaches iBotPeaches added this to the v2.11.1 milestone Feb 3, 2025
@andrewille
Copy link
Author

andrewille commented Feb 5, 2025

Hi @iBotPeaches,
thank you really much for your help. I have tested the tool with the merged code and now I get the same result as you:

I: Using Apktool 2.11.0 on base.apk with 8 threads
I: Baksmaling classes.dex...
I: Baksmaling classes2.dex...
I: Baksmaling classes3.dex...
I: Baksmaling classes4.dex...
I: Baksmaling classes5.dex...
I: Baksmaling classes6.dex...
I: Baksmaling classes7.dex...
I: Loading resource table...
W: End of chunk hit. Skipping remaining entries (13) in type: bool
W: End of chunk hit. Skipping remaining entries (334) in type: color
W: End of chunk hit. Skipping remaining entries (1851) in type: color
W: End of chunk hit. Skipping remaining entries (38) in type: dimen
W: End of chunk hit. Skipping remaining entries (3170) in type: dimen
W: End of chunk hit. Skipping remaining entries (3170) in type: dimen
W: End of chunk hit. Skipping remaining entries (3170) in type: dimen
W: End of chunk hit. Skipping remaining entries (1751) in type: dimen
W: End of chunk hit. Skipping remaining entries (1816) in type: dimen
W: End of chunk hit. Skipping remaining entries (1815) in type: dimen
W: End of chunk hit. Skipping remaining entries (488) in type: dimen
W: End of chunk hit. Skipping remaining entries (1801) in type: dimen
W: End of chunk hit. Skipping remaining entries (1801) in type: dimen
W: End of chunk hit. Skipping remaining entries (3) in type: integer
W: End of chunk hit. Skipping remaining entries (1) in type: string
W: End of chunk hit. Skipping remaining entries (27) in type: string
W: End of chunk hit. Skipping remaining entries (27) in type: string
W: End of chunk hit. Skipping remaining entries (27) in type: string
I: Decoding file-resources...

The amount of resources that were skipped has reduced a lot. However, it is still ignoring some which results in the recompiled .apk crashing at runtime. For instance, there are exactly 4 values found (and decoded) in res/values/bools.xml whereas WhatsApp is trying to access the 15th one.
This might be a different issue though. JadX can not decode them either. Do you have any idea what I could do to extract those resources?

@andrewille
Copy link
Author

Aapt2 can see them:
Image
Left side: APKTool output file
Right side: aapt2 dump resources output

@iBotPeaches
Copy link
Owner

The only thing I can think of without going into research is we check for end of chunk prior to checking the resource. So lets say you hit the end of the chunk, but the offset for the resource was +1 or something - so its actually in range, but we were at end of the chunk and prematurely exited.

It would be basically moving this code after the entryStart jumpTo - https://github.com/iBotPeaches/Apktool/blob/master/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java#L353-L360

@andrewille
Copy link
Author

The only thing I can think of without going into research is we check for end of chunk prior to checking the resource. So lets say you hit the end of the chunk, but the offset for the resource was +1 or something - so its actually in range, but we were at end of the chunk and prematurely exited.

It would be basically moving this code after the entryStart jumpTo - https://github.com/iBotPeaches/Apktool/blob/master/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java#L353-L360

Hi @iBotPeaches ,
thank you very much for pointing me to this. I just commented out the section you mentioned and that made it extract all resources without any problems. Now the app compiles and runs just fine! :)
I think you may want to open another issue for this and rework the check in the future.

@mamiiblt
Copy link

mamiiblt commented Mar 5, 2025

actually we have same issue in latest Instagram Alfa builds too, idk why it happens but im sure it will be fixed in next version

@andrewille
Copy link
Author

actually we have same issue in latest Instagram Alfa builds too, idk why it happens but im sure it will be fixed in next version

@mamiiblt It's actually not surprising as Instagram and WhatsApp are both developed by Meta. They certainly use the same tools for building. You should try the latest version of Apktool which was just released.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment