这个函数的第一个参数指向了内存中的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函数:

代码参考 http://yak.ib911.com/dstmath/frida-unpack


四、准备Frida 环境

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

$?pip?install?frida
$?pip?install?frida-tools

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

$?frida?–version

客户端与服务端都下载完毕后,先把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

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

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

//dex起始位置
var?begin?=?args[1]

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

var?begin?=?this.context.x0

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

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


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


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