在对反编译以后的apk文件进行分析时 ,会无可避免地涉及到其中的Smali文件分析。对于一个合格的IDE,很有必要为用户提供适合的数据,以减少用户的工作量。所以,ART中的SmaliParse模块便是对Smali文件进行处理的地方。
首先,给定一个简单的Smali文件,内容如下
.class public Lcom/F8LEFT;
.super Landroid/app/Application;
.source "StubApplication.java"
.field private static context:Landroid/content/Context;
.method static init()V
.registers
return-void
.end method
这10行不到的代码组成了一个类,我们可以手动地转换为相应的Java代码
package com;
class F8LEFT extends Application {
private static Context context;
void init() {
return;
}
}
那么问题来了,我们是怎么知道上面两个是等价的呢?说不定其实这两个表达的压根就完全不一样呢~~
举个不太恰当的例子
下雨天留客天留我不留
这个要怎么解读呢??
可以理解为
“下雨天留客,天留我不留”
也可以理解为
“下雨天,留客天,留我不?留!”
同样的句子,按照不同的翻译,连意思都不一样了
所以对于smali代码
.class public Lcom/F8LEFT;
我们知道他能够定义一个类,是因为我们可以按照smali语法的规则,去分析其内容。
可以对于程序来说,这只是一窜无任何意义的字符串。他可能是 “.cl” “ass”也可能是”.c” “la” “ss”
因此,我们要做的第一步就是对其按照一定的规律进行分割,并组成有意义的字符。
对于这句,应该划分为这个样子
“.class” “public” “Lcom/F8LEFT;”
可以看到,这3个字符串已经是最小的分割,并且不能再进行分割了。
如果再强行分割,那么被分割的单词将会失去其语义。比如public一词代表java中的public flag。如果分割为pu 和 blic, 那么这两个单词就完全没有意义。
像这样,被划分为最小的分割的单词组,我们称为Token
于是,对于开头给出的smali代码,我们可以最终划分为以下Token
.class public Lcom/F8LEFT;
.super Landroid/app/Application;
.source "StubApplication.java"
.field private static context:Landroid/content/Context;
.method static init()V
.registers
return-void
.end method
“.class” “public” “Lcom/F8LEFT;”
“.super” “Landroid/app/Application;”
“.source” “”StubApplication.java””
“.field” “private” “static” “context” “:” “Landroid/context/Context”;
“.method” “static” “init” “(” “)” “V”
“.registers” “1”
“return-void”
“.end method”
像这样,对文本按照预定义的规律进行划分为有效的最小的字符串的做法,我们称为词法分析。
这也是对代码进行静态分析的第一步。
ART项目地址:
https://github.com/F8LEFT/ART