Android应用隐私合规检测实现方案详解
作者:潇曜
【前言】
为了响应国家对于个人隐私信息保护的号召,各应用渠道平台陆续出台了对应的检测手段去检测上架的应用是否存在隐私合规问题,因而你会发现现在上架应用,随时都会存在被驳回的风险,为了避免被驳回,我们需要做的就是提前检测好自己的应用是否存在隐私合规问题,及时整改过来,下面提供Xposed Hook思路去检测隐私合规问题,建议有Xposed基础的童鞋阅读
一、准备工作
1、准备一台root
过的安卓手机或者安卓模拟器(新版本的手机root比较麻烦,下面以逍遥模拟器为例来做示范,其实从很多平台出的隐私合规报告也可以发现他们很多用的也是云手机,也就是等同于模拟器)
2、在安卓模拟器上安装Xposed框架
1)在逍遥模拟器中搜索栏中搜索下载Xposed Installer
应用
2)Xposed Installer
应用安装完成之后,点击启动,你会看到一段错误的提示文字:无法载入可用的ZIP文件,请下滑刷新重试
,但是你尝试多次刷新发现并没有效果
3)使用Fiddler对逍遥模拟器进行抓包,可以看到下滑刷新时候,会请求这个地址:http://dl-xda.xposed.info/framework.json
,但是http协议的这个地址已经不支持了,所以在fiddler你会看到提示504
4)只需将http协议改为https协议,搭配科学上网,在浏览器中打开https协议的链接就可以下载,下载到本地之后,可以在fiddler中配置好映射关系,打开Xposed Installer
就能成功下载安装了,主要是需要配置以下3个下载链接的映射关系:http://dl-xda.xposed.info/framework.json
:点击下载到本地http://dl-xda.xposed.info/framework/sdk25/x86/xposed-v89-sdk25-x86.zip
:点击下载到本地http://dl.xposed.info/repo/full.xml.gz
: 点击下载到本地
5) 打开Xposed Installer 下滑刷新,点击安装,重启即可生效
二、编写Xposed模块
1、在Android Studio新建一个Android App项目
2、在build.gradle中添加xposed的编译依赖
dependencies { compileOnly 'de.robv.android.xposed:api:82' compileOnly 'de.robv.android.xposed:api:82:sources' }
3、在AndroidManifest.xml application标签下添加对应属性的设置
<!--告诉xposed框架这是一个xposed模块--> <meta-data android:name="xposedmodule" android:value="true" /> <!--模块描述--> <meta-data android:name="xposeddescription" android:value="隐私合规检测工具" /> <!--模块支持Xposed的最低版本--> <meta-data android:name="xposedminversion" android:value="53" />
4、新建一个类实现IXposedHookLoadPackage
接口的handleLoadPackage
方法
public class PrivacyHook implements IXposedHookLoadPackage { @Override public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable { if (loadPackageParam.packageName.startsWith("com.sswl")) { XposedBridge.log("PrivacyHook has Hooked!"); //检测mac的获取 Class<?> NetworkInterfaceCls = XposedHelpers.findClass("java.net.NetworkInterface", loadPackageParam.classLoader); XposedHelpers.findAndHookMethod(NetworkInterfaceCls, "getNetworkInterfaces", new XC_MethodHook() { protected void beforeHookedMethod(MethodHookParam param) throws Throwable { super.beforeHookedMethod(param); Log.w("Xposed", "============================================================="); XposedBridge.log("调用getNetworkInterfaces"); StackTraceElement[] stackTrace = new Exception().getStackTrace(); for (int i = 0; i < stackTrace.length; i++) { Log.e("Xposed", "" + stackTrace[i]); } } protected void afterHookedMethod(MethodHookParam param) throws Throwable { } }); //检测androidId的获取 Class<?> SystemCls = XposedHelpers.findClass("android.provider.Settings$System", loadPackageParam.classLoader); XposedHelpers.findAndHookMethod(SystemCls, "getString", ContentResolver.class, String.class, new XC_MethodHook() { protected void beforeHookedMethod(MethodHookParam param) throws Throwable { super.beforeHookedMethod(param); Log.w("Xposed", "============================================================="); XposedBridge.log("调用android.provider.Settings$System.getString"); StackTraceElement[] stackTrace = new Exception().getStackTrace(); for (int i = 0; i < stackTrace.length; i++) { Log.e("Xposed", "" + stackTrace[i]); } } protected void afterHookedMethod(MethodHookParam param) throws Throwable { } }); } } }
上面示例主要是展示了mac地址 与 androidId获取的检测与调用堆栈的打印,方便快速定位存在隐私合规问题的代码位置,其他隐私信息获取也类似,这里就不一一展示
5、在assets目录下新建文件名为:xposed_init
的文件,并将刚才新建的那个类的完整类名填写到第一行,比如:com.sswl.xposed.PrivacyHook
6、点击打包安装到逍遥模拟器之后,打开Xposed Installer, 点击模块进去,勾选刚才打包安装的应用,重启模拟器即生效
7、最后可以看一下,检测打印的日志
2022-07-25 20:29:30.022 1908-1908/com.sswl.myxmsj W/Xposed: =============================================================
2022-07-25 20:29:30.023 1908-1908/com.sswl.myxmsj I/Xposed: 调用android.provider.Settings$System.getString
2022-07-25 20:29:30.023 1908-1908/com.sswl.myxmsj E/Xposed: com.sswl.xposed.PrivacyHook$2.beforeHookedMethod(PrivacyHook.java:61)
2022-07-25 20:29:30.023 1908-1908/com.sswl.myxmsj E/Xposed: de.robv.android.xposed.XposedBridge.handleHookedMethod(XposedBridge.java:340)
2022-07-25 20:29:30.023 1908-1908/com.sswl.myxmsj E/Xposed: android.provider.Settings$System.getString(<Xposed>)
2022-07-25 20:29:30.023 1908-1908/com.sswl.myxmsj E/Xposed: com.ta.utdid2.device.c.i(SourceFile:196)
2022-07-25 20:29:30.023 1908-1908/com.sswl.myxmsj E/Xposed: com.ta.utdid2.device.c.j(SourceFile:223)
2022-07-25 20:29:30.023 1908-1908/com.sswl.myxmsj E/Xposed: com.ta.utdid2.device.c.h(SourceFile:415)
2022-07-25 20:29:30.023 1908-1908/com.sswl.myxmsj E/Xposed: com.ta.utdid2.device.c.getValue(SourceFile:279)
2022-07-25 20:29:30.023 1908-1908/com.sswl.myxmsj E/Xposed: com.ta.utdid2.device.b.a(SourceFile:50)
2022-07-25 20:29:30.023 1908-1908/com.sswl.myxmsj E/Xposed: com.ta.utdid2.device.b.b(SourceFile:84)
2022-07-25 20:29:30.023 1908-1908/com.sswl.myxmsj E/Xposed: com.ta.utdid2.device.UTDevice.getUtdid(SourceFile:18)
2022-07-25 20:29:30.023 1908-1908/com.sswl.myxmsj E/Xposed: com.ut.device.UTDevice.getUtdid(SourceFile:16)
2022-07-25 20:29:30.023 1908-1908/com.sswl.myxmsj E/Xposed: com.alibaba.sdk.android.push.impl.j.a(Unknown Source)
2022-07-25 20:29:30.023 1908-1908/com.sswl.myxmsj E/Xposed: com.alibaba.sdk.android.push.impl.j.register(Unknown Source)
2022-07-25 20:29:30.023 1908-1908/com.sswl.myxmsj E/Xposed: com.sswl.sdk.g.b.ax(SourceFile:47)
2022-07-25 20:29:30.023 1908-1908/com.sswl.myxmsj E/Xposed: com.sswl.sdk.b.a.initApplication(SourceFile:160)
2022-07-25 20:29:30.023 1908-1908/com.sswl.myxmsj E/Xposed: com.sswl.channel.SSWLSdk.initApplication(SourceFile:41)
2022-07-25 20:29:30.023 1908-1908/com.sswl.myxmsj E/Xposed: com.sswl.template.e.initApplication(SourceFile:110)
2022-07-25 20:29:30.023 1908-1908/com.sswl.myxmsj E/Xposed: com.sswl.template.f.initApplication(SourceFile:32)
2022-07-25 20:29:30.023 1908-1908/com.sswl.myxmsj E/Xposed: com.sswl.myxmsj.HTApplication.onCreate()
2022-07-25 20:29:30.023 1908-1908/com.sswl.myxmsj E/Xposed: android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1024)
2022-07-25 20:29:30.023 1908-1908/com.sswl.myxmsj E/Xposed: android.app.ActivityThread.handleBindApplication(ActivityThread.java:5405)
2022-07-25 20:29:30.023 1908-1908/com.sswl.myxmsj E/Xposed: de.robv.android.xposed.XposedBridge.invokeOriginalMethodNative(Native Method)
2022-07-25 20:29:30.023 1908-1908/com.sswl.myxmsj E/Xposed: de.robv.android.xposed.XposedBridge.handleHookedMethod(XposedBridge.java:360)
2022-07-25 20:29:30.023 1908-1908/com.sswl.myxmsj E/Xposed: android.app.ActivityThread.handleBindApplication(<Xposed>)
2022-07-25 20:29:30.023 1908-1908/com.sswl.myxmsj E/Xposed: android.app.ActivityThread.-wrap2(ActivityThread.java)
2022-07-25 20:29:30.023 1908-1908/com.sswl.myxmsj E/Xposed: android.app.ActivityThread$H.handleMessage(ActivityThread.java:1546)
2022-07-25 20:29:30.023 1908-1908/com.sswl.myxmsj E/Xposed: android.os.Handler.dispatchMessage(Handler.java:102)
2022-07-25 20:29:30.023 1908-1908/com.sswl.myxmsj E/Xposed: android.os.Looper.loop(Looper.java:154)
2022-07-25 20:29:30.023 1908-1908/com.sswl.myxmsj E/Xposed: android.app.ActivityThread.main(ActivityThread.java:6121)
2022-07-25 20:29:30.023 1908-1908/com.sswl.myxmsj E/Xposed: java.lang.reflect.Method.invoke(Native Method)
2022-07-25 20:29:30.023 1908-1908/com.sswl.myxmsj E/Xposed: com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
2022-07-25 20:29:30.023 1908-1908/com.sswl.myxmsj E/Xposed: com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)
2022-07-25 20:29:30.023 1908-1908/com.sswl.myxmsj E/Xposed: de.robv.android.xposed.XposedBridge.main(XposedBridge.java:107)
2022-07-25 20:29:30.170 111-111/? E/Xposed: Unsupported st_mode 16877
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj W/Xposed: =============================================================
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj I/Xposed: 调用getNetworkInterfaces
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj E/Xposed: com.sswl.xposed.PrivacyHook$1.beforeHookedMethod(PrivacyHook.java:37)
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj E/Xposed: de.robv.android.xposed.XposedBridge.handleHookedMethod(XposedBridge.java:340)
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj E/Xposed: java.net.NetworkInterface.getNetworkInterfaces(<Xposed>)
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj E/Xposed: anet.channel.util.d.h(Unknown Source)
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj E/Xposed: anet.channel.util.d.i(Unknown Source)
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj E/Xposed: anet.channel.util.d.e(Unknown Source)
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj E/Xposed: anet.channel.status.b.d(Unknown Source)
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj E/Xposed: anet.channel.status.b.a(Unknown Source)
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj E/Xposed: anet.channel.status.NetworkStatusHelper.startListener(Unknown Source)
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj E/Xposed: anet.channel.SessionCenter.init(Unknown Source)
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj E/Xposed: anetwork.channel.http.NetworkSdkSetting.init(Unknown Source)
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj E/Xposed: com.alibaba.sdk.android.push.vip.AppRegister.h(Unknown Source)
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj E/Xposed: com.alibaba.sdk.android.push.vip.AppRegister.a(Unknown Source)
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj E/Xposed: com.alibaba.sdk.android.push.impl.j.a(Unknown Source)
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj E/Xposed: com.alibaba.sdk.android.push.impl.j.register(Unknown Source)
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj E/Xposed: com.sswl.sdk.g.b.ax(SourceFile:47)
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj E/Xposed: com.sswl.sdk.b.a.initApplication(SourceFile:160)
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj E/Xposed: com.sswl.channel.SSWLSdk.initApplication(SourceFile:41)
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj E/Xposed: com.sswl.template.e.initApplication(SourceFile:110)
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj E/Xposed: com.sswl.template.f.initApplication(SourceFile:32)
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj E/Xposed: com.sswl.myxmsj.HTApplication.onCreate()
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj E/Xposed: android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1024)
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj E/Xposed: android.app.ActivityThread.handleBindApplication(ActivityThread.java:5405)
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj E/Xposed: de.robv.android.xposed.XposedBridge.invokeOriginalMethodNative(Native Method)
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj E/Xposed: de.robv.android.xposed.XposedBridge.handleHookedMethod(XposedBridge.java:360)
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj E/Xposed: android.app.ActivityThread.handleBindApplication(<Xposed>)
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj E/Xposed: android.app.ActivityThread.-wrap2(ActivityThread.java)
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj E/Xposed: android.app.ActivityThread$H.handleMessage(ActivityThread.java:1546)
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj E/Xposed: android.os.Handler.dispatchMessage(Handler.java:102)
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj E/Xposed: android.os.Looper.loop(Looper.java:154)
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj E/Xposed: android.app.ActivityThread.main(ActivityThread.java:6121)
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj E/Xposed: java.lang.reflect.Method.invoke(Native Method)
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj E/Xposed: com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj E/Xposed: com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)
2022-07-25 20:29:30.184 1908-1908/com.sswl.myxmsj E/Xposed: de.robv.android.xposed.XposedBridge.main(XposedBridge.java:107)
到此这篇关于Android应用隐私合规检测实现方案的文章就介绍到这了,更多相关Android隐私合规检测内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!