Smali语法基础

  很多的Android应用都是用JAVA语言进行开发,最后都会将各种.java文件,res、assets等静态资源文件,和lib库等打包在一起,生成.apk文件,其中的java源代码变成了.dex文件。所以,在对某个app进行反编译后,apk中的classes.dex会变成.smali文件,因此我们需要学会分析smali代码才能大概猜到源码所表达的意思。

    

 

  其中,主要分析MainActivity$1.smali,它与MainActivity.smali最大的区别是,MainActivity.smali中不含有内部类,只是与onCreate()同级的其它方法或函数,而要分析内部类就只能去看MainActivity$1.smali。

  下面进行smali语法的总结:

(一)数据类型

  smali中的基本数据类型仅仅通过大写的首字母来表示。其中,long与boolean比较特殊,分别用J与Z表示。

  B---byte  C---char  D---double  F---float  I---int  J---long  S---short  V---void  Z---boolean 

  需要特殊记忆的两个:

  数组类型用 [XX 表示,在基本类型前加上左中括号 [ ,比如 [B 表示byte类型的数组。

  对象类型用 LpackageName/objectName 表示,比如 Ljava/lang/String 表示String对象,它所在的包是java.lang包。

(二)方法

  定义:Func-Name(Para-Type1Para-Type2Para-Type3...)Return-Type

  参数间没有逗号、空格等任何间隔,比如:

  Hello(ICF)V  表示:Void hello(int para1 , char para2 , float para3)

  Hello(Z[I[ILjava/lang/String;J)Ljava/lang/String;  表示String hello(boolean para1 , int [] , int[] , String para2 , long para3)

(三)关键字

  .field public/private [static][final] varname:类型  定义变量

  .method  方法

  .end method  方法结束

  .parameter/.param  方法参数

  .prologue   方法开始

  .line 123  此方法位于源码的第123行

  .locals 2  表示本方法中要用到2个本地寄存器v0,v1

  invoke-super  调用父函数,父函数会写在smali的顶部位置,如.super Landroid/app/Activity;

  invoke-direct  调用private函数

  invoke-virtual  调用public或protected函数

  invoke-static  调用静态函数

  const/high16  v0, 0x7fo3  把0x7fo3赋值给寄存器v0

  return-void  函数返回

  return-object  返回的是一个对象

  new-instance  创建实例

  iput/sput-object  对象赋值

  iget/sget-object  调用对象

  比如:sget-object v0, Lcom/main;->a:Ljava/lang/String  表示获取main类中,String类型,名为a的成员变量,并把它保存到寄存器v0中。

(四)条件跳转

  :cond_**代表代码块

  "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里的所有操作都必须经过寄存器来进行。

  本地寄存器:用v开头数字结尾的符号来表示,如v0,v1,v2…,用于方法内数值之间的传递;

  参数寄存器:用p开头数字结尾的符号来表示,如p0,p1,p2…,表示该方法依次接收过来的参数值。

  【注】p0不一定是函数中的第一个参数。在非static函数中,p0代指“this”,p1表示函数的第一个参数,p2代表函数中的第二个参数…而在static函数中p0才对应第一个参数。因为Java的static方法中没有this方法。

(六)实例

  

posted @ 2021-10-23 13:42  Sunshine_y  阅读(649)  评论(0编辑  收藏  举报