Apk文件用WINRAR压缩软件解压缩后,如下图所示:主要是三个文件(lib、META-INF、res)和三个文件夹(AndroidManifest.xml、classes.dex、resources.arsc)
用工具展开可以看到如下所示的文件结构(文件夹中的内容可能不一致,这里我举得例子是一个JNI的Demo)
下面再详细介绍各个文件或者文件夹的作用或内容
- META-INF文件夹:META-INF目录下存放的是签名信息,用来保证apk包的完整性和系统的安全。在eclipse编译生成一个apk包时,会对所有要打包的文件做一个校验计算,并把计算结果放在META-INF目录下。而在Android平台上安装apk包时,应用管理器会按照同样的算法对包里的文件做校验,如果校验结果与META-INF下的内容不一致,系统就不会安装这个apk。这就保证了apk包里的文件不能被随意替换。比如拿到一个apk 包后,如果想要替换里面的一幅图片,一段代码,或一段版权信息,想直接解压缩、替换再重新打包,基本是不可能的。如此一来就给病毒感染和恶意修改增加了难度,有助于保护系 统的安全。
MENIFEST.MF:
遍历apk包中的所有文件(entry),对非文件夹非签名文件的文件,逐个生成SHA1的数字签名信息,再用Base64进行编码。具体代码见这个方法:
private static Manifest addDigestsToManifest(JarFile jar)
关键代码是
for (JarEntry entry: byName.values()) {
String name = entry.getName();
if (!entry.isDirectory() && !name.equals(JarFile.MANIFEST_NAME) &&
!name.equals(CERT_SF_NAME) && !name.equals(CERT_RSA_NAME) &&
(stripPattern == null ||!stripPattern.matcher(name).matches())){
InputStream data = jar.getInputStream(entry);
while ((num = data.read(buffer)) > 0) {
md.update(buffer, 0, num);
}
Attributes attr = null;
if (input != null) attr = input.getAttributes(name);
attr = attr != null ? new Attributes(attr) : new Attributes();
attr.putValue("SHA1-Digest", base64.encode(md.digest()));
output.getEntries().put(name, attr);
}
}
之后将生成的签名写入MANIFEST.MF文件。关键代码如下:
Manifest manifest = addDigestsToManifest(inputJar);
je = new JarEntry(JarFile.MANIFEST_NAME);
je.setTime(timestamp);
outputJar.putNextEntry(je);
manifest.write(outputJar);
打开MANIFEST.MF
Manifest-Version: 1.0 Created-By: 1.0 (Android)
Name: res/drawable-xhdpi/abc_ab_bottom_solid_light_holo.9.png
SHA1-Digest: 98aPD0Xqx5q4D+vZs6Jb7lXg2Go=
Name: res/drawable-hdpi/abc_list_divider_holo_light.9.png SHA1-Digest:
PoxeeFE1gxgKYYjKMfN1ri2qqEo=
Name: res/drawable-xhdpi/abc_textfield_search_right_default_holo_light
SHA1-Digest: /UIFeo6oXwL7NSIU/486wBQ0Xls=
对前一步生成的Manifest,使用SHA1-RSA算法,用私钥进行签名。
CERT.SF
Signature-Version: 1.0 SHA1-Digest-Manifest:
5C1qwho6z1GTLX93lyVpN/8J7gI= Created-By: 1.0 (Android)
Name: res/drawable-xhdpi/abc_ab_bottom_solid_light_holo.9.png
SHA1-Digest: K4HrHjcFfdlvbiNQU1qsErUvoic=
Name: res/drawable-hdpi/abc_list_divider_holo_light.9.png SHA1-Digest:
KRfdYM/Dt5MyxkMw3p5XG9MQl0k=
Name: res/drawable-xhdpi/abc_textfield_search_right_default_holo_light
.9.png
SHA1-Digest: kkTKqzaczWYCFJkGha/OJn2Vq7Y=
注:红色粗体SHA1-Digest-Manifest是MANIFEST.MF整个文件的SHA1并base64编码的结果。
CERT.RSA
该文件主要用来保存公钥及其相关信息
文章参考:
http://blog.csdn.net/zengyangtech/article/details/5735071
http://drops.wooyun.org/mobile/4296
http://my.oschina.net/blackylin/blog/207480