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流程
## 以上 @BubblePig 3没发论坛? @BubblePig
希望楼主 给来个 调用接口界面的案例,谢谢。 谢谢分享,辛苦了,太有用了 太有用了,学习了。 已收藏,谢谢楼主 很详细的教程 点赞 一直跟着学习,进步不小 点个赞, 向大佬学习~~~
页:
[1]
2