Andriod反編譯總結

工慾善其事必先利其器

前言

Android反編譯需要用到一些工具,使用這些工具可以大大的提高我們的工作效率。當然使用工具是一把雙刃劍,一方面工具使我們的工作更方便,但另一方面工具把一些原理封裝了起來,不利於我們的學習。所以使用工具的時候最好對工具的原理有一定的瞭解。

jadx

github地址,jadx是一個將android 的dex文件解碼爲java的工具。並且有GUI,用起來非常的方便,具體的使用可以看官方的文檔。

apktool

有了上面的工具,可以很方便的將apk的源碼進行反編譯,讓我們瞭解代碼的邏輯。但是這還遠遠不夠,比如我們想幹點壞事,將apk反編譯後,做點手腳,並把它重新打包發佈出去,要實現這樣的功能,光上面的工具已經達不到我們的要求了。我們需要另外一個更加強大的工具-apktool. apktool可以將dex文件反編譯成smali文件。如果對smali語法熟悉,就可以在smali中修改app的邏輯。其實apktool這個工具集成了另外一個開源的項目baksmali,(因爲apktool集成了baksmail, 假如baksmail修復了bug,需要一段時間才能集成的apktool中,所以我們也可以直接使用baksmail)

smali語法

爲了達到我們對一個apk做手腳的目的,需要了解一種新的語言smali, smail語言類似與彙編語言,如果對彙編比較熟悉的學習起來會比較容易。

實戰

下面就舉個例子,演示一下怎麼利用apktool解包,修改smali文件,重新打包,簽名的過程。

首先新建個項目,主要一個MainActivity,裏面只有一個字符串,我的目的就是通過解包apk,在smali語法中注入日誌打印語句,把這個字符串打印出來:


public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        String hello = "Hello World";

    }
}

將項目打包出來的apk(debug包和release包都可以)拷貝到apktool的同級目錄

目錄

然後將apk包用apktool,反編譯,命令爲:


cfp@cfp:~/tools/android_tools/apktool$ ./apktool d app-release.apk 

I: Using Apktool 2.1.1 on app-release.apk

I: Loading resource table...

I: Decoding AndroidManifest.xml with resources...

I: Loading resource table from file: /home/cfp/apktool/framework/1.apk

I: Regular manifest package...

I: Decoding file-resources...

I: Decoding values */* XMLs...

I: Baksmaling classes.dex...

I: Copying assets and libs...

I: Copying unknown files...

I: Copying original files...

cfp@cfp:~/tools/android_tools/apktool$ 

反編譯後多了個app-release目錄,反編譯的文件就都在裏邊了,下面的任務就是找到MainActivity,在裏邊注入日誌打印語言,將裏邊的字符串輸出。


cfp@cfp:~/tools/android_tools/apktool$ ls

apktool      app-release      debug.keystore  sign.jar

apktool.jar  app-release.apk  signapk.jar

反編譯後的目錄:


cfp@cfp:~/tools/android_tools/apktool/app-release$ ls

AndroidManifest.xml  apktool.yml  original  res  smali

所有的smali文件都在smali目錄下,我們找到MainActivity.smali文件


cfp@cfp:~/tools/android_tools/apktool/app-release/smali/com/xray/smali$ ls

BuildConfig.smali   R$bool.smali      R$id.smali       R.smali

MainActivity.smali  R$color.smali     R$integer.smali  R$string.smali

R$anim.smali        R$dimen.smali     R$layout.smali   R$styleable.smali

R$attr.smali        R$drawable.smali  R$mipmap.smali   R$style.smali

MainActivity.smali文件中的代碼:


.class public Lcom/xray/smali/MainActivity; #class的名字

.super Landroid/support/v7/app/AppCompatActivity; #這個類的父類

.source "MainActivity.java" #這個類的java文件名





# direct methods

.method public constructor <init>()V #這個類的構造方法

    .locals 0



    .prologue

    .line 7 #行號

    invoke-direct {p0}, Landroid/support/v7/app/AppCompatActivity;-><init>()V #調用父類的構造方法



    return-void #返回空

.end method





# virtual methods

.method protected onCreate(Landroid/os/Bundle;)V #onCreate方法

    .locals 2

    .param p1, "savedInstanceState"    # Landroid/os/Bundle; #方法的參數



    .prologue

    .line 11

    invoke-super {p0, p1}, Landroid/support/v7/app/AppCompatActivity;->onCreate(Landroid/os/Bundle;)V 

#父類的構造方法





    .line 12

    const v1, 0x7f040019



    invoke-virtual {p0, v1}, Lcom/xray/smali/MainActivity;->setContentView(I)V #調用serContentView方法



    .line 13

    const-string v0, "Hello World" #字符串Hello World,保存在寄存器v0中



    .line 15

    .local v0, "hello":Ljava/lang/String; #變量hello ,類型爲String

    return-void

.end method




前面說了smali語言有點像彙編,通過上面的註釋大概能瞭解這個smali文件的大概意思,要想輸出Hello World,我麼可以加上調用Log的smali語句。


const-string v1, "TAG"

invoke-static {v1, v0}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

修改後的MainActivity.smali文件變成:


.class public Lcom/xray/smali/MainActivity; #class的名字

.super Landroid/support/v7/app/AppCompatActivity; #這個類的父類

.source "MainActivity.java" #這個類的java文件名





# direct methods

.method public constructor <init>()V #這個類的構造方法

    .locals 0



    .prologue

    .line 7 #行號

    invoke-direct {p0}, Landroid/support/v7/app/AppCompatActivity;-><init>()V #調用父類的構造方法



    return-void #返回空

.end method





# virtual methods

.method protected onCreate(Landroid/os/Bundle;)V #onCreate方法

    .locals 2

    .param p1, "savedInstanceState"    # Landroid/os/Bundle; #方法的參數



    .prologue

    .line 11

    invoke-super {p0, p1}, Landroid/support/v7/app/AppCompatActivity;->onCreate(Landroid/os/Bundle;)V 

#父類的構造方法





    .line 12

    const v1, 0x7f040019



    invoke-virtual {p0, v1}, Lcom/xray/smali/MainActivity;->setContentView(I)V #調用serContentView方法



    .line 13

    const-string v0, "Hello World" #字符串Hello World,保存在寄存器v0中



    .line 15

    .local v0, "hello":Ljava/lang/String; #變量hello ,類型爲String

    const-string v1, "TAG"

    invoke-static {v1, v0}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    return-void

.end method

然後重新打包:


cfp@cfp:~/tools/android_tools/apktool$ ./apktool b app-release

I: Using Apktool 2.1.1

I: Checking whether sources has changed...

I: Smaling smali folder into classes.dex...

I: Checking whether resources has changed...

I: Building resources...

I: Building apk file...

I: Copying unknown files/dir...

新的apk包位於


app-release/dist

這個apk包是不能直接安裝的,需要用簽名工具簽名,可以使用另外一個工具sign.jar,命令爲:


cfp@cfp:~/tools/android_tools/apktool$ java -jar sign.jar app-release.apk 


簽名後的新包叫app-release.s.apk,直接安裝就可以打印Hello World的日誌了。


05-25 22:56:25.725 17277-17277/com.xray.smali D/TAG: Hello World

參考文獻

  1. smali語法

  2. http://drops.wooyun.org/papers/6045

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