![Apk文件結(jié)構(gòu)簡介_第1頁](http://file3.renrendoc.com/fileroot_temp3/2022-1/5/16127f87-26e9-493b-8e1d-f0128273ef6d/16127f87-26e9-493b-8e1d-f0128273ef6d1.gif)
![Apk文件結(jié)構(gòu)簡介_第2頁](http://file3.renrendoc.com/fileroot_temp3/2022-1/5/16127f87-26e9-493b-8e1d-f0128273ef6d/16127f87-26e9-493b-8e1d-f0128273ef6d2.gif)
![Apk文件結(jié)構(gòu)簡介_第3頁](http://file3.renrendoc.com/fileroot_temp3/2022-1/5/16127f87-26e9-493b-8e1d-f0128273ef6d/16127f87-26e9-493b-8e1d-f0128273ef6d3.gif)
![Apk文件結(jié)構(gòu)簡介_第4頁](http://file3.renrendoc.com/fileroot_temp3/2022-1/5/16127f87-26e9-493b-8e1d-f0128273ef6d/16127f87-26e9-493b-8e1d-f0128273ef6d4.gif)
![Apk文件結(jié)構(gòu)簡介_第5頁](http://file3.renrendoc.com/fileroot_temp3/2022-1/5/16127f87-26e9-493b-8e1d-f0128273ef6d/16127f87-26e9-493b-8e1d-f0128273ef6d5.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
1、一引言 做過OPhone/Android應(yīng)用開發(fā)的人,對apk文件應(yīng)該不會陌生。apk文件,即Android application package文件。每個要安裝到OPhone平臺的應(yīng)用都要被編譯打包為一個單獨的文件,后綴名為.apk,其中包含了應(yīng)用的二進制代碼、資源、配置文件等。 本文將對apk文件的結(jié)構(gòu)和內(nèi)容做一個簡單介紹,并以一個簡單的hello world程序為例,介紹一下apk文件中二進制代碼dex文件的反編譯過程。(作者:景濤)
2、;二Hello world示例 為了敘述方便,我們先給出一個簡單的hello world程序。工程的目錄結(jié)構(gòu)如下: view plaincopy to clipboardprint?1. |- AndroidManifest.xml |- assets |- bin |- perties |- res | |- drawable | | -
3、160;icon.png | |- layout | | - main.xml | - values | - strings.xml - src - hello - world - hello.java |- AndroidManifest.xml |- assets |- bin |- perties |- res | |- drawable
4、 | | - icon.png | |- layout | | - main.xml | - values | - strings.xml - src - hello - world - hello.java 我使用的開發(fā)環(huán)境是eclipse及adt0.9和OPhone sdk 1.5。上圖中所有文件和目錄都是根據(jù)建立工程時的配置自動生成的。hello.java是我在這個工程中唯一修改的地方,在程序執(zhí)行時會在屏幕上顯示“hello, OPhone”的字樣。源碼如下,注意粗體為修改的代碼。 view p
5、laincopy to clipboardprint?1. package hello.world; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; public class test extends Activity /* Called when the activity is&
6、#160;first created. */ Override public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); TextView test = new TextView(this); Test.setText(“hello, OPhone”); setContentView(test);
7、0; package hello.world; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; public class test extends Activity /* Called when the activity is first created. */ Override public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); T
8、extView test = new TextView(this); Test.setText(“hello, OPhone”); setContentView(test); 使用eclipse編譯之后可以看到工程的目錄結(jié)構(gòu)發(fā)生了變化。bin和gen目錄是編譯之后產(chǎn)生的。 view plaincopy to clipboardprint?1. |- AndroidManifest.xml |- assets |- bin | |- classe
9、s.dex | |- hello | | - world | | |- R$attr.class | | |- R$drawable.class | | |- R$layout.class | | |- R$string.class | | |- R.class | | - hello.c
10、lass | |- helloworld.apk | - resources.ap_ |- perties |- gen | - hello | - world | - R.java |- res | |- drawable | | - icon.png | |- l
11、ayout | | - main.xml | - values | - strings.xml - src - hello - world - hello.java |- AndroidManifest.xml |- assets |- bin | |- classes.dex | |- hello | | - world | | |- R$attr.class | | |- R$drawabl
12、e.class | | |- R$layout.class | | |- R$string.class | | |- R.class | | - hello.class | |- helloworld.apk | - resources.ap_ |- perties |- gen | - hello | - world | - R.java |- res | |- drawable | | - icon.png | |- layout | | - main.xml | - values | - strings.xml - src - hello - world - hel
13、lo.java在gen目錄下生成了R.java文件,這是系統(tǒng)根據(jù)資源文件生成的。在bin目錄下生成了6個.class文件,記住這一點。另外bin目錄下還生成了helloworld.apk,下面我們就來分析這個文件。三Apk文件結(jié)構(gòu)apk文件實際是一個zip壓縮包,可以通過解壓縮工具解開。以下是我們用zip解開helloworld.apk文件后看到的內(nèi)容??梢钥吹狡浣Y(jié)構(gòu)跟新建立的工程結(jié)構(gòu)有些類似。 view plaincopy to clipboardprint?1. |- AndroidManifest.xml |- META-INF |
14、60;|- CERT.RSA | |- CERT.SF | - MANIFEST.MF |- classes.dex |- res | |- drawable | | - icon.png | - layout | - main.xml - resources.arsc |- AndroidManifest.xml
15、|- META-INF | |- CERT.RSA | |- CERT.SF | - MANIFEST.MF |- classes.dex |- res | |- drawable | | - icon.png | - layout | - main.xml - resources.arsc 3.1 Manifest文件AndroidManifest.xml是每個應(yīng)用都必須定義和包含的,它描述了應(yīng)用的名字、版本、權(quán)限、引用的庫文件等等信息 , ,如要把apk上傳到Google Market上,也要對這個xml做一些配置。網(wǎng)上已有很多資料,在此就不多做介紹了。在apk中的Android
16、Manifest.xml是經(jīng)過壓縮的,可以通過AXMLPrinter2工具 , 解開,具體命令為: view plaincopy to clipboardprint?1. java -jar AXMLPrinter2.jar AndroidManifest.xml java -jar AXMLPrinter2.jar AndroidManifest.xml 3.2 META-INF目錄META-INF目錄下存放的是簽名信息,用來保證apk包的完整性和系統(tǒng)的安全。在eclipse編譯生成一個api包時,會對所有要打包的文件做
17、一個校驗計算,并把計算結(jié)果放在META-INF目錄下。而在OPhone平臺上安裝apk包時,應(yīng)用管理器會按照同樣的算法對包里的文件做校驗,如果校驗結(jié)果與META-INF下的內(nèi)容不一致,系統(tǒng)就不會安裝這個apk。這就保證了apk包里的文件不能被隨意替換。比如拿到一個apk包后,如果想要替換里面的一幅圖片,一段代碼, 或一段版權(quán)信息,想直接解壓縮、替換再重新打包,基本是不可能的。如此一來就給病毒感染和惡意修改增加了難度,有助于保護系 統(tǒng)的安全。 3.3 classes.dex文件 classes.dex是java源碼
18、編譯后生成的java字節(jié)碼文件。但由于Android使用的dalvik虛擬機與標(biāo)準(zhǔn)的java虛擬機是不兼容的,dex文件與class文件相比,不論是文件結(jié)構(gòu)還是opcode都不一樣。目前常見的java反編譯工具都不能處理dex文件。 Android模擬器中提供了一個dex文件的反編譯工具,dexdump。用法為首先啟動Android模擬器,把要查看的dex文件用adb push上傳的模擬器中,然后通過adb shell登錄,找到要查看的dex文件,執(zhí)行dexdump xxx.dex。
19、160; 仍然以hello world程序作為演示。 view plaincopy to clipboardprint?1. # dexdump classes.dex Processing 'classes.dex'. Opened 'classes.dex', DEX version '035' Class #0 - Class descriptor :
20、0;'Lhello/world/R$attr;' Class #5 - Class descriptor : 'Lhello/world/hello;' Access flags : 0x0001 (PUBLIC) Superclass : 'Landroid/app/Activity;' Interfaces - Static fields
21、60;- Instance fields - Direct methods - #0 : (in Lhello/world/hello;) name : '<init>' type : '()V' access 0x10001 (PUBLIC CONSTRUCTOR) 2.
22、0; c r : 1
23、
24、 # dexdump classes.dex Processing 'classes.dex'. Opened 'classes.dex', DEX version '035' Class #0 - Class descriptor : 'Lhello/wo
25、rld/R$attr;' Class #5 - Class descriptor : 'Lhello/world/hello;' Access flags : 0x0001 (PUBLIC) Superclass : 'Landroid/app/Activity;' Interfaces - Static fields - Instance fields - Direct methods - #0 : (in Lhello/world/hello;) name : '<init>' type : '()V' a
26、ccess 0x10001 (PUBLIC CONSTRUCTOR) c r : 1 Dexdump的結(jié)果可以看到有class0到class5六個class,跟工程目錄下bin目錄中的class數(shù)目相對應(yīng),可以想象dex文件包含了所有的class文件。但對hello.java的反編譯結(jié)果(Class #5)中很難發(fā)現(xiàn)我們做的修改,即如何輸出“hello, OPhone”。分支跳轉(zhuǎn)表的反編譯不完整,嚴(yán)格來說就沒有完整的dump出來。fill-array-data表也存在同樣的問題。還有其他很多限制??偟膩碚fdexdump反編的結(jié)果可讀性很差。
27、60; 目前在網(wǎng)上能找到的另一個dex文件的反編譯工具是Dedexer。Dedexer可以讀取dex格式的文件,生成一種類似于匯編語言的輸出。這種輸出與jasmin 的輸出相似,但包含的是Dalvik的字節(jié)碼。我們會在下一節(jié)詳細介紹一下Dedexer。 3.4 res目錄 res目錄存放資源文件。關(guān)于apk文件中的資源管理,OPhone SDN網(wǎng)站上已經(jīng)有文章做過詳細介紹 ,就不在此敷述。 3.5 resources.arsc 編譯
28、后的二進制資源文件。 四反編譯工具Dedexer Dedexer是目前在網(wǎng)上能找到的唯一一個反編譯dex文件的開源工具 。Dedexer下載后需要編譯才能使用。如果你用過ant編譯java程序,那么編譯Dedexer是一件非常簡單的工作。注意目前Dedexer的最新版本是1.5,只能使用junit4.5編譯。下面以linux環(huán)境為例,講一下Dedexer的編譯使用過程。 下載ddx1.5.zip后,解壓縮會產(chǎn)生一個ded
29、exer目錄,其中包含build.xml文件。我們需要根據(jù)本機的環(huán)境配置build.xml的內(nèi)容,注意下面的粗體部分是我本機的配置。 view plaincopy to clipboardprint?1. <!- Directories of the project -> <property name="home" value="/home/danny/myproject/dedex/dedexer"/> <property&
30、#160;name="junit-home" value="/home/danny/myproject/dedex"/> <!- Directories derived from the source tree root -> <property name="classdir" value="$home/classes"/> <propert
31、y name="src" value="$home/sources"/> <property name="testbase" value="$home/testfiles"/> <!- Directories derived from the JUnit base -> <property name="junit_jar&
32、quot; value="$junit-home/junit-4.5.jar"/> <!- Directories of the project -> <property name="home" value="/home/danny/myproject/dedex/dedexer"/> <property name="junit-home" value="/home/danny/myproject/dedex"/> <
33、;!- Directories derived from the source tree root -> <property name="classdir" value="$home/classes"/> <property name="src" value="$home/sources"/> <property name="testbase" value="$home/testfiles"/> <!- Directories
34、derived from the JUnit base -> <property name="junit_jar" value="$junit-home/junit-4.5.jar"/> 環(huán)境配置好之后可以開始編譯了。當(dāng)然要保證你已經(jīng)安裝好了ant編譯工具。執(zhí)行ant。 view plaincopy to clipboardprint?1. dannydanny-desktop:/myproject/dedex$ ant Buildfile: build.xml
35、 init: mkdir Created dir: /home/danny/myproject/dedex/dedexer/classes compile: javac Compiling 48 source files to /home/danny/myproject/dedex/dedexer/classes javac Note: /home/danny/myproject/dedex/dedexer/sources/hu/uw/
36、pallergabor/dedexer/Annotation.java uses unchecked or unsafe operations. javac Note: Recompile with -Xlint:unchecked for details. package: jar Building jar: /home/danny/myproject/dedex/dedexer/ddx.jar BUILD
37、0;SUCCESSFUL Total time: 3 seconds dannydanny-desktop:/myproject/dedex$ ant Buildfile: build.xml init: mkdir Created dir: /home/danny/myproject/dedex/dedexer/classes compile: javac Compiling 48 source files to /home/danny/myproject/dedex/dedexer/classes javac Note: /ho
38、me/danny/myproject/dedex/dedexer/sources/hu/uw/pallergabor/dedexer/Annotation.java uses unchecked or unsafe operations. javac Note: Recompile with -Xlint:unchecked for details. package: jar Building jar: /home/danny/myproject/dedex/dedexer/ddx.jar BUILD SUCCESSFUL Total time: 3 seconds好了,編譯dedexer成功
39、,只用了3秒種,生成了ddx.jar文件。我習(xí)慣修改一下它的文件名,加上版本號。用來反編譯的命令如下: view plaincopy to clipboardprint?1. dannydanny-desktop:/myproject/dedex$ java -jar ddx1.5.jar -d target folder classes.dex Processing hello/world/R$string Processing hello/world/R$layout
40、160;Processing hello/world/hello Processing hello/world/R$attr Processing hello/world/R Processing hello/world/R$drawable dannydanny-desktop:/myproject/dedex$ java -jar ddx1.5.jar -d target folder classes.dex Processing hello/world/R$string Processing he
41、llo/world/R$layout Processing hello/world/hello Processing hello/world/R$attr Processing hello/world/R Processing hello/world/R$drawable dedexer為每個class文件生成了一個后綴為ddx的文件。不出所料,有6個ddx文件。 view plaincopy to clipboardprint?1. dannydanny-desktop:/myproject/dedex$ ls hello/world/
42、2. R$attr.ddx R.ddx R$drawable.ddx R$layout.ddx R$string.ddx hello.ddx dannydanny-desktop:/myproject/dedex$ ls hello/world/ R$attr.ddx R.ddx R$drawable.ddx R$layout.ddx R$string.ddx hello.ddx 看一下我們所關(guān)心的hello.ddx
43、的內(nèi)容。 view plaincopy to clipboardprint?1. class public hello/world/hello 2. .super android/app/Activity 3. .source hello.java 4. 5. .method public <init>()V 6. .line 7 7. &
44、#160; invoke-direct v0,android/app/Activity/<init> <init>()V 8. return-void 9. .end method 10.
45、 11. .method public onCreate(Landroid/os/Bundle;)V 12. .line 11 13. invoke-super v2,v3,android/app/Activity/onCreate onCreate(Landroid/os/Bundle;)V 14.
46、 .line 13 15. new-instance v0,android/widget/TextView 16. invoke-direct v0,v2,android/widget/TextView/<init> <
47、init>(Landroid/content/Context;)V 17. .line 14 18. const-string v1,"hello, OPhone" 19. invoke-virtual v0,v1,android/widget/TextView/setText setText(Ljava/lang/CharSequence;)V 20. .line 15 21. invoke-virtual v2,v0
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年全球及中國自動式雙面研磨床行業(yè)頭部企業(yè)市場占有率及排名調(diào)研報告
- 土地廠房買賣合同
- 空心磚采購合同
- 石材采購合同范本
- 涂料勞務(wù)承包合同協(xié)議書
- 醫(yī)療器械配送合同
- 汽車貨物運輸合同樣本
- 2025農(nóng)村簡易買賣合同
- 2025如何確定勞動合同的成立商業(yè)保理資格
- 最高額抵押擔(dān)保合同
- 2025財年美國國防預(yù)算概覽-美國國防部(英)
- 2024年江西省南昌市中考一模數(shù)學(xué)試題(含答案)
- 48貴州省貴陽市2023-2024學(xué)年五年級上學(xué)期期末數(shù)學(xué)試卷
- 《采暖空調(diào)節(jié)能技術(shù)》課件
- 游戲綜合YY頻道設(shè)計模板
- arcgis軟件操作解析課件
- 中興ZCTP 5GC高級工程師認(rèn)證考試題庫匯總(含答案)
- 大學(xué)生創(chuàng)新創(chuàng)業(yè)教程PPT全套完整教學(xué)課件
- 小學(xué)科學(xué)項目化作業(yè)的設(shè)計與實施研究
- 2020年中考生物試卷及答案
- MCNP-5A程序使用說明書
評論
0/150
提交評論