今天,我要记录的是smali注入攻击。我们在破解某个apk时,通常的流程是这样的:先用某个工具逆向apk获取到源代码,然后再修改源代码,再用工具进行二次打包。
通过前面一些文章的介绍,我们知道可以用dex2jar反编译classes.dex以获取java源代码,但是我们是无法对java源代码进行修改的。如果想要修改某个apk的源代码,我们必须先将该apk反编译,然后修改反编译所得到的smali代码,而这个操作有一个很高大上的名字:smali注入攻击。
我在学习安卓逆向时,一般先用dex2jar反编译classes.dex以获取java源代码(这样的做是为了方便获取源程序的设计逻辑),然后再用apktool反编译apk以获取smali代码(当然还可以用baksmali工具直接将classes.dex转换为为smali代码,最后再修改smali文件并进行二次打包。
下面以某厂的贴吧客户端为例,介绍一下smali注入的流程。本文反编译的客户端版本为6.5.3,我们的目标是通过smali注入在App的欢迎界面(也就是App运行后最先启动的Activity)添加一个Toast。下面介绍一下具体步骤:
一、 反编译客户端
将apk放入某个文件夹中,在该文件夹中打开命令提示符,输入命令” apktool d baidutieba_100991744.apk” ,如图1所示:
/*注意如果想在任意文件夹中使用apktool命令,只需要在系统变量Path中添加apktool的安装路径即可*/
图1 输入命令反编译客户端
二、 查找App最先启动的Activity
打开AndroidManifest.xml文件,找到App最先启动的Activity。我是这样判断Activity是否为最先启动的:查看Activity配置信息中的intent-filter节点,如果action为android.intent.action.MAIN,category为android.intent.category.LAUNCHER,那么我就认为这个Activity是App运行后最先启动的。(关于android.intent.category.LAUNCHER和android.intent.action.MAIN的具体作用,请看这篇文章:android.intent.action.MAIN 与 android.intent.category.LAUNCHER 网友的误解) 所以通过查看AndroidManifest.xml中的Activity的配置信息,我们可以判定LogoActivity就是最先启动的Activity,也就是我们所需要修改的欢迎界面,具体如图2所示:
图2 在AndroidManifest.xml文件中找到最先启动的Activity
三、 定位LogoActivity的onCreate方法进行代码注入
打开\smali\com\baidu\tieba\LogoActivity.smali文件,定位到onCreate方法,如图3所示:
图3 定位LogoActivity中的onCreate方法
下面介绍一下smali注入的过程:
(1)修改onCreate方法中的本地寄存器的个数,这点非常重要!因为smali是基于寄存器的,所有的操作都要经过寄存器,所以在进行smali代码注入时首先要适当修改寄存器的个数。因为构造和显示Toast函数至少需要3个寄存器,所以我们应该先将onCreate方法中的.locals值由7修改为10,如图4所示:
图4 修改onCreate方法的本地寄存器的个数
(2) 在“ invoke-super{p0,p1},Lcom/baidu/tbadk/BaseActivity;->onCreate(Landroid/os/Bundle;)V ” 这条语句后面添加构造和显示Toast的代码,如图5所示:
图5 在onCreate方法中注入Toast代码
四、 二次打包apk并进行签名
在命令提示符中输入命令”apktool b baidutieba_100991744”对修改后的apk二次打包。如图6所示:
图6 输入命令二次打包客户端
然后用签名对生成的apk进行签名,具体可以参考这篇文章:安卓逆向学习笔记(2)- 利用apktool反编译apk并进行二次打包
运行二次打包生成的apk可以得到运行结果如图7所示:
图7 运行二次打包的客户端所得到的结果
由于smali代码和java代码之间存在着一一对应的关系,所以我在学习smali代码注入的时候,如果不知道某段smali代码该如何实现,就先写好java代码,然后编译生成classes.dex,再用baksmali工具将classes.dex转换为smali代码。