Android 11 限制反射,如何破解?
https://github.com/Pangu-Immortal
先来分析一下问题出现的原因
我们看一眼Android 11 的源码,如下:
static jobject Class_getDeclaredMethodInternal(JNIEnv* env, jobject javaThis, jstring name, jobjectArray args) {// ……Handle<mirror::Method> result = hs.NewHandle(mirror::Class::GetDeclaredMethodInternal<kRuntimePointerSize>(soa.Self(),klass,soa.Decode<mirror::String>(name),soa.Decode<mirror::ObjectArray<mirror::Class>>(args),GetHiddenapiAccessContextFunction(soa.Self())));if (result == nullptr || ShouldDenyAccessToMember(result->GetArtMethod(), soa.Self())) {return nullptr;}return soa.AddLocalReference<jobject>(result.Get());
}
如果 ShouldDenyAccessToMember 返回 true,那么就会返回 null,上层就会抛出方法找不到的异常。这里和 Android P 没什么不同,只是把 ShouldBlockAccessToMember 改了个名而已。
ShouldDenyAccessToMember 会调用到 hiddenapi::ShouldDenyAccessToMember,该函数是这样实现的:
template<typename T>
inline bool ShouldDenyAccessToMember(T* member,const std::function<AccessContext()>& fn_get_access_context,AccessMethod access_method)REQUIRES_SHARED(Locks::mutator_lock_) {const uint32_t runtime_flags = GetRuntimeFlags(member);// 1:如果该成员是公开API,直接通过if ((runtime_flags & kAccPublicApi) != 0) {return false;}// 2:不是公开API(即为隐藏API),获取调用者和被访问成员的 Domain // 主要看这个const AccessContext caller_context = fn_get_access_context();const AccessContext callee_context(member->GetDeclaringClass());// 3:如果调用者是可信的,直接返回if (caller_context.CanAlwaysAccess(callee_context)) {return false;}// ......}
原来的方案失效了能在 FirstExternalCallerVisitor 的 VisitFrame 方法中找到答案
bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) {ArtMethod *m = GetMethod();......ObjPtr<mirror::Class> declaring_class = m->GetDeclaringClass();if (declaring_class->IsBootStrapClassLoaded()) {......// 如果 PREVENT_META_REFLECTION_BLACKLIST_ACCESS 为 Enabled,跳过来自 java.lang.reflect.* 的访问// 系统对“套娃反射”的限制的关键就在此ObjPtr<mirror::Class> proxy_class = GetClassRoot<mirror::Proxy>();if (declaring_class->IsInSamePackage(proxy_class) && declaring_class != proxy_class) {if (Runtime::Current()->isChangeEnabled(kPreventMetaReflectionBlacklistAccess)) {return true;}}}caller = m;return false;
}
我们看一下如何解决
- native hook 住 ShouldDenyAccessToMember 方法,直接返回 false
- 破坏调用堆栈绕过去,使 VM 无法识别调用方
我们采用的是第二种方案,有什么方法可以让 VM 无法识别我的调用栈呢?这可以通过 JniEnv::AttachCurrentThread(…) 函数创建一个新的 Thread 来完成。
具体我们可以参考这:https://developer.android.com/training/articles/perf-jni
然后配合 std::async(…) 与 std::async::get(…) 就能搞定了。
下面是关键代码:
// java 层直接用 jni 调用这个方法
static jobject Java_getDeclaredMethod(JNIEnv *env,jclass interface,jobject clazz,jstring method_name,jobjectArray params) {// ...... 省掉一些转换代码// 先用 std::async 调用 getDeclaredMethod_internal 方法auto future = std::async(&getDeclaredMethod_internal, global_clazz,global_method_name,global_params);auto result = future.get();return result;
}static jobject getDeclaredMethod_internal(jobject clazz,jstring method_name,jobjectArray params) {// 这里就是一些普通的 jni 操作了JNIEnv *env = attachCurrentThread();jclass clazz_class = env->GetObjectClass(clazz);jmethodID get_declared_method_id = env->GetMethodID(clazz_class, "getDeclaredMethod","(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;");jobject res = env->CallObjectMethod(clazz, get_declared_method_id,method_name, params);detachCurrentThread();return env->NewGlobalRef(res);
}JNIEnv *attachCurrentThread() {JNIEnv *env;// AttachCurrentThread 核心在这里int res = _vm->AttachCurrentThread(&env, nullptr);return env;
}
https://github.com/Pangu-Immortal
Android 11 限制反射,如何破解?相关推荐
- 大叔也说Xamarin~Android篇~环境部署与破解
原文:大叔也说Xamarin~Android篇~环境部署与破解 现在移动开发很HOT,以至于很多人都转向了它,大叔也不例外,这次有机制接触一下xamarin这个东西,其实之前也用于xamarin,只是 ...
- Android利用Java反射获取用户手机的rom定制系统及版本,EMUI,MIUI,ColorOS,FunthouchOS等
Android利用Java反射获取用户手机的rom定制系统版本及版本号,EMUI,MIUI,ColorOS,FunthouchOS等 前言 正文 结语 前言 现在手机厂商都推出了自己的基于Androi ...
- Android 11 开发者常见问题 | FAQ・第一期
注: 由于部分问题答案较长,可上下滑动以查看完整内容 存储 01 Q: Android 11 的分区存储是强制的吗?如果 targetSdkVersion 低于 Android 10,运行在 Andr ...
- Android 11(platfrom 30)APP启动流程(含Activity)核心点记录
前言:边分析,边记录 不断更新. 注意:阅读此文请同时打开android-30的源码,一步一步按文章同步跟进阅读源码,因为源码量太大,这里只能贴出部分核心代码. 场景一.从桌面点击APP图标进行启动 ...
- 谷歌官方版android,谷歌Android 11正式官方版
谷歌Android 11正式官方版终于和广大用户朋友们见面了,今天,谷歌正式发布了最新版本的移动操作系统Android 11,此次更新为大家新增了很多的功能,分别分为三个主题,人. 控件和隐私.And ...
- 未找到beta版怎么解决_刚刚,谷歌正式发布Android 11 Beta版,带来多项重磅更新...
作者 | 安卓开发者博客 译者 | 核子可乐 策划 | 小智 转发链接:https://mp.weixin.qq.com/s/gp2XZGe69KDMAtsOeu56YA 前言 今日,谷歌安卓开发者博 ...
- android11测试版下载,Find X2系列 Android 11 Beta1 测试版发布,你要尝试一下吗?
原标题:Find X2系列 Android 11 Beta1 测试版发布,你要尝试一下吗? 今年的特殊情况导致安卓11发布日期的一波三折,然而最后谷歌还是在6月11日发布了安卓Beta1版本.有趣的是 ...
- 安卓用户又少了一项自由,Android 11不再支持更改默认相机程序
萧萧 发自 凹非寺 量子位 报道 | 公众号 QbitAI 在微博.微信上想要拍照上传时,想直接用FaceU或美图秀秀作为默认拍照程序,给自拍加个滤镜? 在即将推出的Android 11里,这些第三方 ...
- Android11模拟定位开发,Android 11 中的位置信息更新
为了进一步保护用户隐私,Android 11 增加了单次位置信息访问权限,并更改了用户授予在后台访问位置信息权限的方式.这些更新会影响到 Android 11 及更高版本上运行的所有应用. 单次访问权 ...
最新文章
- 阿里、腾讯、美团、小米……各公司月饼大PK,看完简直想哭泣!
- 读《可复制的领导力》
- 使用多线程拷贝文件夹
- python之多并发socket
- python什么是调用_Python中包(package)的调用方式
- [数字dp] hdu 3271 SNIBB
- 从零基础入门Tensorflow2.0 ----一、1.2 实战分类模型(数据归一化)
- chmod与chown
- 传统方法做分割 解析种子cues
- 结构梁配筋最牛插件_结构分析|结构抗震概念——强柱弱梁
- 解决udhcpc命令无法自动获取并设置网卡IP和系统DNS
- 概率论-多维随机变量及其分布思维导图
- 西安交大计算机考研分数线2020院线,2020西安交通大学考研复试分数线已公布
- cocos 微信小游戏 加载云端资源
- 专精特新企业认定条件
- 哪款蓝牙耳机音质好?内行推荐四款高音质蓝牙耳机
- 百度BD09加密经纬度转国测局GCJ02经纬度
- 推荐几款适合孩子玩的编程游戏
- 关于M1版Macbook Pro 安装JDK 方法
- 计算机专业毕业论文4000字免费,计算机专业毕业生毕业论文攻略
热门文章
- Linux下kafka的部署
- Lucene排序以及自定义排序
- 译: 3. RabbitMQ Spring AMQP 之 Publish/Subscribe 发布和订阅
- JTextField类(单行文本框)/JPasswordFiel(密码框)/JTextArea(多行文本框)常用方法
- ASP.NET MVC编程——控制器
- 6. H.264/AVC编码器原理
- 做红颜知己就要恪守界限
- iPhone放大模式详解
- vue-electron 写一个markdown文章编辑器(一)
- 国际域名和境外域名能否提交备案