当然,我们关注的是我们所做的android对于系统,我们的系统源代码可以随意更改,不需要第三方应用的奇妙方法来逃避hidden api(毕竟这属于野路子,google也许下一个版本会改变,野路无效),所以这个方案只适用于可以修改源代码的第三方应用,可访问系统应用hidden api
也可以关注我的哔哩哔哩视频,获得更多课程。哔哩哔哩可以直接私下谈论我想要的优惠群:422901085: https://www.bilibili.com/video/BV1TS4y1e7De/
千里马android framework所有实战资料
我们以ActivityManager的类为例子
frameworks/base/core/java/android/app/ActivityManager.java
这里的 public static int checkUidPermission(String permission, int uid) {
try {
return AppGlobals.getPackageManager() .checkUidPermission(permission, uid); } catch (RemoteException e) {
throw e.rethrowFromSystemServer(); } }
/** @hide */ 这个标签是最关键的,这意味着这种方法是一种隐藏的方法,不会出现sdk中间不会有编译报错make update-api
其实这个hidden接口访问有两种方式
1.反射方法,最简单直接调用的地方可以写反射,但代码可读性差
ClassLoader loader = MainActivity.this.getClassLoader(); Class<?> clz; clz = Class.forName("android.app.ActivityManager"); @SuppressLint("SoonBlockedPrivateApi") Method m = clz.getDeclaredMethod("checkUidPermission"
,
String
.
class
,
int
.
class
)
;
int permisson
=
(
Integer
) m
.
invoke
(clz
,
"android.permission.INJECT_EVENTS"
,
1000
)
;
2、制作一个包装接口jar包,jar是有系统源码编译的,可以访问hidden接口,具体如下:
package com.android.third.call;
import android.app.ActivityManager;
public class ThirdInterface {
public ThirdInterface() {
}
public static int callHiddenFun() {
return ActivityManager.checkUidPermission("android.permission.INJECT_EVENTS", 1000);
}
}
注意哦,这里我们需要android源码环境编译哦,编译成一个jar,对应的mk

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_MODULE := thirdinterface
LOCAL_MODULE_STEM := thirdinterface
LOCAL_DEX_PREOPT := false
include $(BUILD_STATIC_JAVA_LIBRARY)
然后 :make thirdinterface 就可以获取对应的jar包
路径大概如下:
out/target/product/gemini/obj/JAVA_LIBRARIES/thirdinterface_intermediates/javalib.jar
然后需要使用这个jar包的app进行拷贝这个javalib.jar到工程中的lib路径:
导入后就可以源码中调用了:
int permisson = ThirdInterface.callHiddenFun();
调用起来就真的非常简单,可读性还是要比反射好很多
那么系统层面桌面解决让访问调用的hidden api呢?这个其实我们系统层面早就考虑到了需要给一些应用让其可以访问hidden,具体代码可以看这里:
base/core/java/android/content/pm/ApplicationInfo.java
这里其实就有一个isAllowedToUseHiddenApis方法,这个非常关键,分别对代码进行注释讲解:
private boolean isAllowedToUseHiddenApis() {
if (isSignedWithPlatformKey()) {
return true;
} else if (isSystemApp() || isUpdatedSystemApp()) {
return usesNonSdkApi() || isPackageWhitelistedForHiddenApis();
} else {
return isPackageWhitelistedForHiddenApis();
}
}
那么这个白名单在哪呢?
源码在
~/xiaomi5/frameworks/base/data/etc/hiddenapi-package-whitelist.xml
手机上在:
/system/etc/sysconfig/
看目前内容:
<config>
<hidden-api-whitelisted-app package="com.example.anrdemo" />
<hidden-api-whitelisted-app package="android.ext.services" />
<hidden-api-whitelisted-app package="com.android.apps.tag" />
<hidden-api-whitelisted-app package="com.android.basicsmsreceiver" />
<hidden-api-whitelisted-app package="com.android.bookmarkprovider" />
<hidden-api-whitelisted-app package="com.android.calllogbackup" />
<hidden-api-whitelisted-app package="com.android.camera" />
<hidden-api-whitelisted-app package="com.android.car.dialer" />
<hidden-api-whitelisted-app package="com.android.car.messenger" />
<hidden-api-whitelisted-app package="com.android.car.overview" />
<hidden-api-whitelisted-app package="com.android.car.stream" />
<hidden-api-whitelisted-app package="com.android.companiondevicemanager" />
<hidden-api-whitelisted-app package="com.android.dreams.basic" />
<hidden-api-whitelisted-app package="com.android.gallery" />
<hidden-api-whitelisted-app package="com.android.launcher3" />
<hidden-api-whitelisted-app package="com.android.mtp" />
<hidden-api-whitelisted-app package="com.android.musicfx" />
<hidden-api-whitelisted-app package="com.android.permissioncontroller" />
<hidden-api-whitelisted-app package="com.android.printservice.recommendation" />
<hidden-api-whitelisted-app package="com.android.printspooler" />
<hidden-api-whitelisted-app package="com.android.providers.blockednumber" />
<hidden-api-whitelisted-app package="com.android.providers.calendar" />
<hidden-api-whitelisted-app package="com.android.providers.contacts" />
<hidden-api-whitelisted-app package="com.android.providers.downloads" />
<hidden-api-whitelisted-app package="com.android.providers.downloads.ui" />
<hidden-api-whitelisted-app package="com.android.providers.media" />
<hidden-api-whitelisted-app package="com.android.providers.tv" />
<hidden-api-whitelisted-app package="com.android.providers.userdictionary" />
<hidden-api-whitelisted-app package="com.android.smspush" />
<hidden-api-whitelisted-app package="com.android.spare_parts" />
<hidden-api-whitelisted-app package="com.android.statementservice" />
<hidden-api-whitelisted-app package="com.android.storagemanager" />
<hidden-api-whitelisted-app package="com.android.systemui.plugins" />
<hidden-api-whitelisted-app package="com.android.terminal" />
<hidden-api-whitelisted-app package="com.android.wallpaper" />
<hidden-api-whitelisted-app package="jp.co.omronsoft.openwnn" />
config>
其实很容易看懂,这下面的名单都可以进行hidden api,我们要增加啥应用只需要加上包名如:
当然这里如果android原生只支持system app,大家有疑问system app难道不应该是platform签名么?那么签名不就直接返回么?其实还真的不是,其实很多系统应用也不一定系统签名哈,有media,啥的签名故就靠这个白名单了。
我们前面对ApplicationInfo进行了修改就可以进行第三方应用包名也写入了。
然后进行编译后,我们第三方应用就可以正常执行hidden api通过了:
正常打印了:
2021-11-28 10:04:40.740 29000-29000/com.example.anrdemo I/test: PackageManager.PERMISSION_GRANTED == permisson true