前言:
各位同学大家好 最近在学习逆向的知识点, 所以现在就总结写 在学些这篇文章之前我默认 你已经看过我之前出的安卓反编译的基础知识了 如果那个还不会 麻烦可以前面去查阅
如果不会基础的同学可以看 安卓反编译教程 这篇文章
效果图
理论知识
Smali文件
Smali是将Android字节码用可阅读的字符串形式 表现出来的一种语言,可以称之为Android字节码的 反汇编语言,即Smali语言是Dalvik的反汇编语言。
作用:
APK文件>dex文件>smali文件>修改代码
结构:
头文件 – 字段 – 方法 和Java类似
Smali数据类型
¨ B----byte
¨ C----char
¨ D----double
¨ F----float
¨ I----int
¨ J----long
¨ S----short
¨ V----void
¨ Z----boolean
¨ [XXX-----array
¨ Lxxx/yyy----object
数组的表示方式是:在基本类型前加上前中括号“[”,例如 [I、[F;
对象的表示则以L作为开头,格式是LpackageName/objectName;
类的表示:LpackageName/objectName;
内部类的表示: LpackageName/objectName$subObjectName;
Smali字段
字段定义:
field public/private [static] [final] varName:<Type>
举例说明(smali -> java):
.field public static HELLO:Ljava/lang/String;
public static String HELLO = "hello";
field private button:Landroid/widget/Button;
private Button button;
field public number:I
public int number =5;
Smali方法
方法定义:
Func-Name (Para-Type1Para-Type2Para-Type3...)Return-Type
举例说明( smali -> java 注意:参数与参数之间没有任何分隔符 ):
hello ()V
void hello()
hello (III)Z
boolean hello(int, int, int)
hello (Z[I[ILjava/lang/String;J)Ljava/lang/String;
String hello (boolean, int[], int[], String, long)
Smali方法(smali转java)
smali 代码 示例
.method private static getCount(II)V
.registers 2
.param p0, "x"
.param p1, "y"
.prologue
.line 28
return-void
.end method
java 代码示例
private static void getCount(int x,int y){
}
Smali基本语法
field 定义变量
method 方法
parameter 方法参数
prologue 方法开始
line 12 此方法位于第12行
const/high16 v0, 0x7fo3 把0x7fo3赋值给v0
return-void 函数返回void
end method 函数结束
new-instance 创建实例
iput-object 对象赋值
iget-object 调用对象
invoke-static 调用静态函数
invoke-super 调用父函数
invoke-direct 调用函数
Smali跳转语句
"if-eq vA, vB, :cond_\**" 如果vA等于vB则跳转到:cond_**
"if-ne vA, vB, :cond_\**" 如果vA不等于vB则跳转到:cond_**
"if-lt vA, vB, :cond_\**" 如果vA小于vB则跳转到:cond_**
"if-ge vA, vB, :cond_\**" 如果vA大于等于vB则跳转到:cond_**
"if-gt vA, vB, :cond_\**" 如果vA大于vB则跳转到:cond_**
"if-le vA, vB, :cond_\**" 如果vA小于等于vB则跳转到:cond_**
"if-eqz vA, :cond_\**" 如果vA等于0则跳转到:cond_**
"if-nez vA, :cond_\**" 如果vA不等于0则跳转到:cond_**
"if-ltz vA, :cond_\**" 如果vA小于0则跳转到:cond_**
"if-gez vA, :cond_\**" 如果vA大于等于0则跳转到:cond_**
"if-gtz vA, :cond_\**" 如果vA大于0则跳转到:cond_**
"if-lez vA, :cond_\**" 如果vA小于等于0则跳转到:cond_**
Smali函数调用
函数类型:
- direct - private函数
- virtual - public和protected函数
寄存器:
- 本地寄存器用v开头数字结尾的符号来表示,如v0、v1、v2、…
- 参数寄存器则使用p开头数字结尾的符号来表示,如p0、p1、p2、…
调用函数:
1. invoke-static
2. invoke-super
3. invoke-direct
4. invoke-virtual
Smali函数调用:invoke-static
invoke-static:
作用:用于调用static函数。
例如:
const-string v0, "NDKLIB"
invoke-static {v0}, Ljava/lang/System;-
>loadLibrary(Ljava/lang/String;)V
static void System.loadLibrary(String)
Smali函数调用:invoke-super
invoke-direct:
作用:用于调用private函数。
例如:
invoke-direct {p0}, Landroid/app/TabActivity;-
><init>()V
init()就是定义在TabActivity中的一个private函数
Smali函数调用:invoke-virtual
invoke-virtual:
作用:用于调用protected或public函数。
例如:
sget-object v0, Lcom/dddd;->bbb:Lcom/ccc;
invoke-virtual {v0, v1}, Lcom/ccc;-
>Messages(Ljava/lang/Object;)V
v0是bbb:Lcom/ccc
v1是传递给Messages方法的Ljava/lang/Object参数
Smali函数返回结果
move-result(返回基本数据类型)
move-result-object(返回对象)
const-string v0, ”Tom"
invoke-static {v0}, Lcmb/pbi;-
>hi(Ljava/lang/String;)Ljava/lang/String;
move-result-object v2
最后总结
smali语法比较枯燥和难以阅读 同学们一定要耐心去阅读可以自己写一些demo 对照java代码去阅读 smali代码 这样去学习能使我们更快掌握samli的语法 然后才能让我们在实战用修改smali 里面代码逻辑 达到修改和注入的目的 最后希望我都文章能帮助到各位网友的工作和学习 如果你觉得文章还不错麻烦给我三连 关注点赞和转发 谢谢