首页
社区
课程
招聘
[旧帖] [原创]自己动手学习smali语法一 0.00雪花
发表于: 2016-4-28 13:25 2614

[旧帖] [原创]自己动手学习smali语法一 0.00雪花

2016-4-28 13:25
2614
该文的csdn地址953K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3u0D9L8$3N6Q4x3X3g2U0M7$3c8F1i4K6u0W2L8X3g2@1i4K6u0r3N6e0l9I4x3U0b7I4y4K6x3^5x3q4)9J5c8X3q4J5N6r3W2U0L8r3g2Q4x3V1k6V1k6i4c8S2K9h3I4K6i4K6u0r3y4e0p5J5y4U0t1$3x3K6b7`.
#一、什么是smali  
   Android程序员用Java语言开发APP,编译工具会将Java源文件(.java)编译成Dalvik可执行文件(.dex)。Android系统中Dalvik Virtual Machine 会执行该文件。[smali/baksmali](e3bK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6v1k6i4y4#2M7@1k6J5k6h3E0W2i4K6u0r3M7$3#2S2L8r3W2Q4x3U0W2Q4c8e0g2Q4z5o6S2Q4z5e0W2Q4c8e0k6Q4z5e0S2Q4b7f1k6p5j5h3I4$3K9h3D9`. VM可执行文件的汇编器/反汇编器。反汇编Dalvik可执行文件(.dex)后,将会得到.smali后缀文件。smali代码拥有特定的语法。
   相比于.dex文件,smali文件的语法更容易理解些。下面是.dex文件、.smali文件、.java文件三者之间的转化关系。
   ![这里写图片描述](113K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3W2E0k6#2)9J5k6h3u0D9L8$3N6Q4x3X3g2U0M7$3c8F1i4K6u0W2L8X3g2@1i4K6u0r3x3U0l9I4y4U0l9@1x3U0M7I4y4U0x3#2x3e0j5I4x3K6p5`.)
   其中.dex文件和.smali文件可以通过smali/baksmali工具进行相互转换。而.smali文件无法完整转化成.java文件,可能是由于Android SDK 中dx工具将.java文件的字节码.class文件转换成.dex文件的过程中,进行了重新排列,去除了多余的信息,虽然提高了.dex文件的执行效率,却也丢失了信息,无法完全转化回去。
#二、将.java文件转化成.dex文件,在Dalvik VM中执行.dex文件
为了将自己写的.java文件能够在Dalvik VM中执行,需要先将.java文件编译成.class文件

```java
//Foo.java文件
public class Foo{
    public static void main(String [] args){
        System.out.println("Hello,world");
    }
}
```

用javac编译器对Foo.java文进行编译,生成Foo.class文件

```
>javac Foo.java
```
用dx工具(位于sdk\build-tools\{sdk版本}\中,可以先将该路径放在Path中方便调用)将Foo.class文件转化成classes.dex文件。

```
>dx --dex --output=foo.apk Foo.class
//the dx command accepts lists of individual class files, directories, or Jar archives. When the --output filename ends with .jar, .zip, or .apk, a file called classes.dex is created and stored inside the archive.
```
用adb将foo.apk上传到安卓设备上

```
>adb push foo.apk  /sdcard/
```
调用Dalvik VM执行foo.jar

```
>adb shell dalvikvm -cp /sdcard/foo.apk Foo
//The -cp option sets the classpath.
```
会看到输出如下结果
![这里写图片描述](91bK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3W2E0k6#2)9J5k6h3u0D9L8$3N6Q4x3X3g2U0M7$3c8F1i4K6u0W2L8X3g2@1i4K6u0r3x3U0l9I4y4U0l9@1x3U0M7J5x3o6p5#2y4e0V1^5y4K6f1`.)

#三、smali.jar与baksmail.jar的使用

1. baksmail.jar反编译.dex文件生成.smali文件

由 .java 文件得到 .dex 文件后,我们则可以尝试用 basksmail .jar将 .dex 文件反编译成.smali文件了。[smali/baksmali下载](8ebK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6T1K9i4c8T1N6h3y4C8k6i4c8Q4x3X3g2G2M7X3N6Q4x3V1k6v1k6i4y4#2M7@1k6J5k6h3E0W2i4K6u0r3M7$3#2S2L8r3W2Q4x3V1k6V1L8%4N6F1L8r3!0S2k6s2x3`.)
先解压上节中生成foo.apk文件取出其中的classes.dex文件
将 .dex 文件反编译成 .smali 文件,执行下面的命令:

```
>java -jar baksmali.jar -o FooOutdir classes.dex
```
可以看到输出文件夹 FooOutdir中有Foo.smali

```
//Foo.smali文件
.class public LFoo;
.super Ljava/lang/Object;
.source "Foo.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

```
2.smali.jar编译 .smali 文件生成 .dex文件
   
用smali.jar 将上小节反编译生成的 FooOutdir文件夹中的 .smali文件编译成.dex文件。

```
>java -jar smali-2.1.2.jar -o  classes.dex  FooOutdir
```

本文参考自:
[1]c81K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3k6G2M7Y4g2E0i4K6u0W2P5r3c8S2i4K6u0V1k6r3g2$3k6h3I4G2M7r3g2J5M7#2)9J5k6h3y4G2L8g2)9J5c8Y4y4Z5L8%4N6@1K9s2u0W2j5h3c8Q4x3X3g2H3K9s2m8Q4x3@1k6@1i4K6y4p5x3U0p5&6x3K6M7K6y4b7`.`.
[2]smali学习笔记.pdf

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 154
活跃值: (763)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
2
该文的csdn地址b36K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3u0D9L8$3N6Q4x3X3g2U0M7$3c8F1i4K6u0W2L8X3g2@1i4K6u0r3N6e0l9I4x3U0b7I4y4K6x3^5x3q4)9J5c8X3q4J5N6r3W2U0L8r3g2Q4x3V1k6V1k6i4c8S2K9h3I4K6i4K6u0r3y4e0p5J5y4U0t1$3x3K6b7`.
2016-4-28 13:30
0
雪    币: 79
活跃值: (125)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
学习一下 谢谢
2016-4-28 14:07
0
游客
登录 | 注册 方可回帖
返回