/**
* Sets the target SDK version. Should only be called before the
* app starts to run, because it may change the VM's behavior in
* dangerous ways. Defaults to {@link #SDK_VERSION_CUR_DEVELOPMENT}.
*
* @param targetSdkVersion the SDK version the app wants to run with.
*
* @hide
*/@UnsupportedAppUsage(maxTargetSdk=0, publicAlternatives="Use the {@code targetSdkVersion}"
+" attribute in the {@code uses-sdk} manifest tag instead.")@SystemApi(client = MODULE_LIBRARIES)publicsynchronizedvoidsetTargetSdkVersion(int targetSdkVersion) {
this.targetSdkVersion = targetSdkVersion;
setTargetSdkVersionNative(this.targetSdkVersion);
}
hiddenapi: Accessing hidden method Ldalvik/system/VMRuntime;->setTargetSdkVersion(I)V (runtime_flags=CorePlatformApi, domain=core-platform, api=blocked,core-platform-api) from Lcom/android/hiddenapi/MainActivity; (domain=app) using reflection: denied
java.lang.NoSuchMethodException: dalvik.system.VMRuntime.setTargetSdkVersion [int]
at java.lang.Class.getMethod(Class.java:2940)
at java.lang.Class.getDeclaredMethod(Class.java:2919)
at com.android.hiddenapi.MainActivity.VMRuntimeSetTargetSdkVersion(MainActivity.java:138)
at com.android.hiddenapi.MainActivity$1.onClick(MainActivity.java:43)
at android.view.View.performClick(View.java:8083)
at android.view.View.performClickInternal(View.java:8060)
at android.view.View.-$$Nest$mperformClickInternal(Unknown Source:0)
at android.view.View$PerformClick.run(View.java:31549)
at android.os.Handler.handleCallback(Handler.java:995)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loopOnce(Looper.java:248)
at android.os.Looper.loop(Looper.java:338)
at android.app.ActivityThread.main(ActivityThread.java:9067)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:593)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:932)
Init libart.so handle: 0xb4000077c46762c0
Load /data/app/~~VGNwNanmQ4UBtavm8SqM-w==/com.android.hiddenapi-VIzkuLnqpv5NAhGt5WmmUw==/base.apk!/lib/arm64-v8a/libjato.so using classloader ns clns-9 (caller=/data/data/com.android.hiddenapi/code_cache/.overlay/base.apk/classes6.dex): ok
Found the Ldr instruction in GetHiddenApiEnforcementPolicy, target_instruction is 0xb9443d08, i = 14
Get the offset of enforcement_policy: 43c
setTargetSdkVersion success!
绕过分析
分析 libjato.so 的 Java_com_bytedance_common_jato_boost_HiddenApiOpt_nOptimize 是如何绕过 HIDE API 限制的, 主要代码如下:
如果 ANDROID API 大于等于 23 ,则调用 dl_iterate_phdr 来遍历所有加载的模块,然后在回调函数中根据模块的名称来获取对应的加载基址,dl_iterate_phdr 的函数原型如下:
/**
* [dl_iterate_phdr(3)](4f2K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6E0j5h3^5%4i4K6u0W2L8%4u0Y4i4K6u0r3L8r3W2F1N6i4S2Q4x3V1k6E0j5h3&6Q4x3X3c8H3j5h3N6W2M7#2)9J5c8X3#2S2L8U0y4Q4x3V1k6V1L8q4)9#2k6X3W2@1k6i4u0S2N6r3g2Q4y4h3k6H3K9r3c8J5i4K6u0W2x3#2)9J5k6h3S2@1L8h3I4Q4x3U0V1`.
* calls the given callback once for every loaded shared object. The size
* argument to the callback lets you determine whether you have a smaller
* `dl_phdr_info` from before API level 30, or the newer full one.
* The data argument to the callback is whatever you pass as the data argument
* to dl_iterate_phdr().
*
* Returns the value returned by the final call to the callback.
*/intdl_iterate_phdr(int (* _Nonnull __callback)(struct dl_phdr_info* _Nonnull __info, size_t __size, void* _Nullable __data), void* _Nullable __data);
hiddenapi::AccessContext GetReflectionCallerAccessContext(Thread* self)REQUIRES_SHARED(Locks::mutator_lock_) {
// Walk the stack and find the first frame not from java.lang.Class,// java.lang.invoke or java.lang.reflect. This is very expensive.// Save this till the last.
...
FirstExternalCallerVisitor visitor(self);
visitor.WalkStack();
// Construct AccessContext from the calling class found on the stack.// If the calling class cannot be determined, e.g. unattached threads,// we conservatively assume the caller is trusted.
ObjPtr<mirror::Class> caller =
(visitor.caller == nullptr) ? nullptr : visitor.caller->GetDeclaringClass();
return caller.IsNull() ? AccessContext(/* is_trusted= */true) : AccessContext(caller);
}
hiddenapi: Accessing hidden method Ldalvik/system/VMRuntime;->setTargetSdkVersion(I)V (runtime_flags=CorePlatformApi, domain=core-platform, api=blocked,core-platform-api) from Lcom/android/hiddenapi/MainActivity; (domain=app) using reflection: denied
java.lang.NoSuchMethodException: dalvik.system.VMRuntime.setTargetSdkVersion [int]
at java.lang.Class.getMethod(Class.java:2940)
at java.lang.Class.getDeclaredMethod(Class.java:2919)
at com.android.hiddenapi.MainActivity.VMRuntimeSetTargetSdkVersion(MainActivity.java:142)
at com.android.hiddenapi.MainActivity$1.onClick(MainActivity.java:43)
at android.view.View.performClick(View.java:8083)
at android.view.View.performClickInternal(View.java:8060)
at android.view.View.-$$Nest$mperformClickInternal(Unknown Source:0)
at android.view.View$PerformClick.run(View.java:31549)
at android.os.Handler.handleCallback(Handler.java:995)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loopOnce(Looper.java:248)
at android.os.Looper.loop(Looper.java:338)
at android.app.ActivityThread.main(ActivityThread.java:9067)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:593)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:932)
Found the Ldr instruction in GetHiddenApiEnforcementPolicy, target_instruction is 0xb9443d08, i = 14
Get the offset of enforcement_policy: 43c
setTargetSdkVersion success!