破解Android P对非SDK接口限制

绕过 Android14以上非SDK接口调用限制的方法 将双重反射调用的相关代码单独编译成一个dex文件,然后构造一个DexFile对象来执行双重反射的方法,并且在加载时,设置加载的classloader为空,从而绕过限制。这种方案的本质是,本来App的DexFile对应的domain应该是kApplication, 由于加载class时传进来了空的classloader,导致domain值变成了kPlatform,从而绕过了访问限制。每个线程中JNIEnv都是已知的。的指针, 第二个参数是方法的name,第三个参数是方法的签名,第四个参数是指针的大小。 阅读详情

众所周知,Android P 引入了针对非 SDK 接口(俗称为隐藏API)的使用限制。这是继 Android N上针对 NDK 中私有库的链接限制之后的又一次重大调整。从今以后,不论是native层的NDK还是 Java层的SDK,我们只能使用Google提供的、公开的标准接口。这对开发者以及用户乃至整个Android生态,当然是一件好事。但这也同时意味着Android上的各种黑科技有可能会逐渐走向消亡。

作为一个有追求的开发者,我们既要尊重并遵守规则,也要有能力在必要的时候突破规则的束缚,带着镣铐跳舞。恰好最近有人反馈 VirtualXposed 在 Android P上无法运行,那么今天就来探讨一下,如何突破Android P上针对非SDK接口调用的限制。

系统是如何实现这个限制的?

知己知彼,百战不殆。既然我们想要突破这个限制,自然先得弄清楚,系统是如何给我们施加这个限制的。

文档 中说,通过反射或者JNI访问非公开接口时会触发警告/异常等,那么不妨跟踪一下反射的流程,看看系统到底在哪一步做的限制(以下的源码分析大可以走马观花的看一下,需要的时候自己再仔细看)。我们从 java.lang.Class.getDeclaredMethod(String) 看起,这个方法在Java层最终调用到了 getDeclaredMethodInternal 这个native方法,看一下这个方法的源码:

注意那个 ShouldBlockAccessToMember 调用了吗?如果它返回false,那么直接返回nullptr,上层就会抛 NoSuchMethodXXX 异常;也就触发系统的限制了。于是我们继续跟踪这个方法,这个方法的实现在 java_lang_Class.cc,源码如下:

毫无疑问,我们应该继续看 hidden_api.cc 里面的 GetMemberAction方法 :

可以看到,关键来了。此方法有三个return语句,如果我们能干涉这几个语句的返回值,那么就能影响到系统对隐藏API的判断;进而欺骗系统,绕过限制。

应对之策

在分析这三个条件之前,我们再思考一下,在调用一个方法/获取一个成员的时候,除了反射(JNI也算)就没有别的办法了吗?看起来系统只是把反射这条路堵死了,那如果我不走这条路呢?

首先,很显然,除了反射,我们还能直接调用。打个比方,我们要调用 ActivityThread.currentActivityThread()这个方法,除了使用反射;我们还可以把 Android 源码中的 ActivityThread 这个类copy到我们的项目中,然后使用 provided 依赖,这样就能像系统一样直接调用了。至此,我们得到了第一个信息:public类的public方法,可以通过直接调用的方式访问;当然,private的就都不行了。

其次,我们要访问一个类的成员,除了直接访问,反射调用/JNI就没有别的方法了吗?当然不是。如果你了解ART的实现原理,知道对象布局,那么这个问题就太简单了。所有的Java对象在内存中其实就是一个结构体,这份内存在 native 层和Java层是对应的,因此如果我们拿到这份内存的头指针,直接通过偏移量就能访问成员。你问我方法怎么访问?ART的对象模型采用的类似Java的 klass-oop方式,方法是存储在 java.lang.Class对象中的,它们是Class对象的成员,因此访问方法最终就是访问成员。(后续我会专门介绍ART的对象模型,解释 ArtMethod/java.lang.Method/jmethodId之间的关系)。

思考完毕,我们会到反射调用的流程;仔细分析一下这三个条件。

第一个条件

先看第一个return语句,GetActionFromAccessFlags,看方法名貌似是根据 Method/Field 的 access_flag 来判断,具体看下代码:

首先,如果 Method/Field 是白名单,那么直接允许访问。我们再往前看,发现这个 api_list 其实是存储在 Method/Field 的 access_flag中的。

也就是说,所有的Method/Field的access_flag 中存储了hidden_api 的信息,如果有办法把这个flag直接设置为 kAllow,那么系统就认为它不是隐藏API了。但是,如果要修改 Method/Field 的 access_flag这个成员变量,我们首先得拿到这个 Method/Field 的引用,然而 Android P上就是限制了我们拿这个引用的过程,似乎死循环了;前面我们提到可以通过偏移量的方式修改,但实际上这个场景还有别限制(比如压根拿不到Class对象);因此这个条件看似可以达到,实际上比较麻烦,于是我们暂且放下。

继续观察这个方法,接下来 调用了 GetHiddenApiEnforcementPolicy 方法获取限制策略,如果是 kNoChecks 直接允许;那 GetHiddenApiEnforcementPolicy 这个方法是啥样呢?在 runtime.h 中,如下:

也就是说,返回的是 runtime 这个对象的一个成员。如果我们直接修改内存,把这个成员设置为 kNoChecks,那么不就达到目标了吗?

获取runtime指针

既然需要修改runtime对象的内存,那么首先得拿到runtime对象的指针。本来这个过程需要去分析 ART runtime的启动过程,但如果完全写出来那就又是几篇文章了;这里直接给出结论:

在JNI中,我们可以通过 JNIEnv指针拿到 JavaVM指针,这个JavaVM指针实际上是一个 JavaVMExt对象,runtime是 JavaVMExt结构体的成员。说起来比较绕,实际上你看看代码就明白了:

感兴趣的可以自己去分析为什么可以这么做。

搜索内存

我们已经拿到了 runtime指针,也就是这个对象的起始位置;如果要修改对象的成员,必须要知道偏移量。如何知道这个偏移量呢?直接硬编码写死也是可行的,但是一旦厂商做一点修改,那就完蛋了;你程序的结果就没法预期。因此,我们采用一种动态搜索的办法。

runtime是一个很大的结构体,里面的成员不计其数;如果我们要精准定位里面的某一个成员,需要找一些参照物;然后通过这些参照物进一步定位。我们先来观察一下这个结构体:

这个结构体非常大,可以直接去看源码 runtime.h,上面我们挑出了一些我们能够使用的参照物,辅助进行内存定位:

javavm :我们很熟悉的JavaVM对象,上面我们已经通过 JNIEnv 获取了,是个已知值。

target_sdk_version: 这个是我们APP的 targetSdkVersion,我们可以提前知道。

safe_mode:safe_mode 是 AndroidManifest 中的配置,已知值。

因此结合这三个条件,我们对runtime指针执行线性搜索,首先找到 JavaVM指针,然后找到target_sdk_version,最后直达目标;顺便用 safe_mode, java_debuggable 等成员验证正确性。

找到目标 hidden_api_policy_之后,直接修改内存,就能达到目的。用伪代码表示就是:

代码我已经放到 github 上了:FreeReflection,使用起来非常简单,添加依赖;一步调用即可。觉得好用别忘了 star 哦~

看起来我们已经达到目标了,但是不要慌;还有2个条件呢,我们继续,说不定有新发现。

第二个条件

然后看第二个return语句,fn_caller_is_trusted,这里面的代码我就不分析了,直接给结论:这个方法通过回溯调用栈,通过调用者的Class来判断是否是系统代码的调用(所有系统的代码都通过BootClassLoader加载,判断ClassLoader即可),如果是系统代码,那么就允许调用(系统自己的API肯定得让它调)。这里我们又发现一个判断条件:caller.classloader == BootClassLoader。因此,如果能把这个调用类的ClassLoader修改为 BootClassLoader,那么问题不就解决了吗?

那么问题来了,如何修改Class的classloader?我们看看Class 类的结构:

classloader实际上是Class类的第一个成员,而这个java.lang.Class我们肯定是能拿到的,因此我们可以通过上面提到的修改偏移的方式直接修改ClassLoader,进而绕过限制。

但是需要注意一下这个偏移量。虽然 Class 声明没有继承任何东西,但实际上它继承自 Object。我们看下 java.lang.Object:

因此,Class对象在内存中实际上是这样:

JVM规范中,一个int占4字节;在ART实现中,一个Java对象的引用占用4字节(不论是32位还是64位),因此 classloader的偏移量为8;我们拿到调用者的Class对象,在JNI层拿到对象的内存表示,直接把偏移量为8处置空(BootClassLoader在为null)即可。当然,如果你不想用JNI,Unsafe也能满足这个需求。

看起来我们已经有好几种办法达到目的了,别着急;我们继续看第三个条件。

第三个条件

当代码流程走到这里,那个action已经不可能是 kAllow了;不要放弃治疗,说不定还能复活。观察代码:

果然有“豁免”条件:GetHiddenApiExemptions()。跟踪这个方法之后,你会发现解决办法跟上面两种是一样的。要么去修改 runtime 的内存,要么修改signature;我就不赘述啦。

剑走偏锋

上面我们分析了系统的源代码,结合各种条件来实现绕过对非SDK API调用的检测;但实际上所有这些方式我们的目的都是一样的—— 通过某种方式修改函数的执行流程;而达到这个目标最直接的方法就是 inline hook!!由于inline hook太强大,你只需要找到一个关键的执行流程,hook其中的某个函数,修改他的返回值就OK了;这里我也没啥好分析的,只能给大家推荐一个 inline hook 库了,名字叫 HookZz,代码非常优秀,值得一看。

想了解更多开发&投资,可关注微信公众号:码韭

 

 

另一种绕过 Android 10以上非SDK接口调用限制的方法 从Android10开始,Google开始在Android平台限制对非SDK接口的调用。只要应用使用非SDK接口,或尝试使用反射或JNI来调用非SDK接口,都会收到某些限制。而且随着Android版本的升级,这种限制越来越强,被限制的接口也越来越多。这些限制对于Android平台上的一些黑科技来说(插件化,热修复,App双开,性能监控,Art Hook等),简直就是致命的。所以,各路大神都纷纷寻找绕过这个限制的手段。最近在翻阅Android ART虚拟机源码时,发现另外一种简单绕过限制的方法。 阅读详情

相关推荐

HttpCanary安卓抓包原理:非代理式流量镜像与HTTPS明文解密

HTTP抓包是移动应用调试、测试与安全审计的基础能力,其本质是在网络协议层捕获并解析客户端与服务端的真实通信数据。传统工具依赖系统代理,受限于Android证书信任机制、代理检测和UDP支持不足;而现代方案如HttpCanary采用iptables流量镜像与TLS握手级介入,实现零代理、免Root(部分场景)、全TCP流量捕获及HTTPS明文解密。其技术价值在于最小侵入性下的最大协议可见性,适用于QA接口验证、竞品网络行为分析、敏感信息传输审计等工程场景。本文深入解析HttpCanary如何绕过Androi

weixin_30572613的博客 789

Google针对非 SDK 接口的限制

最近在项目中遇到一个问题,非系统签名应用预装到android sdk为28的系统vender或者system分区下,调用隐藏api时,程序崩溃。报错信息如下: 主要原因在于: Accessing hidden method Landroid/view/RenderNode;>getClipToOutline(),不能访问隐藏的getClipToOutline()方法。预装到系统的应用为什么会受到这种限制呢?从 Android 9(API 级别 28)开始,Android 平台对应用能使用的非 SDK 接口实

feng海涛 3875

安卓逆向实战:从JADX静态分析到IDA二进制修改破解授权验证

在软件安全与移动应用分析领域,静态分析是一项基础且核心的技术,它允许安全研究人员在不运行程序的情况下,通过反编译和反汇编来理解其内部逻辑与潜在漏洞。其原理是通过工具将编译后的二进制代码(如APK中的DEX字节码)转换回更易读的中间形式(如Smali)或高级语言代码,从而还原程序的控制流和数据流。这项技术的价值在于能够深入剖析应用的安全机制、验证逻辑,并识别可被修改的关键点,是进行安全评估、漏洞挖掘和特定场景下合法研究的关键手段。典型的应用场景包括分析应用的授权验证流程、寻找敏感API调用以及理解恶意软件的行

weixin_33742618的博客 348

AOSP12非SDK接口限制放开

因工作原因需要将自己增加的一些接口暴露给第三方应用使用,此时我们需要改动AOSP源码。使用Android非sdk接口时。

z9722的博客 1146

安卓iOS抓包实战:Charles与mitmproxy证书配置与流量分析

抓包是移动应用开发中用于观测HTTP/HTTPS网络通信的基础技术,其核心原理是通过中间人代理(MITM)解密并重放客户端与服务器间的加密流量。技术价值在于暴露真实接口行为、定位性能瓶颈、验证安全策略,广泛应用于接口调试、H5加载分析、第三方SDK行为审计等工程场景。实际落地时,关键挑战集中于HTTPS证书信任链的建立——包括Charles和mitmproxy在Windows/macOS生成证书、安卓7.0+网络安全性配置、iOS 10.3+手动开启证书信任等高频问题。本文聚焦跨平台抓包的可复现配置路径与典

weixin_34007886的博客 504

Android签名伪造技术:基于GmsCore与核心破解的深度实践指南

Android应用签名机制是保障应用完整性与来源可信的核心安全基石,它通过数字证书验证确保应用在安装与更新过程中的一致性。其原理基于非对称加密,开发者使用私钥签名,系统使用公钥验证,从而构建了Android权限与沙箱安全的基础模型。这项技术的核心价值在于为安全研究、应用调试、遗留应用维护等合法场景提供了必要的技术手段。在实际工程实践中,通过结合Magisk、Zygisk与LSPosed等系统级框架,可以介入并修改Android系统的签名验证流程,实现签名的“绕过”。本文聚焦于利用GmsCore环境与Core

weixin_34318272的博客 295

一种绕过Android P对非SDK接口限制的简单方法

众所周知,Android P 引入了针对非 SDK 接口(俗称为隐藏API)的使用限制。这是继 Android N上针对 NDK 中私有库的链接限制之后的又一次重大调整。从今以后,不论是native层的NDK还是 Java层的SDK,我们只能使用Google提供的、公开的标准接口。这对开发者以及用户乃至整个Android生态,当然是一件好事。但这也同时意味着Android上的各种黑科技有可能会逐渐...

heng615975867的专栏 923

安卓应用内购逆向分析:从Hook到Smali修改的攻防实践

应用内购是移动应用实现商业变现的核心机制,其本质是客户端与服务器之间的安全交易流程。从技术原理上看,内购系统通常涉及客户端SDK集成、订单发起、支付凭证验证及商品发放等多个环节,其中客户端校验逻辑往往是安全链条中的薄弱点。在工程实践中,开发者常使用Google Play Billing Library等官方SDK,但若未配合可靠的服务器端验证,仅依赖本地标志位或客户端状态判断,极易被逆向破解。通过静态分析工具(如Jadx、Apktool)可定位关键校验代码,而动态插桩框架(如Frida)则能实时Hook支付

weixin_34268753的博客 349

安卓隐藏API限制绕过实战:从反射到JNI的深度破解方案

在Android开发中,反射机制是访问和调用类、方法、字段的核心技术,它允许程序在运行时动态获取信息并执行操作。其原理是通过Java的反射API,绕过编译时的类型检查,直接与JVM交互。这项技术的价值在于实现高度灵活和动态的代码行为,尤其在框架设计、插件化开发和系统级功能扩展中不可或缺。然而,从Android 9开始,Google引入了严格的非SDK接口限制,将大量系统内部API标记为隐藏,反射调用这些API会触发ART虚拟机的策略检查并抛出异常。为了突破这一限制,开发者探索了多种高阶方案,例如通过双重反射

weixin_30458043的博客 395

Android开发者用Cursor写Kotlin的真实体验与避坑指南

Kotlin作为强类型、高表达力的JVM语言,其协程、DSL和编译器插件生态为AI编程工具带来独特机遇与挑战。AI代码生成的核心原理是基于上下文窗口的模式匹配与语法补全,技术价值在于显著降低样板代码编写成本,尤其在数据转换、算法实现等逻辑层;但在Android框架集成场景(如lifecycleScope绑定、Room注解、WorkManager调度)中,因缺乏完整项目语义理解而易出错。典型应用场景包括快速构建Repository骨架、生成Excel解析逻辑、补全Flow操作符等,但必须配合人工核验关键生命周

weixin_34059951的博客 769

安卓TV流媒体终端轻量适配方案:基于OMX硬解的老旧设备重生实践

流媒体播放器是智能终端内容呈现的核心组件,其性能表现高度依赖底层解码架构与硬件加速能力。在Android TV生态中,MediaCodec作为标准多媒体接口,需结合芯片厂商提供的OMX IL组件实现高效H.264/H.265硬解;而ExoPlayer等高级封装框架虽具备跨平台优势,却常因SoC碎片化导致软解fallback、Z-order冲突与电源管理异常。本方案聚焦低算力终端(如Amlogic S905X2、RK3328)的真实部署瓶颈,通过精简内核、绕过Stagefright框架、强制指定vendor

weixin_34248023的博客 394

UE4Dumper:Android虚幻引擎游戏逆向分析与SDK提取实战指南

在移动游戏安全研究、外挂检测与游戏模组开发领域,逆向工程是理解软件内部逻辑的核心技术。其原理在于通过分析程序的二进制代码与内存结构,提取关键数据与函数信息,从而构建可用的软件开发工具包(SDK)。这项技术的核心价值在于能极大提升分析效率,将原本繁琐的手动逆向过程自动化。在Android平台,针对虚幻引擎(Unreal Engine)游戏的逆向分析常面临关键数据结构定位的挑战。UE4Dumper这类工具通过模式匹配(Pattern Scanning)等策略,自动化定位并提取GUObjectArray、GNam

weixin_30530939的博客 498

安卓原生影视App对接苹果CMS全链路实战

影视类Android App开发涉及前端播放体验、后端内容管理与API对接等核心环节。苹果CMS作为主流PHP影视CMS系统,其RESTful接口需通过OkHttp/Retrofit进行标准化调用,配合ExoPlayer实现硬解播放、防盗链处理与离线缓存。本文围绕安卓原生开发(非WebView套壳)展开,解析苹果CMS API逆向工程、双Token登录鉴权、播放器深度定制及真机兼容性适配等关键技术,覆盖从HTTP通信、权限控制到灰度发布的完整交付链路,适用于具备Android中级开发能力、熟悉HTTP与PH

weixin_34178244的博客 420

破解Android媒体播放碎片化:4步构建ExoPlayer跨设备兼容性验证体系

Android设备碎片化是每个媒体应用开发者必须面对的技术挑战。在超过3万种Android设备型号、15个主要系统版本、5大芯片平台的生态中,ExoPlayer播放器在不同设备上可能表现出截然不同的行为:高端设备流畅播放4K HDR内容,低端设备却在720p视频上卡顿;相同编码格式在联发科平台解码正常,在高通平台却出现花屏。这种跨设备兼容性差异直接导致30%以上的播放故障率,成为Android媒体

gitblog_00532的博客 685

一键解决非SDK接口限制失效下载完成解.zip

一键解决非SDK接口限制失效下载完成解.zip

【BUAA】【计组】计算机组成 pre (含详细解析)

BUAA 计算机组成 本文章旨在为@走肖暂时无法接通的系列文章创造一个目录,收藏本文章,方便查阅! 1. 入门测试 2. 基础知识 3. Logisim   欢迎来到 Logisim 的世界   Logisim 门电路   Logisim 组合电路   Logisim 时序电路   Logisim 仿真与调试   应用与挑战 4. Verilog 与仿真工具   前言   ISE 入门   VCS 入门   Verilog 语法   Verilog 题目实例与分析   Verilog 工程的设计开发调试

Schrodinger007的博客 9809

Android软件开发面试题,安卓面试题库

一、开始的开始 **Android框架体系架构(高级UI+FrameWork源码)**这块知识是现今使用者最多的,我们称之Android2013~2016年的技术,但是,即使是这样的技术,Android开发者也往往因为网上Copy代码习惯了而导致对这块经常“使用”的代码 **熟悉而又陌生:**熟悉的是几乎天天在和它们打交道,天天在复制这些代码;陌生的是虽然天天和这些代码打交道,但是并没有深入研究过这些代码的原理,代码深处的内涵。 所以我们需要从新的角度去分析这些知识点,深入研究他们,要学习源码,模仿源码,.

code8889的博客 729

TPL5010硬件看门狗电路

在做一些采集频率很低的产品的时候,会考虑电池供电,比如表、电气表等,为了控制功耗,往往会在设备不需要工作的时候让它进入低功耗模式。为了设备的稳定性,避免死机后无法恢复,必须配置看门狗,一般的看门狗芯片,喂狗间隔时间是几秒钟。这样在喂狗和低功耗之间就产生了一个矛盾,频繁的喂狗就需要频繁的醒过来,这样功耗就很难做到很低。这颗看门狗芯片,特别适合上面的应用。2小时的间隔意味着主控芯片每2小时醒过来喂狗一次即可,而在2.5V供电的情况下,功耗仅仅35nA,几乎可以忽略不计。

zxm8513优快云博客 3306

2024Android开发社招面试总结,2024阿里巴巴安卓面试真题解析

动画的种类:前者只有透明度,旋转,平移,伸缩4种属性,而对于后者,只要是该控件的属性,且有setter该属性的方法就都可以对该属性执行一种动态变化的效果。可操作的对象:前者只能对UI组件执行动画,但属性动画几乎可以对任何对象执行动画(不管它是否显示在屏幕上)。动画播放顺序。

2401_84874163的博客 462

期末求生指南:手把手教你用F12开发者工具绕过百一测评的切屏检测(JavaScript/jQuery实战)

本文详细介绍了如何利用F12开发者工具绕过百一测评的切屏检测,通过分析JavaScript/jQuery中的blur()和focus()事件监听机制,提供实战技巧动态修改代码。文章涵盖事件监听定位、代码修改方法及应对高级检测机制的策略,适合需要临时解决线上考试限制的学生参考。

weixin_30731305的博客 447

FT2232HL JTAG下载器硬件设计指南:从引脚配置到电平转换实战

本文详细解析了FT2232HL JTAG下载器的硬件设计要点,包括引脚配置、电平转换电路设计及EEPROM配置技巧。通过实战案例展示如何利用FT2232HL实现高速JTAG通信,解决电平不匹配等常见问题,提升嵌入式开发效率。特别适合需要灵活JTAG接口的硬件工程师参考。

weixin_29194693的博客 255

深度揭秘Dexmaker:Android动态代码生成实战指南

在Android开发中,你是否曾遇到过需要在运行时动态生成类、模拟final方法或实现复杂AOP功能的挑战?Dexmaker正是解决这些难题的终极武器。作为专为Dalvik虚拟机设计的动态代码生成库,Dexmaker通过直接生成.dex字节码文件,为Android开发者提供了前所未有的灵活性和控制力。本文将深入探索Dexmaker的核心机制、实战应用场景以及高级技巧,帮助你在Android项目中高

gitblog_01148的博客 715

Python调用CANoe(1)(启动与停止,变量和信号读写)

CANoe因为其封闭性(Vector独有),开发的时候,有很多局限性;Python 因为其开源,容易上手,功能强大,那么Python 和 CANoe结合会产生怎样的火花呢?

蚂蚁小兵 4万+
上一篇: Android P 新特性与适配
码韭
博客等级 码龄20年 1粉丝 1原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值