Smali语法基础
Smali是什么
Smali是Android虚拟机的反汇编语言。
我们都知道,Android代码一般是用java编写的,执行java程序一般需要用到java虚拟机,在Android平台上也不例外,但是出于性能上的考虑,并没有使用标准的JVM,而是使用专门的Android虚拟机(5.0以下为Dalvik,5.0以上为ART)。Android虚拟机的可执行文件并不是普通的class文件,而是再重新整合打包后生成的dex文件。dex文件反编译之后就是Smali代码,所以说,Smali语言是Android虚拟机的反汇编语言。
掌握Smali有哪些好处
1、动态调试APK,通常静态分析APK是不够的,如果需要彻底分析APK的执行逻辑,需要通过动态调试来进行。
具体教程参考:https://www.jianshu.com/p/9931a1e77066
2、修改APK运行逻辑,通过修改Smali代码,再重新编译打包成新的APK,是Android逆向的基本操作。
Smali基本语法
数据类型
语法关键词
寄存器
Java中变量都是存放在内存中的,Android为了提高性能,变量都是存放在寄存器中的,寄存器为32位,可以支持任何类型。
为什么寄存器比内存快,可以参考这篇文章:http://www.ruanyifeng.com/blog/2013/10/register.html
寄存器分为如下两类:
1、本地寄存器
用v开头数字结尾的符号来表示,v0, v1, v2,...
2、参数寄存器
用p开头数字结尾的符号来表示,p0,p1,p2,...
注意:
在非static方法中,p0代指this,p1为方法的第一个参数。
在static方法中,p0为方法的第一个参数。
Smali代码示例:
const/4 v0, 0x1 //把值0x1存到v0本地寄存器
iput-boolean v0,p0,Lcom/aaa;->IsRegisterd:Z //把v0中的值赋给com.aaa.IsRegistered,p0代表this,相当于this.Isregistered=true
成员变量
成员变量定义格式为:
.field public/private [static][final] varName:<类型>
获取指令
iget, sget, iget-boolean, sget-boolean, iget-object, sget-object
操作指令
iput, sput, iput-boolean, sput-boolean, iput-object, sput-object
array的操作是aget和aput
指令解析
sget-object v0,Lcom/aaa;->ID:Ljava/lang/String;
获取ID这个String类型的成员变量并放到v0这个寄存器中
iget-object v0,p0,Lcom/aaa;->view:Lcom/aaa/view;
iget-object比sget-object多一个参数p0,这个参数代表变量所在类的实例。这里p0就是this
Smali代码示例1:
const/4 v3, 0x0
sput-object v3, Lcom/aaa;->timer:Lcom/aaa/timer;
相当于java代码:this.timer = null;
Smali代码示例2:
.local v0, args:Landroid/os/Message;
const/4 v1, 0x12
iput v1,v0,Landroid/os/Message;->what:I
相当于java代码:args.what = 18;
其中args为Message的实例
函数
函数定义格式为:
.method public/private [static][final] methodName()<类型>
.end method
Smali代码示例
.method private ifRegistered()Z
.locals 2 // 本地寄存器的个数
.prologue
const/4 v0, 0x1 //v0赋值为1
if-eqz v0, :cond_0 //判断v0是否等于0,等于0则跳到cond_0执行
const/4 v1, 0x1 //符合条件分支
:goto_0 //标签
return v1 //返回v1的值
:cond_0 //标签
const/4 v1, 0x0 //cond_0分支
goto :goto_0 //跳到goto_0执行
.end method
函数分为两类:direct method和virtual method
direct method就是private方法,virtual method就是指其余的方法。
调用指令:
invoke-direct
invoke-virtual
invoke-static
invoke-super
invoke-interface
调用格式:
invoke-指令类型 {参数1, 参数2,...}, L类名;->方法名
如果不是是静态方法,参数1代表调用该方法的实例。
Smali代码示例:
const-string v0, "NDKLIB"
invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
相当于java代码:System.loadLibrary("NDKLIB")
函数返回结果
Smali需要用指令move-result或move-result-object来保存函数返回的结果
Smali代码示例:
const-string v0, "Eric"
invoke-static {v0}, Lcmb/pbi;->t(Ljava/lang/String;)Ljava/lang/String;
move-result-object v2
表示将方法t返回的String对象保存到v2中。
方法的定义
private static int sum(int a, int b) {
return a+b;
}
使用编译后是这样
.method private static sum(II)I
.locals 4 #表示需要申请4个本地寄存器
.parameter
.parameter #这里表示有两个参数
.prologue
.line 27
move v0, p0
.local v0, a:I
move v1, p1
.local v1, b:I
move v2, v0
move v3, v1
add-int/2addr v2, v3
move v0, v2
.end local v0 #a:I
return v0
.end method
从上面可以看到函数声明使用.method开始 .end method结束,java中的关键词private,static 等都可以使用,同时使用签名来表示唯一的方法,这里是sum(II)I。
指令执行
比如:
move v0, v3 #把v3寄存器的值移动到寄存器v0上.
const v0, 0x1 #把值0x1赋值到寄存器v0上。
invoke-static {v4, v5}, Lme/isming/myapplication/MainActivity;->sum(II)I #执行方法sum(),v4,v5的值分别作为sum的参数
条件跳转分支
"if-eq vA, vB, :cond_x" --- 如果vA等于vB则跳转到:cond_x
"if-ne vA, vB, :cond_x" --- 如果vA不等于vB则跳转到:cond_x
"if-lt vA, vB, :cond_x" --- 如果vA小于vB则跳转到:cond_x
"if-ge vA, vB, :cond_x" --- 如果vA大于等于vB则跳转到:cond_x
"if-gt vA, vB, :cond_x" --- 如果vA大于vB则跳转到:cond_x
"if-le vA, vB, :cond_x" --- 如果vA小于等于vB则跳转到:cond_x
"if-eqz vA, :cond_x" --- 如果vA等于0则跳转到:cond_x
"if-nez vA, :cond_x" --- 如果vA不等于0则跳转到:cond_x
"if-ltz vA, :cond_x" --- 如果vA小于0则跳转到:cond_x
"if-gez vA, :cond_x" --- 如果vA大于等于0则跳转到:cond_x
"if-gtz vA, :cond_x" --- 如果vA大于0则跳转到:cond_x
"if-lez vA, :cond_x" --- 如果vA小于等于0则跳转到:cond_x
Smali语法基础的更多相关文章
- smali 语法基础
dalvik字节码有两种类型,原始类型和引用类型.对象和数组是引用类型,其它都是原始类型. V void Z boolean B byte S short C char I int F ...
- Smali语言基础语法
1.Smali语言基础语法-数据类型与描述符 smali中有两类数据类型:基本类型和引用类型.引用类型是指数组和对象,其它都是基础类型. 基本类型以及每种类型的描述符: Java类型 类型描述符 说明 ...
- Android 反编译 -smali语法
前言 前面我们有说过android反编译的工具,如何进行反编译.反编译后可以得到jar或者得到smali文件.Android采用的是java语言 进行开发,但是Android系统有自己的虚拟机Dalv ...
- Android逆向之smali语法宝典
0x01.前言 Android采用的是java语言进行开发,但是Android系统有自己的虚拟机Dalvik,代码编译最终不是采用的java的class,而是使用的smali.我们反编译得到的代码,j ...
- JAVA 入门第一章(语法基础)
本人初学java 博客分享记录一下自己的学习历程 java我的初步学习分为六章,有c和c++的基础学起来也简便了很多. 第一章 语法基础 第二章 面向对象 第三章 常用工具类 第四章 文件操纵 第五章 ...
- python基础入门一(语法基础)
作为自己正式接触并应用的第一门编程语言,在Alex和武sir两位大王的要求下,开始了写博客总结的日子.学习编程语言是很有趣的一件事情,但有2点请一定要谨记:1.做人靠自己,码代码也必须靠自己.能不能成 ...
- PHP语法基础
1.PHP语法基础 PHP标记符 <?php ?> 常亮与变量 $a = 10; 变量 可以在运行过程中修改 $a = 10; $a = 20; $b = 5; echo $a+$b; c ...
- Smali语法编程
Smali背景: Smali,Baksmali分别是指安卓系统里的Java虚拟机(Dalvik)所使用的一种.dex格式文件的汇编器,反汇编器.其语法是一种宽松式的Jasmin/dedexer语法,而 ...
- Verilog语法基础讲解之参数化设计
Verilog语法基础讲解之参数化设计 在Verilog语法中,可以实现参数化设计.所谓参数化设计,就是在一个功能模块中,对于一个常量,其值在不同的应用场合需要设置为不同的置,则将此值在设计时使用 ...
随机推荐
- 玩转【Mock.js】,前端也能跑的很溜
现在开发已经是前后端分离了,前端和后端可以同时进行开发,互不影响,但是有些时候后端开发的接口慢于前端,导致前端需要等待后端的接口完成才能完成前后端对接,为了解决这个痛点,出现了模拟接口数据的方案,目前 ...
- vs项目模板创建和使用
一.使用dotnet命令创建(适用于.NET Core,可以创建包含任意数量个项目的模板,但不会出现在vs的新建项目模板中) 官方文档:https://docs.microsoft.com/zh-cn ...
- java常见排序算法
今天去面试的时候又考了排序算法,排序这个东西,你以为你懂了,但是真正去写的时候才会发现好多细节自己都模棱两可,我写着写着就全都乱了,回来之后赶紧重新写一遍. (1)冒泡排序 public void b ...
- 图片上传怎么用File接受文件
xl_echo编辑整理,欢迎转载,转载请声明文章来源.欢迎添加echo微信(微信号:t2421499075)交流学习. 百战不败,依不自称常胜,百败不颓,依能奋力前行.——这才是真正的堪称强大!! - ...
- Windows Server 2012 R2上安装.Net4.6.1出错
在Windows Server 2012 R2上安装.Net4.6.1时提示“你需要先安装对应于 KB2919355 的更新,然后才可在……”解决方式: 在官网下载更新包,下载地址:https://w ...
- Eclipse上安装websphere
Eclipse上安装websphere 参考:https://blog.csdn.net/qq_26264237/article/details/90107508 安装websphere插件 WebS ...
- 【20191118会议】针对华为云CCE 问题总结
针对华为云CCE问题总结 如何购买CCE集群 可以分为测试环境和生产环境,针对使用范围进行购买集群. 测试环境 可以进行公用 生产环境建议使用单独集群 尤其针对部门大 耦合性不高 ,生产环境 建议使用 ...
- erase & remove_if 合用
words_.erase( remove_if( words_.begin(), words_.end(), [&](const entry& e) { return (e.type ...
- linux 防火墙 firewall 设置
背景: 机房断电后导致机器关机重启,原先访问的地址访问不了,使用终端能访问到该服务器,服务启起来后,用curl + 地址能访问,但在外部浏览器访问不了该地址: 首先想到了端口限制----防火墙 参考博 ...
- redis危险命令
KEYS 单行遍历,速度很慢很占执行时间,对单核来说,极有可能导致执行完后处理不过来这段时间堆积的任务量,导致雪崩. FLUSHALL FLUSHDB CONFIG 今晚搜索kombu用的key,用了 ...