Android逆向世界之一:smali文件

一直对android的逆向分析很感兴趣,这些年也陆陆续续反编译了一些android的项目,今天开始对这方面的知识做一下总结。先从android的apk文件开始讲起。


APK文件

android工程编译完成会得到我们想要的apk安装包,apk文件其实是一个压缩包,可以直接用解压缩软件解压,解压后的文件如下图所示:

这里写图片描述

  • assets文件夹

    保存一些额外的资源文件,如游戏的声音文件,字体文件等等,在代码中可以用AssetManager获取assets文件夹的资源。

  • lib文件夹

    存放用C/C++编写的,用NDK编译生成的so文件,供java端调用。

  • META-INF文件夹

    存放apk签名信息,用来保证apk包的完整性和系统的安全。
    在IDE编译生成一个apk包时,会对里面所有的文件做一个校验计算,并把计算结果存放在META-INF文件夹内,apk在安装的时候,系统会按照同样的算法对apk包里面的文件做校验,如果结果与META-INF里面的值不一样,系统就不会安装这个apk,这就保证了apk包里的文件不能被随意替换。比如拿到一个apk包后,如果想要替换里面的一幅图片,一段代码, 或一段版权信息,想直接解压缩、替换再重新打包,基本是不可能的。如此一来就给病毒感染和恶意修改增加了难度,有助于保护系 统的安全。

  • res文件夹

    存放资源文件,包括icon,xml文件

  • AndroidManifest.xml文件

    应用程序配置文件,每个应用都必须定义和包含的,它描述了应用的名字、版本、权限、引用的库文件等信息。

  • classes.dex文件

    可以直接在Dalvik虚拟机上加载运行的文件,由java文件经过IDE编译生成。Dalvik虚拟机的指令码不是标准的Jvm指令码,而是使用了自己独有的一套指令集(类似汇编语言),这个也是我们今天要讲的重点。dex文件中共用了很多类名称,常量字符串,使它的体积更小,运行效率更高。

  • resources.arsc文件

    二进制资源文件,包括字符串等。

Smali简介

  Dalvik虚拟机和Jvm一样,也有自己的一套指令集,类似汇编语言,但是比汇编简单许多,只要你会java,了解android的相关知识,就可以轻松的看懂,如果得到这些汇编文件呢,利用apktool或者dex2jar工具包(网上很多),反编译classes.dex文件,就可以得到以smali为后缀的文件,这些smali文件就是Dalvik的寄存器语言。


Smali文件结构解

  Smali文件与java中的类是一一对应的,包括内部类和匿名内部类也会生成对应的smali文件(典型的比如实现某个接口的匿名内部类),所以你会看到.smali文件比.java文件更多。
smali文件是由Dalvik指令组成的,它有自己的一套规则,它的指令都是以“.”开头,常用的指令如下:

指令 说明
.class 包名+类名
.super 父类类名
.source 源文件名称
.implements 接口实现
.field 定义字段
.method/.end method 方法的开始与结束
.locals 方法内使用的v开口的寄存器个数
.prologue 表示方法中代码的开始处
.line 对应java中的行数
.param 指定了方法的参数
.paramter 和.paramter含义相同
.param 指定了方法的参数
.annotation/.end annotation 注解的开始和结束



现在来看下smali文件的结构:

1.头文件

格式如下:

.class <访问权限修饰符> [非权限修饰符] <类名>
.super <父类名>
.source <源文件名称>

访问权限修饰符即所谓的public,protected,private,而非权限修饰符则指的是final,abstract,static,两者都可以为空。
举例如下:

.class public final Llutey/FTPServer/preferences/PreferencesFactory;
.super Ljava/lang/Object;
.source "PreferencesFactory.java"

如果原java代码有经过混淆,那一般.class里面的类名和.source的源文件名会不一样,以下是经过混淆的(类名正常是xxx/PreferencesFactory,混淆以后变成xxx/d):

.class public final Llutey/FTPServer/preferences/d;
.super Ljava/lang/Object;
.source "PreferencesFactor

2.接口实现

格式如下:

#interfaces
.implements <接口名称>

举例如下:

# interfaces
.implements Landroid/view/View$OnClickListener;

其中# interfaces为注释

3.注解

如果一个类中使用了注解,就会出现.annotation,格式如下:

#annotations
.annotation [注解的属性] <注解类名>
    [注解字段=值]
    ...
.end annotation

举例如下:

# annotations
.annotation build Landroid/annotation/TargetApi;
    value = 0xb
  • 53
    点赞
  • 183
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值