Android隐私方法调用监听

前言

不知道大家上架各个应用市场会不会经常审核被拒,反正我刚接手的项目由于隐私策略变更给各种拒,隐私策略其中明确指出用户未同意《隐私协议》前不能采集用户相关的信息,其中就包括imei,deviceId等,虽然现在高版本无法获取了,但是不保证一些旧的第三方sdk存在获取的情况,单单手动查找显得有点力不从心,前阵子刚好看到一篇不错的检测文章 刚好记录一下。

原作者项目地址-感谢大大的分享 https://github.com/huage2580/PermissionMonitor 原理是使用xposed提供的hook method实现

测试效果图
Android隐私方法调用监听_第1张图片

(一)撸起来-我自己测试的lib中只有三个类

直接贴代码吧-懒神附体

1.引入xposed sdk

debugImplementation 'me.weishu:epic:1.0.0'//测试模式才引用

2.添加方法监听处理-继承XC_MethodHook

/**
 * xposed 方法hook
 */
public class NormalMethodHandler extends XC_MethodHook {
    @Override
    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
        super.beforeHookedMethod(param);
        Log.i(MethodMonitor.TAG, "隐私方法被调用--->" + param.method.getDeclaringClass().getName() + "--" + param.method.getName());
        Log.i(MethodMonitor.TAG, getMethodStack());//打印堆栈信息
    }

    @Override
    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
        super.afterHookedMethod(param);
    }

    /**
     * 获取当前调用栈
     */
    private static String getMethodStack() {
        StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
        boolean skip = true;
        StringBuilder stringBuilder = new StringBuilder();
        for (StackTraceElement temp : stackTraceElements) {
            String line = temp.toString();
            boolean isEpic = line.startsWith("me.weishu.epic");

            if (!skip && !isEpic) {
                stringBuilder.append(line);
                stringBuilder.append('\n');
            }

            if (isEpic && skip) {
                skip = false;
            }
        }

        return stringBuilder.toString();

    }
}

3. 监听管理类

/**
	 * 隐私方法监听
	 */
	public class MethodMonitor {
	
	    static String TAG = "MethodMonitor";
	    static NormalMethodHandler normalMethodHandler = new NormalMethodHandler();
	
	    /**
	     * 开启监听
	     */
	    public static void monitor() {
	        List<PrivacyMethod> privacyMethods = initMethods();
	        for (PrivacyMethod privacyMethod : privacyMethods) {
	            epicHook(privacyMethod);
	        }
	    }
	
	    /**
	     * hook对应方法
	     */
	    private static void epicHook(PrivacyMethod privacyMethod) {
	        Method[] declareMethods = privacyMethod.getTargetClass().getDeclaredMethods();
	        List<String> targetMethods = privacyMethod.getTargetMethods();
	        for (Method method : declareMethods){
	            if (targetMethods.contains(method.getName())){
	                DexposedBridge.hookMethod(method,normalMethodHandler);
	            }
	        }
	    }
	
	    /**
	     * 初始化添加隐私监听类以及对应方法
	     */
	    private static List<PrivacyMethod> initMethods() {
	        List<PrivacyMethod> methods = new ArrayList<>();
	        methods.add(new PrivacyMethod(android.telephony.TelephonyManager.class)
	                .addMethod("getDeviceId")
	                .addMethod("getSubscriberId")
	                .addMethod("getImei")
	                .addMethod("getMeid")
	                .addMethod("getSimSerialNumber"));
	        return methods;
	    }
	}

4.方法实体类

/**
	实体方法类
	**/
	public class PrivacyMethod {

    private Class<?> targetClass;

    private List<String> targetMethods = new ArrayList<>();

    public PrivacyMethod(Class<?> targetClass) {
        this.targetClass = targetClass;
    }

    public Class<?> getTargetClass() {
        return targetClass;
    }

    public PrivacyMethod addMethod(String method) {
        targetMethods.add(method);
        return this;
    }

    public void setTargetClass(Class<?> targetClass) {
        this.targetClass = targetClass;
    }

    public List<String> getTargetMethods() {
        return targetMethods;
    }

    public void setTargetMethods(List<String> targetMethods) {
        this.targetMethods = targetMethods;
    }
}

(二)调用

初始化监听类

MethodMonitor.monitor();

测试调用

 TelephonyManager telephonyManager = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
        StringBuilder builder = new StringBuilder();
        try {
            builder.append("imei:").append(telephonyManager.getImei()).append("\n");
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            builder.append("simSerialNumber:").append(telephonyManager.getSimSerialNumber()).append("\n");
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            builder.append("deviceId:").append(telephonyManager.getDeviceId()).append("\n");
            textView.setText(builder.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }

其他方案(androguard+python+pycharm)

这个解决方案是使用python跑脚本检测apk,需要每次发布的时候检测一下,会比较被动,而且一些不是应用层的调用也会扫描出来,可读性比较差,当作一个技术的学习吧,下面是链接地址:
教你如何高效的检查APK中使用敏感权限的地方以及检查某系统方法被调用的地方

总结

其实这些都是去年学的东西,之前想写下来记录一下,想想技术含量不高就不写了,但时间一久相关原理又忘了,所以还是记录下比较好。

你可能感兴趣的:(android开发点滴,android,java,apache,隐私策略,隐私调用)