久久精品精选,精品九九视频,www久久只有这里有精品,亚洲熟女乱色综合一区
    分享

    MIUI ROM適配之旅第三天——反編譯

     shaobin0604@163.com 2012-02-02
    首先說句抱歉,今天事情比較多,教程出來的比較晚,請包含。今后幾天也會稍晚一點,但是我會每天更新的。

        今天我們來詳細的看看反編譯,想要修改一個系統自帶的應用程序和它的代碼,在沒有源碼的情況下,我們就不得不用反編譯來修改。

        和很多書籍一樣,為了向經典的"Hello, World"致敬,我們也從一個簡單的程序開始HelloActivity.apk。當你把這個APK安裝到手機上運行后,在屏幕上就顯示一行文 字"Hello, World!"(世界我來了!是的,兄弟姐妹們,從今天起我們真正進入反編譯的世界,我們來了!)

    1. 反編譯
        為了介紹方便,從現在起,我會用cracker~$作為命令提示符,其后的文字表示我們需要運行的命令。如果其后有斜體字,表示命令的輸出結果。

    cracker~$ apktool d HelloActivity.apk
    這條命令運行完后,在當前目錄下會生成一個名為HelloActivity的目錄。
    該目錄的結構為(名稱后跟/表示這是一個目錄):
    HelloActivity/
           |--------------AndroidManifest.xml
           |--------------apktool.yml
           |--------------res/
           |--------------smali/
    apktool.yml是apktool生成的一個配置文件,基本上你不需要修改這個文件。下面的章節我們逐個介紹剩下的AndroidManifest.xml文件和res, smali目錄。

    2. AndroidManifest.xml
        要想完全理解這個文件,你得對Android的內部運作機制非常清楚。幸好我們修改一個APK的時候基本上不改這個文件。這里幫助你有個大致的了解。
       
        Android安裝程序一般叫apk文件(apk是Android Package的縮寫,表示Android安裝包)。一般來說,程序都會有一個或多個Activity, Activity是什么呢,從概念說它是一個和用戶交互的窗口,你每天使用Android手機的時候基本上你打交道的每個界面都是一個Activity。 AndroidManifest.xml是一個xml格式的清單文件,就像你去超市買東西會打印出一個購物清單,AndroidManifest.xml 也起著一個清單的作用,它告訴系統,我有這些Activity。(實際情況遠比這復雜,想學Android編程的同學請看這個http://developer./guide/index.html,好好學習其中的內容)。
       
        具體到HelloActivity下的AndroidManifest.xml文件,大家可以找到如下內容:
        <application
        android:label="@string/app_name" android:icon="@drawable/ic_launcher_hello">
                <activity android:name="HelloActivity">
                    <intent-filter>
                        <action android:name="android.intent.action.MAIN" />
                        <category android:name="android.intent.category.LAUNCHER" />
                    </intent-filter>
                </activity>
            </application>
        其中有一行<category android:name="android.intent.category.LAUNCHER" />,包含這一行的Activity會顯示在桌面中,就是說你可以通過桌面顯示的圖標啟動這個Activity。里面還有 android:label="@string/app_name" android:icon="@drawable/ic_launcher_hello"。這兩個屬性是做什么的呢,android:label表示程序 顯示在桌面上的名字,android:icon表示程序顯示在桌面上的圖標。如果想要改顯示的名字和圖標,修改其后的兩個資源,如何修改資源,下一節詳細 介紹。

    3. 資源
        res目錄下放置了程序所需要的所有資源。資源是什么呢,一般來說,一個圖形用戶界面(GUI)程序總是會使用一些圖片,或者顯示的文字的大小和顏色等。 或者界面的布局,比如顯示的界面上面是文字,下面是兩個按鈕等等。這些程序的一個重要特點就是用戶界面和代碼邏輯的分離。當我們需要替換圖片或者簡單修改 界面布局的時候,不需要改變代碼。而Android程序會將這些代碼中需要用到的文件都放在res目錄下,稱之為資源。

        可以看到res目錄的內容為:
    res/
    |--------drawable-hdpi/
                 |-----------ic_launcher_hello.png
    |--------layout/
             |---------hello_activity.xml
    |--------values/
             |---------ids.xml
             |---------public.xml
             |---------strings.xml
        對于HelloActivity來說,res目錄下有三個子目錄drawable-hdpi, layout, values。由于HelloActivity比較簡單,因此res下內容不多,但是一個復雜的程序res目錄下內容相應的也會比較多,但是基本原理都是 一樣的。
       
        res下面的子目錄基本上是按照資源類型來分類組織的,以drawable開頭的表示圖片資源,大家可能會看到drawable-hdpi, drawable-mdpi, drawable-ldpi等,這些hdpi,mdpi,lpid分別表示高/中/低分辨率,會根據不同的屏幕分辨率選擇不同的圖片。要想替換圖片,替換 這些目錄下的圖片就可以了。(替換圖片比這稍復雜點,一般替換圖片,最好保持和原圖片兼容,比如說色系,尺寸以及點9圖片的一些參數等)。
       
        以layout開頭的表示布局文件,用來描述程序的界面。anim子目錄存放程序使用到的動畫,xml開頭的目錄存放程序用到的一些xml文件等。
       
        values開頭的目錄下面存放一些我們稱之為基本元素的定義,比如說colors.xml給出顏色值的定義,dimens.xml給出一些大小的定義。 strings.xml是一些字符串的定義。我們看看HellloActivity的strings.xml文件。

        <?xml version="1.0" encoding="utf-8"?>
        <resources>
            <string name="hello_activity_text_text">Hello, World!</string>
            <string name="app_name">HelloWorld</string>
        </resources>
       
        其中的以<string開頭便是這是一個字符串,name是給這個資源起一個名字,后面的字符串表示這個字符串的值。Android的資源大致按這 種形式來組織的,先將資源分成幾種類型,然后每一種類型的所有資源取一個名字,這個名字對應了這個資源的值/內容。
       
        我們一般修改資源通常情況下是修改圖片或者漢化。漢化比較簡單,values/strings.xml文件存放程序用到的所有英文字符串值。要漢化,首先 在values下建立一個目錄values-zh-rCN。然后將values/strings.xml拷貝到該目錄中,將每一個字符串翻譯成中文。我們 現在將strings.xml拷貝到values-zh-rCN目錄下,并將文件內容改為:
        <?xml version="1.0" encoding="utf-8"?>
        <resources>
            <string name="hello_activity_text_text">你好,世界!</string>
            <string name="app_name">你好世界</string>
        </resources>
       
        現在我們需要把修改后的文件在編回apk文件,運行如下命令:
        cracker~$ apktool b HelloActivity HelloActivity.apk
        這條命令表示編譯HelloActivity目錄的內容,輸出文件為HelloActivity.apk,如果你不想覆蓋原有的文件,可以換一個名字或者放在另外一個目錄下。
       
        接下來我們需要對生成的APK進行簽名,下載附件中的壓縮包sign.zip, 解壓后有一個腳本sign.sh。假定你把解壓后的文件都放在/home/cracker/tools目錄中。運行如下命令:
        cracker~$ export KEY_PATH=/home/cracker/tools
        cracker~$ /home/cracker/tools/sign.sh HelloActivity.apk
        cracker~$ adb install -r HelloActivity.apk.signed.aligned
    注意最后一條命令如果失敗,如果你不是用我們提供的HelloActivity做實驗的話,會發生簽名不一致的錯誤,這個時候先卸載原來的,再安裝。運行看看,對的,現在顯示在你面前的是“你好,世界!”

        漢化成功了,是的,漢化就這么簡單。如果你只想停留在漢化或者替換圖片這個階段,從這里開始以后的文章不用看了。如果你沒有Android編程基礎,從這里開始以后的文章也不用看了。
       
        到底發生了什么魔法,為什么這樣替換一下圖片或者改字符串就能改變程序最終運行的結果呢,想要理解這個,我們就的大致的了解一下資源的編譯過程。首先我們看看values目錄下一個有意思的文件publics.xml,它的內容如下:
        <?xml version="1.0" encoding="utf-8"?>
        <resources>
            <public type="drawable" name="ic_launcher_hello" id="0x7f020000" />
            <public type="layout" name="hello_activity" id="0x7f030000" />
            <public type="string" name="hello_activity_text_text" id="0x7f040000" />
            <public type="string" name="app_name" id="0x7f040001" />
            <public type="id" name="text" id="0x7f050000" />
        </resources>
    每一行的id后面都有一個看起來很奇怪的數字,這個數字是干嘛的呢?Android下有一個資源編譯器會編譯res目錄下的所有文件,它為每一個資源名字 分配一個數字標識符,這個標識符分成3個部分,最前面的1個字節表示包名,所有的apk這個字節都是7f。表示這些資源是非共享的,其它APK訪問不到。 所有那些可以共享的資源放在system/framework/framework-res.apk下。/system/framework往往還有其它 共享的資源包。這些共享的資源包前面的1個字節從0x1開始,依次增加。中間的一個字節表示資源的類型,每一個類型的數字標識符是不一樣的,最后的2個字 節是資源的序號,統一類型的資源序號從0依次往上遞增。一般來說,資源id是由資源編譯器(aapt)自動產生的,但是定義在publics.xml中的 值告訴編譯器,你必須為這個id使用這個值。apktool會為所有的資源名稱定義這個值在publics.xml里,這樣可以保證替換資源后資源的id 不會變化。

        為啥資源的id這么重要,如果變了,會怎么樣呢,這得結合代碼理解。我們在Java代碼里通常這樣引用資源,比如R.string.app_name。這 個Java代碼經過編譯后,這條引用直接變成了資源id,即0x7f040001,所以你在下面反編譯后的smali代碼里面是看不到 R.string.app_name這個東西的,只能看到0x7f040001。資源編譯器會生成一個查找表,對于每一個id,查找表中保存了這個id對 應的名字和值(如果是文件,則為文件所在路徑)。程序在運行的時候,會根據id去查詢這個查找表找到對應的資源的值或文件。
       
        最后說一句,資源的ID非常重要,運行adb pull /system/framework/framework-res.apk反編譯這個文件,好好的消化一下這一節的內容吧。

    4. smali
        終于迎來我們最重要的部分了smali目錄,smali目錄存放的是反編譯后的Java代碼,文件名以smali結尾,故稱作smali文件。這些代碼比 一般的Java代碼可讀性差太多了,但是和傳統的x86或者其他體系結構下的匯編文件那又是好讀多了。雖然有工具可以直接把這些反匯編成java代碼,單 是好不了太多,我們還是直接讀取修改smali文件。從這里我們才真正的開始是一名程序員。
       
        我們來看一下反編譯后的smali目錄下的HelloActivity.smali文件,和Java組織源代碼的方式一樣,smali目錄下的文件也是按文件包的包名結構組織目錄結構的,文件的內容如下:
       
        .class public Lcom/example/android/helloactivity/HelloActivity;
        .super Landroid/app/Activity;
        .source "HelloActivity.java"
       
        # direct methods
        .method public constructor <init>()V
            .locals 0
       
            .prologue
            .line 27
            invoke-direct {p0}, Landroid/app/Activity;-><init>()V
       
            return-void
        .end method

        # virtual methods
        .method public onCreate(Landroid/os/Bundle;)V
            .locals 2
            .parameter "savedInstanceState"
       
            .prologue
            .line 33
            invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V
       
            .line 37
            const/high16 v1, 0x7f03
       
            invoke-virtual {p0, v1},
        Lcom/example/android/helloactivity/HelloActivity;->setContentView(I)V
       
            .line 38
            const/high16 v1, 0x7f05
       
            invoke-virtual {p0, v1},
         Lcom/example/android/helloactivity/HelloActivity;->findViewById(I)Landroid/view/View;
       
            move-result-object v0
       
            check-cast v0, Landroid/widget/TextView;
       
            .line 39
            .local v0, txtView:android/widget/TextView;
            const/high16 v1, 0x7f04
       
            invoke-virtual {v0, v1}, Landroid/widget/TextView;->setText(I)V
       
            .line 40
            return-void
        .end method
       
        文件中的以#開頭的文字表示注釋, 以.開頭的叫做annotations,其中的.line表示對應的源代碼的行號,這個對調試很重要。.metho和.end method表示一個方法定義的開始和結束。Smali文件中的這些指令的功能請參照http://pallergabor./androidblog/dalvik_opcodes.html,有一些不懂沒關系,在接下來得兩章我們會接觸到大部分指令。
       
        其中.line 39的代碼對應的源代碼是
        txtView.setText(R.string.hello_activity_text_text)
       
        我們現在想將這行代碼改成txtView.setText("Happy, Cracker!"),將.line 39到.line 40行的代碼改為:
         .line 39
         .local v0, txtView:android/widget/TextView;
         const-string v1, "Happy, Cracker!"
         invoke-virtual {v0, v1}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V
    再按照上一節所說得重新編譯,簽名,安裝運行,好了,現在出現在你面前的是Happy, Cracker!了,真happy!

        接下來的兩章我們都會介紹如何直接修改smali代碼從而改變程序的功能,這種方法我們叫做代碼插樁,接下來的兩章我們將會用代碼插樁的方法將MIUI的功能加到原生ROM中去。

      本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發布,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發現有害或侵權內容,請點擊一鍵舉報。
      轉藏 分享 獻花(0

      0條評論

      發表

      請遵守用戶 評論公約

      類似文章 更多

      主站蜘蛛池模板: 日韩国产精品中文字幕| 无码人妻丝袜在线视频| 成人免费A级毛片无码网站入口| 亚洲第一精品一二三区| 国产99在线 | 免费| 日韩人妻无码精品久久| 亚洲成年轻人电影网站WWW| 久久精品国产一区二区三区| 午夜国产精品福利一二| 亚洲乱码中文字幕小综合| 日韩乱码人妻无码中文字幕视频| 夜鲁夜鲁很鲁在线视频 视频| 中文精品久久久久人妻不卡| 国产福利在线观看免费第一福利 | 国产精品无码一区二区三区电影| 亚洲成av人片无码天堂下载| 天下第二社区在线视频| 欧美人与禽2o2o性论交| 亚洲午夜性猛春交XXXX| 亚洲精品美女一区二区| 国产亚洲精久久久久久无码| 亚洲A综合一区二区三区| 亚洲AV中文无码字幕色最新| 99RE6在线视频精品免费下载| 东京一本一道一二三区| 性饥渴少妇AV无码毛片| 国产综合久久99久久| 亚洲AV无码一区二区乱子伦| 国产黑色丝袜在线观看下| 99福利一区二区视频| 久久久久亚洲精品无码蜜桃| 男人狂桶女人高潮嗷嗷| 中文字幕日韩有码av| 亚洲精品午睡沙发系列| 国产成人一区二区三区视频免费 | 亚洲国产成人精品福利无码| av午夜福利一片免费看久久| 亚洲午夜理论无码电影| 亚洲色大成网站WWW永久麻豆| 亚洲精品无码MV在线观看软件| 国产亚洲999精品AA片在线爽|