简单暴力非provide式突破Android P对调用隐藏API限制的方法
本帖最后由 xiaoxin520 于 2018-5-30 03:13 编辑安卓9.0(Android P)悄然发生,各大加固厂商也于前段期发布了兼容安卓9.0的公告,为什么对安卓9.0那么敏感?因为谷歌在安卓9.0里限制了反射的使用。以前我们可以随意反射使用私有(隐藏)系统API的时代,似乎结束了。众所周知,安卓安全开发中(无论加固还是脱壳机等),反射是至关重要的,很多朋友感到了一丝担忧。其实,反射不能用,不代表正向不能用;正向不能直接导入,不代表自己不能伪造导入;伪造导入编译也不代表必须按自己伪造的运行,而可以逆向修改后运行。
摘要:本文主要阐述了,如何利用本人所研究的“逆向开发”技术(一种正向和逆向相结合的技术,产品生成同于基于逆向和开发)来实现正向调用我们平时喜欢用反射使用的安卓系统隐藏API,由此证明该技术具有极大的实用性。核心思想其实在“E4A开发xposed插件”中早已形成。
本文说明与开发测试环境概述:
声明:因本人设备环境有限,也没有安卓9.0手机,实验是在逍遥模拟器上进行的,至少可以当正向调用系统隐藏API的一个范例。案例为:正向调用系统隐藏API 获取当前运行APP的application,并打印出application类名。
开发环境:AS2.3.3+,SDK26
测试环境:逍遥模拟器(安卓5.1)
1.从反射调用获取application说起
在之前,当我们需要获取application时,我们第一时间想到的就是反射,大概有两种方法,我们这里展示通过反射调用android.app.ActivityThread类的getApplication方法来获取的代码。和简单的反射调用相比,我们发现多了一步,获取ActivityThread对象必须先运行currentActivityThread方法,参数是个null。代码:
我们可以得出,如果是正向调用,其实更为简单,先调用currentActivityThread方法,再调用getApplication方法。
2.当前研究与问题
在网上,有一篇不错的文章来阐述这个问题,链接为:https://mp.weixin.qq.com/s/b1suvQyGOw2hVvfufOAZ0g,文章非常不错,但该文章存在以下几个问题:
1.方法一需要新建依赖module,并需要provide,而对于高版本AndroidStudio3.0以上,好像对该方式有所限制;
2.方法二、方法三过于繁琐,一般非安全开发者几乎是看不懂;
3.貌似没有源码案例
3.简单正向调用隐藏API(正向+逆向-逆向开发!)
首先,我们新建一个AS工程,建好后,不要急于写代码,而是打开源码所在路径的文件夹,新建ActivityThread.java文件。
回到AS开发环境,对ActivityThread.java写代码,需要用到该类的什么函数,就声明什么函数,由于这个类其实是伪造的,我们最终只是为了有这些代码,而交给系统内的对应类和函数运行,因此返回值无所谓,就写为return null。如图:
这里可能很多人有疑问,为什么方法一个写了静态,一个又不是静态,怎么解释呢?如果要仿写,当然和系统源码声明函数的情况一致是最好了。其实原因看代码就可以明白,这个类必然需要动态声明一下的(getApplication就可以调用了),而这个类声明又是有些不同的,不是直接new xxx,而是要通过本身的currentActivityThread方法调用,因此要是静态。代码(如果还是没有看明白,还是参考反射调用的逻辑):
接着,我们来编写上层调用,也就是MainActivity.java代码。我们的目标很清楚了,调用ReflectP类的getcurrent()函数,获取当前运行APP的application的类名。代码:
这样,我们就用很少的代码,解决了一个看似难以解决的系统隐藏API的正向调用开发,而且操作非常方便,也没有额外限制。
开发环节的最后一步,当然要编写该APP的application类以用来测试,代码(记得在Androidmainfest.xml配置application名称):
此时,AS就全部不报错了,编译APK,得到app-debug.apk。
下面进入到逆向环节:
这个环节就更加简单了,我们把生成的APK拉入改之理或Androidkiller,其实这个方案是比较有趣的,因为我们利用的开发环境的SDK在编译时,是把sdk相关代码打包进android.support包的,而我们的伪造在逆向时看起来非常清晰。我们要把这个包删除,回编即可。
最后,测试成功的LOG打印如下:
其实,我们要感谢逆向和逆向技术,从这里可以看到,当你逆向调用或添加了某些代码时,只要在运行环境中,这个类、方法一定是存在的,它就会自己去跑,甚至我们可能只需要加一句
invoke-static{}Landroid/app/ActivityThread;->currentActivityThread()Landroid/app/ActivityThread;
这就是逆向开发的前身,“逆向调用”!
源码下载链接(太土,也不懂国外的啥玩意,小心翼翼地标上原创,老办法,百度网盘):
链接:https://pan.baidu.com/s/18jTUe6ciDk5EcAMVn0c6lw 密码:uh9a
qtfreet00 发表于 2018-5-30 09:48
你测试也应该在p上,用p的sdk去测试啊
这貌似也是个没手机的折中办法,但是呢,用SDK再高,跑低系统手机,和高系统手机还是很大不同的,而且其实这个和开发环境中的SDK关系不大,隐藏API在开发环境根本是没有的,只和手机有关系,私有的咋解决,貌似得see一下,好像目前没公开的方案,但都很需要 xiaoxin520 发表于 2018-5-30 10:02
这貌似也是个没手机的折中办法,但是呢,用SDK再高,跑低系统手机,和高系统手机还是很大不同的,而且其 ...
sdk api会随着系统升级会有变化,私有api变化还是有的,并不通用,5.1有的函数不代表p也有 学习了 哈哈
感谢学习了{:1_899:}{:1_899:} 辛苦辛苦了
感谢分享. 学习了,谢谢分享 学习了,很用心写的帖子,受益匪浅,感谢。
你测试也应该在p上,用p的sdk去测试啊