注意,目前此方案在Android11及以上的手机会闪退
前言
不知道大家上架各个应用市场会不会经常审核被拒,反正我刚接手的项目由于隐私策略变更给各种拒,隐私策略其中明确指出用户未同意《隐私协议》前不能采集用户相关的信息,其中就包括imei,deviceId等,虽然现在高版本无法获取了,但是不保证一些旧的第三方sdk存在获取的情况,单单手动查找显得有点力不从心,前阵子刚好看到一篇不错的检测文章 刚好记录一下。
原作者项目地址-感谢大大的分享 https://github.com/huage2580/PermissionMonitor 原理是使用xposed提供的hook method实现
测试效果图
(一)撸起来-我自己测试的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中使用敏感权限的地方以及检查某系统方法被调用的地方
总结
其实这些都是去年学的东西,之前想写下来记录一下,想想技术含量不高就不写了,但时间一久相关原理又忘了,所以还是记录下比较好。