【逆向教程】读懂Smali代码①

看这系列文章的前提:
懂Java!懂Java!懂Java!
网上关于Java的教程非常多!
不懂完全可以去自学!

Smali实质上就是Java字节码,一句Java代码会对应多句Smali代码(如果你不知道什么是字节码,那汇编总听过吧,两者有点类似,要是汇编也没听过,emmmm。。自个百度去)

例如最简单的Java代码:
System.out.println("Hello World");

把它写成Smali大概就是:
# 获取System类中的out字段,存到v0中
sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;
# 把"Hello World"存到v1中
const-string v1, "Hello World"
# 调用虚方法println,传入参数v0, v1
# 相当于v0.println(v1)
invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V


可以看到一句简单的Java代码会分解成几句较为复杂的Smali代码,你可能会问为什么搞这么复杂啊?因为Java是给人看的,Smali是给虚拟机执行的。

就像你叫一个人走过来,正常人他可以直接走过来,但如果是机器人,你就得告诉它先跨左脚,角度多少,然后右脚抬起后脚跟,重心往前……最后走完多少步停下,如果遇到转弯或者障碍的话就更复杂了。

没错教机器做事就是得这么麻烦,所以同理Smali也是在和机器对话,就比较麻烦。

好了开始正题。


Smali文件格式

在你可以在一个xxx.java中定义多个类(包括匿名内部类),但一个smali文件只能定义一个类,一般格式是:

.class 修饰符 类名
.super 父类的类名
.source 源文件名

{实现的接口}

{注解列表}

{字段列表}

{方法列表}


1、其中修饰符就是public、private、protected、static、final等,和Java中的差不多,另外对于类还有interface和enum来表示这个类是一个接口或者枚举类;

2、Smali中的类名都是L包名路径/类名;,例如Android中的TextView类,它的包名是android.widget,如果你要在Smali中表示这个类,就要写成Landroid/widget/TextView;

3、源文件名就是编译这个类的java文件名,如Main.java,仅用于debug删了也没影响;

4、接口的语法是:
.implements 接口类名
可以有0个或者多个,表示这个类实现了哪些接口;

5、注解的话就是Java代码中@XXX之类的代码,例如比较常见的@Override、@Nullable、@NonNull,它的Smali语法是:
.annotation xxxxxxx
    xxxxxx
.end annotation

如果你不知道注解是干嘛用的也没关系,反正一般情况也用不上,只要在Smali中看到annotation时知道它是注解就行了;

6、字段就是field,方法就是method,下次会详细讲讲。

这篇文章只是简单地开个头,让大家初步了解下Smali,后面我会慢慢介绍更多知识。

© 版权声明
THE END
喜欢就支持以下吧
点赞125
分享
评论 抢沙发