在上一问中:
每日一问 | android hidden api 不是禁用反射,以及如何突破,「元反射」不行了?
中,我也从中学到了很多,其实我预期的答案是小缘所回来的。但是,其他同学的回答完全超出预期,尤其是这个库https://github.com/LSPosed/AndroidHiddenApiBypass 里面的 UnSafe 操作太秀了。
刚哥也提到 stub api 的方式,也能某些情况下解决问题。
忽然想到一个问题:
如果一个接口是 hidden 的,我们是否可以构造出其实现类?如果可以,有几种方式呢?
最后,我们团队一直在招人,欢迎联系招聘要求
更多问答 >>
-
每日一问 | 脱糖对于Android 打包期间插桩的有什么影响?
2022-03-07 21:26 -
每日一问 .class vs Class.forName() vs loadClass() 类加载傻傻分不清楚?
2022-02-11 14:22 -
每日一问 | 被声明为private final 的内部类,能生成一个子类对象吗?逆天篡改~
2022-04-15 21:13 -
每日一问 | 可以不借助 bindService,实现跨进程 binder 通信吗?
2022-04-27 23:43 -
每日一问 | android hidden api 不是禁用反射,以及如何突破,「元反射」不行了?
2022-02-08 23:51 -
每日一问 UndeclaredThrowableException 是什么异常?
2021-12-02 00:50 -
每日一问 | Gson中序列化对象的操作有低侵入的优化方案吗?
2021-12-02 00:50 -
每日一问 | 好奇ActivityThread中为什么会有一个 Application的集合?
2021-08-30 21:36
只是构造一个实现类的话,直接 compileOnly 这个接口类就行。原因是,hidden api 只限制对 member (方法,构造方法,字段的统称)的引用的访问,比如访问一个方法在 java 反射里就是限制你拿到 Method 或者 MethodHandle 对象,JNI 里就是 jmethodID,linking 也就是所谓的 compile only 也就是让你 invoke 这些方法的 smali 指令找不到这个方法而已,而对 class 的访问不会受到限制。当然,这里只考虑 hidden api 限制,还有一种情况,如果你要实现的 interface 的访问权限是 package 的怎么办?动态代理。
不过,我们实现类肯定要实现接口的方法的,这里会不会触发限制呢?我也不确定,跟了一下 art 源码,理论上是不会,override 一个来自接口的方法实际上是根据这个虚方法计算出一个索引,然后放在实现类的 iftable 里,整个过程没有看见有关 hidden api 的检查。用dexmaker分别实现了两个接口:
android.app.Activity$TranslucentConversionListener,这个是带@hide标记但不在黑名单api里android.media.AudioMetadata$DataPackage(黑名单接口):
测试结果:
两个实现类(AudioMetadata$DataPackage接口是private的,set一下accessFlags
就行)都能正常通过反射调用实现的方法,并没有报错。结论:
只要能搞到对应接口的实现类就能正常使用,不管这个接口是否在黑名单api里。进行到这里,用我之前提到的方式就更容易了,因为相对来说它根本不是隐藏的,随便用就可以了。
但是看起来很多小伙伴还是接受不了,那就退而求其次,compileOnly一个新建的module,别问为什么这么操作,问就是经验。其实和替换android.jar一个原理。这个module里是项目里要调用的全部隐藏类,类路径和系统保持一致就可以编译通过了。也可以参考 https://github.com/LawnchairLauncher/lawnchair/blob/12-dev/build.gradle addFrameworkJar部分 ...查看更多
也可以参考 https://github.com/LawnchairLauncher/lawnchair/blob/12-dev/build.gradle addFrameworkJar部分
这个方法在没替换原生sdk之前试过,同名类调用隐藏方法会报错,能编译过,编写的时候提示报错。
动态代理