关于Android突破非SDK接口限制的延伸

从 Android9 开始,系统开始针对非SDK接口做限制。

在国内做 Android 开发的都经历过,如果想要实现一些黑科技,性能优化,或者沙箱等功能,常常需要反射一些隐藏接口。

随着安卓开发生态的逐渐规范化,以及系统的性能与安全性的提升,一方面不再允许直接调用非SDK接口避免安全与稳定性问题,另一方面也无需通过黑科技来提升应用的性能。

developer.android.com/guide/app-c...

然而,国内的应用开发,尤其是多年的老产品,包含了大量的祖传代码。直接全方面修改需要很高的开发成本,甚至由于无百分百替代方案需要修改产品逻辑。除非是功能完全失效,否则做这类兼容对业务"有害无益"(即,消耗了资源但没有提升业务价值)。

而且,非SDK接口的限制通常会区分等级,随 TargetSdkVersion 的提升扩大限制范围。尤其是每一两年,应用市场或有关部门,都会要求活跃的应用必须提升 TargetSdkVersion 才能上架或升级,就导致做相应的适配成为一件必须关注的事情。

有一位技术大神 weishu,曾经在自己的博客中连载两篇分析如何突破限制,并开源了相关代码。

一种绕过Android P对非SDK接口限制的简单方法
weishu.me/2018/06/07/...

另一种绕过 Android P以上非公开API限制的办法
weishu.me/2019/03/16/...

Github - FreeReflection
github.com/tiann/FreeR...

通过查看代码可知,目前所使用的方案,是通过"元反射"去反射被限制的接口,欺骗系统,假装是系统自己的调用以突破限制(毕竟很多隐藏 API 只是不给三方应用调用,并不是功能失效)。

此外,博客和代码里还有修改内存的方案,改变内存变量值以突破限制。这个方案并没有被实际调用,可能是因为风险较高。

目标变量的内存的地址是通过其他变量的相对位置来锁定的,系统升级或厂商定制后数据结构若发生改变,就可能导致未知错误。

当然,最坏的情况还是后续系统升级,判断是否限制的逻辑发生改变,还需要重新适配。

技术细节补充

博客里提到了 fn_caller_is_trusted 这个条件,但并没有给出这个变量的具体逻辑,这里补充下。

首先,fn_caller_is_trusted 是作为参数传进来的,GetMemberAction 方法调用方式 java_lang_Class.cc。

java_lang_Class.cc 中的流程,Class_getDeclaredMethodInternal -> ShouldBlockAccessToMember -> hidden_api.h GetMemberAction

IsCallerTrusted 是一个方法。通过调用栈解析(WalkStack),获取到当前方法的调用者 caller,并调用到 hidden_api.h 的 IsCallerTrusted。

回到 hidden_api.h,如果 caller 的dex是系统的dex,那么就会放过,属于可信caller。

所以,当使用"元反射"去反射目标接口时,Class 所属的 dex 必然就是系统的 dex,从而绕过限制。

相关推荐
LuiChun2 小时前
webview_flutter_android 4.3.0使用
android·flutter
Tanecious.3 小时前
C语言--分支循环实践:猜数字游戏
android·c语言·游戏
闲暇部落4 小时前
kotlin内联函数——takeIf和takeUnless
android·kotlin
Android西红柿14 小时前
flutter-android混合编译,原生接入
android·flutter
大叔编程奋斗记14 小时前
【Salesforce】审批流程,代理登录 tips
android
程序员江同学16 小时前
Kotlin 技术月报 | 2025 年 1 月
android·kotlin
爱踢球的程序员-117 小时前
Android:View的滑动
android·kotlin·android studio
大耳猫17 小时前
Android HandlerThread
android·thread·handler
新玉540117 小时前
PHP反序列化练习
android·开发语言·前端·php