BubblePig 发表于 2018-2-2 11:00

Android逆向-Android基础逆向(4)

# 0x00前言
##不知所以然,请看
(https://www.52pojie.cn/thread-691091-1-1.html)

(https://www.52pojie.cn/thread-693233-1-1.html)

(https://www.52pojie.cn/thread-693233-1-1.html)

(https://www.52pojie.cn/thread-693233-1-1.html)

(http://blog.csdn.net/qq_36869808/article/details/79226672)
##以及java系列:
(https://www.52pojie.cn/thread-690674-1-1.html)

(https://www.52pojie.cn/thread-684492-1-1.html)

(https://www.52pojie.cn/thread-690679-1-1.html)

(https://www.52pojie.cn/thread-685752-1-1.html)

(https://www.52pojie.cn/thread-690689-1-1.html)

(https://www.52pojie.cn/thread-689279-1-1.html)

(https://www.52pojie.cn/thread-689936-1-1.html)

(https://www.52pojie.cn/thread-690542-1-1.html)
## 内容
(1)Android 布局创建
(2)Android布局反编译
(3)反编译改变布局
(4)小工具制作
## 环境:
Android studio
Android killer
python
夜神模拟器
##开始时间
2018年2月1日18:18:27
# 0x01 Android布局
## 1.demo
这里默认有Android开发基础,如果没有,恩。。。那我也没办法。
做一下简要的说明。
整个demo包括一个按钮,一个输入框,一个显示框。然后一个简单的逻辑。
## 1.1 涉及知识点
1.LinearLayout 布局
2.Button
3.TextView
4.EditText
5.监听事件
## 1.2 布局书写
### 1.2.1 更改整体布局
整体布局改成LinearLayout。
![这里写图片描述](http://t1.aixinxi.net/o_1c58fnmvhglt5bh15ej1nskvg1a.png-j.jpg)
然后布局流程改成竖行。
![这里写图片描述](http://t1.aixinxi.net/o_1c58g423pb71cao7161q8df49a.png-j.jpg)
### 1.2.2 添加控件
(1)EditText
(2)TextView
(3)Button
![这里写图片描述](http://t1.aixinxi.net/o_1c58gaecvrh11b5r1vhdr5016eja.png-j.jpg)
(4)代码详解

```
android:layout_width="wrap_content"
android:layout_height="wrap_content"
```
控制控件的长宽,可以使用像素单位,个人喜欢使用dp。
wrap_content的含义就是自适应,有多少就多大。

```
android:id="@+id/out"
```
这句话就是控件的name,控件的唯一标识。
## 1.3 布局引用
### 1.3.1 调用整体布局
![这里写图片描述](http://t1.aixinxi.net/o_1c58gpvft17ns127l1gt41sjt1u0ka.png-j.jpg)
这句代码通过Android R引用资源。也就是调用了activity_main这个名字的布局文件。等下我们看反编译后的东西。
### 1.3.2 定义对象
![这里写图片描述](http://t1.aixinxi.net/o_1c58gvkeevkm1e5dj6elfht8fa.png-j.jpg)
类似于int i;
### 1.3.3 通过id绑定控件
![这里写图片描述](http://t1.aixinxi.net/o_1c58hgqpf10nb1b3bkptsnhlmma.png-j.jpg)
通过findViewById来绑定控件。
## 1.4 按钮监听
![这里写图片描述](http://t1.aixinxi.net/o_1c58hm4si1r3aaqc1hf81ienrjba.png-j.jpg)
使用View.OnClickListener() 来写一个监听事件,因为只有一个按钮所以使用这种方式,如果以后有多个触发逻辑的话,就会使用其他的方式。
## 1.5 逻辑书写
![这里写图片描述](http://t1.aixinxi.net/o_1c58i2av1jld7ui1qlk1avii3ka.png-j.jpg)
这里我只写了一句代码。

```
out.setText(in.getText().toString());
```
这句包含三个知识点。
getText(),获取控件文字
setText(),书写控件文字
.toString(),转化为String类型
## 1.6 结束语
### 1.6.1 源代码
最后直接贴上全部的代码

```
public class MainActivity extends AppCompatActivity {
    private TextView out;
    private EditText in;
    private Button btn;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      Binding();
      btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                out.setText(in.getText().toString());
            }
      });
    }
    public void Binding()
    {
      out= (TextView) findViewById(R.id.out);
      in= (EditText) findViewById(R.id.in);
      btn= (Button) findViewById(R.id.bt);
    }
}
```
###1.6.2 调试
![这里写图片描述](http://t1.aixinxi.net/o_1c58lecf9o84ilp10707jd68ia.png-j.jpg)

# 0x02 反编译demo
## 1.丢在Android killer里
![这里写图片描述](http://t1.aixinxi.net/o_1c58mia03t8rg4aetdfhrmtva.png-j.jpg)
## 2. 查看layout文件
![这里写图片描述](http://t1.aixinxi.net/o_1c58mpvvo1k98l40pk51qbv1rf4a.png-j.jpg)
这里我们发现和Android studio中没有什么差别。
我们更改这里的就可以了。
## 3. 更改Android layout
我们添加这样一行

```
<Buttonandroid:layout_width="wrap_content" android:layout_height="wrap_content" android:text="我是反编译后的按钮" />

```
就是加了一个按钮。
## 4. 反编译,查看
![这里写图片描述](http://t1.aixinxi.net/o_1c58n833j165q3471241p051s8aa.png-j.jpg)
这里我们发现界面可以进行更改,但是没有逻辑。接下来就是我们研究逻辑的时候了。
## 5. smali分析
### 5.1 smali主要代码

```
.class public Lcom/example/hanlei/first_demo/MainActivity;
.super Landroid/support/v7/app/AppCompatActivity;
.source "MainActivity.java"


# instance fields
.field private btn:Landroid/widget/Button;

.field private in:Landroid/widget/EditText;

.field private out:Landroid/widget/TextView;


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

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

    return-void
.end method

.method static synthetic access$000(Lcom/example/hanlei/first_demo/MainActivity;)Landroid/widget/EditText;
    .locals 1
    .param p0, "x0"    # Lcom/example/hanlei/first_demo/MainActivity;

    .prologue
    .line 14
    iget-object v0, p0, Lcom/example/hanlei/first_demo/MainActivity;->in:Landroid/widget/EditText;

    return-object v0
.end method

.method static synthetic access$100(Lcom/example/hanlei/first_demo/MainActivity;)Landroid/widget/TextView;
    .locals 1
    .param p0, "x0"    # Lcom/example/hanlei/first_demo/MainActivity;

    .prologue
    .line 14
    iget-object v0, p0, Lcom/example/hanlei/first_demo/MainActivity;->out:Landroid/widget/TextView;

    return-object v0
.end method


# virtual methods
.method public Binding()V
    .locals 1

    .prologue
    .line 32
    const v0, 0x7f0b0058

    invoke-virtual {p0, v0}, Lcom/example/hanlei/first_demo/MainActivity;->findViewById(I)Landroid/view/View;

    move-result-object v0

    check-cast v0, Landroid/widget/TextView;

    iput-object v0, p0, Lcom/example/hanlei/first_demo/MainActivity;->out:Landroid/widget/TextView;

    .line 33
    const v0, 0x7f0b0057

    invoke-virtual {p0, v0}, Lcom/example/hanlei/first_demo/MainActivity;->findViewById(I)Landroid/view/View;

    move-result-object v0

    check-cast v0, Landroid/widget/EditText;

    iput-object v0, p0, Lcom/example/hanlei/first_demo/MainActivity;->in:Landroid/widget/EditText;

    .line 34
    const v0, 0x7f0b0059

    invoke-virtual {p0, v0}, Lcom/example/hanlei/first_demo/MainActivity;->findViewById(I)Landroid/view/View;

    move-result-object v0

    check-cast v0, Landroid/widget/Button;

    iput-object v0, p0, Lcom/example/hanlei/first_demo/MainActivity;->btn:Landroid/widget/Button;

    .line 35
    return-void
.end method

.method protected onCreate(Landroid/os/Bundle;)V
    .locals 2
    .param p1, "savedInstanceState"    # Landroid/os/Bundle;

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

    .line 21
    const v0, 0x7f04001b

    invoke-virtual {p0, v0}, Lcom/example/hanlei/first_demo/MainActivity;->setContentView(I)V

    .line 22
    invoke-virtual {p0}, Lcom/example/hanlei/first_demo/MainActivity;->Binding()V

    .line 23
    iget-object v0, p0, Lcom/example/hanlei/first_demo/MainActivity;->btn:Landroid/widget/Button;

    new-instance v1, Lcom/example/hanlei/first_demo/MainActivity$1;

    invoke-direct {v1, p0}, Lcom/example/hanlei/first_demo/MainActivity$1;-><init>(Lcom/example/hanlei/first_demo/MainActivity;)V

    invoke-virtual {v0, v1}, Landroid/widget/Button;->setOnClickListener(Landroid/view/View$OnClickListener;)V

    .line 29
    return-void
.end method

```

### 5.2 第一部分
![这里写图片描述](http://t1.aixinxi.net/o_1c58njsr9mgfln751hn5a1eefa.png-j.jpg)

这个部分就是 定义了三个变量

### 5.3 第二部分
![这里写图片描述](http://t1.aixinxi.net/o_1c58nv2h2ci912ovei6knu1f5pa.png-j.jpg)
这个部分应该很熟悉,在java中常见。请看java系列。
### 5.4 第三部分
首先找到onCreate部分,onCreate相当于c语言里的main函数

```
.method protected onCreate(Landroid/os/Bundle;)V
    .locals 2
    .param p1, "savedInstanceState"    # Landroid/os/Bundle;

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

    .line 21
    const v0, 0x7f04001b

    invoke-virtual {p0, v0}, Lcom/example/hanlei/first_demo/MainActivity;->setContentView(I)V

    .line 22
    invoke-virtual {p0}, Lcom/example/hanlei/first_demo/MainActivity;->Binding()V

    .line 23
    iget-object v0, p0, Lcom/example/hanlei/first_demo/MainActivity;->btn:Landroid/widget/Button;

    new-instance v1, Lcom/example/hanlei/first_demo/MainActivity$1;

    invoke-direct {v1, p0}, Lcom/example/hanlei/first_demo/MainActivity$1;-><init>(Lcom/example/hanlei/first_demo/MainActivity;)V

    invoke-virtual {v0, v1}, Landroid/widget/Button;->setOnClickListener(Landroid/view/View$OnClickListener;)V

    .line 29
    return-void
.end method

```
我们来一句一句进行分析:
#### 1.第一句
```
invoke-super {p0, p1}, Landroid/support/v7/app/AppCompatActivity;->onCreate(Landroid/os/Bundle;)V

```
使用oncreate方法
#### 2.第二句

```
const v0, 0x7f04001b

invoke-virtual {p0, v0}, Lcom/example/hanlei/first_demo/MainActivity;->setContentView(I)V

```
这里可以看到调用了setContentView方法,然后引用了v0这段数字,这个数字就是资源索引号。通过这个找到资源。
#### 3.第三句

```
.line 22
    invoke-virtual {p0}, Lcom/example/hanlei/first_demo/MainActivity;->Binding()V
```
调用Binding()方法
这里我们就要分析一下Binding是什么了。
#### 4. Binding()

```
# virtual methods
.method public Binding()V
    .locals 1

    .prologue
    .line 32
    const v0, 0x7f0b0058

    invoke-virtual {p0, v0}, Lcom/example/hanlei/first_demo/MainActivity;->findViewById(I)Landroid/view/View;

    move-result-object v0

    check-cast v0, Landroid/widget/TextView;

    iput-object v0, p0, Lcom/example/hanlei/first_demo/MainActivity;->out:Landroid/widget/TextView;

    .line 33
    const v0, 0x7f0b0057

    invoke-virtual {p0, v0}, Lcom/example/hanlei/first_demo/MainActivity;->findViewById(I)Landroid/view/View;

    move-result-object v0

    check-cast v0, Landroid/widget/EditText;

    iput-object v0, p0, Lcom/example/hanlei/first_demo/MainActivity;->in:Landroid/widget/EditText;

    .line 34
    const v0, 0x7f0b0059

    invoke-virtual {p0, v0}, Lcom/example/hanlei/first_demo/MainActivity;->findViewById(I)Landroid/view/View;

    move-result-object v0

    check-cast v0, Landroid/widget/Button;

    iput-object v0, p0, Lcom/example/hanlei/first_demo/MainActivity;->btn:Landroid/widget/Button;

    .line 35
    return-void
.end method
```
来看这个函数部分的最主要部分:

```
const v0, 0x7f0b0058

invoke-virtual {p0, v0}, Lcom/example/hanlei/first_demo/MainActivity;->findViewById(I)Landroid/view/View;

move-result-object v0

check-cast v0, Landroid/widget/TextView;

iput-object v0, p0, Lcom/example/hanlei/first_demo/MainActivity;->out:Landroid/widget/TextView;

```
定义资源号 v0。
来看下一句

```
invoke-virtual {p0, v0}, Lcom/example/hanlei/first_demo/MainActivity;->findViewById(I)Landroid/view/View;

```
这句就是调用findViewById,然后把v0放进去相当于findViewById(v0)

下一句
move-result-object v0
就是把上一句的结果放在v0中
然后下一句

```
check-cast v0, Landroid/widget/TextView;
```
这句之前没有见过,意思就是强制转换。强制转换为TextView类型

接来下的一句

```
iput-object v0, p0, Lcom/example/hanlei/first_demo/MainActivity;->out:Landroid/widget/TextView;

   
```
简单的说就是给out赋值。
现在我们回到onCreate
#### 5.第四句

```
iget-object v0, p0, Lcom/example/hanlei/first_demo/MainActivity;->btn:Landroid/widget/Button;

```
相当与使用开始btn
#### 6第五句

```
new-instance v1, Lcom/example/hanlei/first_demo/MainActivity$1;

```
实例化了一个Lcom/example/hanlei/first_demo/MainActivity$1;变量

#### 7.第六句

```
invoke-direct {v1, p0}, Lcom/example/hanlei/first_demo/MainActivity$1;-><init>(Lcom/example/hanlei/first_demo/MainActivity;)V

```
调用了init。我们来看下init。int在MainActivity$1中。

#### 8. MainActivity$1
首先来看代码:

```
.class Lcom/example/hanlei/first_demo/MainActivity$1;
.super Ljava/lang/Object;
.source "MainActivity.java"

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


# annotations
.annotation system Ldalvik/annotation/EnclosingMethod;
    value = Lcom/example/hanlei/first_demo/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:Lcom/example/hanlei/first_demo/MainActivity;


# direct methods
.method constructor <init>(Lcom/example/hanlei/first_demo/MainActivity;)V
    .locals 0
    .param p1, "this$0"    # Lcom/example/hanlei/first_demo/MainActivity;

    .prologue
    .line 23
    iput-object p1, p0, Lcom/example/hanlei/first_demo/MainActivity$1;->this$0:Lcom/example/hanlei/first_demo/MainActivity;

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

    return-void
.end method


# virtual methods
.method public onClick(Landroid/view/View;)V
    .locals 2
    .param p1, "v"    # Landroid/view/View;

    .prologue
    .line 26
    iget-object v0, p0, Lcom/example/hanlei/first_demo/MainActivity$1;->this$0:Lcom/example/hanlei/first_demo/MainActivity;

    # getter for: Lcom/example/hanlei/first_demo/MainActivity;->out:Landroid/widget/TextView;
    invoke-static {v0}, Lcom/example/hanlei/first_demo/MainActivity;->access$100(Lcom/example/hanlei/first_demo/MainActivity;)Landroid/widget/TextView;

    move-result-object v0

    iget-object v1, p0, Lcom/example/hanlei/first_demo/MainActivity$1;->this$0:Lcom/example/hanlei/first_demo/MainActivity;

    # getter for: Lcom/example/hanlei/first_demo/MainActivity;->in:Landroid/widget/EditText;
    invoke-static {v1}, Lcom/example/hanlei/first_demo/MainActivity;->access$000(Lcom/example/hanlei/first_demo/MainActivity;)Landroid/widget/EditText;

    move-result-object v1

    invoke-virtual {v1}, Landroid/widget/EditText;->getText()Landroid/text/Editable;

    move-result-object v1

    invoke-virtual {v1}, Ljava/lang/Object;->toString()Ljava/lang/String;

    move-result-object v1

    invoke-virtual {v0, v1}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V

    .line 27
    return-void
.end method

```
来看onClick部分

先来看看这三句。

```
iget-object v0, p0, Lcom/example/hanlei/first_demo/MainActivity$1;->this$0:Lcom/example/hanlei/first_demo/MainActivity;

    # getter for: Lcom/example/hanlei/first_demo/MainActivity;->out:Landroid/widget/TextView;
    invoke-static {v0}, Lcom/example/hanlei/first_demo/MainActivity;->access$100(Lcom/example/hanlei/first_demo/MainActivity;)Landroid/widget/TextView;

    move-result-object v0
```
这三句在做一件事情就是用先实例化,然后把这个东西放在v0里,就是可以使用v0代替以上。

接着来看

```
invoke-virtual {v1}, Landroid/widget/EditText;->getText()Landroid/text/Editable;

    move-result-object v1
```
调用getText()

```
invoke-virtual {v1}, Ljava/lang/Object;->toString()Ljava/lang/String;

```
调用toString()

```
invoke-virtual {v0, v1}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V
```
调用 setText
## 6.结束语
以上就是简单的smali分析,当然我们的目的不只是为了分析而已。我们还要进行一个改进才可以。还有一个目的就是可以为我们添加的控件增加一个简单的逻辑。
# 0x03 结尾
由于篇幅问题,其他的内容将在Android逆向-Android基础逆向(4-2)中进行剩余说明。
## 遗留内容
1.反编译增加一个Button,然后写一段自己的逻辑。
2.制作一个工具,辅助反编译。
## 收获
1.复习了Android界面编程
2.复习了Android监听事件的书写
3.反编译了一段代码,知道了smali流程
## 以上

Hmily 发表于 2018-2-2 11:14

@BubblePig 3没发论坛?

冥界3大法王 发表于 2018-2-2 11:20

@BubblePig
希望楼主 给来个 调用接口界面的案例,谢谢。

抱书人人 发表于 2018-2-2 12:57

谢谢分享,辛苦了,太有用了

iamhaozi1 发表于 2018-2-2 14:13

太有用了,学习了。

回忆微凉 发表于 2018-2-2 16:06

已收藏,谢谢楼主

hackerchen 发表于 2018-2-2 16:39

很详细的教程 点赞

liguodejia 发表于 2018-2-2 16:52

一直跟着学习,进步不小

lbq凯越 发表于 2018-2-2 16:58

点个赞,

m3316133 发表于 2018-2-2 17:11

向大佬学习~~~
页: [1] 2
查看完整版本: Android逆向-Android基础逆向(4)