该文的csdn地址
http://blog.csdn.net/u012417380/article/details/51262634
#一、什么是smali
Android程序员用Java语言开发APP,编译工具会将Java源文件(.java)编译成Dalvik可执行文件(.dex)。Android系统中Dalvik Virtual Machine 会执行该文件。[smali/baksmali](
https://github.com/JesusFreke/smali)则是Dalvik VM可执行文件的汇编器/反汇编器。反汇编Dalvik可执行文件(.dex)后,将会得到.smali后缀文件。smali代码拥有特定的语法。
相比于.dex文件,smali文件的语法更容易理解些。下面是.dex文件、.smali文件、.java文件三者之间的转化关系。
![这里写图片描述](
http://img.blog.csdn.net/20160427163516131 )
其中.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.
```
会看到输出如下结果
![这里写图片描述](
http://img.blog.csdn.net/20160427201559875 )
#三、smali.jar与baksmail.jar的使用
1. baksmail.jar反编译.dex文件生成.smali文件
由 .java 文件得到 .dex 文件后,我们则可以尝试用 basksmail .jar将 .dex 文件反编译成.smali文件了。[smali/baksmali下载](
https://bitbucket.org/JesusFreke/smali/downloads )
先解压上节中生成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]http://forum.xda-developers.com/showthread.php?t=2193735
[2]smali学习笔记.pdf
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!