一、APK 結(jié)構(gòu)
Android 應(yīng)用的 APK(Android Package)安裝文件是一個包含所有代碼和資源文件的壓縮包
AndroidManifest.xml
是Android應(yīng)用程序的配置文件申眼,是一個用來描述Android應(yīng)用“整體資訊”的設(shè)定文件哄孤,簡單來說,相當(dāng)于Android應(yīng)用向Android系統(tǒng)“自我介紹”的配置文件侠仇,Android系統(tǒng)可以根據(jù)這個“自我介紹”完整地了解APK應(yīng)用程序的資訊从隆,每個Android應(yīng)用程序都必須包含一個AndroidManifest.xml文件歉眷,且它的名字是固定的崇决,不能修改材诽。程序打包時,會把AndroidManifest.xml進(jìn)行簡單的編譯恒傻,便于Android系統(tǒng)識別脸侥,編譯之后的格式是AXML格式
Assets
用來存放需要打包到 Android 應(yīng)用程序的靜態(tài)資源文件,例如圖片資源文件盈厘、JSON 配置文件睁枕、渠道配置文件、二進(jìn)制數(shù)據(jù)文件沸手、HTML5離線資源文件等外遇。與res/raw 目錄不同的是,assets 目錄支持任意深度的子目錄罐氨,同時該目錄下面的文件不會生成資源ID。
lib
這里存放應(yīng)用程序依賴的native庫文件滩援,一般是用C/C++編寫栅隐,這里的lib庫可能包含4中不同類型,根據(jù)CPU型號的不同玩徊,大體可以分為ARM租悄,ARM-v7a,MIPS恩袱,X86泣棋,分別對應(yīng)著ARM架構(gòu),ARM-V7架構(gòu)畔塔,MIPS架構(gòu)和X86架構(gòu)潭辈,不同的CPU架構(gòu)對應(yīng)著不同的目錄,每個目錄中可以放很多對應(yīng)版本的so庫澈吨,且這個目錄的結(jié)構(gòu)固定把敢,用戶只能按照這個目錄存放自己的so庫。目前市場上使用的移動終端大多是基于ARM或者ARM-V7a架構(gòu)的谅辣,X86和MIPS架構(gòu)的移動智能終端比較少修赞,所以有些應(yīng)用程序lib目錄下只包含armeabi目錄或者armeabi-v7a目錄,也就是說桑阶,這四個目錄要根據(jù)CPU的架構(gòu)來選柏副,而市面上ARM架構(gòu)的手機(jī)占大多數(shù)勾邦,所以一般的APK只包含ARM和ARM-V7a的so。
res
res是resource的縮寫割择,這個目錄存放資源文件眷篇,存在這個文件夾下的所有文件都會映射到Android工程的.R文件中,生成對應(yīng)的ID锨推,訪問的時候直接使用資源ID即R.id.filename铅歼,res文件夾下可以包含多個文件夾,其中anim存放動畫文件换可;drawable目錄存放圖像資源椎椰;layout目錄存放布局文件;values目錄存放一些特征值沾鳄,colors.xml存放color顏色值慨飘,dimens.xml定義尺寸值,string.xml定義字符串的值译荞,styles.xml定義樣式對象瓤的;xml文件夾存放任意xml文件,在運(yùn)行時可以通過Resources.getXML()讀韧碳摺圈膏;raw是可以直接復(fù)制到設(shè)備中的任意文件,他們無需編譯
classes.dex
傳統(tǒng)的Java程序篙骡,首先先把Java文件編譯成class文件稽坤,字節(jié)碼都保存在了class文件中,Java虛擬機(jī)可以通過解釋執(zhí)行這些class文件糯俗。而Dalvik虛擬機(jī)是在Java虛擬機(jī)進(jìn)行了優(yōu)化尿褪,執(zhí)行的是Dalvik字節(jié)碼,而這些Dalvik字節(jié)碼是由Java字節(jié)碼轉(zhuǎn)換而來得湘,一般情況下杖玲,Android應(yīng)用在打包時通過AndroidSDK中的dx工具將Java字節(jié)碼轉(zhuǎn)換為Dalvik字節(jié)碼。dx工具可以對多個class文件進(jìn)行合并淘正,重組摆马,優(yōu)化,可以達(dá)到減小體積鸿吆,縮短運(yùn)行時間的目的
resources.arsc
用來記錄資源文件和資源ID之間的映射關(guān)系今膊,用來根據(jù)資源ID尋找資源。Android的開發(fā)是分模塊的伞剑,res目錄專門用來存放資源文件斑唬,當(dāng)在代碼中需要調(diào)用資源文件時,只需要調(diào)用findviewbyId()就可以得到資源文件,每當(dāng)在res文件夾下放一個文件恕刘,aapt就會自動生成對應(yīng)的ID保存在.R文件缤谎,我們調(diào)用這個ID就可以,但是只有這個ID還不夠褐着,.R文件只是保證編譯程序不報(bào)錯坷澡,實(shí)際上在程序運(yùn)行時,系統(tǒng)要根據(jù)ID去尋找對應(yīng)的資源路徑含蓉,而resources.arsc文件就是用來記錄這些ID和資源文件位置對應(yīng)關(guān)系的文件频敛。
備注:
1.兩者目錄下的文件在打包后會原封不動的保存在apk包中,不會被編譯成二進(jìn)制馅扣。
*res/raw和assets的不同點(diǎn):
1.res/raw中的文件會被映射到R.java文件中斟赚,訪問的時候直接使用資源ID即R.id.filename;assets文件夾下的文件不會被映射到R.java中差油,訪問的時候需要AssetManager類拗军。
2.res/raw不可以有目錄結(jié)構(gòu),而assets則可以有目錄結(jié)構(gòu)蓄喇,也就是assets目錄下可以再建立文件夾
META-INF
該目錄存放的是簽名相關(guān)的信息发侵,用于驗(yàn)證 APK 包的完整性以及保證系統(tǒng)的安全。主要包含三個文件:
① MANIFEST.MF:主要存放 APK 包中每個文件的名字及每個文件的 SHA1 哈希值妆偏。
② CERT.SF:通常每個 APP 會有一個特定的名字刃鳄,例如 BDMOBILE.SF、NETDISK_.SF等钱骂, 它保存的是 MANIFEST.MF 的哈希值以及 MANIFEST.MF 文件中每一個哈希項(xiàng)的哈希值叔锐。
③ CERT.RSA:這個文件保存了 APK 包的簽名和證書的公鑰信息
二、APK生成過程
AAPT
一句話解釋:Android Asset Packaging Tool罐柳,即Android資源打包工具
常見API:
Method:壓縮方法掌腰,Deflate及Stored兩種狰住,即該Zip目錄采用的算法是壓縮模式還是存儲模式张吉;
可以看出resources.arsc、*.png采用壓縮模式催植,而其它采用壓縮模式肮蛹。
Ratio:壓縮率
設(shè)置debbug
http://www.reibang.com/p/8d691b6bf8b4
三、反編譯:
3.1创南、java伦忠、class、dex稿辙、smali之間的轉(zhuǎn)化
工具 | 作用 | 資源 |
---|---|---|
javac | java------>class | |
dx | class------>dex | |
baksmali | dex------>smali | https://bitbucket.org/JesusFreke/smali/downloads/ |
smali | smali------>dex | https://bitbucket.org/JesusFreke/smali/downloads/ |
dex2jar | dex------>jar(class的壓縮包) | https://sourceforge.net/projects/dex2jar/files/ |
apktool | apk------>smali | https://ibotpeaches.github.io/Apktool/install/ |
3.1.1昆码、定義
java
文件即普通文本文件
class
class文件是一種能夠被JVM識別,加載并且執(zhí)行的文件格式,
記錄一個類文件的所有信息.
//生成class
javac -target 1.6 -source 1.6 hello.java
//執(zhí)行class
java **
dex
dex文件的作用是記錄整個工程(通常是一個Android工程)的所有類文件的信息
java -jar dx.jar --dex --output Hello.dex Hello.class
class文件與dex文件的比較
本質(zhì)上都是一樣的,都是二進(jìn)制流文件格式赋咽,dex文件是從class文件演變而來的旧噪,class文件存在冗余信息,dex文件則去掉了冗余脓匿,并且整合了整個工程的類信息淘钟。
3.2、dex 的使用
dex -> jar
3.3陪毡、Jar的使用
生成Jar
jar cvfm name.jar 清單文件 class名|文件夾
jar命令生成的壓縮文件會包含它后邊出的目錄米母。我們應(yīng)該進(jìn)入到指定目錄再執(zhí)行jar命令
清單文件
Manifest-Version: 1.0
Created-By: 1.8.0_131 (Oracle Corporation)
Class-Path: . //主類路徑、可以寫當(dāng)前Jar包名 或者 .
Main-Class: Hello //注明名稱
查看jar
java tvf **.jar
jar命令格式:jar {c t x u f }[ v m e 0 M i ][-C 目錄]文件名...
-c 創(chuàng)建一個jar包
-t 顯示jar中的內(nèi)容列表
-x 解壓jar包
-u 添加文件到j(luò)ar包中
-f 指定jar包的文件名
-v 生成詳細(xì)的報(bào)造毡琉,并輸出至標(biāo)準(zhǔn)設(shè)備
-m 指定manifest.mf文件.(manifest.mf文件中可以對jar包及其中的內(nèi)容作一些一設(shè)置)
-0 產(chǎn)生jar包時不對其中的內(nèi)容進(jìn)行壓縮處理
-M 不產(chǎn)生所有文件的清單文件(Manifest.mf)铁瞒。這個參數(shù)與忽略掉-m參數(shù)的設(shè)置
-i 為指定的jar文件創(chuàng)建索引文件 jar i hello.jar
-C 表示轉(zhuǎn)到相應(yīng)的目錄下執(zhí)行jar命令,相當(dāng)于cd到那個目錄,然后不帶-C執(zhí)行jar命令
3.3绊起、APKTool
可以查看APK 的原始 資源文件精拟,同時將dex 轉(zhuǎn)化為smali 文件。
3.3.1虱歪、decode
apktool d -o dir demo.apk
3.3.2蜂绎、build
apktool b -o new.pak dir
3.3.3、jarsinger
jarsigner -verbose -digestalg SHA1 -sigalg SHA1withRSA -keystore key文件路徑 -storepass password -keypass aliasPassWord pkg alias
四笋鄙、APK修改
Java2Smali插件:https://github.com/ollide/intellij-java2smali
4.1师枣、smali
smali是將Android字節(jié)碼用可閱讀的字符串形式表現(xiàn)出來的一種語言,可以稱之為Android字節(jié)碼的反匯編語言萧落。使用baksmali或apktool可以將Android應(yīng)用程序包(apk或jar)反編譯為smali代碼
4.1.1践美、smali基礎(chǔ)語法
1、基本數(shù)據(jù)類型
http://www.reibang.com/p/04c3c8566ee1
4.1.2找岖、smali文件修改
1陨倡、找到對應(yīng)文件位置
2、根據(jù)帶修改位置的方法參數(shù)许布,編寫Java 文件
3兴革、生成smali 文件
4、替換相關(guān)方法
5蜜唾、apktool重新打包
6杂曲、簽名生成新包
五、APK簽名
5.1袁余、簽名文件的生成
1擎勘、MANIFEST.MF
打開待簽名的apk文件(由于apk其實(shí)是一個用zip壓縮的文件,其實(shí)就是用zip解壓整個apk文件)颖榜,逐一遍歷里面的所有條目棚饵,如果是目錄就跳過煤裙,如果是一個文件,就用SHA1(或者SHA256)消息摘要算法提取出該文件的摘要然后進(jìn)行BASE64編碼后噪漾,作為“SHA1-Digest”屬性的值寫入到MANIFEST.MF文件中的一個塊中积暖。該塊有一個“Name”屬性,其值就是該文件在apk包中的路徑怪与。
2夺刑、CERT.SF
計(jì)算這個MANIFEST.MF文件的整體SHA1值,再經(jīng)過BASE64編碼后分别,記錄在CERT.SF主屬性塊(在文件頭上)的“SHA1-Digest-Manifest”屬性值值下遍愿;然后,再逐條計(jì)算MANIFEST.MF文件中每一個塊的SHA1耘斩,并經(jīng)過BASE64編碼后沼填,記錄在CERT.SF中的同名塊中,屬性的名字是“SHA1-Digest”括授。
3坞笙、CERT.RSA
把之前生成的 CERT.SF文件, 用私鑰計(jì)算出簽名, 然后將簽名以及包含公鑰信息的數(shù)字證書一同寫入 CERT.RSA 中保存荚虚。CERT.RSA是一個滿足PKCS7格式的文件薛夜,可以通過openssl工具來查看簽名證書的信息。
//查看簽名證書信息
openssl pkcs7 -inform DER -in CERT.RSA -text -print_certs
相關(guān)鏈接:http://www.reibang.com/p/a27783a713f2
5.2版述、簽名的校驗(yàn)
https://blog.csdn.net/qq_27419187/article/details/76339326
六梯澜、界面化
jadx:https://github.com/skylot/jadx