Apk檔案的格式
Android application package檔案。每個要安裝到android平台的應用都要被編譯打包為一個單獨的檔案,尾碼名為.apk,其中包含了應用的二進位代碼、資源、設定檔等。
apk檔案實際是一個zip壓縮包,可以通過解壓縮工具解開。可以用zip解開*.apk檔案,下面是一個helloword的apk樣本檔案
|– AndroidManifest.xml
|– META-INF
| |– CERT.RSA
| |– CERT.SF
| `– MANIFEST.MF
|– classes.dex
|– res
| |– drawable
| | `– icon.png
| `– layout
| `– main.xml
`– resources.arsc
- Manifest檔案:AndroidManifest.xml是每個應用都必須定義和包含的,它描述了應用的名字、版本、許可權、引用的庫檔案等等資訊[ , ],如要把apk上傳到Google Market上,也要對這個xml做一些配置。注意:在apk中的xml檔案是經過壓縮的,不可以直接開啟。
- Res檔案:res檔案夾下為所有的資源檔。
- resources.arsc檔案:為編譯後的二進位資源檔,許多做漢化軟體的人都是修改該檔案內的資源以實現軟體的漢化的。
- META-INF目錄:META-INF目錄下存放的是簽名資訊,用來保證apk包的完整性和系統的安全。在eclipse編譯產生一個api包時,會對所有要打包的檔案做一個校正計算,並把計算結果放在META-INF目錄下。而在OPhone平台上安裝apk包時,應用管理器會按照同樣的演算法對包裡的檔案做校正,如果校正結果與META-INF下的內容不一致,系統就不會安裝這個apk。這就保證了apk包裡的檔案不能被隨意替換。比如拿到一個apk包後,如果想要替換裡面的一幅圖片,一段代碼, 或一段著作權資訊,想直接解壓縮、替換再重新打包,基本是不可能的。如此一來就給病毒感染和惡意修改增加了難度,有助於保護系 統的安全。
- classes.dex是java源碼編譯後產生的java位元組碼檔案。但由於Android使用的dalvik虛擬機器與標準的java虛擬機器是不相容的,dex檔案與class檔案相比,不論是檔案結構還是opcode都不一樣。
XML檔案的反編譯
在apk中的xml檔案是經過壓縮的,可以通過AXMLPrinter2工具解開,具體命令為:
java -jar AXMLPrinter2.jar AndroidManifest.xml
HelloAndroid程式中Manifest檔案的執行個體:
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1"
android:versionName="1.0"
package="name.feisky.android.test"
>
<application
android:label="@7F040001"
android:icon="@7F020000"
>
<activity
android:label="@7F040001"
android:name=".HelloAndroid"
>
<intent-filter
>
<action
android:name="android.intent.action.MAIN"
>
</action>
<category
android:name="android.intent.category.LAUNCHER"
>
</category>
</intent-filter>
</activity>
</application>
<uses-sdk
android:minSdkVersion="6"
>
</uses-sdk>
</manifest>
而原檔案為:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="name.feisky.android.test"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".HelloAndroid"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="6" />
</manifest>
classes.dex檔案反編譯
classes.dex是java源碼編譯後產生的java位元組碼檔案。但由於Android使用的dalvik虛擬機器與標準的java虛擬機器是不相容的,dex檔案與class檔案相比,不論是檔案結構還是opcode都不一樣。目前常見的java反編譯工具都不能處理dex檔案。
Android模擬器中提供了一個dex檔案的反編譯工具,dexdump。用法為首先啟動Android模擬器,把要查看的dex檔案用adb push上傳的模擬器中,然後通過adb shell登入,找到要查看的dex檔案,執行dexdump xxx.dex。但是這樣得到的結果,其可讀性是極差的。下面介紹一個可讀性比較好的工具。
工具準備:
1、把dex檔案反編譯為jar檔案的工具。(dex2jar)
2、把jar反編譯為java的工具。(JD-GUI)
反編譯的步驟
1、從APK中提取classes.dex檔案,對APK檔案解壓即可得到。 將其放到dex2jar的目錄下,開啟cmd,運行dex2jar.bat classes.dex,產生classes.dex.dex2jar.jar。
2、運行JD-GUI工具,開啟上面的jar檔案,即可看到原始碼。
HelloAndroid執行個體:
package name.feisky.android.test;
import android.app.Activity;
import android.os.Bundle;
public class HelloAndroid extends Activity
{
public void onCreate(Bundle paramBundle)
{
super.onCreate(paramBundle);
setContentView(2130903040);
}
}
其原程式為:
package name.feisky.android.test;
import android.app.Activity;
import android.os.Bundle;
public class HelloAndroid extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
本文參加“首屆 Google 暑期大學生部落格分享大賽——2010 Android 篇”。