1. Smali介绍
Smali,Baksmali分别是指Android的Dalvik虚拟机所使用的一种.dex格式文件的汇编器,反汇编器。语法是以一种宽松式的Jasmin/dedexen语法,实现了.dex格式的所有功能
2. 生成Smali
使用apktool工具可以将apk生成为smali文件。也可以使用apktook将smali打包成apk文件。
3. Smali语法
Dalvik字节码中,寄存器是32位的,能够支持任何类型,64位使用两个寄存器表示。
3.1 确定函数使用的寄存器个数
有两种方法可以确定函数使用的寄存器个数: 1) .registers伪指令指示了函数使用的寄存器个数 2) .locals伪指令指示了函数使用的非参数寄存器个数(不用做保存参数的寄存器个数,也就是一般说的corrupted register)
3.2 传参方式(ABI)
当进行函数调用的时候,参数总是保存在最后的n个寄存器中。如果一个函数又两个参数,并且使用5个寄存器(v0-v4),那么参数 将保存到v3和v4中。非static函数的第一个参数总是一个object对象(this)。假如某个非static函数:foo(int i, int j),使用5个寄存器(v0-v4)调用该函数时,this对象将保存在v2,i保存在v3,j保存在v4。对于static函数来说,情况和非static类似,就是不用传递this罢了。
3.3 寄存器名
寄存器有两个名字,一个是v,另一个是p。p的意思是parameter,即参数。我们继续foo(int i, int j)这个例子,仍假设该函数 使用5个寄存器,那么寄存器情况如下:
v0  ----- the first local register v1  ----- the second local register v2/p0 ----- the first parameter register v3/p1----- the second parameter register v4/p2----- the third parameter reigster
函数中我们可以使用v名称来指代寄存器,也可以使用p名称。
3.4 添加p名称寄存器的意义
如果函数使用n名称:假设某个函数使用了若干个寄存器,而黑客想注入一些别的代码到该函数中,黑客发现他必须额外添加 函数使用的寄存器个数来达到目的。添加寄存器数量意味着函数内所有的参数寄存器都将无效,因为函数调用使用的是最后几 个寄存器作为传参寄存器的。
如果函数采用p名称:此时如果要修改函数,仅需要添加寄存器个数即可。
可以使用-p或-no-parameter-registers来强制生成使用n寄存器名来完成函数。默认使用p寄存器。
3.5 Long/double
Long和double在smali中皆为64位,使用2个寄存器。假设我们调用一个非static函数void bar(long a1, double a2) 假设该函数使用5个寄存器,该函数的寄存器使用情况如下:
p0 ------ this p1/p2 ------ a1 p3/p4   ------ a2
3.6 类型
dalvik的类型比较像JNI。主要分为两个类型:原生类型和引用类型。引用类型主要指objects和arrays,其他类型都是原生类型。 原生类型如下:
V------ void - only be used for return types Z------ boolean B------ byte S------ short C------ char I------ int J------ long(64bits) F------ float D------ double(64bits)
引用类型如下:
Objects:
形如L包名/类名;,比如Lpackage/name/ObjectName; 注意结尾必须要有;符号。对应Java为package.name.ObjectName。比如String: Ljava/lang/String;
Arrays:
形如[type-。比如int[]就是[I。如果是多维数组,则采用多个[号,比如:
int    [][] ------ [[I double [][][][]------ [[[[D String []------ [Ljava/lang/String;
3.7 函数
函数形如: Lpackage/name/ObjectName;->MethodName(III)Z 这个函数的意思是,该函数位于package/name/ObjectName,该函数有三个参数,都是int,返回值为Z,意思是void。 再举个例子: method(I[[IILjava/lang/String;[Ljava/lang/Object;)Ljava/lang/String; 这个函数是: String method(int , int[][], String, Object[])
Lpackage/name/ObjectName;->为字段,字段的表示方式如下: Lpackage/name/ObjectName;->FiledName:Ljava/lang/String; 这意思是,Lpackage/name/ObjectName下的FiledName,该字段类型为String。


更多相关文章

  1. C语言函数的递归(上)
  2. 使用Android(安卓)Studio进行JNI开发 - Mac篇
  3. Android(安卓)关机流程分析-----(1)Framework层
  4. unity重写软键盘for Android(安卓)NGUI
  5. Flutter中高级培训
  6. Android(安卓)的RIL驱动模块
  7. 【基础系列】Input控件专题
  8. Android(安卓)8.0新特性
  9. Swift 的强大之处 - iOS移动开发周报

随机推荐

  1. 全能HOOK框架 JNI NATIVE JAVA ART DALVI
  2. 谈谈新窜起的新操作系统平台 - Android平
  3. android 通过lint以及android-resource-r
  4. Android学习记录(6)—将java中的多线程下载
  5. Android(安卓)setting中添加桌面循环滑动
  6. 尝试用Android获取IMEI,折腾的一天,结果只
  7. Android(安卓)仿今日头条频道管理(下)(GridV
  8. Android对移动计算的影响及产业变革
  9. 解剖Android(安卓)USB MTP 的激活流程
  10. Android(安卓)修图(换证件照背景,污点修复)