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。

指令执行

smali字节码是类似于汇编的,如果你有汇编基础,理解起来是非常容易的。
比如:
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

转自:https://www.jianshu.com/p/ba9b374346dd

Smali语法基础的更多相关文章

  1. smali 语法基础

    dalvik字节码有两种类型,原始类型和引用类型.对象和数组是引用类型,其它都是原始类型. V  void Z  boolean B  byte S  short C  char I  int F   ...

  2. Smali语言基础语法

    1.Smali语言基础语法-数据类型与描述符 smali中有两类数据类型:基本类型和引用类型.引用类型是指数组和对象,其它都是基础类型. 基本类型以及每种类型的描述符: Java类型 类型描述符 说明 ...

  3. Android 反编译 -smali语法

    前言 前面我们有说过android反编译的工具,如何进行反编译.反编译后可以得到jar或者得到smali文件.Android采用的是java语言 进行开发,但是Android系统有自己的虚拟机Dalv ...

  4. Android逆向之smali语法宝典

    0x01.前言 Android采用的是java语言进行开发,但是Android系统有自己的虚拟机Dalvik,代码编译最终不是采用的java的class,而是使用的smali.我们反编译得到的代码,j ...

  5. JAVA 入门第一章(语法基础)

    本人初学java 博客分享记录一下自己的学习历程 java我的初步学习分为六章,有c和c++的基础学起来也简便了很多. 第一章 语法基础 第二章 面向对象 第三章 常用工具类 第四章 文件操纵 第五章 ...

  6. python基础入门一(语法基础)

    作为自己正式接触并应用的第一门编程语言,在Alex和武sir两位大王的要求下,开始了写博客总结的日子.学习编程语言是很有趣的一件事情,但有2点请一定要谨记:1.做人靠自己,码代码也必须靠自己.能不能成 ...

  7. PHP语法基础

    1.PHP语法基础 PHP标记符 <?php ?> 常亮与变量 $a = 10; 变量 可以在运行过程中修改 $a = 10; $a = 20; $b = 5; echo $a+$b; c ...

  8. Smali语法编程

    Smali背景: Smali,Baksmali分别是指安卓系统里的Java虚拟机(Dalvik)所使用的一种.dex格式文件的汇编器,反汇编器.其语法是一种宽松式的Jasmin/dedexer语法,而 ...

  9. Verilog语法基础讲解之参数化设计

    Verilog语法基础讲解之参数化设计   在Verilog语法中,可以实现参数化设计.所谓参数化设计,就是在一个功能模块中,对于一个常量,其值在不同的应用场合需要设置为不同的置,则将此值在设计时使用 ...

随机推荐

  1. ef core2.2 mysql迁移问题

    前段时间,遇到的是ef core mysql迁移的时候,bool类型会自动yingsheweishort的问题,需要手动更正一下今天测试的时候,遇到了MySQL数据表修改后迁移的问题. 问题详情如下  ...

  2. LunHui 的生命观

    LunHui 的生命观 来源 https://www.zhihu.com/question/346510295 作者:齐天大圣链接:https://www.zhihu.com/question/346 ...

  3. oracle 的分页、截断查询

    oracle 分页.截断查询 需求:从车管所的备案库中(oracle)取出数据,放到车综大数据平台(http方式) 现场情况:oracle中有三张表,CZRKXX(常住人口信息),ZDRYXX(重点人 ...

  4. 数据结构之链表(LinkedList)(一)

    链表(Linked List)介绍 链表是有序的列表,但是它在内存中是存储如下 1)链表是以节点方式存储的,是链式存储 2)每个节点包含data域(value),next域,指向下一个节点 3)各个节 ...

  5. QuickJS 快速入门 (QuickJS QuickStart)

    1. QuickJS 快速入门 (QuickJS QuickStart) 1. QuickJS 快速入门 (QuickJS QuickStart) 1.1. 简介 1.2. 安装 1.3. 简单使用 ...

  6. Java 之 ObjectOutputStream 类

    ObjectOutputStream 类 1.概述 java.io.ObjectOutputStream extends OutputStream ObjectOutputStream:对象的序列化流 ...

  7. FICO-Payment Terms 收付款条件和分期付款设置

    转载:https://www.cnblogs.com/weichuo/p/3524278.html Payment Terms 收付款条件和分期付款设置 SAP Payment Terms 中文翻译为 ...

  8. RFC destination fails with error Incomplete Logon Data after system copy

    1. 问题现象 1.1在system copy后,提示RFC报错Unable to configure STMS 2.  重要的参考文件: 2.1RFC passwords not available ...

  9. nginx日志文件的配置

    文章来源 运维公会: nginx日志文件的配置 1.日志介绍 nginx有两种日志,一种是访问日志,一种是错误日志. 访问日志中记录的是客户端对服务器的所有请求. 错误日志中记录的是在访问过程中,因为 ...

  10. 微信小程序 之wxml保留小数点后两位数的方法及转化为字符串的方法

    原理:wxml中不能直接使用较高级的js语法,如‘.toFixed’,‘toString()’,但可以通过引入wxs模块实现效果 1.新建`filter.wxs` var filters = {    ...