android反編譯集錦

反編譯apk工具

目前有幾種工具:

  • smali
  • dedexer
  • dexdump
  • apktool
  • dex2jar and jd
  • AXMLPrinter2.jar

關於smali的使用,請參考jserv的http://jserv.blogspot.com/2010/05/android.html

 把 classes.dex 反編譯成 jar, 然後用 jd 查看
 java 對照着 smail 就容易些了
 (反編譯出來的 java, 編譯不回去 只能看看)

dexdump功能比較弱,且麻煩,就不討論介紹了。

解壓apk

這裏拿com.himsn.apk 做例子,apk包其實是一個zip文件,把它重命名,然後解壓

 mv com.himsn.apk com.himsn.zip
 unzip com.himsn.zip

得到一駝的東西:

.
├── AndroidManifest.xml
├── classes.dex
├── META-INF
│   ├── ALIAS_NA.RSA
│   ├── ALIAS_NA.SF
│   └── MANIFEST.MF
├── res
│   ├── anim
│   │   ├── cycle_7.xml
│   │   └── shake.xml
│   ├── drawable
│   │   ├── avatar_unknown.png
│   │   ├── ...
│   │   ├── button_choose_contact.xml
│   │   ├── typing4.png
│   │   └── typing.xml
│   ├── layout
│   │   ├── add_contact.xml
│   │   ├── ...
│   │   └── two_line_list_item.xml
│   ├── menu
│   │   ├── choose_contact_offline.xml
│   │   ├── choose_contact.xml
│   │   └── main.xml
│   ├── raw
│   │   ├── key_char.jpg
│   │   ├── key_num.jpg
│   │   ├── ...
│   │   ├── key_pressed_right.png
│   │   └── winks.png
│   └── xml
│       └── preferences.xml
└── resources.arsc

目錄下三個文件兩個文件夾,一一來說

[deli@athena himsn]$ ls -p
AndroidManifest.xml  classes.dex  META-INF/  res/  resources.arsc

AndroidManifest.xml

這個沒必要解釋了,不過用vim打開,都是亂碼,看看這是什麼文件類型的:

[deli@athena himsn]$ file AndroidManifest.xml
AndroidManifest.xml: DBase 3 data file (4256 records)

除了這個,還有layout目錄下的二進制xml文件,可以使用AXMLPrinter工具將其轉換爲可讀的xml文件,工具下載地址:http://code.google.com/p/android4me/downloads/list, 使用很簡單:

java -jar AXMLPrinter2.jar AndroidManifest.xml AndroidManifest2.xml

很多xml一個個轉化很麻煩,這樣的工作,當然是用shell完成了。

$ cd res
$  for file in */*.xml; do java -jar AXMLPrinter2.jar $file > temp; echo $file; mv temp $file -f; done

AndroidManifest2.xml的內容如下:(省略一部分)

<?xml version="1.0" encoding="utf-8"?>
<manifest
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:versionCode="210"
	android:versionName="2.1.0"
	package="com.himsn"
	>
	<uses-sdk
		android:minSdkVersion="2"
		>
	</uses-sdk>
	<uses-permission
		android:name="android.permission.READ_PHONE_STATE"
		>
	</uses-permission>
	<application
		android:label="@7F080000"
		android:icon="@7F02002A"
		>
		<activity
			android:label="@7F080000"
			android:name=".ChooseContactActivity"
			android:launchMode="2"
			android:configChanges="0x000000E0"
			>
			<intent-filter
				>
				<action
					android:name="android.intent.action.MAIN"
					>
				</action>
				<category
					android:name="android.intent.category.LAUNCHER"
					>
				</category>
			</intent-filter>
		</activity>
		<activity
			android:theme="@7F090001"
			android:label="@7F080004"
			android:name=".AuthReqActivity"
			android:configChanges="0x000000E0"
			>
		</activity>
		<meta-data
			android:name="ADMOB_PUBLISHER_ID"
			android:value="a149c8f51949be3"
			>
		</meta-data>
	</application>
</manifest>

感覺還行,但是像 android:label="@7F080000" android:icon="@7F02002A"

@7F080000這個神祕的東西,是什麼意思呢? 下面會有提到。

classes.dex

目前反編譯classes.dex比較好的工具是 Dedexer,可以下載已經編譯好的jar文件 ddx1.11.jar.

mkdir src
java -jar ddx1.11.jar --help
java -jar ddx1.11.jar -o -D -r -d src classes.dex

然後在src目錄下,又生成一坨東西。

注意: ddx1.11.jar 對應java 1.6版本,我用 1.5.0_18,就會遇到

[deli@athena tools-common]$ java -jar ddx1.11.jar
Exception in thread "main" java.lang.UnsupportedClassVersionError: Bad version number in .class file

也可以下載源代碼自行編譯。

進入 src/com/himsn 目錄

[deli@athena himsn]$ grep -i 7F080000 *

R$string.ddx:.field public static final app_name I = 2131230720 ; 0x7f080000

好傢伙,回前面提到的 @7F080000,原來在 R$string。其他xml文件出現神祕的字符,grep 一下,就出來了。 xml還有其他神祕數字, 比如

<ImageView>
android:scaleType="3"

這個3是啥意思? 開始我是用最原始的方式,我深信,一切盡在ApiDemos中,結果在ApiDemos的反編譯文件裏grep,一般80%都可以找到,然後跟源代碼對 比,就出來了。

android:scaleType="3" 就是android:scaleType="fitCenter" 類似的

| android:scaleType="7"| android:scaleType="centerInside"

android:scaleType="6" android:scaleType="centerCrop"
android:ellipsize="4" android:ellipsize="marquee"
android:ellipsize="3" android:ellipsize="end"

後面發現用eclipse打開xml layout文件,在屬性選項裏,點擊,在下拉菜單,都有相應的數字,從0開始,那麼就好辦多了。

還有一些情況,比如

android:textColor="?android:01010036" android:textColor="?android:01010212"

這個比較好辦,看到有android字樣,就知道是系統定義的常量,在android sdk Reference android.R.xxx 頁面搜索01010036,找到:

"?android:01010036" 對應 "?android:attr/textColorSecondary" "?android:01010212" 對應 "?android:attr/textColorTertiary"

反編譯過兩個apk,我都能把xml文件100%還原出來。

解讀ddx格式

挑個src/com/himsn/HiMSN.ddx 看看吧。

.class public com/himsn/HiMSN
.super android/app/Activity
.source HiMSN.java

.field public static final ACTIVITY_ONGOING_CONTACTS I = 112	; 0x70
.field public static final ACTIVITY_WINKS I = 113	; 0x71
.field private static final TAG Ljava/lang/String; = "IMEasy"
.field private final mFilter Landroid/content/IntentFilter;
.field private mManager Lcom/shiyansucks/imeasy/manager/IMMgr;
.field mMenu Landroid/view/Menu;
.field private final mReceiver Landroid/content/BroadcastReceiver;

.method public <init>()V
.limit registers 3

.line 41
	invoke-direct	{v2},android/app/Activity/<init>	; <init>()V

.line 43
	new-instance	v0,com/himsn/HiMSN$1

....

真是難懂! 沒關係,Gabor Paller爲我們整理好了 Dalvik opcodes 文檔,對照一下,記住常用的,慢慢研讀,會有一番風景,enjoy!

學習ddx格式最簡單的方法,就是把現成的代碼編譯成apk的,再用反編譯工具弄出ddx格式文件,代碼與ddx文件對照閱讀,一目瞭然。這段時間 花了不少時間去研讀ddx,或多或少做一些筆記,零零散散,再補充一下。

行首爲 ".field" 字段的,是類變量。 grep "\.field" xxx.ddx ,列出所有的變量。

行首爲 ".method " 字段的,是成員函數 grep "\..method " xxx.ddx ,列出所有的成員函數。

 88     if-eqz  v1,l2d9da
 89 ; v1 : single-length
 90 .line 482
 91     new-instance    v0,android/content/Intent
 92 ; v0 : Landroid/content/Intent;
 93     invoke-direct   {v0},android/content/Intent/<init>  ; <init>()V
 94 ; v0 : Landroid/content/Intent;
 95 l2d9ca:

上面的條件是這樣的:

 if (v != 0) {
	 intent = new Intent(); // intent 在該代碼段上邊有定義過。
 } else {
	 // l2d9ca:
 }

if 裏的判斷順序正好相反。

基本的數據類型

 Long => Long
 J => long
 I => int
 V => void
 Z => boolean 

Android 反編譯方法的總結

ps:對於軟件開發人員來說,保護代碼安全也是比較重要的因素之一,不過目前來說Google Android平臺選擇了Java Dalvik 
VM的方式使其程序很容易破解和被修改,首先APK文件其實就是一個MIME爲ZIP的壓縮包,我們修改ZIP後綴名方式可以看到內部的文件結構,類似
Sun 
JavaMe的Jar壓縮格式一樣,不過比較去別的是Android上的二進制代碼被編譯成爲Dex的字節碼,所有的Java文件最終會編譯進該文件中
去,作爲託管代碼既然虛擬機可以識別,那麼我們就可以很輕鬆的反編譯。所有的類調用、涉及到的方法都在裏面體現到,至於邏輯的執行可以通過實時調試的方法
來查看,當然這需要藉助一些我們自己編寫的跟蹤程序。Google最然在Android 
Market上設置了權限保護app-private文件夾的安全,但是最終我們使用修改定值的系統仍然可以獲取到需要的文件。

    總結反編譯主要的目的在於學習。利用反編譯進行相關的漢化或修改,還是儘量不要吧,畢竟人家寫個程序不容易啊!

    我目前接觸的反編譯的方法總共有三種,分別如下:

    1.  第一種反編譯的方法主要是利用模擬器自帶的一個dexdump。

       具體如下面的介紹:

       反編譯一個.apk文件,需要做以下幾步:1) 找到.apk安裝文件   2)找到安裝軟件的*.dex文件    3)dump dex文件    4)分析dex文件獲取想要的代碼

       一、找到apk安裝文件這個比較容易,把手機或者模似器安裝好後,可以在eclipse的File Explorer下找到安裝程序的apk譯文件,也可以通過adb命令找到:

                      $ adb shell

                      # cd /system/app

                      cd /system/app

                      # ls


       二、找到安裝軟件的*.dex文件運行安裝軟件後,會在android文件系統下生成一個*.dex文件,一般在目錄/data/dalvik- cache下,也可以通過adb命令找到:
                     $ adb shell

                     # cd /data/dalvik-cache

                     cd /data/dalvik-cache

                     # ls

        (注意:一般來說,如果你能夠通過File Exploere找到data/dalvik-cache文件,其實一二兩個步驟可以跳過,直接進入adb  shell後執行第三步;命令行中直         接輸入adb shell後執行的前提是你已經在系統的環境變量中配置了tools文件,否則你得先cd到tools文件中執行adb.exe後才能執行以後的命令。另 外你得確           保自己的虛擬機中安裝了應用程序才能進行下一步的操作。對於系統自帶的程序,我也試了進行反編譯,結果輸出的txt沒有具體內容,沒有成功。有興趣的             話,大家可以試一下。)

            
        三、編譯軟件對應的dex文件,通過以下指令:
                #dexdump -d -f -h /data/dalvik-cache/data@[email protected][email protected] > ophone.text
                指令參數解釋:-d : disassemble code sections

                                    -f : display summary information from file header

                                    -h : display file header details

                                    -C : decode (demangle) low-level symbol names

                                    -S : compute sizes only

        這執行完了後,大家應該可以在dalcik-cache文件夾下找到ophone.txt文件。如果沒有的話,可以重新啓動虛擬 器。 之後我們可以將該txt文件導出到桌面上進行相關操作。(File Explorer中的按鈕)

          四、 獲取需要的代碼:打開剛纔得到的編譯出來的text文件,會看到形如以下的代碼:      

 

                   總體來看,這種反編譯的效果不太理想。

    第二種是:通過dex2jar工具進行反編譯。(dex2jar:http://code.google.com/p/dex2jar/downloads/list    查看Jar包的GUI工具:http://java.decompiler.free.fr/?q=jdgui

    

   

    反編譯步驟:

    1、下載一個.apk程序安裝包,將其文件名*.apk改爲*.rar後進行解壓。我這兒是將南方週末的讀報器進行反編譯的。
   
    2、 把其中的class.dex拷貝到dex2jar.bat所在目錄。運行dex2jar.bat   class.dex,將會在其文件夾下生成classes.dex.dex2jar.jar。
    3、可以將jar文件重新命名後拷貝到GUI文件夾下,運行JD-GUI工具(它是綠色無須安裝的),打開上面的jar文件,即可看到源代碼。

         與第一種方法相比較,該方法生成的文件全面,代碼整齊,雖然有些中文會出現亂碼,id等全部是數字代替,但整體結構很完整,不 錯。
   類似的工具還有Dedexerhttp://sourceforge.net/projects/dedexer/files/

   具體的應用代碼爲(先進入jar包所在路徑):

    java -jar ddx.jar -d  <directory>  <dex file>
   可以再其中加入-o,這樣可以生成一個介紹文件內部結構的日誌文件。

    第三種:網上還流傳着這樣一種用smali工具的方法(http://code.google.com/p/smali/downloads/list):

        反編譯命令  java -jar baksmali-1.2.jar  <dex文件>  -o  <新生成的文件名>

        重新編譯     java -jar  smali-1.2.jar <需編譯文件夾>

       本人親自實踐了一下,確實新版本的baksmali可以直接對.apk文件進行直接的反編譯。


   但是這種方法生成的文件也不是很好。

     說到這兒,對於xml的文件的編譯,需要工具AXMLPrinter2.jar(http://code.google.com/p/android4me/downloads/list)。 具體的使用方法,與上面的差不多,可以運用命令      java -jar AXMLPrinter2.jar main.xml > main.txt  進行相關的操作。大家可以參照這位仁兄的(http://hi.baidu.com/linrw/blog/item/cc3afd2233ab88a94723e878.html

 

查看全部評論(0)我來說兩句

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