Android 使用隐藏api所可能带来的隐患
2018-02-05 08:39
260 查看
最近在研究安Android 源码的时候偶然发现,在framework中有一个如下的提交,让人感觉比较有意思
字面意思比较直接:不让或者限制使用非公开的api方法(也就算@hide 注塑的public方法).根据这个提交,顺带研究了下大部分提交。原理,水平有限没太看懂。
以下的跟人见解是基于初步研读了当前(截止2018/02/03)的关于限制使用hide api的方案之后的。不一定正确,
是如何限制使用hide api的?
对此专门开发了一个名为hiddenapi的工具,在并且在编译生成odex文件的时候,会去check是否有使用你hide 标注的public方法。
如何绕过该限制呢?
初步看应该是可以通过config文件类进行配置,类似private-runtime-permission.xml这种
配置文件的路径:framework/base/config/, 可以看到hiddenapi-blacklist.txt hiddenapi-dark-greylist.txt两个文件。
对应的代码提交
framework层提示使用了隐藏的api的控制属性
上传两张相关的代码片段
通过上一步的分析,可以看出,其实在install独立的应用时,也是会check是否使用了非公开的api的;这对于后续的app开发也算是指明了个大体的方向把。
建议:
ODM、Android设备厂商禁止使用make update-api 这种方式来动态的增加暴露给外部的api函数。所有framework新增的public方法一律添加@hide注释。
后续可能存在的风险,例如无法测试通过cts
无法正常升级等等
规范使用android 所提供的接口信息。让你做什么你就做什么
反射、等通过各种技术手段所绕过的独立的app,要注意了。
个人猜测目前你应该是有大量的应用直接或者间接的使用了个字hide方法
字面意思比较直接:不让或者限制使用非公开的api方法(也就算@hide 注塑的public方法).根据这个提交,顺带研究了下大部分提交。原理,水平有限没太看懂。
commit 927d6de11fa038ee78bb90933eee3ebc20b68751 Author: David Brazdil <dbrazdil@google.com> Date: Wed Jan 24 19:54:30 2018 +0000 Show a warning toast/dialog when an app uses hidden APIs Check VMRuntime.hasUsedHiddenApi() on each Activity start and show a toast/dialog urging the user to check logcat. Test: manual Bug: 64382372 Change-Id: Ida8a6ed9ab9b56a76882501b2a3473a5f1448cb3 diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index dbdb81c..2e7a0ed 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -128,6 +128,8 @@ import com.android.internal.app.WindowDecorActionBar; import com.android.internal.policy.DecorView; import com.android.internal.policy.PhoneWindow; +import dalvik.system.VMRuntime; + import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.annotation.Retention; @@ -7039,11 +7041,12 @@ public class Activity extends ContextThemeWrapper mFragments.dispatchStart(); mFragments.reportLoaderStart(); - // This property is set for all builds except final release - boolean isDlwarningEnabled = SystemProperties.getInt("ro.bionic.ld.warning", 0) == 1; boolean isAppDebuggable = (mApplication.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; + // This property is set for all builds except final release + boolean isDlwarningEnabled = SystemProperties.getInt("ro.bionic.ld.warning", 0) == 1; + if (isAppDebuggable || isDlwarningEnabled) { String dlwarning = getDlWarning(); if (dlwarning != null) { @@ -7064,6 +7067,28 @@ public class Activity extends ContextThemeWrapper } } + // We might disable this for final builds. + boolean isApiWarningEnabled = true; + + if (isAppDebuggable || isApiWarningEnabled) { + if (VMRuntime.getRuntime().hasUsedHiddenApi()) { + String appName = getApplicationInfo().loadLabel(getPackageManager()) + .toString(); + String warning = "Detected problems with API compatiblity\n" + + "(please consult log for detail)"; + if (isAppDebuggable) { + new AlertDialog.Builder(this) + .setTitle(appName) + .setMessage(warning) + .setPositiveButton(android.R.string.ok, null) + .setCancelable(false) + .show(); + } else { + Toast.makeText(this, appName + "\n" + warning, Toast.LENGTH_LONG).show(); + } + } + } + mActivityTransitionState.enterReady(this); }
以下的跟人见解是基于初步研读了当前(截止2018/02/03)的关于限制使用hide api的方案之后的。不一定正确,
基于源码环境编译的app
这种也就是我们俗称的手机厂商、ODM厂商通常会遇到的情况是如何限制使用hide api的?
对此专门开发了一个名为hiddenapi的工具,在并且在编译生成odex文件的时候,会去check是否有使用你hide 标注的public方法。
如何绕过该限制呢?
初步看应该是可以通过config文件类进行配置,类似private-runtime-permission.xml这种
配置文件的路径:framework/base/config/, 可以看到hiddenapi-blacklist.txt hiddenapi-dark-greylist.txt两个文件。
对应的代码提交
define hiddenapi-copy-dex-files $(2): $(1) $(HIDDENAPI) $(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST) \ $(INTERNAL_PLATFORM_HIDDENAPI_DARK_GREYLIST) $(INTERNAL_PLATFORM_HIDDENAPI_BLACKLIST) @rm -rf $(dir $(2)) @mkdir -p $(dir $(2)) find $(dir $(1)) -maxdepth 1 -name "classes*.dex" | sort | \ xargs -I{} cp -f {} $(dir $(2)) find $(dir $(2)) -name "classes*.dex" | sort | sed 's/^/--dex=/' | \ xargs $(HIDDENAPI) --light-greylist=$(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST) \ --dark-greylist=$(INTERNAL_PLATFORM_HIDDENAPI_DARK_GREYLIST) \ --blacklist=$(INTERNAL_PLATFORM_HIDDENAPI_BLACKLIST) endef define hiddenapi-copy-soong-jar $(2): PRIVATE_FOLDER := $(dir $(2))dex-hiddenapi $(2): $(1) $(HIDDENAPI) $(SOONG_ZIP) $(MERGE_ZIPS) $(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST) \ $(INTERNAL_PLATFORM_HIDDENAPI_DARK_GREYLIST) $(INTERNAL_PLATFORM_HIDDENAPI_BLACKLIST) @echo "Hidden API: $$@" $$(copy-file-to-target) @rm -rf $${PRIVATE_FOLDER} @mkdir -p $${PRIVATE_FOLDER} unzip -q $(2) 'classes*.dex' -d $${PRIVATE_FOLDER} find $${PRIVATE_FOLDER} -name "classes*.dex" | sort | sed 's/^/--dex=/' | \ xargs $(HIDDENAPI) --light-greylist=$(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST) \ --dark-greylist=$(INTERNAL_PLATFORM_HIDDENAPI_DARK_GREYLIST) \ --blacklist=$(INTERNAL_PLATFORM_HIDDENAPI_BLACKLIST) $(SOONG_ZIP) -o $${PRIVATE_FOLDER}/classes.dex.jar -C $${PRIVATE_FOLDER} -D $${PRIVATE_FOLDER} $(MERGE_ZIPS) -D -zipToNotStrip $${PRIVATE_FOLDER}/classes.dex.jar -stripFile "classes*.dex" \ $(2) $${PRIVATE_FOLDER}/classes.dex.jar $(1) endef
framework层提示使用了隐藏的api的控制属性
# ----------------------------------------------------------------- # Enable dynamic linker and hidden API developer warnings for # userdebug, eng and non-REL builds ifneq ($(TARGET_BUILD_VARIANT),user) ro.art.hiddenapi.warning=1 else # Enable it for user builds as long as they are not final. ifneq ($(PLATFORM_VERSION_CODENAME),REL) ro.art.hiddenapi.warning=1 endif endif
上传两张相关的代码片段
基于Google release的SDK所编写的app
者在也就所我们通常在各个应用市场上所下载的app.通过上一步的分析,可以看出,其实在install独立的应用时,也是会check是否使用了非公开的api的;这对于后续的app开发也算是指明了个大体的方向把。
建议:
ODM、Android设备厂商禁止使用make update-api 这种方式来动态的增加暴露给外部的api函数。所有framework新增的public方法一律添加@hide注释。
后续可能存在的风险,例如无法测试通过cts
无法正常升级等等
规范使用android 所提供的接口信息。让你做什么你就做什么
反射、等通过各种技术手段所绕过的独立的app,要注意了。
个人猜测目前你应该是有大量的应用直接或者间接的使用了个字hide方法
相关文章推荐
- Android应用开发中如何使用隐藏API
- Android应用开发中如何使用隐藏API
- 使用android隐藏api实现亮度调节
- android 开发之 使用Android系统隐藏api 读取*.apk 程序安装包信息
- 使用android隐藏api实现亮度调节
- Android中使用隐藏API(大量图解)
- [置顶] Android应用开发中如何使用隐藏的API
- 使用内部(com.android.internal)和隐藏(@hide)API[第3部分,定制android平台]
- 使用内部(com.android.internal)和隐藏(@hide)API[第2部分,定制android.jar]
- android使用隐藏api的方法(使用被@hide的api)
- 使用内部(com.android.internal)和隐藏(@hide)API[第3部分,定制android平台]
- Android应用开发中如何使用隐藏API(转)
- 使用内部(com.android.internal)和隐藏(@hide)API[第4部分,定制ADT]
- 使用内部(com.android.internal)和隐藏(@hide)API[第1部分,介绍]
- android使用隐藏api的方法(使用被@hide的api)!!!!!!!
- 使用Android系统隐藏api 读取*.apk 程序安装包信息[转]
- Android应用开发中如何使用隐藏的API
- 使用android隐藏api实现亮度调节
- 使用内部(com.android.internal)和隐藏(@hide)API手记
- 使用android隐藏api实现亮度调节的方法