zoukankan      html  css  js  c++  java
  • 8 smali文件格式

    Apktool反编译apk后程序中每一个类都会有一个smali文件。

    一、当前类信息:smali文件的头三行描述了当前类的一些信息。

    Eg:

    .class <访问权限> [修饰关键字]<类名>

    .super<父类名>

    .source<源文件名>

    根据DexClassDef结构解析获取三个字段的信息

    说明:经过混淆的dex文件反编译出来的smali文件可能没有源文件,及 .source为空

    二、Smali文件类的主体部分:一个类由字段和方法组成

    1.字段

      .field字段声明,字段分两类:

    1. 静态字段,baksmali会在静态字段起始处添加“static fields”注释,以#开头。

    静态字段格式:

    #static fields

    .field<访问权限>static[修饰关键字]<字段名>:<字段类型>

    2. 实例字段,类似静态字段,没有“static”关键字

    实例字段格式:

    #instance fields

    .field<访问权限>[修饰关键字]<字段名>:<字段类型>

    Eg:

          

    2.方法声明使用的是 .method有两种:

    1. 直接方法

    格式:

    #direct methods

    .method<访问权限>[修饰关键字]<方法原型>

    <.locals>    局部变量个数

    [.parameter]      指定一个参数,与参数个数一一对应

    [.prologue]        指定代码的开始处,混淆过的代码可能没有

    [.line]                指定该条指令在源码中的行号,混淆过的代码可能没有

    <代码体>

    .end method

    2. 虚方法:与直接方法相同只是起始处有“virtual methods”注释

    3.接口,如果类实现了接口,smali文件中会使用“.implements”

           格式:

    #interfaces

    .implements<接口名>

    接口名对应

    4.注解“.annotation”,作用范围:类,方法或字段。

    格式:

    #annotations

    .annotation[注解属性]<注解类名>

                  [注解字段 = 值]

           .end annotation

           作用范围是类,“annotation”直接定义在smali文件中,

           如果是方法或字段,“annotation”定义在方法或字段中

    三、Android中的类

    1.内部类:Java允许类的内部定义另一个类

    内部类分:成员内部类、静态嵌套类,方法内部类,匿名内部类。baksmali反编译时每个单独类都会有一个smali文件。

    内部类的文件格式:

    [外部类]$[内部类].smali

    this$x 字段都被指定为synthetic属性,他们是被编编译器合成的、虚构的。

    Eg:

    对于一个非静态方法,会隐含使用p0寄存器当作类的this引用。

    内部类的初始化步骤:

    1. 保存外部类的引用到本类的一个所有难题hetic字段

    2. 调用内部类的父类构造函数初始化父类

    3. 对内部类自身初始化

    Eg:

    2.监听器:按钮响应事件,本质是接口

    由于监听器只是临时使用,没有复用价值,所以大多采用内部类的方式实现。

    分析smali文件时内部类:[外部类]$[内部类].smali文件开头的 .implements接口的实现,应该注意。另外注解器和监听器的构造函数都是编译器自动生成的,不必太关心。

    3.注解类

    注解包分两类:

    1。dalvik.annotation:该注解不对外开放,仅供核心库与代码测试用

    在libcoredalviksrcmainjavadalvikannotation

    2。android.annotation

    在frameworksasecorejavaandroidannotation

    4。自动生成的类:

    R类:为资源设置ID

    BuildConfig类:只有一个boolean类型的DEBUG字段标示发布的版本类型。默认true

           修改为false的方法:

    使用Eclipse导出项目既可

           注解类:反编译后在smaliandroidannotation目录下的smali文件

    四、smali代码语句

           1。循环语句:

                  常见循环语句,迭代器,for,while,do while

           一般格式:

           Iterator<对象><对象名>=<方法返回一个对象列表>;

           for(<对象><对象名>:<对象列表>){

                  [处理单个对象的代码体]

    }

           Iterator<对象><迭代器>=<方法返回一个迭代器>;

           while(<迭代器>.hasNext()){

                  <对象><对象名>=<迭代器>.next();

                  [处理单个对象的代码体]

    }

    迭代器特点:

    1。调用hasNext()方法检测循环条件是否满足

    2。调用next()方法获取单个对象

    3。循环使用goto指令控制代码的流程

    4。for形式的迭代器循环展开后即为while形式迭代循环

    for循环代码特点:

    1。循环前线初始化循环计数器变量,且值在循环体中更改

    2。循环条件判断可以使条件跳转指令组成的合法语句

    3。循环使用goto指令控制代码流程

    switch语句,采用的是packed-switch指令

    1。有规律的跳转:

    packed-switch指令在Dalvik中格式:

    packed-switch vAA,+BBBBBBBB

    其中+BBBBBBBB被指明一个packed-switch-payload格式的偏移,它的格式:

    struct packed-switch-payload{

           ushort ident; // 值固定为0x100

           ushort size; // case数目

           int first_key; // 初始case的值

           int[] target; // 每个case相对switch指令处的偏移

    }

    2。没有规律的跳转

    packed-switch vAA,+BBBBBBBB

    struct packed-switch-payload{

           ushort ident; // 值固定为0x200

           ushort size; // case数目

           int first_key; // 初始case的值,顺序从低到高

           int[] target; // 每个case相对switch指令处的偏移

    }

    2。try/catch语句

    try语句块使用try_start_0 开头,以try_end_0 标号结束,后面跟数字,语句块后面的数值依次递增。在try_end_0下面使用 .catch指令处理异常类型与catch的标号格式:

    .catch<异常类型>{<try 起始标号>...<try 结束标号>}<catch 标号>

    在Dalvik指令集中,并没有Try/Catch相关指令,通过相关的数据结构来保存异常信息

    try_item保存了try语句信息,DexTry声明

    354struct DexTry {

    355    u4  startAddr;          /* 起始地址 */

    356    u2  insnCount;          /* 指令数量 */

    357    u2  handlerOff;         /* handler的偏移 */

    358};

    使用Android SDK的dexdump工具获取dex文件的try/catch信息

    命令行:dexdump [dex文件路径] > [文件名.txt]   打开生成的 文件名.txt 文件

    Eg:

                 

  • 相关阅读:
    POJ 1795 DNA Laboratory
    CodeForces 303B Rectangle Puzzle II
    HDU 2197 本源串
    HDU 5965 扫雷
    POJ 3099 Go Go Gorelians
    CodeForces 762D Maximum path
    CodeForces 731C Socks
    HDU 1231 最大连续子序列
    HDU 5650 so easy
    大话接口隐私与安全 转载
  • 原文地址:https://www.cnblogs.com/heixiang/p/10965710.html
Copyright © 2011-2022 走看看