android内核集成Frida,Android安全指南 之 Frida脱壳实战

cf12f15867f6acc3e7e5b5ff8f93a2dd.png

一、Frida技术原理

Android脱壳的目的是从内存中dump下解密的应用dex文件,为了实现这个目的我们需要知道dex文件在内存中dex地址与dex文件大小。Android系统的libart.so库文件中提供了一个导出的OpenMemory函数用来加载dex文件。

dc59a67d98e51fb052f90fb09473deec.png

这个函数的第一个参数指向了内存中的dex文件,如果我们可以Hook 这个函数,就可以得到dex文件加载进内存时的起始地址,再根据dex文件格式计算得到文件头保存的dex文件的长度fileSize。

二、获取函数签名

在编写Frida脚本之前我们需要在libart.so文件中找到OpenMemory的函数签名,这个签名根据android版本或者架构的不同会有些许差异,下面介绍如何从运行待脱壳应用的设备中提取libart.so文件:

$ adb pull /system/lib/libart.so /本地目录

$ adb pull /system/lib64/libart.so /本地目录

获取libart.so文件后有两个方法可以获得函数签名,第一种是利用IDA pro 分析so文件,搜索OpenMemory函数:

29a3944664d92eade7d07ad5d4045093.png

第二种方法实在linux系统下使用nm命令直接查看libart.so文件的函数签名:

$ nm libart.so | grep OpenMemory

d3d02b2c5c562224cacc55ac7f6128c2.png

三、编写脚本

Frida可以执行js脚本也可以执行python脚本:

· JS脚本:

5909f084dd8f769b89e4277c3911c7a0.png

· Python脚本:

31ff57003811e5cdc8d55b87c269675a.png

代码参考 https://github.com/dstmath/frida-unpack

四、准备Frida 环境

安装 frida客户端与服务端,建议使用Python的pip命令安装frida客户端:

$ pip install frida

$ pip install frida-tools

下载完毕后查看下载的客户端版本:

$ frida –version

264e9b735a23214569d0710a152ce91f.png

客户端与服务端都下载完毕后,先把frida-server推送到设备中:

$ adb push frida-server /data/local/tmp

设置frida-server的权限并运行:

$ su

# cd /data/local/tmp

# chmod 777 frida-server

# ./frida-server

如果运行失败,可以尝试关闭android系统的SELinux:

# setenforce 0

我们打开另一个控制台,运行客户端命令查看与服务端的交互:

$ frida-ps -U

出现以下信息,则说明交互成功:

b89552c6654b2bdd339e70af38fff86c.png

五、执行脱壳脚本

我们先将一个简单的测试程序丢到腾讯乐固上去加固,我们可以看到加固完成后的结果:

0c66d9dc46e8c9970482c14f9bc27f1d.png

可以看到加固过后程序的原本代码被隐藏了,被替换成乐固的壳程序代码,将加固后的应用安装到手机上,赋予该应用读写sd卡权限:

100ac51c7fc63fed244ffdb13c88bf33.png

在sd卡中创建unpack目录,执行命令运行JS脚本:

$ frida -U -f  -l  –no-pause

-U参数表示我们使用了USB server进行链接,-f 参数表示在设备中启动一个指定的android程序,需要配合 –no-pause参数来使进程恢复。-l参数表示需要注入的js脚本。

Python脚本的运行就简单得多了:

$ python unpack.py 

61043108c6167aabecd7d8f102479231.png

另外注意一个问题,如果应用运行过程中使用了64位的libart.so,脚本的这个地方需要进行一些小修改:

//dex起始位置

var begin = args[1]

获取dex起始位置的语句需要改成:

var begin = this.context.x0

不然可能会出现这样的问题:

f13e5fddbb8993bc55c5f9128a09185c.png

脱壳完成后从sd卡中将unpack文件夹pull到本地:

$ adb pull /sdcard/unpack .

6f09c187e7e2579d04168d2af803fafb.png

可以看到脱壳成功了。由于这一类脱壳法是将内存中的dex文件直接dump下来的,对于指令抽取等针对方法体进行处理的加固方式并没有做对应的修复工作。如果应用经过了指令抽取或者dex2c处理,这种方法拿到的dex文件就是残缺不全的,对于那些加固就需要通过对Android源码进行修改的脱壳方法比如dexhunter或者是比较新的FART脱壳机。

作者简介:叶绍琛,Unix/Linux/Android操作系统内核技术专家,大中华区前50位RHCA系统架构师,曾任网易互娱云计算平台技术负责人。

《Android安全指南》系列文章,未完待续。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值