Apk文件結(jié)構(gòu)簡介_第1頁
Apk文件結(jié)構(gòu)簡介_第2頁
Apk文件結(jié)構(gòu)簡介_第3頁
Apk文件結(jié)構(gòu)簡介_第4頁
Apk文件結(jié)構(gòu)簡介_第5頁
已閱讀5頁,還剩1頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論