zoukankan      html  css  js  c++  java
  • Smail语法(1)

    【情景分析】Android apk,反编译之后,我们能阅读到的代码是 dalvik字节码 - smali 。有时候,工作需要,必须破解apk里面的一些协议或者方法。以此,借鉴经验,来开发自己的项目。

    【官方语法链接】 http://www.blogjava.net/midea0978/archive/2012/01/04/367847.html

    【语法】

    一. 数据类型

    原始类型:
    
    V void,只能用于返回值类型
    Z     boolean
    B	byte
    S	short
    C	char
    I	int
    J	long(64位)
    F	float
    D	double(64位)
    
    引用类型:
    
    对象 和 数组
    

     Smail表现形式

    原始类型:用大写字母代替即可,用法无异
    引用类型:   对象: L + 包名.对象 + ;       对象的表示则以L作为开头,格式是LpackageName/objectName;(注意必须有个分号跟在最后),例如String对象在smali中为:Ljava/lang/String;,其中java/lang对应java.lang包,String就是定义在该包中的一个对象。  
     数组:[ + 数据类型      数组的表示方式是:在基本类型前加上前中括号“[”,例如int数组和float数组分别表示为:[I、[F
          
         [I——表示一个整型一维数组,相当于java中的int[]。
    对于多维数组,只要增加[就行了。[[I相当于int[][],[[[I相当于int[][][]。注意每一维的最多255个。
    对象数组的表示:[Ljava/lang/String;表示一个String对象数组。

    二. 方法

     方法定义:

    表示形式:Lpackage/name/ObjectName;->MethodName(III)Z
    	Lpackage/name/ObjectName;表示类型,MethodName是方法名。III为参数(在此是3个整型参数),Z是返回类型(bool型)。
    	方法的参数是一个接一个的,中间没有隔开。

    一个更复杂的例子:

    method(I[[IILjava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;
    在java中则为:
    String method(int, int[][], int, String, Object[])

    内部类:

    既然类是用LpackageName/objectName;来表示,那类里面的内部类又如何在smali中引用呢?答案是:LpackageName/objectName$subObjectName;。也就是在内部类前加“$”符号
    

    字段:

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

    标记说明:

    # static fields             定义静态变量的标记
    # instance fields        定义实例变量的标记
    # direct methods       定义静态方法的标记
    # virtual methods      定义非静态方法的标记
    构造函数的返回类型为V,名字为<init>。
    

    语法:If语句

    if-eq p1, v0, :cond_8 表示如果p1和v0相等,则执行cond_8的流程:
        :cond_8
        invoke-direct {p0}, Lcom/paul/test/a;->d()V
    调用com.paul.test.a的d()方法
    if-ne p1, v0, :cond_b 表示不相等则执行cond_b的流程: :cond_b const/4 v0, 0x0 invoke-virtual {p0, v0}, Lcom/paul/test/a;->setPressed(Z)V invoke-super {p0, p1, p2}, Landroid/view/View;->onKeyUp(ILandroid/view/KeyEvent;)Z move-result v0 大概意思就是调用com.paul.test.a的setPressed方法,然后再调用父类View的onKeyUp方法,最后 return v0

      

    三. 寄存器(重点)

    概念:

    在dalvik字节码中,寄存器都是32位的,能够支持任何类型。64位类型(Long和Double型)用2个寄存器表示。
    有两种方式指定一个方法中有多少寄存器是可用的。

      .registers指令指定了方法中寄存器的总数。 [注意:一个方法内,不允许超过15个;如果超过15个,需要做特殊处理,处理方法找google大神,度娘]
      .locals指令表明了方法中非参寄存器的数量。

    命名方式

    有两种方式——V命名方式和P命名方式。P命名方式中的第一个寄存器就是方法中的第一个参数寄存器。在下表中我们用这两种命名方式来表示上一个例子中有5个寄存器和3个参数的方法。
    v0	第一个local register
    v1	第二个local register
    v2	p0	第一个parameter register
    v3	p1	第二个parameter register
    v4	p2	第三个parameter register
    你可以用任何一种方式来引用参数寄存器——他们没有任何差别。
    注意:baksmali默认对参数寄存器使用P命名方式。如果想使用V命名方式,可以使用-pl—no-parameter-registers选项。
    使用P命名方式是为了防止以后如果要在方法中增加寄存器,需要对参数寄存器重新进行编号的缺点。
    
    Long/Double值 Long和double类型是64位的,需要2个寄存器(切记切记)。 例如,对于非静态方法LMyObject;->MyMethod(IJZ)V,参数分别是LMyObject;,int,long,bool。故该方法需要5个寄存器来存储参数。 p0 this p1 I p2,p3 J p4 Z

    下篇文章继续。

  • 相关阅读:
    创建型模式
    react-React深入-一等公民-props-onChange
    [react] React 新手必须知道的 N 件事
    [react] 细数 React 的原罪
    创业一年,苟且偷生
    好书推荐-《人类简史》.md—/Users/zjh/Documents/我的文章/好书推荐-《人类简史》
    社会科学-主题阅读.md—/Users/zjh/Documents/我的文章
    好书推荐-《国富论》-15-09.md—/Users/zjh/Documents
    readme.md—/Users/zjh/Documents/我的文章/[PHP]swoole_server几个进程的分工
    [PHP]Yii2框架的坑.md—/Users/zjh/Documents/我的文章/[PHP]Yii2框架的坑
  • 原文地址:https://www.cnblogs.com/codeAnimal/p/4053858.html
Copyright © 2011-2022 走看看