由于 Web 安全相对来二进制来说更容易上手,最早的时候选择了相对简单的路。随着接触的时间变长,感觉局限于 Web 而抵触二进制实在狭隘,同时也是生活的百无聊赖给了充足的时间,开始尝试学一些新的事物。
在此之前没有接触过安卓或者是 Java 方面的内容,学起来难免有些迟钝,不过好在时间很多~
OK,闲扯到此结束,q
我是通过《Android 软件安全与逆向分析》这本书结合网上的资源(Drops/Pediy/博客)来开始学习的。书能够给予部分基础知识的详解,而网上的资源则大多偏向于实践,针对具体某个apk进行分析,结合起来学习加上自己亲身实践效果很好。不过有一点需要指出的是《Android 软件安全与逆向分析》中的内容并不完全正确,有描述不准确或是明显有错误的地方最好是多印证。
BTW,为了节省时间部分显而易见的地方只做简单的文字说明,可以通过自己实践或者是简单的搜索解决问题,除非必要关键的地方不上传步骤图。另外本文中操作系统为 OS X,部分终端指令与其他系统有所差异 。
接触安卓逆向最早了解到的是 smali,smali 具体定义是什么不过分追究了,先来看一下语法,下面代码用的是 安卓动态调试七种武器之长生剑 - Smali Instrumentation 中的内容。
知道了 smali 是什么东西之后再来看看它是怎么来的。每个安卓 apk 其实都是一个压缩文件,解压缩之后可以看到有一个 classes.dex ,而反编译 classes.dex 即可得到很多 smali 文件。
反编译 classes.dex 的方法我这里使用的是 baksmali,反编译后会在当前目录生成一个 out 文件夹,smali 文件就在这个文件夹里。
另外一种比较傻瓜的方法是直接使用 apktool 反编译整个 apk 文件,反编译后会在当前目录生成 crackme 文件夹,下面有一个 smali 子文件夹就存放了 smali 文件。
apktool 相对于 baksmali 来说就是很多种工具的结合体,把各个步骤结合起来了。推荐使用 baksmali 自己一步步动手操作,这样对各个流程能够有更清晰地认识,而 apktool 的好处是反编译得到的 xml 内容可以直接查看,通过解压缩得到的部分 xml 存在乱码的情况。
我是通过《Android 软件安全与逆向分析》这本书结合网上的资源(Drops/Pediy/博客)来开始学习的。书能够给予部分基础知识的详解,而网上的资源则大多偏向于实践,针对具体某个apk进行分析,结合起来学习加上自己亲身实践效果很好。不过有一点需要指出的是《Android 软件安全与逆向分析》中的内容并不完全正确,有描述不准确或是明显有错误的地方最好是多印证。
BTW,为了节省时间部分显而易见的地方只做简单的文字说明,可以通过自己实践或者是简单的搜索解决问题,除非必要关键的地方不上传步骤图。另外本文中操作系统为 OS X,部分终端指令与其他系统有所差异 。
接触安卓逆向最早了解到的是 smali,smali 具体定义是什么不过分追究了,先来看一下语法,下面代码用的是 安卓动态调试七种武器之长生剑 - Smali Instrumentation 中的内容。
package com.mzheng; # JAVA 源代码 public class MZLog { public static void Log(String tag, String msg) { Log.d(tag, msg); } public static void Log(Object someObj) { Log("mzheng", someObj.toString()); } public static void Log(Object[] someObj) { Log("mzheng",Arrays.toString(someObj)); } }对应的 smali 代码
.class public Lcom/mzheng/MZLog; # class的名字 .super Ljava/lang/Object; #这个类继承的对象 .source "MZLog.java" # java的文件名 # direct methods #直接方法 .method public constructor可以看到 smali 相对于 JAVA 源代码来说虽然复杂了一点,但是比二进制文件逆向得到的汇编代码简单和直观的多,可读性还是很高的。smali 的具体语法和格式在上面已经很清楚了,更加详细的也在《Android 软件安全与逆向分析》中有所说明,这里不加赘述。()V #这是class的构造函数实现 .registers 1 #这个方法所使用的寄存器数量 .prologue # prologue并没有什么用 .line 7 #行号 invoke-direct {p0}, Ljava/lang/Object;-> ()V #调用Object的构造方法,p0相当于"this" 指针 return-void #返回空 .end method .method public static Log(Ljava/lang/Object;)V # Log(Object)的方法实现 .registers 3 .param p0, "someObj" # Ljava/lang/Object; 参数信息 .prologue .line 16 const-string v0, "mzheng" #给v0赋值”mzheng” invoke-virtual {p0}, Ljava/lang/Object;->toString()Ljava/lang/String; #调用toString()函数 move-result-object v1 #将toString()的结果保存在v1 invoke-static {v0, v1}, Lcom/mzheng/MZLog;->Log(Ljava/lang/String;Ljava/lang/String;)V #调用MZLog的另一个Log函数,参数是v0和v1 .line 17 return-void .end method .method public static Log(Ljava/lang/String;Ljava/lang/String;)V #Log(String, String)的方法实现 .registers 2 .param p0, "tag" # Ljava/lang/String; .param p1, "msg" # Ljava/lang/String; .prologue .line 11 invoke-static {p0, p1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I #调用android API里的Log函数实现Log功能 .line 12 return-void .end method .method public static Log([Ljava/lang/Object;)V #Log(Object[])函数实现 ‘[’符号是数组的意思 .registers 3 .param p0, "someObj" # [Ljava/lang/Object; .prologue .line 21 const-string v0, "mzheng" invoke-static {p0}, Ljava/util/Arrays;->toString([Ljava/lang/Object;)Ljava/lang/String; #将Object数组转换为String move-result-object v1 #转换后的结果存在v1中 invoke-static {v0, v1}, Lcom/mzheng/MZLog;->Log(Ljava/lang/String;Ljava/lang/String;)V #调用Log(String, String)函数 .line 22 return-void .end method
知道了 smali 是什么东西之后再来看看它是怎么来的。每个安卓 apk 其实都是一个压缩文件,解压缩之后可以看到有一个 classes.dex ,而反编译 classes.dex 即可得到很多 smali 文件。
反编译 classes.dex 的方法我这里使用的是 baksmali,反编译后会在当前目录生成一个 out 文件夹,smali 文件就在这个文件夹里。
https://bitbucket.org/JesusFreke/smali/downloads baksmali classes.dex
另外一种比较傻瓜的方法是直接使用 apktool 反编译整个 apk 文件,反编译后会在当前目录生成 crackme 文件夹,下面有一个 smali 子文件夹就存放了 smali 文件。
brew install apktool apktool d crakeme.apk
apktool 相对于 baksmali 来说就是很多种工具的结合体,把各个步骤结合起来了。推荐使用 baksmali 自己一步步动手操作,这样对各个流程能够有更清晰地认识,而 apktool 的好处是反编译得到的 xml 内容可以直接查看,通过解压缩得到的部分 xml 存在乱码的情况。