AndroidManifest反编译失败问题分析

系列 - Android逆向

AndroidManifest 反编译失败问题分析

问题

问题

​ 最近使用 jadx​反编译一个 apk​时,发现 AndroidManifest.xml​反编译失败了,提示如下错误信息

1
2
3
4
5
6
Error decode manifest
java.io.IOException: Expected strings start, expected offset: 0x550, actual: 0x48ac
	at jadx.core.xmlgen.ParserStream.checkPos(ParserStream.java:124)
	at jadx.core.xmlgen.CommonBinaryParser.parseStringPoolNoType(CommonBinaryParser.java:29)
	at jadx.core.xmlgen.BinaryXMLParser.decode(BinaryXMLParser.java:109)
	at jadx.core.xmlgen.BinaryXMLParser.parse(BinaryXMLParser.java:81)

使用 apktool​进行解包,提示类似的错误信息

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
>java -jar apktool.jar d f5a.apk
I: Using Apktool 2.6.0 on f5a.apk
I: Loading resource table...
W: Skipping package group: im.poqoxovpld.messenger
I: Decoding AndroidManifest.xml with resources...
Exception in thread "main" brut.androlib.err.RawXmlEncounteredException: Could not decode XML
        at brut.androlib.res.decoder.XmlPullStreamDecoder.decode(XmlPullStreamDecoder.java:145)
        at brut.androlib.res.decoder.XmlPullStreamDecoder.decodeManifest(XmlPullStreamDecoder.java:151)
        at brut.androlib.res.decoder.ResFileDecoder.decodeManifest(ResFileDecoder.java:159)
        at brut.androlib.res.AndrolibResources.decodeManifestWithResources(AndrolibResources.java:193)
        at brut.androlib.Androlib.decodeManifestWithResources(Androlib.java:140)
        at brut.androlib.ApkDecoder.decode(ApkDecoder.java:109)
        at brut.apktool.Main.cmdDecode(Main.java:175)
        at brut.apktool.Main.main(Main.java:78)
Caused by: java.io.EOFException: reached end of stream after reading 32680 bytes; 877722808 bytes expected
        at com.google.common.io.ByteStreams.readFully(ByteStreams.java:790)
        at com.google.common.io.ByteStreams.readFully(ByteStreams.java:771)
        at com.google.common.io.LittleEndianDataInputStream.readFully(LittleEndianDataInputStream.java:65)
        at brut.util.DataInputDelegate.readFully(DataInputDelegate.java:66)
        at brut.androlib.res.decoder.StringBlock.read(StringBlock.java:70)
        at brut.androlib.res.decoder.AXmlResourceParser.doNext(AXmlResourceParser.java:814)
        at brut.androlib.res.decoder.AXmlResourceParser.next(AXmlResourceParser.java:98)
        at brut.androlib.res.decoder.AXmlResourceParser.nextToken(AXmlResourceParser.java:108)
        at org.xmlpull.v1.wrapper.classic.XmlPullParserDelegate.nextToken(XmlPullParserDelegate.java:105)
        at brut.androlib.res.decoder.XmlPullStreamDecoder.decode(XmlPullStreamDecoder.java:138)
        ... 7 more

​​

错误信息提示我们文件格式可能被修改了,由于 AndroidManifest.xml​​文件已经被编译成了二进制文件,我们需要借助 010 Editor​​工具辅助分析。

010 Editor 导入模板

010 Editor​支持导入模板,模板可以根据指定的规则解析二进制文件格式,并提供可视化界面进行分析和修改,官方的模板仓库在 010 Editor - Binary Template Repository

AndroidManifestg.xml​拖入 010 Editor​中,此时只能查看二进制信息

我们导入 AndroidManifest.bt,将模板文件下载到本地后,首先 Open Template​选择模板文件,再点击 Run Template​运行模板文件

此时 Template Results​界面出现了文件的格式数据,我们可以进行下一步分析了

文件格式分析

查看报错信息

1
Expected strings start, expected offset: 0x550, actual: 0x48ac

如图中所示正常情况 0X550​应该为第一个字符串数据,但是实际位置为 0x24+0x4888=0x48ac​,导致 jadx​解析失败了

​​​​

对比下 AndroidManifest.xml结构图

stringChunk​中的参数如下

  • String count​:4bytes​,表示字符串的数量
  • String Offsets​:int​数组,大小为 String Count​, 存储每个字符串在字符串池中的相对偏移量
  • Style Offets​:同上为 int​数组,大小为 Style Count * 4 bytes
  • String pool​:字符串池,存储了所有字符串

以上参数是顺序存储的,style count​值为 0,意味着没有 Style offsets​,所以 String Offsets​与 string pool​位置连续。

string pool​的起始位置为 0X550​,String Offsets​的起始位置为 0x24​,可得以下公式

1
2
3
scStringOffsets.start + (scStringCount * 4) = scStringPool.start
=> 0x24 + (scStringCount * 4) = 0x550
=> scStringCount = 0x14B = 331

文件修复

由上可知,scStringcount​的值是错误的,应该为 331 而不是 4642,修改为正确的值后保存

按 F5 重新解析文件格式,发现其它数据也正常显示出来了

xml​文件放回 apk​中,再次使用 jadx​反编译,xml​已经可以正常解析

0%