1、反射访问系统限制API
前提:Android 9以后通过 hidden 隐藏系统级API,反射无法访问API问题;
结论:
- 系统自带的 App 具备系统签名,所以具有访问系统限制API的能力,反射访问不受限制(保证可以编译通过即可);
- 第三方App需要访问系统限制API,需要通过漏洞来绕开API限制能力;思路:因为System.loadLibrary 加载 so 库时, domain 级别较高是 corePlatform,因为可以在该时机在 jni 层反射修改 VMRuntime 的 setHiddenApiExemptions ,从而放开API访问限制;
//
// Created by liuzhuangzhuang on 2021/8/16.
//
#define DEBUG
#include <android/log.h>
#include <jni.h>
#define LOG_TAG "apifake"
#define DEBUG
#ifdef DEBUG
#define ALOGD(fmt, args...) do {__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, fmt, ##args);} while(0)
#define ALOGI(fmt, args...) do {__android_log_print(ANDROID_LOG_INFO, LOG_TAG, fmt, ##args);} while(0)
#else
#define ALOGD(fmt, args...) do {} while(0)
#define ALOGI(fmt, args...) do {} while(0)
#endif
#define ALOGE(fmt, args...) do {__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, fmt, ##args);} while(0)
typedef union {
JNIEnv* env;
void* venv;
} UnionJNIEnvToVoid;
bool setApiBlacklistExemptions(JNIEnv* env) {
/*=================在这里使用了ZygoteInit,而不是VMRuntime, 效果一样==================*/
jclass zygoteInitClass = env->FindClass("com/android/internal/os/ZygoteInit");
if (zygoteInitClass == nullptr) {
ALOGE("not found class");
env->ExceptionClear();
return false;
}
jmethodID setApiBlackListApiMethod =
env->GetStaticMethodID(zygoteInitClass,
"setApiBlacklistExemptions",
"([Ljava/lang/String;)V");
if (setApiBlackListApiMethod == nullptr) {
env->ExceptionClear();
setApiBlackListApiMethod =
env->GetStaticMethodID(zygoteInitClass,
"setApiDenylistExemptions",
"([Ljava/lang/String;)V");
}
if (setApiBlackListApiMethod == nullptr) {
ALOGE("not found method");
return false;
}
jclass stringCLass = env->FindClass("java/lang/String");
jstring fakeStr = env->NewStringUTF("L");
jobjectArray fakeArray = env->NewObjectArray(
1, stringCLass, NULL);
env->SetObjectArrayElement(fakeArray, 0, fakeStr);
env->CallStaticVoidMethod(zygoteInitClass,
setApiBlackListApiMethod, fakeArray);
env->DeleteLocalRef(fakeStr);
env->DeleteLocalRef(fakeArray);
ALOGD("fakeapi success!");
return true;
}
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
UnionJNIEnvToVoid uenv;
uenv.venv = NULL;
jint result = -1;
JNIEnv* env = NULL;
ALOGD("JNI_OnLoad");
if (vm->GetEnv(&uenv.venv, JNI_VERSION_1_6) != JNI_OK) {
ALOGE("ERROR: GetEnv failed");
goto bail;
}
env = uenv.env;
if (!setApiBlacklistExemptions(env)) {
ALOGE("failed");
goto bail;
}
result = JNI_VERSION_1_6;
bail:
return result;
}