精华内容
下载资源
问答
  • smalijava

    2017-10-17 16:54:41
    smali2java,通过apktool获得的smail文件,可通过该工具查看转化为java
  • smail语言java工具

    2020-08-28 17:20:36
    smali语言是Davlik的寄存器语言,语法上汇编语言相似,Dalvik VM与JVM的最大的区别之一就是Dalvik VM是基于寄存器的。基于寄存器的意思是,在smali里的所有操作都必须经过寄存器来进行。
  • Smali2Java

    2018-07-19 12:03:24
    java反编译的smali语言,转成java语言,算是比较好用的一个工具包
  • java_to_smali.bat

    2020-04-26 22:05:23
    该资源能够将java代码直接反编译为smali代码,方便进行smali语言学习修改,要求:(1)需要安装baksmali-2.4.0.jar,(2)拥有java环境
  • smali文件编译java文件

    2018-11-27 14:56:54
    smali2java是一个将smali代码反编译成java代码的工具。 什么是smalismali是将Android字节码用可阅读的字符串形式表现出来的一种语言,可以称之为Android字节码的反汇编语言。使用baksmali或apktool可以将Android...
  • java2smali

    千次阅读 2019-01-04 14:47:14
    Android Studio 下载 Java2Smail 插件: File——> Settings——> Plusigns 搜索 java2smali 点击下载,下载完成后 重启...选中要转换的java文件,build——&...如果想学习smali 语言的话,...

    Android Studio 下载 Java2Smail 插件:

    File——> Settings——> Plusigns    搜索 java2smali

    点击下载,下载完成后 重启Android Studio。

    使用:

    选中要转换的java文件,build——> Compile to samil 即可

     

    转换结果:

    如果想学习smali 语言的话,对比着来学习,比较高效。

    展开全文
  • smali2java——直接将smali转换成java

    千次阅读 2020-04-11 20:55:10
    主界面图 ...smali是将Android字节码用可阅读的字符串形式表现出来的一种语言,可以称之为Android字节码的反汇编语言。使用baksmali或apktool可以将Android应用程序包(apk或jar)反编译为smali...

    http://www.hensence.com/cn/smali2java/

    在这里插入图片描述
    主界面图

    smali2java是一个将smali代码反编译成java代码的工具。

    什么是smali?smali是将Android字节码用可阅读的字符串形式表现出来的一种语言,可以称之为Android字节码的反汇编语言。使用baksmali或apktool可以将Android应用程序包(apk或jar)反编译为smali代码。

    smali2java工具基于apktool v1.5.0(baksmali v1.3.4)生成的smali文件,依赖于smali文件中的代码行数(.line关键字)和变量别名(.local关键字)等信息,可以最大程度还原原始的java代码。还原出的java代码将具有原始的变量命名,代码的顺序也与原始的java代码保持一致。因此,本工具也具有局限性,仅适用于带有行数和变量别名信息的smali文件(java编译器的编译选项可以在生成的字节码中剔除这些信息)。

    smali2java使用了apktool将Android字节码文件转换为smali文件。界面显示中使用了CCrystalTextView(作者:Stcherbatchenko Andrei)作为java语法高亮显示控件,在此向这些软件或代码的作者表示感谢。

    使用工具:https://pan.baidu.com/s/1Cr1E4Cw7d_djRkU92R12kQ

    展开全文
  • Smali语言基础语法

    2021-06-29 13:53:19
    PS:如上图所示,Smali语言中的数据类型的关键词基本上为Java中同名数据类型的首字母大写,需要着重记忆的例外为:1.long类型的关键词为大写J;2.boolean类型的关键词为大写Z;3.数组的关键词为左半边中括号[;4....

    目录

     Smali前期知识

    可省略的关键字

     Smali注释

    Smali内部寄存器

    Smali全类名路径

    Smali基础(定义/声明)

    Smali数据类型

    Smali类声明

    Smali函数声明

    Smali函数返回关键字

    Smali构造函数声明

    Smali字段(变量)声明

    Smali字段(常量)声明

    Smali静态代码块

    Smali提高(调用/修改)

    Smali函数调用

    Smali字段取值与赋值

    Smali补充

    Smali对象创建

    Smali常量数据定义

    Smali字符串常量定义

    Smali字节码常量定义

    Smali数值常量定义

    Smali条件跳转

    Smali逻辑循环


     Smali前期知识

    可省略的关键字

    定义:因Smali语言实质为一种便于逆向java的语言,因此其中包含许多便于阅读者理解其对应java源码的关键字,这些关键字即使省略也不影响smali的语法逻辑。

    示例1:.line N关键字

    .line 3  
    const/4 v0, 0x1
    
    iput v0, p0, LTest;->a:I

    PS:.line N代表其下代码还原成java代码在源文件第N行 

    示例2:.prologue关键字

    .method public Test()V
        .registers N
        .prologue
    
        #do-something
    
        return-void
    .end method

    PS:.prologue代表函数的开始位置,其上为类似.registers的关键字,其下为函数逻辑。

    示例3:.local关键字

    move-result-object v0 # 调用方法后结果储存在v0中
    .local v0, "b":Ljava/lang/String;  # 局部变量v0别名为b 是一个String类型 也就是 String b=v0
    

    PS:.local关键字用于标识变量的别名与类型,在java中,一个变量会有一个类似i/j之类的变量名,并且对应的数据类型,而smali中数据都使用寄存器存储16进制数值,不存在这样的区分。因此使用.local关键字注明该变量的别名以及类型,方便理解。

     Smali注释

    定义:同其他编程语言,Smali语言中也存在用于标识注释的符号:#

    示例:注释示范

    # 这是一段注释

    Smali内部寄存器

    定义:同高级编程语言将数据存入内存时刻调用实现变量存储不同,smali语言类似汇编,将所有的变量和常量都使用寄存器存储。因此,为了在函数的开头便将需要用到的寄存器入栈(其他函数也会用到寄存器,先将寄存器中原本的值入栈,在使用完毕后出栈,以保证当前函数对寄存器的使用不会导致其他函数存储在寄存器中的值被破坏),在一个函数内部的变量个数应当尽量少,并且总数必须在函数的开头声明。

    格式:

    .registers 寄存器总数(包括参数)    #若函数包含参数,则参数占用的寄存器也计算在内
    .locals 寄存器总数(不包括参数)    #不考虑参数占用的寄存器

    示例:smali中的函数形式

    .method public callMe(II)V
        .registers 5
     	const-string v0,"1"
        const-string v1,"1"
       
       return-void
    .end method
    #或者
    .method public callMe(II)V
        .locals 2
     	const-string v0,"1"
        const-string v1,"1"
       return-void
    .end method

    PS1:如上代码段所示,使用.registers时需要考虑参数的格式,故其后的寄存器总数更多。

    PS2:以上callMe函数为非静态函数,因此对其的调用必须将其对应的类对象作为第一个参数传入,故以上callMe函数的参数实际上为三个,p0为类对象,p1为int,p2为int。

    PS3:寄存器名从v0~v15一共16个,不可使用超过16个寄存器!(若参数中同样使用了寄存器则对应减少)

    PS4:除非为abstract或final修饰的函数,否则.registers或.locals必须存在

    Smali全类名路径

    定义:在Smali中,常用到一个称为‘全类名路径’的概念,此概率意味着将一个类的类名以绝对路径的形式给出

    示例:在com包下的Test类

    Lcom/Test;

    PS:如上,当需要使用Test类的‘全类名路径’时,将com.Test改写为com/Test,并在首部加上L,在末尾加上;

    JAVA——APK——Smali转换

    定义:转换过程:.java文件(java源码)=>.class文件(字节码文件)=>.dex文件(构成apk的文件)=>.smali文件

    示例1:smali——java关系图

    示例2:java编译为APK

    对于用Java编写的Android程序,其转换过程为.java文件(java源码)=>.class文件(字节码文件)=>.dex文件(构成apk的文件)。

    PS:.dex文件类似.class文件,是一种底层的,方便机器理解与运行的文件,要逆向修改一个APK可以通过直接修改dex文件实现,但是其难度较高。

    示例3:APK反编译为smali文件包

    对一个apk进行反编译即对构成apk的.dex文件包进行反编译,使用baksmali.jar可实现:.dex文件=>.smali文件。每个.smali文件实质上对应一个.java文件,对.smali文件进行修改后使用smali.jar可实现:.smali文件=>.dex文件。

    PS:.smali文件是由smali语言书写的代码文件,而smali语言和java语言几乎具有一一对应的关系。相对来说易于理解、修改、书写。通过smali语言作为中转,可以实现反编译并修改一个APK。

    Smali基础(定义/声明)

    Smali数据类型

    定义:与Java相同,Smali中也有一套数据类型体系,且该体系实质上是同Java一一对照的。

    示例1:Smali——Java数据类型对照表

    PS:如上图所示,Smali语言中的数据类型的关键词基本上为Java中同名数据类型的首字母大写,需要着重记忆的例外为:1.long类型的关键词为大写J;2.boolean类型的关键词为大写Z;3.数组的关键词为左半边中括号[;4.object类型(各种类)的关键词为大写L加上该类的全类名路径,路径中的层级用/分割。

    示例2:smali——java变量定义对照

    byte _byte=127;
    short _short=888;
    int _int=1234;
    long _long=786565455;
    float _float=347823.99f;
    double _double=6875654564.121;
    char _char='易';
    boolean _bool=true;
    
    const/16 v1, 0x7f
    .local v1, "_byte":B
    
    const/16 v3, 0x378
    .local v3, "_short":S
    
    const/16 v6, 0x4d2
    .local v6, "_int":I
    
    const-wide/32 v4, 0x2ee2094f
    .local v4, "_long":J
    
    const v7, 0x48df8c00
    .local v7, "_float":F
    
    const-wide v8, 0x41f99d229a41ef9eL
    .local v8, "_double":D
    
    const/16 v2, 0x6613
    .local v2, "_char":C
    
    const/4 v0, 0x1
    .local v0, "_bool":Z
    

    PS1:如上代码段2,其中const/16 v1, 0x7f    .local v1, "_byte":B这两句对应代码段1中的byte _byte=127;第一句const/16 v1, 0x7f意为将常量0x7f存入v1寄存器,在其中占用16位字节;第二句.local v1, "_byte":B意为将v1寄存器的别名定为_byte,并确定其数据类型为B(在smali中数据类型B对应java中的数据类型byte)

    PS2:根据PS1中的逻辑递推,每两句smali中的变量定义代码对应一句java中的变量定义代码。

    PS3:对于以上代码段2中以v0~v7命名的各寄存器,可见到其中缺失了v5寄存器,其原因为代码段:const-wide/32 v4, 0x2ee2094f    .local v4, "_long":J中J类型(long类型)的数据占用64位字节,因此需要两个寄存器才可完整存放,由此实质上v4、v5寄存器在此处都被占用了,只不过此时保存在其中的数据较小用不到v5寄存器,此处才未写出,若数值增大,则此处的代码中会出现对v5寄存器的使用,同理v9寄存器也在使用v8寄存器的同时被使用了。

    Smali类声明

    定义:在Smali中声明一个类的意义同Java,但Smali会将Java中省略的一些步骤显现出来,因此其更为繁琐、底层。

    基础格式:

    .class+权限修饰符+类名;

    示例:Smali——Java类声明对照

    public class Test implements CharSequence
    {
    }
    .class public LTest;    #声明类(不可省略)
    .super Ljava/lang/Object;    #声明该类所继承的父类,同Java,若没有指定其他父类,则所有类的父类都是Object(不可省略)
    .implements Ljava/lang/CharSequence;    #若该类实现了接口,则添加该代码(视情况可省略)
    .source "Test.java"    #反编译的过程中自动生成的标识该smali类对应的java源码类的标识,无实际作用(可省略)

    PS:如上代码块,在Smali中定义一个类时必须将该类所有的信息完整表现,且该类的类名、继承的类名、实现的类名都要用L+全类名路径+分号的格式给出,以上Test类若非定义与根目录而是定义于com.temp包内,则全类名要用Lcom/temp/Test;的格式。

    Smali函数声明

    定义:在Smali中声明一个函数的内核通Java,但表现方式略有不同。

    格式:

    .method 权限修饰符+静态修饰符+方法名(参数类型)返回值类型
        #方法体
    .end method

    示例1:Smali——Java函数(无参无返回值)声明对照

    public class Test
    {
        public static void getName(){}
    }
    .class public LTest;
    .super Ljava/lang/Object;
    .source "Test.java"
    
    .method public static getName()V
        return-void
    .end method

    PS:如上代码段所示,在Smali中的函数不以大括号结束而以.end method结束。且即使返回值为void也必须使用return-void进行返回

    示例2:Smali——Java函数(带参带返回值)声明对照

    public class Test
    {
        public static String getName(String a,int b){
            return "hello"
        }
    }
    .class public LTest;
    .super Ljava/lang/Object;
    .source "Test.java"
    
    .method public static getName(Ljava/lang/String;I)Ljava/lang/String;
        const-string v0, "hello"
        return-object v0
    .end method

    PS:如上代码段所示,当函数带参数时将参数在函数声明头中列出,各参数间不需要分隔符

    PS:如上代码段所示,当函数带返回值时,将对应类型的值通过寄存器返回。

    Smali函数返回关键字

    定义:不同于Java,在Smali中,不同的函数返回类型需要使用不同的返回关键字

    示例:函数返回关键字类别及数据类型对照表

    PS:如上图1所示,smali中总共分为四种函数返回关键字。如上图2所示,对于不同的数据类型,使用不同的函数返回关键字

    PS2:如上图2,long、double为64位数据类型,因此需要使用return-wide关键字,而其他基本数据类型为32位及以下,只需要使用return。对于空类型使用return-void。而对于大小未知的数组及object,则使用return-object。

    Smali构造函数声明

    定义:构造函数的声明类同函数的声明,但在几个地方有其独特性。

    格式:

    .method+权限修饰符+constructor <init>(参数类型)返回值类型
        #方法体
    .end method

    示例:Smali——Java构造函数对照

    public class Test
    {
        public Test(String a){
        }
    }
    .class public LTest;
    .super Ljava/lang/Object;
    .source "Test.java"
    
    .method public constructor <init>(Ljava/lang/String;)V
        invoke-direct {p0},Ljava/lang/Object;-><init>()V #调用父类(Object)的构造函数
        return-void
    .end method

    PS:如上代码段,构造函数的声明与普通函数声明的区别在于:1.必须加constructor修饰符;2.函数名必须为<init>;3.函数中必须调用父类的构造函数(java的构造函数中默认会调用父类的构造函数,但在代码中可以省略,而在Smali中不能省略)。

    Smali字段(变量)声明

    定义:在Smali中声明一个字段(变量)的方式类似Java。

    格式:

    .field 权限修饰符+静态修饰符+变量名:变量全类名路径;

    示例:Smali——Java字段声明对照

    public class Test
    {
        private static String a;
    }
    .class public LTest;
    .super Ljava/lang/Object;
    .source "Test.java"
    
    .field private static a:Ljava/lang/String;    #声明一个String类的对象,命名为a

    PS:如上代码段所示,在一个类中声明变量

    Smali字段(常量)声明

    定义:在Smali中声明一个字段(常量)的方式几乎同声明一个字段(变量)。

    格式:

    .field 权限修饰符+静态修饰符+final+常量名:常量全类名路径;=常量值

    示例:Smali——Java常量声明对照

    public class Test
    {
        private static final String a="hello";
    }
    .class public LTest;
    .super Ljava/lang/Object;
    .source "Test.java"
    
    .field private static final a:Ljava/lang/String;="hello"    #声明一个String类的常量对象,命名为a,赋值为"hello"

    PS:如上代码段所示,在一个类中声明常量

    Smali静态代码块

    定义:在Smali中同样可声明静态代码块,其声明方式类同构造函数的声明。

    格式:

    .method+static+constructor <clinit>()V
        #方法体
    .end method

    示例1:Smali——Java静态代码块对照

    public class Test
    {
        static{}
    }
    .class public LTest;
    .super Ljava/lang/Object;
    
    .method public static constructor<clinit>()V
        return-void
    .end method

    PS:如上代码块所示,静态代码块的声明同构造函数的声明的区别在于:1.增加了static修饰符;2.函数名改为了<clinit>;3.无参数;4.返回类型固定为void

    示例2:Smali静态字段声明位置

    public class Test
    {
        public static String a="a";
        static{}
    }
    .class public LTest;
    .super Ljava/lang/Object;
    
    .method public static constructor<clinit>()V
        .field public static a:Ljava/lang/String;="a"
        return-void
    .end method

    PS:如上代码块所示,当类中声明了静态的字段时,该字段的声明必须于静态代码块中进行,因该字段属于类而非对象,且静态代码块在构造函数之前被执行。

    Smali提高(调用/修改)

    Smali函数调用

    定义:在Smali中调用方法的函数与Java中略有区别,对于不同的函数使用了不同的调用关键字

    格式:

    invoke-virtual    #非私有实例函数的调用
    invoke-direct    #构造函数以及私有函数的调用
    invoke-static    #静态函数的调用
    invoke-super    #父类函数的调用
    invoke-interface    #接口函数的调用

    示例1:非私有实例函数的调用

    invoke-virtual {参数},函数所属类名;->函数名(参数类型)返回值类型;
    public class Test
    {
        public Test(String a){
            getName();
        }
        public String getName(){
            return "hello";
        }
    }
    .class public LTest;
    .super Ljava/lang/Object;
    
    .method public constructor<init>(Ljava/lang/String;)V
        invoke-direct{p0},Ljava/lang/Object;-><init>()V    #调用父类的构造函数
        invoke-virtual{p0},LTest;->getName()Ljava/lang/String;    #调用普通成员getName函数
        return-void
    .end method
    
    .method public getName()Ljava/lang/String;
        const-string v0,"hello"    #定义局部字符串常量
        return-object v0    #返回常量
    .end method

    PS:以上代码段中定义的getName函数是没有参数的,但是在调用该函数时却传入了一个参数p0,该p0参数实质上为类的对象,即java中的this。因被调用的getName函数非静态函数,因此在使用该函数时必须传入一个this作为参数,而这一步在java中被默认执行,故书写代码时常被省略。

    示例2:构造函数以及私有实例函数的调用

    invoke-direct {参数},函数所属类名;->函数名(参数类型)返回值类型;
    public class Test
    {
        public Test(String a){
            getName();
        }
        private String getName(){
            return "hello";
        }
    }
    .class public LTest;
    .super Ljava/lang/Object;
    
    .method public constructor<init>(Ljava/lang/String;)V
        invoke-direct{p0},Ljava/lang/Object;-><init>()V    #调用父类的构造函数
        invoke-direct{p0},LTest;->getName()Ljava/lang/String;    #调用私有成员getName函数
        return-void
    .end method
    
    .method private getName()Ljava/lang/String;
        const-string v0,"hello"    #定义局部字符串常量
        return-object v0    #返回常量
    .end method

    PS:如以上代码段所示,对于私有函数以及构造函数,只需更改调用关键词。

    示例3:静态函数的调用

    invoke-static {参数},函数所属类名;->函数名(参数类型)返回值类型;
    public class Test
    {
        public Test(String a){
            String b=getName();
        }
        private static String getName(){
            return "hello";
        }
    }
    .class public LTest;
    .super Ljava/lang/Object;
    
    .method public constructor<init>(Ljava/lang/String;)V
        invoke-direct{p0},Ljava/lang/Object;-><init>()V    #调用父类的构造函数
        invoke-static{},LTest;->getName()Ljava/lang/String;    #调用私有成员getName函数
        move-result-object v0    #将返回值赋给v0
        return-void
    .end method
    
    .method private getName()Ljava/lang/String;
        const-string v0,"hello"    #定义局部字符串常量
        return-object v0    #返回常量
    .end method

    PS:如以上代码段所示,对于静态函数的调用,不需要传入this,因此不需要p0参数。

    示例4:父类成员函数的调用

    invoke-super {参数},函数所属类名;->函数名(参数类型)返回值类型;
    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
    }
    .method protected onCreate(Landroid/os/Bundle;)V
        .registers 2
        
        invoke-super{p0,p1},Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V
        return-void
    .end method

    PS:如以上代码段1所示为安卓开发中常见的onCreate函数,该函数在smali中的表现形式如上代码段2。

    示例5:接口函数的调用

    invoke-interface {参数},函数所属类名;->函数名(参数类型)返回值类型;
    public class Test
    {
        private InterTest a=new Test2();
        public Test(String a){}
        public void setAa(){
            InterTest aa=a;
            //调用接口方法
            aa.est2();
        }
        public class Test2 implements InterTest
        {
            public Test2(){}
            public void est2(){}
        }
        interface InterTest
        {
            public void est2();
        }
    }
    .method public setAa()V
        .registers 2
        iget-object v0,p0,LTest;->a:LTest$InterTest;
        #调用接口方法
        invoke-interface{v0},LTest$InterTest;->est2()V
        return-void
    .end method

    PS:如以上代码段1所示为java中调用一个接口内的函数,如上代码段2为调用接口函数的核心代码,接口定义等代码暂略。

    Smali字段取值与赋值

    定义:在Smali中为此前声明的字段进行取值与赋值操作,其中若该字段非静态字段,则赋值时需额外传入该字段对应的对象作为参数。

    格式:

    iput 存储值的寄存器,对象全类名路径->字段名:字段类型全类名路径    #静态字段
    iput 存储值的寄存器,存储字段的对象,对象全类名路径->字段名:字段类型全类名路径    #字段
    iget 存储值的寄存器,对象全类名路径->字段名:字段类型全类名路径    #静态字段
    iget 存储值的寄存器,对象全类名路径->字段名:字段类型全类名路径    #字段

    示例1:Smali基本数据类型取值赋值关键字表

    PS:对于不同的数据类型,对其进行取值/赋值时需要使用不同的关键字

    示例2:Smali实例变量取值赋值关键字表

    PS:示例对象基本使用object后缀进行取值/赋值

    示例3:smali——java取值赋值对照

    public class Test
    {
        private  String a="hello";
        public Test(String a){
        }
        public String getA(){
           String aa=a;
       }
    }
    .class public LTest;#声明类 (必须)
    .super Ljava/lang/Object;#声明父类 默认继承Object (必须)
    .source "Test.java" # 源码文件 (非必须)
    
    # 声明静态字段
    .field private static a:Ljava/lang/String;
    
    #构造方法
    .method public constructor <init>(Ljava/lang/String;)V
        .registers 3
    
        .prologue
    
        invoke-direct {p0}, Ljava/lang/Object;-><init>()V
    
        const-string v0, "hello"
    	# 初始化成员变量
        iput-object v0, LTest;->a:Ljava/lang/String;
    
        return-void
    .end method
    
    
    # 取值方法
    .method public getA()Ljava/lang/String;
        .registers 2
    
    	# 类非静态字段取值
        iget-object v0, LTest;->a:Ljava/lang/String;
        return-object v0
    .end method

    PS:如上,为静态方法的取值与赋值。

    Smali数组的取值与赋值

    定义:在Smali语法中,对数组元素进行操作有其专有方法

    格式:

    aput 存储值的寄存器,存储数组的寄存器,存储数组下标的寄存器
    aget 存储值的寄存器,存储数组的寄存器,存储数组下标的寄存器

    示例:

    invoke-virtual {v1, v0}, Ljava/security/MessageDigest;->digest([B)[B
    move-result-object v0
    const/16 v4,47
    const/16 v5,0
    aput-byte v4,v0,v5
    aget-byte v3,v0,v5
    

    PS:如上,先将一个数字45从v4中存入字节数组的第0位,后从中将之取出放入v3。

    Smali补充

    Smali对象创建

    定义:Smali语言的内核同Java,同样拥有对象的创建方式

    格式:

    new-instance+对象名,对象全包名路径;    #声明实例
    invoke-direct{变量名},对象全包名路径;-><init>(参数)返回类型    #调用构造函数(若构造函数内还定义了成员变量,则在调用之前需要提前声明该变量并在invoke时作为参数一并传入)

    示例:Smali——Java对象创建对照

    Test _test=new Test();
    new-instance v0,LTest;
    invoke-direct {v0},LTest;-><init>()V

    PS1:如上代码段所示为在Smali中建立对象的方式,但注意此处只是建立了对象并将之存入寄存器,并未给对象命名

    PS2:如上代码段2所示,在创建对象并调用其构造函数时,需要将该对象作为参数传入。

    Smali常量数据定义

    定义:在Smali语言中,函数返回或函数调用等处若需使用常量,应当如同使用变量一般先行将之定义并存入寄存器中,后方可使用。

    Smali字符串常量定义

    定义:字符串常量的定义方式

    格式:

    const-string 常量名,"字符串内容"

    示例:Smali中定义字符串常量并将之作为函数返回值

    .class public LTest;
    .super Ljava/lang/Object;
    
    .method public static getHello()Ljava/lang/String;
        .registers 1    #该函数总共使用了1个寄存器
        const-string v0,"hello"    #定义字符串常量
        return-object v0    #将字符串常量作为返回值
    .end method

    PS:如上代码段所示,定义一个"hello"字符串存入寄存器,命名为v0,并将之作为返回值返回(因字符串为Object类型的数据,因此使用return-object)

    Smali字节码常量定义

    定义:字节码常量的定义方式

    格式:

    const-class 常量名,类全包名路径;

    示例:Smali——Java定义字节码常量对照

    Class a=TestClass.class
    const-class v0,LTestClass;

    PS:如上代码段所示,class类型的常量定义

    Smali数值常量定义

    定义:Smali中的数值常量定义相对复杂,根据数值的类别、大小需使用多种定义关键字。

    格式:

    const 寄存器,数值 #占用一个寄存器(32位)
        const/4    #占用一个寄存器中的低4位(最高位为符号位)
        const/16    #占用一个寄存器中的低16位(最高位为符号位)
        const    #占用一个寄存器中全部32位(最高位为符号位)
        const/high16    #占用一个寄存器中的16位,且只将数据的高16位存入(最高位为符号位)
    const-wide 寄存器,数值 #占用两个寄存器(64位)
        const-wide/16    #占用两个寄存器的同时只使用第一个寄存器的低16位
        const-wide/32    #占用两个寄存器的同时只使用第一个寄存器的32位
        const-wide    #占用两个寄存器的同时只使用两个寄存器的全部64位
        const-wide/high16    #占用两个寄存器的同时只使用第一个寄存器的16位,且只将数据的高16位存入
    

    示例:Smali——Java定义数值常量对照

    int i=100;
    long j=10000;
    const/16 v0,64   
    const-wide v1,2710

    PS:smali语言中数值默认为16进制

    Smali条件跳转

    定义:Smali中同样有类似if-else结构的条件跳转语句,其逻辑类似汇编中的条件跳转。

    格式:

    if-eq vA, vB, :cond_**  #如果vA等于vB则跳转到:cond_** equal
    
    if-ne vA, vB, :cond_**  #如果vA不等于vB则跳转到:cond_**   not  equal
    
    if-lt vA, vB, :cond_**  #如果vA小于vB则跳转到:cond_**    less than
    
    if-ge vA, vB, :cond_**  #如果vA大于等于vB则跳转到:cond_**   greater equal
    
    if-gt vA, vB, :cond_**  #如果vA大于vB则跳转到:cond_**   greater than
    
    if-le vA, vB, :cond_**  #如果vA小于等于vB则跳转到:cond_**  less equal
    
    if-eqz vA, :cond_**  #如果vA等于0则跳转到:cond_** zero
    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——Java条件跳转对照

    public class Test {
        public static void main(String[] args) {
            int a=2;
            if(a>1){
                //do-something
            }
        }
    }
    .method public static main([Ljava/lang/String;)V
    
        const/16 v0,0x2
        const/4 v1, 0x1
        if-le v0,v1,:cond_0
            #do-something
        :cond_0
        return-void
    .end method

    PS:如上所示,可以看到因smali中的条件跳转同汇编逻辑相似,因此实现同样的效果时其if判定条件实际上同java中是相反的。

    Smali逻辑循环

    定义:Smali中同样有类似for结构的逻辑循环语句,其逻辑类似汇编中的jmp。

    格式:

    goto :cond_**  #跳转到:cond_**

    示例:Smali——Java逻辑循环对照

    public class Test {
        public static void main(String[] args) {
       
            for(int i=0; i<3;i++){
            }
        }
    }
    .method public static main([Ljava/lang/String;)V
    
        const/4 v0, 0x0
    
        :goto_1
        const/4 v1, 0x3
    
        if-ge v0, v1, :cond_7
    
        add-int/lit8 v0, v0, 0x1 # 加法运算符 v0=v0+0x1
    
        goto :goto_1
    
        :cond_7
        return-void
    .end method

    PS:如上所示,通过if-ge配合goto实现条件循环。

    展开全文
  • smalidea是 / 的smali语言插件 目前这是非常试验性的,您可能会遇到问题。 消息 2021-03-02-v0.06已发布。 对于现代版本的IDEA / Android Studio,这使smalidea恢复到鼻烟 强制更新与该插件关联的smali文件类型,而...
  • Smali语言入门

    千次阅读 2018-07-11 09:35:17
    工欲善其事必先利其器,所以想做好一件事情,务必准备一个好的工具。  这里推荐Java2Smali这个UI工具,CSDN里面搜得到... 这个时候还需要一个工具叫Smali2Java这个工具,他可以直接将smali解释成Java。所以整个过程...

        工欲善其事必先利其器,所以想做好一件事情,务必准备一个好的工具。

        这里推荐Java2Smali这个UI工具,CSDN里面搜得到。

        首先 了解一下什么是Smali,相信玩过逆向的朋友,使用ApkTool反编译AP后打开Src目录里面全部都是.smali文件。

        这个时候还需要一个工具叫Smali2Java这个工具,他可以直接将smali解释成Java。所以整个过程中我们都没怎么留意它,这边之所以提及它是应为如果能够使用静态分析的方式直接修改smali文件,就可以省去反编译又回编译的繁琐过程,有时候工具也不是万能的,他也会崩溃,效果也会差强人意,多说无益,自己体会就知道了。

        这边直接使用J2S2J v13 这个是吾爱破解上面的发布的一个Smali Java互转GUI工具,有了这个你的学习将事半功倍。

    先上段代码

    public class Test {
        public static void main(String[] args) {
            System.out.println("Hello World!");
        }
    }

    经过转换

    .class public LTest;
    .super Ljava/lang/Object;
    .source "Test.java"
    
    # direct methods
    .method public constructor <init>()V
        .registers 1
    
    
        .prologue
        .line 1
        invoke-direct {p0}, Ljava/lang/Object;-><init>()V
    
    
        return-void
    .end method
    
    
    .method public static main([Ljava/lang/String;)V
        .registers 3
    
    
        .prologue
        .line 3
        sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;
    
    
        const-string v1, "Hello World!"
    
    
        invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
    
    
        .line 4
        return-void
    .end method

     

    首先 申明文件名 类名 以及 他的父类

    .class public LTest;
    .super Ljava/lang/Object;
    .source "Test.java"

    这个当然是构造函数了

    # direct methods
    .method public constructor <init>()V
        .registers 1
    
    
        .prologue
        .line 1
        invoke-direct {p0}, Ljava/lang/Object;-><init>()V
    
    
        return-void
    .end method
    

     

    关于 direct methods 和 virtual methonds 

     

    invoke-virtual 或 invoke-virtual/range 调用实例的虚方法
    invoke-super 或 invoke-super/range 调用实例的父类方法
    invoke-direct 或 invoke-direct/range 调用实例的直接方法

    也就是说direct是该Java文件中的方法

    而virtual则是其父类中的override方法

    而super则是其父类中的protected方法(没有被重写)

    https://www.cnblogs.com/larrylawrence/p/3985464.html

    关于init 和client的区别 就是static的区别了 

    http://www.cnblogs.com/diyunpeng/archive/2010/07/11/1775200.html

    这里的V是Void的意思 这里有一些基本的参数类型

    1、原始类型
    V void (只能用于返回值类型) 
    Z boolean
    B byte
    S short
    C char
    I int
    J long(64位)
    F float
    D double(64位)

    https://blog.csdn.net/hp910315/article/details/51823236

    关于 registers  prologue

    .locals 局部变量个数 
    .parameter 参数个数,每条指令声明一个参数 
    .prologue 代码开始 
    .line 行号

    https://blog.csdn.net/junjunyanyan/article/details/45726775

    现在看看main函数

    .method public static main([Ljava/lang/String;)V
        .registers 3
    
        .prologue
        .line 3
        sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;
    
        const-string v1, "Hello World!"
    
        invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
    
        .line 4
        return-void
    .end method

    第一行 .method 申明方法 还是可以查看这里 https://blog.csdn.net/lostinai/article/details/48975661

    sget-object  这是获取指令 获取out这个实例存入寄存器v1当中 可参考 https://www.cnblogs.com/linwx/p/7965893.html

    1.sget-object v0, Lcom/aaa;->ID:Ljava/lang/String;
    sget-object就是用来获取变量值并保存到紧接着的参数的寄存器中
    本例中,它获取ID这个String类型的成员变量并放到v0这个寄存器中。

    当中有一段写的特别好 那么这个p0在构造函数中也就是this的意思。

    三.寄存器
      本地寄存器用v开头数字结尾的符号来表示,如v0、v1、v2、...
    
      参数寄存器则使用p开头数字结尾的符号来表示,如p0、p1、p2、...
    
    注意:p0不一定是函数中的第一个参数,在非static函数中,p0代指“this”,p1表示函数的第一个参数,p2代表函数中的第二个参数…而在static函数中p0才对应第一个参数(因为Java的static方法中没有this方法。      
    
    简单分析:
    const/4 v0, 0x1
    iput-boolean v0, p0, Lcom/aaa;->IsRegistered:Z
    上面两句smali代码,首先使用本地v0寄存器,并将0x1存到v0中,然后第二句用iput-boolean这个指令把v0中的值存放到com.aaa.IsRegistered这个成员变量中。
    
    相当于:this.IsRegistered=v0;

    最后的输出语句即为:v0 代表 out  v1 代表 字符串“hello world” 我们可以这样理解v0代表实例 后面统一为参数。

    invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V

    这边我们具体研究 该方法

    public class Test {
        public static void main(String[] args) {
            Test test = new Test();
            test.getname("12",22);
        }
        public  void getname(String age ,int nice){
    
        }
    }

    编译之后生成smail代码

    .class public LTest;
    .super Ljava/lang/Object;
    .source "Test.java"
    
    
    # direct methods
    .method public constructor <init>()V
        .registers 1
    
        .prologue
        .line 1
        invoke-direct {p0}, Ljava/lang/Object;-><init>()V
    
        return-void
    .end method
    
    .method public static main([Ljava/lang/String;)V
        .registers 4
    
        .prologue
        .line 4
        new-instance v0, LTest;
    
        invoke-direct {v0}, LTest;-><init>()V
    
        .line 
        const-string v1, "12"
    
        const/16 v2, 0x16
    
        invoke-virtual {v0, v1, v2}, LTest;->getname(Ljava/lang/String;I)V
    
        .line 6
        return-void
    .end method
    
    
    # virtual methods
    .method public getname(Ljava/lang/String;I)V
        .registers 3
    
        .prologue
        .line 9
        return-void
    .end method

    看下面这里  :

    v0 存Test实例

    v1 存字符串“12”

    v2 存 22 也就是0x16

    关于 invoke-virtual 和 invoke-direct 上面做过解释,可能理解有误 暂时当一个意思。

    这里涉及到一些基本语法直接粘贴出来

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

     

    new-instance v0, LTest;
    
        invoke-direct {v0}, LTest;-><init>()V
    
        .line 
        const-string v1, "12"
    
        const/16 v2, 0x16
    
        invoke-virtual {v0, v1, v2}, LTest;->getname(Ljava/lang/String;I)V

    这个就好理解了 即:调用v0(test)的getname函数 参数为v1 v2

    参数用;隔开 分别为String 和 int 类型,返回值为空。

    # virtual methods
    .method public getname(Ljava/lang/String;I)V
        .registers 3
    
        .prologue
        .line 9
        return-void
    .end method

    给出smail基本类型 https://blog.csdn.net/lpohvbe/article/details/7981386

     一、smali的数据类型
    
    在smali中,数据类型和Android中的一样,只是对应的符号有变化:
    
    B---byte
    C---char
    D---double
    F---float
    I---int
    J---long
    S---short
    V---void
    Z---boolean
    [XXX---array
    Lxxx/yyy---object

     

     

     

     

    展开全文
  • Smali2Java1.0.0.558

    2018-10-19 11:18:15
    注:当前是1.0.0.558 官方版...smali是将Android字节码用可阅读的字符串形式表现出来的一种语言,可以称之为Android字节码的反汇编语言。使用baksmali或apktool可以将Android应用程序包(apk或jar)反编译为smali代码。
  • Android逆向不可不知的smali语言

    千次阅读 2019-11-12 09:49:02
    smali语言比较简单,如果你会java和Android相关知识,就可以通过修改smali语言来改变java的代码,进而可以修改apk文件。 2.smali语法 前三行指明了类名,父类名,和源文件名。 类名以“L”开头相信熟悉Jni的...
  • 与安卓应用相关的文件类型有许多,他们之间通过编译、反编译可以互相转换,下面总结...逆向的过程一般是:输入apk---apktool解析为smali和dex---dex2jar转换为jar---使用jd-gui查看java代码 这些文件的关系如图: ...
  • java生成smali

    2018-05-10 12:28:10
    Smali是Android系统中Dalvik虚拟机指令语言 java代码转smali代码 第一步:生成class文件 javac Demo.class 第二步:class转成dex文件,android-sdk\build-tools\xx.xx.xx\lib下提供了dx工具。 java -jar dx....
  • 1、Smali中的包信息 .class <访问权限> [修饰关键字] <类名> .super <父类名> .source <....source "ccc.java" ...该smali文件是由ccc.java编译而来的,它是com.aaa这个包下的一个类,...
  • Smali2Java.7z

    2020-05-16 12:20:40
    可以反编译apk变成java代码,...smali是将Android字节码用可阅读的字符串形式表现出来的一种语言,可以称之为Android字节码的反汇编语言。使用baksmali或apktool可以将Android应用程序包(apk或jar)反编译为smali代码
  • Smali to JAVA

    2018-06-26 19:06:49
    smali to java这个软件能够使安卓的smali语言变成可读的JAVA语言,使用方便,适合初学者使用。
  • 反编译入门,主要对.smali文件解析,并与java语言做对比
  • 1、概述 Smali是Android系统中Dalvik虚拟机指令语言,在apk逆向过程中有许多...但是在学习Smali语法的过程中,有时候需要进行java代码和smali代码的对照,如果可以把java代码转换成smali代码,学习起来岂不是很...
  • 从网站看的信息发现其存在一定的局限性没有 行数变量名的smali 文件 我们就看不到Java 源码了、工具用起来也简单,加压执行exe 文件 打开我们的 apk 包就好。   3.dex2jar jd-gui 这两个工具要配合使用...
  • android 逆向工程apktool dex2jar jd-gui Jadx Smali2Java app安全–签名校验: (签名只是对完整性签名发布机构的校验机制,不能阻止 Apk 被修改,只是签名无法保持一致 不同私钥对应着不同的公钥,实质上不同的...
  • Android逆向——初识smalijava

    千次阅读 2018-05-22 20:01:12
    请学好smali代码,对之后的学习有很大的帮助,当然也在这里等待你们回来复习 很多人都问学逆向需不需要有编程基础?需要是需要一点吧,只要最基础的就可以了。当然建议在学逆向的时候一起学习编程。 0x00 前言 ...
  • .method public md5(Ljava/lang/String;)Ljava/lang/String; .locals 13 .param p1, "s" # Ljava/lang/String; ... new-instance v11, Ljava/lang/StringBuilder;... {:try_start_0 ......end method
  • smali语言入门 操作流

    千次阅读 2018-07-11 15:38:40
    经过前面的基础 案例已经初步掌握了smali https://blog.csdn.net/qq_20330595/article/details/80979939 这边我们上点有意思的代码(俗称:解忧程序员)相信大家看了这个都有小激动了吧? 上代码先 我们将学到...
  • assets: 资源目录1,assets res 都是资源目录但有所区别: res 目录下的资源文件在编译时会自动生成索引文件(R.java),在Java代码中用R.xxx.yyy来引用; 而asset 目录下的资源文件不需要生成索引,在Java 代码...
  • 注意编程语言选择java,自己设定Name程序最低要求的Android的SDK版本 构建项目如下: 为我们的应用程序选择一个虚拟的手机,这里我选择pixel2api level 27,system image x86的Orea的Android8,并下载。 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,056
精华内容 822
关键字:

java语言和smali语言

java 订阅