经过前面的基础 案例已经初步掌握了smali
https://blog.youkuaiyun.com/qq_20330595/article/details/80979939
这边我们上点有意思的代码(俗称:解忧程序员)相信大家看了这个都有小激动了吧?
上代码先 我们将学到如下内容
1.数组
2.for 循环
3.if 语句
4.算数操作符
为了免得翻的累 直接将分析写在这里,查看源码时候在去下面看。
我们直接看main中的数组部分
关于数组的初始化 可以查看 https://blog.youkuaiyun.com/woblog/article/details/52106571
const/16 v3, 0x15
new-array v1, v3, [I
fill-array-data v1, :array_32
.line 10
.local v1, "posAry":[I
const/16 v3, 0x10
new-array v2, v3, [C
fill-array-data v2, :array_60
.line 11
.local v2, "websiteAry":[C
new-array v1, v3, [I
新建一个数组 v1存实例 v3为长度 [I 表示这是一个int数组
const/16 v3, 0x15
很明显v3大小为 21
fill-array-data v1, :array_32
这里的array_32返回一个长度为21的int数组.
:array_32
.array-data 4
0x5
0x4
0x6
0xb
0xb
0xc
0xe
0x5
0x7
0x5
0xf
0x4
0x6
0xa
0x3
0x7
0x1
0xd
0xa
0x0
0x8
.end array-data
.line 10
指定在JAVA中的10行
.local v1, "posAry":[I
这边赋值就是 将v1赋给 posAry 这个int数组
表示局部变量 posAry的int数组 这里做出了充分解//https://blog.youkuaiyun.com/dd864140130/article/details/52076515
const/16 v3, 0x10
给V3 赋值 16
new-array v2, v3, [C
新建一个长度为16的char 数组 赋给V2
fill-array-data v2, :array_60
给V2 赋值 长度为16的char数组
.line 10
:array_60
.array-data 2
0x33s
0x6fs
0x31s
0x77s
0x68s
0x74s
0x77s
0x6ds
0x36s
0x63s
0x3as
0x6es
0x70s
0x2fs
0x2es
0x77s
.end array-data
.line 11
.local v2, "websiteAry":[C
将V2赋给一个叫websiteAry的char数组
这个在前面一篇中做过介绍 就是System.out.printl("jieyouwang");
sget-object v3, Ljava/lang/System;->out:Ljava/io/PrintStream;
获取实例
const-string v4, "jieyouwang"
新建String
invoke-virtual {v3, v4}, Ljava/io/PrintStream;->print(Ljava/lang/String;)V
调用v3的print方法传参V4.
v3后面都是参数
;分割参数
for循环 这位大神写的比较好 https://www.cnblogs.com/lee0oo0/p/3728271.html
划分for循环区域依据:goto_16 成对存在。
.line 12
const/4 v0, 0x0
初始化 int =0;
.local v0, "i":I
:goto_16
array-length v3, v1
给v3赋值 v1数组的长度 也就是数组posAry 长度为21
if-ge v0, v3, :cond_30
如果v0大于等于v3则跳转到:cond_30
这个还用解释 也就是i超过了数组postAry的长度/如不符合往下走, 符合执行分支 :cond_30 也就是跳出循环
.line 13
sget-object v4, Ljava/lang/System;->out:Ljava/io/PrintStream;
获取out实例 https://blog.youkuaiyun.com/lpohvbe/article/details/7981386
rem-int/lit8 v3, v0, 0x2
这个就NB了 是smali的算数操作符 参考 https://blog.youkuaiyun.com/wizardforcel/article/details/54730253
结合java源码看就知道是 2%i 的意思。
其中<litn>可以为lit8或lit16,即 8 位或 16 位的整数字面值。比如int a = 0; a += 2;可能编译为const/4 v0, 0和add-int/lit8 v0, v0, 0x2。
if-nez v3, :cond_2b
如果v3不等于零(不能被2整除) 就去cond_2b 不符合往下执行
Java源码却是个三目运算符
aget v3, v1, v0
数组取值 v3 = v1[v0]
add-int/lit8 v3, v3, -0x1
v3= v3-1
:goto_23
标记为23行
aget-char v3, v2, v3
数组取值 v3 = v2[v3]//这里的v2 是局部变量数组websiteAry
为什么这么节约再加个v4寄存器接收不可以吗?
invoke-virtual {v4, v3}, Ljava/io/PrintStream;->print(C)V
执行v4(out)的print方法参数V3为char类型 返回空
.line 12
add-int/lit8 v0, v0, 0x1
自加 v0++;
goto :goto_16
下一个循环 这个v0 也就是参数i 是在for循环之外申明的所以会保留值
.line 13
:cond_2b
aget v3, v1, v0
aget系列指令用于读取数组元素,效果为v3 = v1[v0]
参考 https://blog.youkuaiyun.com/wizardforcel/article/details/54730253
add-int/lit8 v3, v3, 0x1
然后让 v3=v3+1;
goto :goto_23
.line 15
:cond_30
能执行到这里说明遍历已经结束了。
return-void
goto_16
array-length v3, v1
给v3赋值 v1数组的长度 也就是数组posAry 长度为21
if-ge v0, v3, :cond_30
如果v0大于等于v3则跳转到:cond_30
这个还用解释 也就是i超过了数组postAry的长度/如不符合往下走, 符合执行分支 :cond_30 也就是跳出循环
.line 13
sget-object v4, Ljava/lang/System;->out:Ljava/io/PrintStream;
获取out实例 https://blog.youkuaiyun.com/lpohvbe/article/details/7981386
rem-int/lit8 v3, v0, 0x2
这个就NB了 是smali的算数操作符 参考 https://blog.youkuaiyun.com/wizardforcel/article/details/54730253
结合java源码看就知道是 2%i 的意思。
其中<litn>可以为lit8或lit16,即 8 位或 16 位的整数字面值。比如int a = 0; a += 2;可能编译为const/4 v0, 0和add-int/lit8 v0, v0, 0x2。
if-nez v3, :cond_2b
如果v3不等于零(不能被2整除) 就去cond_2b 不符合往下执行
Java源码却是个三目运算符
aget v3, v1, v0
数组取值 v3 = v1[v0]
add-int/lit8 v3, v3, -0x1
v3= v3-1
:goto_23
标记为23行
aget-char v3, v2, v3
数组取值 v3 = v2[v3]//这里的v2 是局部变量数组websiteAry
为什么这么节约再加个v4寄存器接收不可以吗?
invoke-virtual {v4, v3}, Ljava/io/PrintStream;->print(C)V
执行v4(out)的print方法参数V3为char类型 返回空
.line 12
add-int/lit8 v0, v0, 0x1
自加 v0++;
goto :goto_16
下一个循环 这个v0 也就是参数i 是在for循环之外申明的所以会保留值
.line 13
:cond_2b
aget v3, v1, v0
aget系列指令用于读取数组元素,效果为v3 = v1[v0]
参考 https://blog.youkuaiyun.com/wizardforcel/article/details/54730253
add-int/lit8 v3, v3, 0x1
然后让 v3=v3+1;
goto :goto_23
.line 15
:cond_30
能执行到这里说明遍历已经结束了。
return-void
=================================源码部分=====================================
package com.example.hellojni;
import java.util.Date;
public class Jieyou {
public String name;
private int age;
protected double height;
private Show show;
public static void main(String[] args) {
int[] posAry = new int[]{5, 4, 6, 11, 11, 12, 14, 5, 7, 5, 15, 4, 6, 10, 3, 7, 1, 13, 10, 0, 8};
char[] websiteAry = new char[]{'3', 'o', '1', 'w', 'h', 't', 'w', 'm', '6', 'c', ':', 'n', 'p', '/', '.', 'w'};
System.out.print("jieyouwang");
for (int i = 0; i < posAry.length; i++) {
System.out.print(websiteAry[i % 2 == 0 ? posAry[i] - 1 : posAry[i] + 1]);
}
}
}
.class public Lcom/example/hellojni/Jieyou;
.super Ljava/lang/Object;
.source "Jieyou.java"
# instance fields
.field private age:I
.field protected height:D
.field public name:Ljava/lang/String;
# direct methods
.method public constructor <init>()V
.registers 1
.prologue
.line 3
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
return-void
.end method
.method public static main([Ljava/lang/String;)V
.registers 6
.param p0, "args" # [Ljava/lang/String;
.prologue
.line 9
const/16 v3, 0x15
new-array v1, v3, [I
fill-array-data v1, :array_32
.line 10
.local v1, "posAry":[I
const/16 v3, 0x10
new-array v2, v3, [C
fill-array-data v2, :array_60
.line 11
.local v2, "websiteAry":[C
sget-object v3, Ljava/lang/System;->out:Ljava/io/PrintStream;
const-string v4, "jieyouwang"
invoke-virtual {v3, v4}, Ljava/io/PrintStream;->print(Ljava/lang/String;)V
.line 12
const/4 v0, 0x0
.local v0, "i":I
:goto_16
array-length v3, v1
if-ge v0, v3, :cond_30
.line 13
sget-object v4, Ljava/lang/System;->out:Ljava/io/PrintStream;
rem-int/lit8 v3, v0, 0x2
if-nez v3, :cond_2b
aget v3, v1, v0
add-int/lit8 v3, v3, -0x1
:goto_23
aget-char v3, v2, v3
invoke-virtual {v4, v3}, Ljava/io/PrintStream;->print(C)V
.line 12
add-int/lit8 v0, v0, 0x1
goto :goto_16
.line 13
:cond_2b
aget v3, v1, v0
add-int/lit8 v3, v3, 0x1
goto :goto_23
.line 15
:cond_30
return-void
.line 9
nop
:array_32
.array-data 4
0x5
0x4
0x6
0xb
0xb
0xc
0xe
0x5
0x7
0x5
0xf
0x4
0x6
0xa
0x3
0x7
0x1
0xd
0xa
0x0
0x8
.end array-data
.line 10
:array_60
.array-data 2
0x33s
0x6fs
0x31s
0x77s
0x68s
0x74s
0x77s
0x6ds
0x36s
0x63s
0x3as
0x6es
0x70s
0x2fs
0x2es
0x77s
.end array-data
.end method