原创
首页
›
逆向
初识 Smali
LinJHS
0
简单记一下,大部分都是大佬的文章摘抄过来的,原文地址在本文文末。
本文主要是方便后续需要查找使用。
什么是 JVM、Dalvik、ART
JVM 跑的是 Java 字节码,是 Java 的虚拟机。
Android 没有直接拿 JVM 来用:Google 专门为 Android 设计了一个 Dalvik,它有专属的文件执行格式 dex(Dalvik executable)。
ART(Android Runtime)相当于 Dalvik 的升级版,本质上还是干同一件事。
smali 及其语法
smali 是 Dalvik 用的寄存器式语言,把 dex 反编译出来得到的就是它。
关键字
名称 | 注释 |
|---|
.class | 类名 |
.super | 父类名,继承的上级类名名称 |
.source | 源名 |
.field | 变量 |
.method | 方法名 |
.register | 寄存器 |
.end method | 方法名的结束 |
public | 公有 |
protected | 半公开,只有同一家人才能用 |
private | 私有,只能自己使用 |
.parameter | 方法参数 |
.prologue | 方法开始 |
.line xxx | 位于第xxx行 |
数据类型对应
smali类型 | java类型 | 注释 |
|---|
V | void | 无返回值 |
Z | boolean | 布尔值类型,返回0或1 |
B | byte | 字节类型,返回字节 |
S | short | 短整数类型,返回数字 |
C | char | 字符类型,返回字符 |
I | int | 整数类型,返回数字 |
J | long (64位 需要2个寄存器存储) | 长整数类型,返回数字 |
F | float | 单浮点类型,返回数字 |
D | double (64位 需要2个寄存器存储) | 双浮点类型,返回数字 |
string | String | 文本类型,返回字符串 |
Lxxx/xxx/xxx | object | 对象类型,返回对象 |
常用指令
关键字 | 注释 |
|---|
const | 重写整数属性,真假属性内容,只能是数字类型 |
const-string | 重写字符串内容 |
const-wide | 重写长整数类型,多用于修改到期时间。 |
return | 返回指令 |
if-eq | 全称equal(a=b),比较寄存器ab内容,相同则跳 |
if-ne | 全称not equal(a!=b),ab内容不相同则跳 |
if-eqz | 全称equal zero(a=0),z即是0的标记,a等于0则跳 |
if-nez | 全称not equal zero(a!=0),a不等于0则跳 |
if-ge | 全称greater equal(a>=b),a大于或等于则跳 |
if-le | 全称little equal(a<=b),a小于或等于则跳 |
goto | 强制跳到指定位置 |
switch | 分支跳转,一般会有多个分支线,并根据指令跳转到适当位置 |
iget | 获取寄存器数据 |
寄存器
在 smali 里的所有操作都必须经过寄存器来进行:本地寄存器用 v 开头数字结尾的符号来表示,如 v0、v1、v2。参数寄存器则使用 p 开头数字结尾的符号来表示,如 p0、p1、p2。
特别注意的是,p0 不一定是函数中的第一个参数:在非 static 函数中,p0 代指 this ,p1 表示函数的第一个参数,p2 代表函数中的第二个参数;而在 static 函数中 p0 才对应第一个参数(因为 Java 的 static 方法中没有 this 方法)。
修改方式
修改判断:把 if-xx 的条件改成相反,或者让它永远不成立/成立,逻辑就反过来了;
强制跳转:用 # 把原指令注释掉,或者直接 goto 到想要的地方;
修改寄存器的值:用 const 系列指令把内容换成想要的值。
补充
01 去广告页
可以使用 MT 的 Activity 记录,获取 Activity 信息,然后修改。
02 去弹窗
同理。
参考资料:
[Android 原创] 《安卓逆向这档事》三、初识smali,vip终结者 https://www.52pojie.cn/thread-1701353-1-1.html
分享
如果这篇文章帮到你,可以请我喝一杯茶。