0x01.前言

Android采用的是java语言进行开发,但是Android系统有自己的虚拟机Dalvik,代码编译最终不是采用的java的class,而是使用的smali。我们反编译得到的代码,jar的话可能很多地方无法正确的解释出来,如果我们反编译的是smali则可以正确的理解程序的意思。因此,我们有必要熟悉smali语法。

0x02.关键字

  • .field private isFlag:z — 定义变量
  • .method — 方法
  • .parameter — 方法参数
  • .prologue — 方法开始
  • .line 12 — 此方法位于第12行
  • invoke-super — 调用父函数
  • const/high16 v0, 0x7f03 — 把0x7f03赋值给v0
  • invoke-direct — 调用函数
  • return-void — 函数返回void
  • .end method — 函数结束
  • new-instance — 创建实例
  • iput-object — 对象赋值
  • iget-object — 调用对象
  • invoke-static — 调用静态函数

0x03.数据类型

java里面包含两种数据类型,基本数据类型和引用类型(包括对象),同时映射到smali也是有这两大类型。

1)基本数据类型

  • B — byte
  • C — char
  • D — double (64 bits)
  • F — float
  • I — int
  • J — long (64 bits)
  • S — short
  • V — void    只能用于返回值类型
  • Z — boolean

2)对象类型

  • Lxxx/yyy/zzz; — object

L表示这是一个对象类型
xxx/yyy是该对象所在的包
zzz是对象名称
;标识对象名称的结束

3)数组类型

  • [XXX — array

[I表示一个int型的一维数组,相当于int[]
增加一个维度增加一个[,如[[I表示int[][]
数组每一个维度最多255个;
对象数组表示也是类似,如String数组的表示是[Ljava/lang/String

0x04.寄存器与变量

java中变量都是存放在内存中的,android为了提高性能,变量都是存放在寄存器中的,寄存器为32位,可以支持任何类型,其中long和double是64为的,需要使用两个寄存器保存。
寄存器采用v和p来命名
v表示本地寄存器,p表示参数寄存器,关系如下
如果一个方法有两个本地变量,有三个参数

v0第一个本地寄存器
v1第二个本地寄存器
v2 p0(this)
v3 p1第一个参数
v4 p2第二个参数
v5 p3第三个参数

当然,如果是静态方法的话就只有5个寄存器了,不需要存this了。
.registers使用这个指令指定方法中寄存器的总数
.locals使用这个指定表明方法中非参寄存器的总数,放在方法的第一行。

0x05.寄存器与变量

java中变量都是存放在内存中的,android为了提高性能,变量都是存放在寄存器中的,寄存器为32位,可以支持任何类型,其中long和double是64为的,需要使用两个寄存器保存。
寄存器采用v和p来命名

  • v 表示本地寄存器
  • p 表示参数寄存器

关系如下
    如果一个方法有两个本地变量,有三个参数

v0第一个本地寄存器
v1第二个本地寄存器
v2 p0(this)
v3 p1第一个参数
v4 p2第二个参数
v5 p3第三个参数

当然,如果是静态方法的话就只有5个寄存器了,不需要存this了。
.registers使用这个指令指定方法中寄存器的总数
.locals使用这个指定表明方法中非参寄存器的总数,放在方法的第一行。

0x06.方法和字段

1)方法签名

methodName(III)Lpackage/name/ObjectName;
    如果做过ndk开发的对于这样的签名应该很熟悉的,就是这样来标识一个方法的。上面methodName标识方法名,III表示三个整形参数,Lpackage/name/ObjectName;表示返回值的类型。

2)方法的表示

Lpackage/name/ObjectName;——>methodName(III)Z
即 package.name.ObjectName中的 function boolean methondName(int a, int b, int c) 类似这样子

3)字段的表示

Lpackage/name/ObjectName;——>FieldName:Ljava/lang/String;
即表示: 包名,字段名和各字段类型

4)方法的定义

比如下面的一个方法

private static int sum(int a, int b) {
return a+b;
} .method private static sum(II)I
.locals #表示需要申请4个本地寄存器
.parameter
.parameter #这里表示有两个参数
.prologue
.line
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。

5)声明成员

.field private name:Lpackage/name/ObjectName;
比如:private TextView mTextView;表示就是
.field private mTextView:Landroid/widget/TextView;
private int mCount;
.field private mCount:I

0x07.指令执行

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的参数。

0x08.条件跳转分支

“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

Android逆向之smali语法宝典的更多相关文章

  1. Android逆向之smali

    Android逆向之smali 头信息 smail文件前三行 .class <访问权限> [关键修饰字] <类名>; .super <父类名>; .source & ...

  2. Android 反编译 -smali语法

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

  3. Android逆向之smali学习

    Smali是Android虚拟机Dalvik反汇编的结果. Dalvik指令集 指令格式为:[op]-[type](可选)/[位宽,默认4位] [目标寄存器],[源寄存器](可选) 赋值:move*  ...

  4. android 逆向project smail 语法学习

    众所周知,android 是开源的.如今市场上反编译别人的劳动果实的人也不少.所以我们也是有必要学习下smail语言,(就是androidproject反编译后出的语法语音),看看改怎么给我们的代码 ...

  5. Android逆向——smali复杂类解析

    i春秋作家:HAI_ 之前在Android逆向——初识smali与java类中讲解了基本的HelloWorld和简单类.这节课就要进一步深入.如果能够耐下心来分析一定会有所收获.——写给自己和后来人. ...

  6. Android逆向破解表单登录程序

    Android逆向破解表单登录程序 Android开发 ADT: android studio(as) 程序界面如下,登录成功时弹出通知登录成功,登录失败时弹出通知登录失败. 布局代码 <?xm ...

  7. Android逆向之静态分析

    想必打过CTF的小伙伴多多少少都触过Android逆向,所以斗哥将给大家整一期关于Android逆向的静态分析与动态分析.本期先带来Android逆向的静态分析,包括逆向工具使用.文件说明.例题解析等 ...

  8. 【转】Android逆向入门流程

    原文:https://www.jianshu.com/p/71fb7ccc05ff 0.写在前面 本文是笔者自学笔记,以破解某目标apk的方式进行学习,中间辅以原理性知识,方便面试需求. 参考文章的原 ...

  9. smali语法详解

    smali文件格式 每个smali文件都由若干条语句组成,所有的语句都遵循着一套语法规则.在smali 文件的头3 行描述了当前类的一些信息,格式如下: .class < 访问权限> [  ...

随机推荐

  1. appium自动化测试- 元素操作

    本文转自:https://www.cnblogs.com/sinder2018/articles/9699801.html 一.滑动屏幕 1.appium - 滑动屏幕 滑动接口: swipe(起始X ...

  2. 个人笔记 - C++相关收藏

    一.文件操作 1.C++从txt文件中读取二维的数组

  3. javaScript 通过location对象获取项目的url

    项目中有些要通过jQuery 动态加载,其中需要一些路径,使用相对路径会出现错误,报 $("#t1").html("设置或返回从井号 (#) 开始的 URL(锚)---& ...

  4. eclispse指针变成十字型

    按ATL+Shift+A可以十字和箭头切换.

  5. sparkSQL获取DataFrame的几种方式

    sparkSQL获取DataFrame的几种方式 1. on a specific DataFrame. import org.apache.spark.sql.Column df("col ...

  6. Python2和Python3的安装以及pycharm安装,path环境变量的配置

    一:安装python2.7过程步骤 1.官网下载pythonan安装包: ·输入python搜索 ·找到python官网,点击进入 ·鼠标放在Downloads上,在新弹出的选项中选择Windows, ...

  7. Linux/x86-64 - setuid(0) & chmod ("/etc/passwd", 0777) & exit(0) - 63 byes

    /* Title: Linux/x86-64 - setuid(0) & chmod ("/etc/passwd", 0777) & exit(0) - 63 by ...

  8. shell script 二 判断符号【】 shift 偏移量 if then fi

    判断符号[]类似于test.但是[]有通配符及正则表达式,为了区分,利用[]来做判断时,前后都需要加空格来区分.又一个坑 [ -z "$HOME" ];echo $? 例: 1 r ...

  9. 【扯淡篇】CTSC/APIO/SDOI R2时在干什么?有没有空?可以来做分母吗?

    注意: 我比较弱, 并没有办法把外链bgm搞成https, 所以大家可以选择"加载不安全的脚本"或者把https改成http以获得更好的阅读体验! 据说, 退役了要写写回忆录. 但 ...

  10. 【LeetCode】拓扑排序

    [207] Course Schedule 排课问题,n门课排课,有的课程必须在另外一些课程之前上,问能不能排出来顺序. 题解:裸的拓扑排序.参考代码见算法竞赛入门指南这本书. class Solut ...