Apktool
Apktool copied to clipboard
decompiling latest Facebook APK - unsupported res type name for bags. Found: style2
Information
- Apktool Version: 2.3.1
- Operating System: Linux
- APK From: APKMirror (https://www.apkmirror.com/apk/facebook-2/facebook/facebook-157-0-0-38-97-release/facebook-157-0-0-38-97-android-apk-download/)
Stacktrace/Logcat
Very long sequence of "Could not decode file" lines:
https://pastebin.com/edit/rHKMqygQ
Steps to Reproduce
- Any attempt to decompile the official Facebook apk (versions 157 and later)
- ./apktool d _in/Facebook_157.0.0.38.97.apk -o _working/Facebook_157.0.0.38.97.apk
Frameworks
If this APK is from an OEM ROM (Samsung, HTC, LG): Nope
APK
If this APK can be freely shared, please upload/attach a link to it: https://www.apkmirror.com/apk/facebook-2/facebook/facebook-157-0-0-38-97-release/facebook-157-0-0-38-97-android-apk-download/
Questions to ask before submission
- Have you tried
apktool d,apktool bwithout changing anything? yes - If you are trying to install a modified apk, did you resign it? issues during decompile/recompile
- Are you using the latest apktool version? yes
Great. Facebook is doing something crazy with resources. Looks like a tweaked (probably custom) version of AndroResGuard.
There are two types of images I see - **.g.png and some .m4a files. I have no idea if these are serialized or raw form yet, but these are the conflict files.
I'll take a look tonight.
@ahmed-ais , @iBotPeaches It seems to be that guys from Facebook start using AndResGuard (https://github.com/shwenzhang/AndResGuard). It's Proguard's for resource files. IMHO, o understending how process them you should understend how it works.
I have a good idea of how it works. Been doing this never ending patch war with AndroResGuard for years. However, AndroResGuard just needs to run on a device, so it can strip everything that the host doesn't care about. This means that taking an application back to a point that it can be rebuilt is very difficult. We are looking at hundreds, if not, thousands of resources at the root level renamed and obfuscated which Android doesn't care about because it just follows resourceIds and file paths. It doesn't care about any human-readable names.
Our decoder is handling those correctly, but this time instead of being serialized and moved/renamed - they are left in the "raw" state. Likewise, m4a is a type unknown to apktool so it tries to decode it.
@iBotPeaches m4a is Apple audio and video files. It's mean that Apktool should just copy this as is?
Yeah, I patched that one already locally. The issue is the pngs. You can't exactly assume they are in the raw state when they aren't in other applications. So you either attempt to decode and fail, fallback to raw processing which is where I'm at.
I'll have a patch up later today.
@iBotPeaches it sounds great. Thank you for that. Can you explain to me why some resource folders after decompilation named like drawable2, drawable4-xxhdpi, raw2 and etc.
I'm taking a look. It seems a new level of obfuscation is creating a new type tree. So instead of a drawable type, they create drawable2. This pattern is everywhere. Its part of the reason why the apktool decoder is crashing, its getting confused on what these images are.
Okay, throwing up a WIP commit here any minute. Since AndroResGuard is open source, I'm going to build a small little test application and add it into test suite to prevent regressions. Once that is done, I'll get this merged into mainline master.
Currently blocked on understanding the types. I think AndroResGuard just is making fake type names, but keeping the underlying typeId the same. This is why the application continues to work on Android. However, apktool decodes the human-readable name into the directory structure which is not valid.
W: invalid resource directory name: /Users/connortumbleson/Desktop/Apktool/Bugs/Bug1719/katana/res layout3
W: invalid resource directory name: /Users/connortumbleson/Desktop/Apktool/Bugs/Bug1719/katana/res layout2
W: invalid resource directory name: /Users/connortumbleson/Desktop/Apktool/Bugs/Bug1719/katana/res raw2
W: invalid resource directory name: /Users/connortumbleson/Desktop/Apktool/Bugs/Bug1719/katana/res drawable4-xxhdpi
W: invalid resource directory name: /Users/connortumbleson/Desktop/Apktool/Bugs/Bug1719/katana/res drawable2
W: invalid resource directory name: /Users/connortumbleson/Desktop/Apktool/Bugs/Bug1719/katana/res drawable3-xhdpi
W: invalid resource directory name: /Users/connortumbleson/Desktop/Apktool/Bugs/Bug1719/katana/res drawable4
W: invalid resource directory name: /Users/connortumbleson/Desktop/Apktool/Bugs/Bug1719/katana/res drawable3
As shown from that stacktrace. Since AndroResGuard doesn't require any update to aapt binary, there is no way this is valid. So about 60% done. Just need tests and that thing to patch.
Need to sleep on this. Need more research. These extra types like "drawable2" are entirely valid with a type entry table. Rewriting them is not worth it. My first attempt was to rewrite "drawable2" to "drawable" and treat it as such.
That produced a valid filepath and aapt built it...almost.
W: /Users/connortumbleson/Desktop/Apktool/Bugs/Bug1719/katana/res/values/public.xml:29786: error: Public resource style/APKTOOL_0x7f1b0753 has conflicting type codes for its public identifiers (0x11 vs 0x1b).
It knows it has the wrong resourceType. So the obvious solution is to remap the typeId back to the original (drawable typeId) instead of the drawable2 typeId. That doesn't seem right though, all that rewriting.
So I went back to keeping the weird types, just rewriting the path name. Which leads to even stranger errors:
/Users/connortumbleson/Desktop/Apktool/Bugs/Bug1719/katana/res/values/style2s.xml:9608: error: Resource entry APKTOOL_0x7f1b06d8 already has bag item android:textColor.
W: /Users/connortumbleson/Desktop/Apktool/Bugs/Bug1719/katana/res/values/style2s.xml:9607: Originally defined here.
I just need to sit down, since this tool is open source and do test after test with simple applications until I understand how these extra types play in at the resources.arsc file.
I pushed my highly broken and probably wrong to the branch above. Will revisit.
Okay, so here is the rub. AndResGuard works by manually rebuilding the resources.arsc file, so it can make some nifty improvements that Android doesn't care about.
Unfortunately, Apktool build process currently works using aapt. This means it decodes the application (as it has) to nearly original shape so the original Android build procedure can take over and build it.
If we leave the original types (drawable/drawable2/etc), then the build process of aapt does not obviously find/allow those types and rejects them with failures like
W: /Users/connortumbleson/Desktop/Apktool/Bugs/Bug1719/katana/res/values-v16/style3s.xml:207: error: Error retrieving parent for item: No resource found that matches the given name '@style2/APKTOOL_0x7f1b05df'.
The only solution I have for rebuild support is probably rewriting all these types back to the original, so native aapt can process them.
Merged some changes into master that will help with at least decoding (Perhaps decode in an invalid format).
I need to get aapt2 finished before I jump back to this. I think the limitations I'm dealing with when rebuilding are different in aapt2 and don't want to waste time.
Note to self. Look into skipping resource decoding (-r) and look into why that is not working. Context: #1739
Hi @iBotPeaches, Is there any update about this issue? I am facing the same problem that it couldn't decode the resources.
Thanks!
Version 2.4.0 still have problems with the facebook apk. But now it crashes with an exception.
c:\temp>apktool -f d com.facebook.katana-1.apk
I: Using Apktool 2.4.0 on com.facebook.katana-1.apk
I: Loading resource table...
Exception in thread "main" brut.androlib.AndrolibException: unsupported res type name for bags. Found: style2
at brut.androlib.res.data.value.ResValueFactory.bagFactory(ResValueFactory.java:115)
at brut.androlib.res.decoder.ARSCDecoder.readComplexEntry(ARSCDecoder.java:350)
at brut.androlib.res.decoder.ARSCDecoder.readEntryData(ARSCDecoder.java:276)
at brut.androlib.res.decoder.ARSCDecoder.readTableType(ARSCDecoder.java:252)
at brut.androlib.res.decoder.ARSCDecoder.readTableTypeSpec(ARSCDecoder.java:175)
at brut.androlib.res.decoder.ARSCDecoder.readTablePackage(ARSCDecoder.java:131)
at brut.androlib.res.decoder.ARSCDecoder.readTableHeader(ARSCDecoder.java:82)
at brut.androlib.res.decoder.ARSCDecoder.decode(ARSCDecoder.java:48)
at brut.androlib.res.AndrolibResources.getResPackagesFromApk(AndrolibResources.java:748)
at brut.androlib.res.AndrolibResources.loadMainPkg(AndrolibResources.java:67)
at brut.androlib.res.AndrolibResources.getResTable(AndrolibResources.java:59)
at brut.androlib.Androlib.getResTable(Androlib.java:68)
at brut.androlib.ApkDecoder.setTargetSdkVersion(ApkDecoder.java:228)
at brut.androlib.ApkDecoder.decode(ApkDecoder.java:118)
at brut.apktool.Main.cmdDecode(Main.java:167)
at brut.apktool.Main.main(Main.java:76)```
I was able to get around the crash by adding the resource type "style2".
https://github.com/thejunkjon/Apktool/commit/5f3fc54fd5541926bef9a6af797464997e64fde9
That type doesn't seem to be documented though so I am not sure the change is correct.
https://android.googlesource.com/platform/frameworks/base/+/master/tools/aapt2/Resource.h#66
I was able to get around the crash by adding the resource type "style2".
That type doesn't seem to be documented though so I am not sure the change is correct.
https://android.googlesource.com/platform/frameworks/base/+/master/tools/aapt2/Resource.h#66
I had to add style3, style4, and style5 to get it to work for me (working on a more recent Facebook APK). If this is a correct fix, do you want a PR?
Looks like same issue as above (style2)
I: Using Apktool 2.4.0 on com.playstation.remoteplay.apk
I: Loading resource table...
Exception in thread "main" brut.androlib.AndrolibException: unsupported res type name for bags. Found: style2
at brut.androlib.res.data.value.ResValueFactory.bagFactory(ResValueFactory.java:115)
at brut.androlib.res.decoder.ARSCDecoder.readComplexEntry(ARSCDecoder.java:350)
at brut.androlib.res.decoder.ARSCDecoder.readEntryData(ARSCDecoder.java:276)
at brut.androlib.res.decoder.ARSCDecoder.readTableType(ARSCDecoder.java:252)
at brut.androlib.res.decoder.ARSCDecoder.readTableTypeSpec(ARSCDecoder.java:175)
at brut.androlib.res.decoder.ARSCDecoder.readTablePackage(ARSCDecoder.java:131)
at brut.androlib.res.decoder.ARSCDecoder.readTableHeader(ARSCDecoder.java:82)
at brut.androlib.res.decoder.ARSCDecoder.decode(ARSCDecoder.java:48)
at brut.androlib.res.AndrolibResources.getResPackagesFromApk(AndrolibResources.java:748)
at brut.androlib.res.AndrolibResources.loadMainPkg(AndrolibResources.java:67)
at brut.androlib.res.AndrolibResources.getResTable(AndrolibResources.java:59)
at brut.androlib.Androlib.getResTable(Androlib.java:68)
at brut.androlib.ApkDecoder.setTargetSdkVersion(ApkDecoder.java:228)
at brut.androlib.ApkDecoder.decode(ApkDecoder.java:118)
at brut.apktool.Main.cmdDecode(Main.java:167)
at brut.apktool.Main.main(Main.java:76)
I have the same problem when decompiling with 2.4.0. 2.3.4 decompiles but can't recompile because there are lots of non existing references to some dummy locations in AndroidManifest.xml.
I: Using Apktool 2.4.0 on Test.apk
I: Loading resource table...
Exception in thread "main" brut.androlib.AndrolibException: unsupported res type name for bags. Found: style2
at brut.androlib.res.data.value.ResValueFactory.bagFactory(ResValueFactory.java:115)
at brut.androlib.res.decoder.ARSCDecoder.readComplexEntry(ARSCDecoder.java:350)
at brut.androlib.res.decoder.ARSCDecoder.readEntryData(ARSCDecoder.java:276)
at brut.androlib.res.decoder.ARSCDecoder.readTableType(ARSCDecoder.java:252)
at brut.androlib.res.decoder.ARSCDecoder.readTableTypeSpec(ARSCDecoder.java:175)
at brut.androlib.res.decoder.ARSCDecoder.readTablePackage(ARSCDecoder.java:131)
at brut.androlib.res.decoder.ARSCDecoder.readTableHeader(ARSCDecoder.java:82)
at brut.androlib.res.decoder.ARSCDecoder.decode(ARSCDecoder.java:48)
at brut.androlib.res.AndrolibResources.getResPackagesFromApk(AndrolibResources.java:748)
at brut.androlib.res.AndrolibResources.loadMainPkg(AndrolibResources.java:67)
at brut.androlib.res.AndrolibResources.getResTable(AndrolibResources.java:59)
at brut.androlib.Androlib.getResTable(Androlib.java:68)
at brut.androlib.ApkDecoder.setTargetSdkVersion(ApkDecoder.java:228)
at brut.androlib.ApkDecoder.decode(ApkDecoder.java:118)
at brut.apktool.Main.cmdDecode(Main.java:167)
at brut.apktool.Main.main(Main.java:76)
I have same error when decompile apk recently. It seems apktool failed on all new obfuscate algorithm. It is very bad news :(.
I have tried with all tools that have similar apktool functionality. But in the end is the error
Updated title to reflect true crash and to start linking duplicate issues to this ticket. Sorry for the delay.
Another sample crashing evenly:
https://play.google.com/store/apps/details?id=it.icbpi.mobile&hl=en
[14:36 edu@xps tmp] > apktool d base.apk -f
I: Using Apktool 2.4.1 on base.apk
I: Loading resource table...
Exception in thread "main" brut.androlib.AndrolibException: unsupported res type name for bags. Found: style2
at brut.androlib.res.data.value.ResValueFactory.bagFactory(ResValueFactory.java:119)
at brut.androlib.res.decoder.ARSCDecoder.readComplexEntry(ARSCDecoder.java:350)
at brut.androlib.res.decoder.ARSCDecoder.readEntryData(ARSCDecoder.java:276)
at brut.androlib.res.decoder.ARSCDecoder.readTableType(ARSCDecoder.java:252)
at brut.androlib.res.decoder.ARSCDecoder.readTableTypeSpec(ARSCDecoder.java:175)
at brut.androlib.res.decoder.ARSCDecoder.readTablePackage(ARSCDecoder.java:131)
at brut.androlib.res.decoder.ARSCDecoder.readTableHeader(ARSCDecoder.java:82)
at brut.androlib.res.decoder.ARSCDecoder.decode(ARSCDecoder.java:48)
at brut.androlib.res.AndrolibResources.getResPackagesFromApk(AndrolibResources.java:786)
at brut.androlib.res.AndrolibResources.loadMainPkg(AndrolibResources.java:67)
at brut.androlib.res.AndrolibResources.getResTable(AndrolibResources.java:59)
at brut.androlib.Androlib.getResTable(Androlib.java:66)
at brut.androlib.ApkDecoder.setTargetSdkVersion(ApkDecoder.java:236)
at brut.androlib.ApkDecoder.decode(ApkDecoder.java:118)
at brut.apktool.Main.cmdDecode(Main.java:170)
at brut.apktool.Main.main(Main.java:76)
~Seems like even apktool --no-res (no resources) fails as well - the apk gets built but crashes with "resource not found" in logcat once installed.~
Edit: seems like this has already been mentioned in #1739
It seems like skipping resource decoding (via --no-res) does not copy over the 'r/' directory from the apk.
Removing the "r" (and "R", I guess) directories from APK_STANDARD_ALL_FILENAMES seems to fix this issue.
For anyone facing the same problem, here is the full patch which is able to recompile the latest Messenger apk (with --no-res, haven't tested decoding resources yet)
@iBotPeaches Since this is only a workaround for now, have you made any progress on this?
diff --git c/brut.apktool/apktool-lib/src/main/java/brut/androlib/Androlib.java w/brut.apktool/apktool-lib/src/main/java/brut/androlib/Androlib.java
index df3ec28..3c3862c 100644
--- c/brut.apktool/apktool-lib/src/main/java/brut/androlib/Androlib.java
+++ w/brut.apktool/apktool-lib/src/main/java/brut/androlib/Androlib.java
@@ -794,7 +794,7 @@ public class Androlib {
private final static String[] APK_MANIFEST_FILENAMES = new String[] {
"AndroidManifest.xml" };
private final static String[] APK_STANDARD_ALL_FILENAMES = new String[] {
- "classes.dex", "AndroidManifest.xml", "resources.arsc", "res", "r", "R",
+ "classes.dex", "AndroidManifest.xml", "resources.arsc", "res",
"lib", "libs", "assets", "META-INF", "kotlin" };
private final static Pattern NO_COMPRESS_PATTERN = Pattern.compile("(" +
"jpg|jpeg|png|gif|wav|mp2|mp3|ogg|aac|mpg|mpeg|mid|midi|smf|jet|rtttl|imy|xmf|mp4|" +
diff --git c/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResTypeSpec.java w/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResTypeSpec.java
index ace8dd5..48c157f 100644
--- c/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResTypeSpec.java
+++ w/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResTypeSpec.java
@@ -28,6 +28,11 @@ public final class ResTypeSpec {
public static final String RES_TYPE_NAME_ARRAY = "array";
public static final String RES_TYPE_NAME_PLURALS = "plurals";
public static final String RES_TYPE_NAME_STYLES = "style";
+ public static final String RES_TYPE_NAME_STYLES2 = "style2";
+ public static final String RES_TYPE_NAME_STYLES3 = "style3";
+ public static final String RES_TYPE_NAME_STYLES4 = "style4";
+ public static final String RES_TYPE_NAME_STYLES5 = "style5";
+ public static final String RES_TYPE_NAME_ITEM = "item";
public static final String RES_TYPE_NAME_ATTR = "attr";
private final String mName;
diff --git c/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResValueFactory.java w/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResValueFactory.java
index e7a5e43..8a6ea59 100644
--- c/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResValueFactory.java
+++ w/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResValueFactory.java
@@ -112,6 +112,26 @@ public class ResValueFactory {
return new ResStyleValue(parentVal, items, this);
}
+ if (ResTypeSpec.RES_TYPE_NAME_STYLES2.equals(resTypeName)) {
+ return new ResStyleValue(parentVal, items, this);
+ }
+
+ if (ResTypeSpec.RES_TYPE_NAME_STYLES3.equals(resTypeName)) {
+ return new ResStyleValue(parentVal, items, this);
+ }
+
+ if (ResTypeSpec.RES_TYPE_NAME_STYLES4.equals(resTypeName)) {
+ return new ResStyleValue(parentVal, items, this);
+ }
+
+ if (ResTypeSpec.RES_TYPE_NAME_STYLES5.equals(resTypeName)) {
+ return new ResStyleValue(parentVal, items, this);
+ }
+
+ if (ResTypeSpec.RES_TYPE_NAME_ITEM.equals(resTypeName)) {
+ return new ResStyleValue(parentVal, items, this);
+ }
+
if (ResTypeSpec.RES_TYPE_NAME_ATTR.equals(resTypeName)) {
return new ResAttr(parentVal, 0, null, null, null);
}
If you need only decode apk than quick solution:
brut.androlib.res.data.value.ResValueFactory#ResScalarValue
//if (ResTypeSpec.RES_TYPE_NAME_STYLES.equals(resTypeName)) {
if (resTypeName != null && resTypeName.startsWith(ResTypeSpec.RES_TYPE_NAME_STYLES)) {
return new ResStyleValue(parentVal, items, this);
}
For me it decodes Facebok apk without errors with resources.
This site is able to decompile Facebook App http://apk-deguard.com/. But I didn't find the file AndroidManifest