apk編譯與反編譯

/*

author:少仲

blog: http://blog.csdn.net/py_panyu

weibo: http://weibo.com/u/3849478598

歡迎轉載,轉載請註明出處.

*/


0x1 apk編譯過程


步驟中提到的工具如下表:

名稱

功能介紹

在操作系統中的路徑

aapt

Android資源打包工具

${ANDROID_SDK_HOME}/platform-tools/appt

aidl

Android接口描述語言轉化爲.java文件的工具

${ANDROID_SDK_HOME}/platform-tools/aidl

javac

Java Compiler

${JDK_HOME}/javac或/usr/bin/javac

dex

轉化.class文件爲Davik VM能識別的.dex文件

${ANDROID_SDK_HOME}/platform-tools/dx

apkbuilder

生成apk

${ANDROID_SDK_HOME}/tools/opkbuilder

jarsigner

.jar文件的簽名工具

${JDK_HOME}/jarsigner或/usr/bin/jarsigner

zipalign

字節碼對齊工具

${ANDROID_SDK_HOME}/tools/zipalign

 

第一步:打包資源文件,生成R.java文件
【輸入】Resource文件(就是工程中res中的文件)、Assets文件(相當於另外一種資源,這種資源Android系統並不像對res中的文件那樣優化它)、AndroidManifest.xml文件(包名就是從這裏讀取的,因爲生成R.java文件需要包名)、Android基礎類庫(Android.jar文件)
【輸出】打包好的資源(一般在Android工程的bin目錄可以看到一個叫resources.ap_的文件就是它了)、R.java文件(在gen目錄中,大家應該很熟悉了)
【工具】aapt工具,它的路徑在${ANDROID_SDK_HOME}/platform-tools/aapt(如果你使用的是Windows系統,按慣例路徑應該這樣寫:%ANDROID_SDK_HOME%\platform-tools\aapt.exe,下同).


第二步:處理AIDL文件,生成對應的.java文件(當然,有很多工程沒有用到AIDL,那這個過程就可以省了)
【輸入】源碼文件、aidl文件、framework.aidl文件
【輸出】對應的.java文件
【工具】aidl工具


第三步:編譯Java文件,生成對應的.class文件
【輸入】源碼文件(包括R.java和AIDL生成的.java文件)、庫文件(.jar文件)
【輸出】.class文件
【工具】javac工具


第四步:把.class文件轉化成Davik VM支持的.dex文件
【輸入】 .class文件(包括Aidl生成.class文件,R生成的.class文件,源文件生成的.class文件),庫文件(.jar文件)
【輸出】.dex文件
【工具】javac工具


第五步:打包生成未簽名的.apk文件
【輸入】打包後的資源文件、打包後類文件(.dex文件)、libs文件(包括.so文件,當然很多工程都沒有這樣的文件,如果你不使用C/C++開發的話)
【輸出】未簽名的.apk文件
【工具】apkbuilder工具


第六步:對未簽名.apk文件進行簽名
【輸入】未簽名的.apk文件
【輸出】簽名的.apk文件
【工具】jarsigner


第七步:對簽名後的.apk文件進行對齊處理(不進行對齊處理是不能發佈到Google Market的)
【輸入】簽名後的.apk文件
【輸出】對齊後的.apk文件
【工具】zipalign工具


知道了這些細節以後,我們就可以實現很多自動化的東西,比如日構建系統,自動生成發佈文件等等.


0x2 apk文件結構

新建一個hello.apk,默認編譯,然後將編譯好的apk重命名成zip文件,用winrar打開.



(1).AndroidManifest.xml

       這裏的AndroidManifest.xml就是源代碼中的AndroidManifest.xml編譯後所得到的文件.AndroidManifest.xml是安卓應用程序的全局配置文件,該文件保存了apk的包名,版本信息,sdk版本,Activity ,Service, Boardcast Receiver, Content Provider等應用組件的配置信息.還有程序所需要的權限也是在AndroidManifest.xml這個文件中聲明的.


(2).classes.dex

雖然Android開發的源語言是java,但是Android應用程序卻不在標準的java虛擬機上運行.Google爲Android平臺專門設計了一套用於運行Android程序的虛擬機,這就是Dalvik虛擬機(Dalvik Virtual Machine).而classes.dex就是運行在Dalvik虛擬機上的可執行文件.我們編寫的java源代碼經過java編譯器編譯後會生成.class文件;而Android SDK自帶的dx工具(dx.bat在\sdk安裝目錄\sdk\build-tools\android-4.4這條路徑下,dx.jar在\sdk安裝目錄\sdk\build-tools\android-4.4\lib這條路徑下)會將這些.class文件轉換爲classes.dex.值得一提的是,在Android5.0中,Dalvik虛擬機已經被ART虛擬機(Android Runtime)所取代.


(3).resources.arsc

arsc,是一個包含了已被編譯好的資源的二進制格式文件.我們知道,一個安卓應用程序往往包含了很多的資源(例如:layout文件,圖片,字符串,菜單).那麼程序在運行時,是怎麼調用這些資源的呢?其實在apk編譯和生成過程中,AAPT一方面會在源代碼中爲每個資源文件都賦予一個32位的整數做爲標記,這些整數全部保存在R.java這個源文件中,R.java是系統自動生成的,用戶是無法對其進行修改的.這裏需要注意一點:assets文件夾中的資源文件是不會被編譯的.另一方面,AAPT會生成一個resources.arsc文件,這個二進制文件包含了所有的資源名字以及標記這些資源的數字.resources.arsc的作用是當app運行時,手機設備通過該文件能夠很方便匹配和解析apk中的資源.


(4).res文件夾

 apk中的res文件夾由drawable文件夾,layout文件夾,menu文件夾這3個子文件夾組成.其中,drawable文件夾用於存放apk的圖片資源,layout文件夾用於存放佈局文件,menu文件夾用於存放菜單文件.

 

(5).META-INF文件夾

存放的是簽名信息,用來保證apk包的完整性和系統的安全


總結,android開發就是把源代碼和資源編譯成apk形式,而android逆向就是爲了把apk還原成源代碼和資源.apk文件就是一個帶簽名的zip包,目前主流的程序將核心代碼都採用ndk開發,所以會多生成一個.so文件.


0x3 反編譯

使用反編譯工具dex2jar可將dex文件反編譯成.jar文件,然後運用jd-gui工具即可查看反編譯後得到的源代碼.

(1).將classes.dex放到dex2jar的目錄下

(2).dex2jar classes.dex


(3).使用jd-gui查看jar文件




0x4 反編譯+重打包

使用apktool反編譯apk文件:apktool d Hello.apk



之後找到Hello\res\values\string.xml,它包含了apk中的字符串資源.我們將hello_world的值改爲”hellohell”



我這裏反編譯出現了錯誤,之後我就懶得去看爲什麼了,反正也不重要…..然後我就找了一個工具



反編譯+修改+回編譯+簽名..然後搞定了


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章