总结一下smali 的分析 。
smali代码相当于dalvik虚拟机的汇编语言。
--
- 如何得到smali代码参考百度,或我的文章s001android逆向安全初级篇之apk逆向常用工具及简单使用一览 利用这些工具可以得到。
- smali 的dalvik 操作码链接dalvik_opcodes
smali 中的数据类型
smali中有两类数据类型:基本类型和引用类型。
引用类型是指数组和对象,其他都是基础类型。
基础类型
使用一个简单的字符表示,在dex文件中实际上以字符串的形式存储。
V 空类型---仅仅可以用来作为返回类型
Z Boolean 布尔型
B Byte字节型
S Short短整型(16位)
C Char字符型
I Int 整形
J long (64 bits)长整型(64位)
F Float浮点型
D double (64 bits)双精度型(64位)
引用类型
对象 以Lpackagename/ObjectName;的形式表示
1. 开始的L表明这是一个对象类型
2. packagename 使用"/"代替"."
3. ObjectName是对象的名称,
4. 分号表明对象名的结束.
数组 以[数据类型 的形式表示
如:
[I 表示一维整形数组
[[I 表示二维数组
[Ljava/lang/String 表示String数组
方法
Lpackage/name/ObjectName;->MethodName(III)Z
- Lpackage/name/ObjectName; 是一个类,
- MethodName明显是一个方法名,
- (III)Z是方法的签名,
- ‘III’在这个例子中是三个整形参数,
- Z是表示返回一个布尔类型的返回值。
寄存器
在dalvik字节码中,寄存器都是32位的,能够支持任何类型。64位类型(Long和Double型)用2个寄存器表示。
有两种方式指定一个方法中有多少寄存器是可用的。
.registers指令指定了方法中寄存器的总数。
.locals指令表明了方法中非参寄存器的数量。
方法的传参
- 当一个方法被调用的时候,方法的参数被置于最后N个寄存器中。如果一个方法有2个参数,5个寄存器(v0-v4),那么参数将置于最后2个寄存器——v3和v4。
- 非静态方法中的第一个参数总是调用该方法的对象。
例如,
非静态方法LMyObject;->callMe(II)V有2个整型参数,另外还有一个隐含的LMyObject;参数,所以总共有3个参数。假如在该方法中指定了5个寄存器(v0-v4),以.registers方式指定5个或以.locals方式指定2个(即2个local寄存器+3个参数寄存器)。当该方法被调用的时候,调用该方法的对象(即this引用)存放在v2中,第一个整型参数存放在v3中,第二个整型参数存放在v4中。
对于静态方法除了没有隐含的this参数外其它都一样。
寄存器的命名方式
有两种方式——V命名方式和P命名方式。P命名方式中的第一个寄存器就是方法中的第一个参数寄存器。在下表中我们用这两种命名方式来表示上一个例子中有5个寄存器和3个参数的方法。
v0 第一个local register
v1 第二个local register
v2 p0 第一个parameter register
v3 p1 第二个parameter register
v4 p2 第三个parameter register
你可以用任何一种方式来引用参数寄存器——他们没有任何差别。
注意:baksmali默认对参数寄存器使用P命名方式。如果想使用V命名方式,可以使用-pl—no-parameter-registers选项。
使用P命名方式是为了防止以后如果要在方法中增加寄存器,需要对参数寄存器重新进行编号的缺点。
Long/Double值
Long和double类型是64位的,需要2个寄存器(切记切记)。
例如,对于非静态方法LMyObject;->MyMethod(IJZ)V,参数分别是LMyObject;,int,long,bool。故该方法需要5个寄存器来存储参数。
p0 this
p1 I
p2,p3 J
p4 Z
方法的修饰词
对于方法的修饰
.method static constructor ()V 表示不带参数的缺醒构造方法。
.registers 指令指定了方法中寄存器的总数
.locals 指令表明了方法中非参寄存器的总数,出现在方法中的第一行
类
如果没有内部类的话一个类在一个文件中;
如果有内部类,则内部类单独一个文件文件名格式为:类名$内部类
类的声明
如下:声明了一个类NetProviderApplication 继承自Landroid/app/Application
.class public Lcom/android/netprovider/NetProviderApplication;
.super Landroid/app/Application;
集成接口Ljava/io/FilenameFilter 用如下表达
.implements Ljava/io/FilenameFilter;
未完持续。。。
其他
同样对于类或者接口的静态程序块,在JVM层面也给了他一个特殊的名字
说了这么多,其实读到这里只要记住两点:在字节码层面
参考链接
- dalvik_opcodes
- s001android逆向安全初级篇之apk逆向常用工具及简单使用一览
- apk反汇编之smali语法
- Android apk的混淆
- Dalvik (software)
smali是一个开源并且注释清晰的反编译的java工程
apktool是基于smali开发的帮助反编译apk的利器
dedexer是独立与smali又一个反编译apk的工具
而dexdump就是android自带的c语言实现的dump dex文件的工具