文档章节

【C#】【APK】APK文件解析AXML-层层深入APK文件解析之一

Parser7
 Parser7
发布于 2015/02/14 18:13
字数 1660
阅读 3100
收藏 126

APK解析是很久以前想完成的一件事,但是因为一些事情搁下了。

当时使用Iteedee的代码在200多个APK文件中有将近四分之一的文件是无法成功解析AXML的。Iteedee下称I

因此,本文的代码基于I的代码修改,效果基本接近于APKTOOL(https://code.google.com/p/android-apktool/)

毋庸置疑的是,在解析的时候,会遇到各种奇葩的编码问题,首先会遇到文件的压缩解压缩码流问题,不得不说SharpZip的性能还是可以的,注意APK使用的Zip压缩格式是非固实压缩,虽然压缩性能(Performance of Compression ,BenchMark)降低了,但是对于文件寻址来说还是很方便的。

常用的APK解析读取APK信息的方法有很多种:

1、AAPT工具、2、apkTool工具、3、AXMLPrinter2工具、4、自带ZIP解压引擎纯字节流解码分析、5、其它...

这里要讲的就是第四种,是基于开源库SharpZipLib的。

‍‍下面言归正传,谈谈个中遇到的一些问题:

1、关于怎么解压zip可以看这个问题的某层回答:

http://bbs.csdn.net/topics/390421494

注意GZip和Zip不一样,Gzip在HTTP请求中比较常见

使用到的sharp库到如下网站去找

http://icsharpcode.github.io/SharpZipLib/

2、zip版本问题(788):

大部分文件的解压版本都是0x14,而个别文件出现0x0314,因此抛出了异常,具体原因无法考究,解决方案是在SharpZipLib源码中加入代码过滤掉,影响应该不大:

 if (extractVersion==788)
{
    extractVersion &= 0xff; 
}

记得备案,免得那天遇到问题了不知道这一茬。


3、文本编码问题:

从I那儿下载的代码经过测试后还是存在不少问题的,这里说的文本编码就是一个典型的例子。

I使用的是UTF8编码格式进行转码

通过 http://tool.chinaz.com/Tools/URLEncode.aspx  查了下"赶集"两字的UTF8的码流形式为:%e8%b5%b6%e9%9b%86 .

 然而,把解析之前的AndroidManifest.xml在程序里dump出来发现实际上是这样的:

那么问题就来了,通过http://tool.chinaz.com/Tools/Unicode.aspx 查了一下unicode码流(unicode的编码据说没有一个统一的标准,所以才出现了UTF8\16\32等编码),给出的结果是:\u8d76\u96c6\u7b80\u6613\u5730\u56fe。

原因真的就找到了吗,有时候人真的是聪明反被聪明误啊,博主考虑了大小端的问题,于是字节换序、去00字节、重返UTF8(为什么再使用UTF8也是基于很多原因)各种方法试过皆无果之后,探究了下Unicode编码在c#中实现的具体码流:

            byte[] bytes = Encoding.Unicode.GetBytes(textBox1.Text);
            for (int ii = 0; ii < bytes.Length; ii++)
            {
                textBox2.Text += string.Format("{0:x2} ", bytes[ii]);
            }

结果如下:

显然字序跟AXML中的是一模一样,注意00字节,可见AXML和c#中的unicode都使用了双字节对齐的(这不废话么),那么修复了编码Bug之后的某个子函数是这样的:

 private String compXmlStringAt(byte[] arr, int strOff)
        {
            int strLen = arr[strOff + 1] << 8 & 0xff00 | arr[strOff] & 0xff;
            byte[] chars = new byte[strLen<<=1 ];
            for (int ii = 0; ii < strLen ; ii++)
            {
                chars[ii] = arr[strOff + 2 + ii];
            }
            return Encoding.Unicode.GetString(chars);//Change to Unicode of Encoding by Parser7
        }

如此而来,就成功支持了中文/多语言了。然而让我郁闷的是,通篇的注释都在说Unicode,只字未提UTF8,代码的原作者居然赫然在目地写着错误的代码,令人费解的注释


4、TEXT事件类型的处理:

I写的代码,只对startTag之类的事件做了处理,然而XmlPullParser使用了五类事件,但是I对未知事件的处理是直接break了,这样会造成manifest等元素在流中未关闭的问题,严重的致命/FATOL ERROR。

由于此处对TEXT内容并不关心,所以使用对offset简单处理防止死循环的方法跳过。后面有空了再来细细研究这个东西。有需要的朋友可以一起交流下。

XmlPullParser的源码我估计可能就在这个网站http://www.xmlpull.org/ ,找到的记得发我一份,先谢谢了。

相关资料:

http://blog.csdn.net/andyhuabing/article/details/8036340

5、size=0问题导致无法正确读到androidmanifest.xml:

I使用了如下的方法遍历每一个压缩包中的文件

 while ((item = zip.GetNextEntry()) != null)
{...}

在某个APK的解析中发现出现size=0导致未能成功读取androidmanifest.xml文件。

跟踪了size读写器所有的过程后,发现在ZipFile构造函数中已经能够获得所有的ZipEntry,而I的代码这里调用GetNextEntry方法显然不仅是画蛇添足而且还引入了Bug,废话少说,使用迭代器轻松搞定:

PZipFile = new ZipFile(fsStream);
 foreach (ZipEntry entry in PZipFile )
 {    ...    }

小结:

至此,已经能成功解析1021个文件的AXML,但还有35个文件不能成功解析。

经检验,有21个文件已经损坏,但还有14个文件可以成功打开压缩包,具体原因还在分析中。

6、XmlException抛出的EntityName解析错误:并指出在35行51列

I的代码似乎没有实现将decompressXML之后的result转为XMLDocument,这里是我自己加了相应的代码,但是却出现这样的问题。

dump出解析的xml内容后发现在指定位置出现了xml非法字符'&',将非法字符转义处理就行了。

下面就是很直接、赤裸裸的代码了:

public static string HandleInvalidCharAtXMLDoc(string filename)
{
 return filename.Replace("<", "&lt;").Replace(">", "&gt;").Replace("&", "&amp;").Replace("'", "&apos;").Replace("\"", "&quot;");
}


7、压缩包签名头问题:

apktool解不开,winrar能看到目录结构,从压缩档中拖拽文件貌似可以解压AXML,但是会提示文件损坏,将解压出来的AXML文件放入成功解析的APK后能正确解析出AXML明文内容。

经过一些实验后,发现dump出来的字节流跟能解析出来的字节流不一样,说明可能是entry索引出了问题,或者内容被破坏了。根据上文描述,明显问题出在entry索引问题,或者是其它问题(不是788等版本问题)

© 著作权归作者所有

共有 人打赏支持
Parser7
粉丝 25
博文 16
码字总数 21280
作品 1
杭州
程序员
私信 提问
加载中

评论(4)

Parser7
Parser7

引用来自“yujiff”的评论

涉及编码,就应该弄清unicode与utf8,utf16,utf32等等的关系。
是的,一般的系统unicode好像都是16位实现,其实就是宽char吧,之前因为解析过sqlite,对编码接触也不多,所以绕了一大弯。
yujiff
yujiff
涉及编码,就应该弄清unicode与utf8,utf16,utf32等等的关系。
Parser7
Parser7

引用来自“FlashCHen”的评论

这是所谓的反编译的意思吗?

只是解析了AXML,反编译的一部分。
FlashCHen
FlashCHen
这是所谓的反编译的意思吗?
OSChina 技术周刊第二十二期 —— DUBBO 配置规则详解

每周技术抢先看,总有你想要的! 移动开发 【翻译】为你的 Android 应用增加本地搜索功能 前端开发 【软件】AngularJS 的剪贴板扩展 ngClip 【软件】国际化和本地化 JavaScript 库 Globaliz...

OSC编辑部
2015/02/16
0
0
OSChina 技术周刊第二十二期 —— DUBBO配置规则详解

每周技术抢先看,总有你想要的! 移动开发 【翻译】为你的 Android 应用增加本地搜索功能 前端开发 【软件】AngularJS 的剪贴板扩展 ngClip 【软件】国际化和本地化 JavaScript 库 Globaliz...

OSC编辑部
2015/02/16
2K
0
转载分享:Android APP二次打包操作步骤介绍

看到好的技术教程就想转载一下,不喜勿喷!谢谢配合,仅供菜鸟学习研究,不要做坏事哦\(^o^)/~ 关于Android APP 二次打包现象已经屡见不鲜,为何“打包党”就吃准了Android平台,二次打包的操...

科技创造
2015/08/26
1K
2
Android apk仿反编译套路(一)

反编译Apk时你是否遇到过下图中的错误,反编译进行到就报错了,然后就没有然后了。 pic001.png 这是因为该apk的文件被特殊处理过,导致在反编译时报错。 我们知道是以AXML格式存在于apk中的,...

hellsam
03/22
0
0
Android包管理机制(五)APK是如何被解析的

本文首发于微信公众号「刘望舒」 原文链接:APK是如何被解析的? 相关文章 包管理机制系列 前言 在本系列的前面文章中,我介绍了PackageInstaller的初始化和安装APK过程、PMS处理APK的安装和...

刘望舒
10/18
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Flink-数据流编程模型

1、抽象等级 Flink提供了不同级别的抽象来开发流/批处理应用程序。 1) 低层级的抽象 最低层次的抽象仅仅提供有状态流。它通过Process函数嵌入到DataStream API中。它允许用户自由地处理来自一...

liwei2000
24分钟前
1
0
Java开发Swing实战JFrame和JTabbedPane容器的用法详细解析

概述: 项目是一个桌面程序,涉及标签和按钮组件、布局管理器组件、面板组件、列表框和下拉框组件等组件,以及Swing事件处理机制。 下面先从最基础的界面开始。 /** * @author: lishuai * @...

金铭鼎IT教育
30分钟前
9
0
flask 之旅

环境 为了正确地跑起来,你的应用需要依赖许多不同的软件。 就算是再怎么否认这一点的人,也无法否认至少需要依赖Flask本身。 你的应用的运行环境,在当你想要让它跑起来时,是至关重要的。 ...

hblt-j
30分钟前
6
0
easyui的上传文件

记录一下自己亲手操刀easyui的心得:不用不知道,一用就问题多,网上查资料,有用的真的太少了 ——————————————————正文 FileBox,还是不错的讲真,至少我去自己写就gaga了...

anlve
31分钟前
4
0
如何做好SQLite 使用质量检测,让事故消灭在摇篮里

本文由云+社区发表 SQLite 在移动端开发中广泛使用,其使用质量直接影响到产品的体验。 常见的 SQLite 质量监控一般都是依赖上线后反馈的机制,比如耗时监控或者用户反馈。这种方式问题是: ...

腾讯云加社区
33分钟前
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部