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