Android逆向(四)彈Toast

        上一篇博客,介紹了反編譯後如何修改資源文件,修改資源文件幾乎不會設計Java源代碼的修改,只需要修改xml文件。接下來的博客,將會介紹和總結一下,如何修改原有的邏輯和功能代碼。與修改資源文件不同,修改原有的功能邏輯代碼將涉及到smali代碼的修改。smali的語法我個人認爲不需要完全掌握,我也只是研究了那麼幾天時間。

        我們還是用上一篇博客用到的apk。先看一下我們上次修改的樣子:

        接下來,看一下,如何實現在反編譯後的源代碼中增加Toast顯示。我們要實現的修改是:點擊按鈕1,彈出Toast(You clicked button one.)。

一、爲Button1註冊OnclickListener

        首先,我們回憶一下,在Java代碼中爲按鈕增加點擊事件時是如何操作的?

        (1)定義一個Button,Java代碼如下:

private Button btn1;

        (2)在註冊監聽器前,先findViewById,否則空指針,Java代碼如下:

btn1 = findViewById(R.id.btn_1);

        (3)註冊監聽器,做自己想做的操作,Java代碼如下:

btn1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        });

        在反編譯後的smali源碼中,我們仍然需要按照這些步驟爲Button增加點擊事件。那麼,我們如何操作呢?很簡單,讓我們一步一步來。首先,在Android Killer中打開MainActivity的smali代碼:

.class public Ltudu/mreversedemo/MainActivity;
.super Landroid/support/v7/app/AppCompatActivity;
.source "MainActivity.java"


# direct methods
.method public constructor <init>()V
    .locals 0

    .line 6
    invoke-direct {p0}, Landroid/support/v7/app/AppCompatActivity;-><init>()V

    return-void
.end method


# virtual methods
.method protected onCreate(Landroid/os/Bundle;)V
    .locals 0

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

    const p1, 0x7f09001b

    .line 11
    invoke-virtual {p0, p1}, Ltudu/mreversedemo/MainActivity;->setContentView(I)V

    return-void
.end method

        (1)定義一個Button對象

        打開MainActivity.smali文件,在# direct methods這一段註釋上面增加如下smali代碼。這段代碼的意意思是,聲明一個private的變量btn1,類型是Button。這裏需要注意的是:Lxxx/xxx/xxx,定義Object前面是需要使用L:

.field private btn1:Landroid/widget/Button;

 

        (2)findViewById

        我在代碼中使用“#”增加了部分註釋,在return-void之前增加如下smali代碼:

    # button的findviewbyid  start
    const p1, 0x7f070022

    invoke-virtual {p0, p1}, Ltudu/mreversedemo/MainActivity;->findViewById(I)Landroid/view/View;

    move-result-object p1

    check-cast p1, Landroid/widget/Button;

    iput-object p1, p0, Ltudu/mreversedemo/MainActivity;->btn1:Landroid/widget/Button;
    #button的findviewbyid end

        注意:這裏的“0x7f070022”,是在R$id.smali和public.xml中的id,可以搜索“btn_1”,查找這個id,搜索結果如下圖所示:

        (3)註冊監聽器

        在上一步findViewById增加的代碼下面,增加如下代碼。下面這段代碼就是註冊OnClickListener監聽器:

    #註冊監聽器 start
    iget-object p1, p0, Ltudu/mreversedemo/MainActivity;->btn1:Landroid/widget/Button;

    new-instance v0, Ltudu/mreversedemo/MainActivity$1;

    invoke-direct {v0, p0}, Ltudu/mreversedemo/MainActivity$1;-><init>(Ltudu/mreversedemo/MainActivity;)V

    invoke-virtual {p1, v0}, Landroid/widget/Button;->setOnClickListener(Landroid/view/View$OnClickListener;)V
    #註冊監聽器end

        在註冊監聽器代碼中,我們可以看到MainActivity$1,這是我們接下來需要新增加的一個smali文件。這裏需要注意的是,因爲我們爲Button增加了監聽器,也就是OnClickListener接口,我們需要對MainActivity的OnCreate方法稍作修改。需要把.locals 1修改爲.locals 2。關於.locals,我在這裏暫時不詳細解釋。這裏比較通俗的的原則就是:我們的MainActivityXXX定義了幾個,.locals就必須大於等於幾。

.locals 2

        (4)增加MainActivity$1.smali文件

        那麼,如何增加一個文件?其實我們在上一篇博客已經說過。複製MainActivity.smali,並且命名爲MainActivity$1。回到Android Killer,點擊刷新按鈕,如下所示:        MianActivity$1這個文件的作用是:實現我們的OnClickListener接口。接下來我們要在OncClick方法中彈Toast,也是在這個文件中去實現。MainActivity$1的代碼如下:

.class Ltudu/mreversedemo/MainActivity$1;
.super Ljava/lang/Object;
.source "MainActivity.java"

# interfaces
.implements Landroid/view/View$OnClickListener;


# annotations
.annotation system Ldalvik/annotation/EnclosingMethod;
    value = Ltudu/mreversedemo/MainActivity;->onCreate(Landroid/os/Bundle;)V
.end annotation

.annotation system Ldalvik/annotation/InnerClass;
    accessFlags = 0x0
    name = null
.end annotation


# instance fields
.field final synthetic this$0:Ltudu/mreversedemo/MainActivity;


# direct methods
.method constructor <init>(Ltudu/mreversedemo/MainActivity;)V
    .locals 0

    iput-object p1, p0, Ltudu/mreversedemo/MainActivity$1;->this$0:Ltudu/mreversedemo/MainActivity;

    invoke-direct {p0}, Ljava/lang/Object;-><init>()V

    return-void
.end method


# virtual methods
.method public onClick(Landroid/view/View;)V
    .locals 0

    return-void
.end method

        (5)增加Toast代碼

        接下來,在MainActivity$1中實現我們彈Toast的需求。修改onClick中的代碼如下:

    .locals 2

    iget-object p1, p0, Ltudu/mreversedemo/MainActivity$1;->this$0:Ltudu/mreversedemo/MainActivity;

    const-string v0, "You clicked button one."

    const/4 v1, 0x0

    invoke-static {p1, v0, v1}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;

    move-result-object p1

    invoke-virtual {p1}, Landroid/widget/Toast;->show()V

    return-void

        通過以上五個步驟,我們完成了點擊Button彈出Toast的修改,我們是通過修改反編譯後的smali代碼完成的。保存我們的所有修改,編譯並且運行一下apk,看一下效果:

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