免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
MIUI ROM適配之旅第三天——反編譯
首先說句抱歉,今天事情比較多,教程出來的比較晚,請包含。今后幾天也會稍晚一點,但是我會每天更新的。

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

    和很多書籍一樣,為了向經(jīng)典的"Hello, World"致敬,我們也從一個簡單的程序開始HelloActivity.apk。當你把這個APK安裝到手機上運行后,在屏幕上就顯示一行文字"Hello, World!"(世界我來了!是的,兄弟姐妹們,從今天起我們真正進入反編譯的世界,我們來了?。?br>
1. 反編譯
    為了介紹方便,從現(xiàn)在起,我會用cracker~$作為命令提示符,其后的文字表示我們需要運行的命令。如果其后有斜體字,表示命令的輸出結(jié)果。

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

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

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

    可以看到res目錄的內(nèi)容為:
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下內(nèi)容不多,但是一個復雜的程序res目錄下內(nèi)容相應的也會比較多,但是基本原理都是一樣的。
   
    res下面的子目錄基本上是按照資源類型來分類組織的,以drawable開頭的表示圖片資源,大家可能會看到drawable-hdpi, drawable-mdpi, drawable-ldpi等,這些hdpi,mdpi,lpid分別表示高/中/低分辨率,會根據(jù)不同的屏幕分辨率選擇不同的圖片。要想替換圖片,替換這些目錄下的圖片就可以了。(替換圖片比這稍復雜點,一般替換圖片,最好保持和原圖片兼容,比如說色系,尺寸以及點9圖片的一些參數(shù)等)。
   
    以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的資源大致按這種形式來組織的,先將資源分成幾種類型,然后每一種類型的所有資源取一個名字,這個名字對應了這個資源的值/內(nèi)容。
   
    我們一般修改資源通常情況下是修改圖片或者漢化。漢化比較簡單,values/strings.xml文件存放程序用到的所有英文字符串值。要漢化,首先在values下建立一個目錄values-zh-rCN。然后將values/strings.xml拷貝到該目錄中,將每一個字符串翻譯成中文。我們現(xiàn)在將strings.xml拷貝到values-zh-rCN目錄下,并將文件內(nèi)容改為:
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <string name="hello_activity_text_text">你好,世界!</string>
        <string name="app_name">你好世界</string>
    </resources>
   
    現(xiàn)在我們需要把修改后的文件在編回apk文件,運行如下命令:
    cracker~$ apktool b HelloActivity HelloActivity.apk
    這條命令表示編譯HelloActivity目錄的內(nèi)容,輸出文件為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做實驗的話,會發(fā)生簽名不一致的錯誤,這個時候先卸載原來的,再安裝。運行看看,對的,現(xiàn)在顯示在你面前的是“你好,世界!”

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

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

4. smali
    終于迎來我們最重要的部分了smali目錄,smali目錄存放的是反編譯后的Java代碼,文件名以smali結(jié)尾,故稱作smali文件。這些代碼比一般的Java代碼可讀性差太多了,但是和傳統(tǒng)的x86或者其他體系結(jié)構(gòu)下的匯編文件那又是好讀多了。雖然有工具可以直接把這些反匯編成java代碼,單是好不了太多,我們還是直接讀取修改smali文件。從這里我們才真正的開始是一名程序員。
   
    我們來看一下反編譯后的smali目錄下的HelloActivity.smali文件,和Java組織源代碼的方式一樣,smali目錄下的文件也是按文件包的包名結(jié)構(gòu)組織目錄結(jié)構(gòu)的,文件的內(nèi)容如下:
   
    .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表示對應的源代碼的行號,這個對調(diào)試很重要。.metho和.end method表示一個方法定義的開始和結(jié)束。Smali文件中的這些指令的功能請參照http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html,有一些不懂沒關(guān)系,在接下來得兩章我們會接觸到大部分指令。
   
    其中.line 39的代碼對應的源代碼是
    txtView.setText(R.string.hello_activity_text_text)
   
    我們現(xiàn)在想將這行代碼改成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
再按照上一節(jié)所說得重新編譯,簽名,安裝運行,好了,現(xiàn)在出現(xiàn)在你面前的是Happy, Cracker!了,真happy!

    接下來的兩章我們都會介紹如何直接修改smali代碼從而改變程序的功能,這種方法我們叫做代碼插樁,接下來的兩章我們將會用代碼插樁的方法將MIUI的功能加到原生ROM中去。
本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Android開發(fā)學習筆記(三)——基于Eclipse開發(fā)環(huán)境的搭建及HelloAndroid示例程序的創(chuàng)建
andriod的apk文件相關(guān)的編譯反編譯工具
手把手教你逆向分析 Android 程序
Android逆向之旅---反編譯利器Apktool和Jadx源碼分析以及錯誤糾正
Android安全攻防戰(zhàn),反編譯與混淆技術(shù)完全解析(上)
破解驗證,讓爬取更隨心所欲!
更多類似文章 >>
生活服務
分享 收藏 導長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服