iBotPeaches / Apktool

A tool for reverse engineering Android apk files
https://apktool.org/
Apache License 2.0
20.15k stars 3.58k forks source link

Unable to decode AndroidManifest.xml #1976

Closed sebras closed 5 years ago

sebras commented 5 years ago

Information

  1. Apktool Version (apktool -version) - v2.4.0-261e16-SNAPSHOT
  2. Operating System (Mac, Linux, Windows) - Linux
  3. APK From? (Playstore, ROM, Other) - Xiaomi store

Stacktrace/Logcat

I: Using Apktool 2.4.0-261e16-SNAPSHOT on com.unionpay.apk
I: Loading resource table...
I: Decoding AndroidManifest.xml with resources...
Exception in thread "main" brut.androlib.AndrolibException: Could not decode XML
        at brut.androlib.res.decoder.XmlPullStreamDecoder.decode(XmlPullStreamDecoder.java:147)
        at brut.androlib.res.decoder.XmlPullStreamDecoder.decodeManifest(XmlPullStreamDecoder.java:153)
        at brut.androlib.res.decoder.ResFileDecoder.decodeManifest(ResFileDecoder.java:155)
        at brut.androlib.res.AndrolibResources.decodeManifestWithResources(AndrolibResources.java:204)
        at brut.androlib.Androlib.decodeManifestWithResources(Androlib.java:136)
        at brut.androlib.ApkDecoder.decode(ApkDecoder.java:122)
        at brut.apktool.Main.cmdDecode(Main.java:164)
        at brut.apktool.Main.main(Main.java:73)
Caused by: java.io.IOException: Expected: 0x00080003, got: 0x00080001
        at brut.util.ExtDataInput.skipCheckInt(ExtDataInput.java:48)
        at brut.androlib.res.decoder.AXmlResourceParser.doNext(AXmlResourceParser.java:855)
        at brut.androlib.res.decoder.AXmlResourceParser.next(AXmlResourceParser.java:102)
        at brut.androlib.res.decoder.AXmlResourceParser.nextToken(AXmlResourceParser.java:112)
        at org.xmlpull.v1.wrapper.classic.XmlPullParserDelegate.nextToken(XmlPullParserDelegate.java:105)
        at brut.androlib.res.decoder.XmlPullStreamDecoder.decode(XmlPullStreamDecoder.java:140)
        ... 7 more

Steps to Reproduce

  1. apktool d com.unionpay.apk

Frameworks

This APK is not from an OEM ROM.

APK

If this APK can be freely shared, please upload/attach a link to it.

Questions to ask before submission

  1. Have you tried apktool d, apktool b without changing anything? Yes, the very first step fails.
  2. If you are trying to install a modified apk, did you resign it? No, the APK has not been modified.
  3. Are you using the latest apktool version? Yes, the very latest I can get from git, 261e163bc9ace48555c515b87662eccb0725a073.

I did some investigation as to why this fails.

According to the aapt source code an AndroidManifest.xml ought to start with a 16 bit RES_XML_TYPE which is 0x0003, followed by a 16 bit size (describing the size of a struct ResXMLTree_header which is really a struct ResChunk_header which is 8 bytes large, hence should be 0x0008). And then a total size fo the chunk in bytes.

After the initial here there might be StringPool which is created by a call to createStringPool() which calls writeStringBlock() which eventually writes its header consisting of a 16 bit RES_STRING_POOL_TYPE which is 0x0001 followed by a 16 bit size (describing the size of a ResStringPool_header which in total is 28 bytes large, hence should be 0x001C).

apktool's AXmlResourceParser correctly assumes that an AndroidManifest.xml starts with this same 0x0003 followed by 0x0008, however they have been concatenate into a 32bit CHUNK_AXML_FILE with the value 0x00080003. This is then followed by a StringBlock

Now, the AndroidManifest.xml in the APK begins like this

00000000: 01 00 08 00 a4 09 01 00 01 00 1c 00 f4 75 00 00  .............u..
00000010: 71 01 00 00 00 00 00 00 00 00 00 00 e0 05 00 00  q...............
00000020: 00 00 00 00 00 00 00 00 1a 00 00 00 34 00 00 00  ............4...
...
00010990: 18 00 00 00 c2 01 00 00 ff ff ff ff 1f 00 00 00  ................
000109a0: 20 00 00 00                                       ...

The bytes at offset 0 are almost identical with a RES_XML_TYPE followed by a size and a chunk size, but it should begin with 03 00 08 00, not 01 00 08 00. The chunksize of 0x000109a4 also seems reasonable given the size of the file. At offset 8 I do find a RES_STRING_POOL_TYPE followed by a size as it starts with 01 00 1c 00.

This leads me to believe that the AndroidManifest.xml in the downloaded APK is actually faulty, but running unzip -t com.unionpay.apk reports no errors. The APK may have been processed by some tool at or after build time that incorrectly wrote a RES_STRING_POOL_TYPE at the beginning of the file instead of a RES_XML_TYPE. I'm not sure what that tool would be though.

iBotPeaches commented 5 years ago

Thanks for the detailed research and attached PR! I'll do some digging with those magic values and see what I can find.

In the middle of investigating the broken aapt builds for windows, but I'll loop back to this when done.

zawawimanja commented 4 years ago

any info about this issue ? I already decompiled apk and want to open androidmanifest file but it fail like above.