美文网首页
4.smali语法学习笔记

4.smali语法学习笔记

作者: 普通的程序员 | 来源:发表于2017-12-03 15:16 被阅读0次

smali语言还是相对纯机器码来说,比较容易理解的
--但最好是结合工具一起学--
--还可以参考其他的整理文章--

先来一个最简单的模型类


simpeModel.java

对应的smali


simpleModel.smali

(表格只是简单做一个映射关系的整理)

java smali description
package .class 包名
extends .super 父类名
class .source 类名
params .field 定义字段
int I int类型
Integer Ljava/lang/Integer Integer类型
引用类型 Lxx/xx/xx 该引用类型的完整包名
boolean Z 布尔值
byte B 字节
short S 短整型
char C 字符
long J 长整型
float F 浮点数
double D 浮点数
void V
数组类型 [ 数组
function .method 定义方法
constructor 构造器方法
.prologue 开始了
.registers 申请寄存器的个数,貌似不用关心这个
.line x 对应源java文件行数
两个简单的方法 image.png

func1括号里有Lxx/xx/xx说明有形参,形参类型是String,也有返回值,返回值类型也是String
.param 指名 形参名 value
.prologue以下开始正式的代码逻辑
.line 38 ,源码38行的代码
return-object 返回该对象的引用,其实就是把p0里的值返回来。

func2无形参,返回值类型String
const-string 声明了一个String 类型的变量 ,值是 "abcdefg"
.local 说是 指定了使用的局部变量的个数,我这里简单的认为,就是把v0给了一个局部变量 func2string

简单的if-else判断 fun3的smali

没想到这么长。
这里有点绕,根据


跳转指令 if-else跳转指令

当vB为0的时候


image.png

则直接翻译smali为

L93-int类型形参num,放到寄存器p1

L96~L97-源码47行,如果p1的值小于等于0,跳到cond_3

L99~L102-源码49行,结束local寄存器p1,跳到goto_2,
返回p1的值

L104~L109-源码48行,重开寄存器p1,cond_3 入口
如果p1的值 不等于0,跳到cond_7
否则(也就是p1等于0)把 0x0这个值给p1,然后跳到goto_2

L113~L115 -也就是源码49行,cond_7入口,
neg-int对第一个p1进行求补,然后把值给第二个p1

L117~L118 -goto_2入口,end_method

是不是感觉和java代码func3看起来不一样?
我给自己的解释是类似java内存模型发生了重排序的优化,也不知道对不对,有大神知道的话评论区求解答。
不过回过头来再看这个smali,
顺序上虽然和源码顺序并不一致,但是按照直接翻译的意思去写java代码

if( p1 <= 0){
    if(p1 != 0)return -p1
    else return 0
} else return p1

结果是一样的。

再来一个


image.png image.png

有了func3的翻译经验
func4就很好翻译了
if-eqz p1,也就是形参num p1等于0的话,直接到cond_3,赋值0,最后返回。
其余的直接返回p1

if(p1 == 0)return 0
else return p1

这个优化感觉更能说服自己了,==操作比!=操作更简单

来一个switch跳转


switch
太长了

L145~L146-源码59行,拿p1做switch(packed-switch关键字)偏移区pswitch_data_a
要看到底部
L174~L179-实际上只有两个case需要做判断 pswitch-6和pswitch-8(也就是两个偏移区)
L156~L163-pswitch_6,把0x0给v0,跳到goto_5
L165~L172-pswitch_8,把0x1给v0,跳到goto_5
L151~L154-goto_5入口把int型的本地(.local关键字)参数result指向寄存器v0,返回v0
其余的 把0x29a给v0

int result;
switch(p1){
  case pswitch_6:
          result = 0;
          break;
  case pswitch_8:
          result = 1;
          break;
  default:
          result = 0x29a;
          break;
}
return result;

相当于帮我优化了case -1,因为case -1和default都是同样的处理方法


常用的加log打印信息的方法


image.png System.out.println("sout"); Log.d("log", func2())

那加入在有些情况下,调用Log.d,该类并没有引入
android.util.Log包怎么办?


通过完整的包名调用 我发誓这两种写法,smali编译出来是一样的

放一个四哥的自定义代码添加方案
以上笔记,仅供参考。

相关文章

  • 4.smali语法学习笔记

    smali语言还是相对纯机器码来说,比较容易理解的--但最好是结合工具一起学----还可以参考其他的整理文章-- ...

  • Kotlin学习笔记:类和接口

    Kotlin学习笔记:概述Kotlin学习笔记:基本语法和函数Kotlin学习笔记:类和接口Kotlin学习笔记:...

  • Kotlin学习笔记:概述

    Kotlin学习笔记:概述Kotlin学习笔记:基本语法和函数Kotlin学习笔记:类和接口Kotlin学习笔记:...

  • Kotlin 学习笔记:基本语法和函数

    Kotlin学习笔记:概述Kotlin学习笔记:基本语法和函数Kotlin学习笔记:类和接口Kotlin学习笔记:...

  • Kotlin学习笔记:注解和反射

    Kotlin学习笔记:概述Kotlin学习笔记:基本语法和函数Kotlin学习笔记:类和接口Kotlin学习笔记:...

  • Kotlin学习笔记:泛型

    Kotlin学习笔记:概述Kotlin学习笔记:基本语法和函数Kotlin学习笔记:类和接口Kotlin学习笔记:...

  • Kotlin学习笔记:类型系统

    Kotlin学习笔记:概述Kotlin学习笔记:基本语法和函数Kotlin学习笔记:类和接口Kotlin学习笔记:...

  • Kotlin 学习笔记: lambda编程

    Kotlin学习笔记:概述Kotlin学习笔记:基本语法和函数Kotlin学习笔记:类和接口Kotlin学习笔记:...

  • Markdown 语法学习笔记

    Markdown 语法学习笔记 学习 Markdown 语法说明做的笔记 写了一些例子,按这些例子自己动手输入一遍...

  • js学习笔记

    js学习笔记 语法 后续补充笔记 join()方法var fruits = ["Banana", "Orange"...

网友评论

      本文标题:4.smali语法学习笔记

      本文链接:https://www.haomeiwen.com/subject/eusomxtx.html