前言
android程序中调用了很多第三方库,由于工信部的监管政策,各个业务需要对第三方库的具体行为负责,如果在APP抽查中发现应用中调用的第三方库有违规行为,APP也会被通知整改或者下架。
因此有必要使用技术手段对第三方库的具体行为进行测试,例如检测第三方库是否有采集MAC地址的行为。由于第三方库的网络请求都进行了加密,因此很难从网络层去检测是否有敏感信息回传。但是可以通过xpose hook关键函数的形式,判断第三方库是否有采集mac信息等行为。
具体方案
一,VirtualXposed的安装
VirtualXposed是一个虚拟环境,可以在设备没有Root的情况下hook系统的api。如果有已经root的设备,或者使用的是手机模拟器,可以使用xposed。
VirtualXposed源码及APK下载地址:https://github.com/android-hacker/VirtualXposed/releases
将VirtualXposed APK文件安装到测试手机(这里需要注意测试手机的CPU架构也需要跟VirtualXposed支持的架构保持一致),安装后需手动进入VirtualXposed的应用权限设置界面,将所有的权限都开启(VirtualXposed并不会自动请求权限,所以需要手动开启),然后运行VirtualXposed。
二,编写Hook程序
编写Hook程序前需要先知道通过哪些接口可以获取到MAC地址
获取MAC地址方法一:调用NetworkInterface类的getHardwareAddress()方法
获取MAC地址方法二:调用WifiInfo类的getMacAddress()方法
获取MAC地址方法三:通过Runtime.getRuntime().exec("cat /sys/class/net/wlan0/address ")方法获取
明确了需要hook的方法,开始编写Hook程序:
1,新建一个类,实现IXposedHookLoadPackage接口
public class Main implements IXposedHookLoadPackage {
private static final String TAG ="Main";
private String HOOK_PREFIX ="getmachook -> ";,
2,针对上文介绍的三种获取mac的形式,进行hook,通过日志形式进行输出
private void hookMacAddresshighversion(XC_LoadPackage.LoadPackageParam lpparam) {
try {
Class clazz = lpparam.classLoader.loadClass("java.net.NetworkInterface");
String methodName ="getHardwareAddress";
XposedHelpers.findAndHookMethod(clazz,methodName,new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param)throws Throwable {
super.beforeHookedMethod(param);
Log.i(TAG,HOOK_PREFIX +"hookMacAddresshighversion getHardwareAddress");
Log.e(TAG,HOOK_PREFIX + getStackTrace(new Exception()));
}
});
}catch (Throwable e) {
Log.e(TAG,"hookMacAddresshighversion", e);
}
}
/**
* Detects whether the App has obtained mac , applicable to the system lower 7.0
*/
private void hookMacAddresslowversion1(XC_LoadPackage.LoadPackageParam lpparam) {
try {
Class clazz = lpparam.classLoader.loadClass("android.net.wifi.WifiInfo");
String methodName ="getMacAddress";
XposedHelpers.findAndHookMethod(clazz,methodName,new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param)throws Throwable {
super.beforeHookedMethod(param);
Log.i(TAG,HOOK_PREFIX +"hookMacAddresslowversion1 getMacAddress");
Log.e(TAG,HOOK_PREFIX + getStackTrace(new Exception()));
}
});
}catch (Throwable e) {
Log.e(TAG,"hookMacAddresslowversion1", e);
}
}
private void hookMacAddresslowversion2(XC_LoadPackage.LoadPackageParam lpparam) {
try {
Class clazz = lpparam.classLoader.loadClass("java.lang.Runtime");
String methodName ="exec";
XposedHelpers.findAndHookMethod(clazz,methodName,String.class,new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param)throws Throwable {
super.beforeHookedMethod(param);
Log.i(TAG,HOOK_PREFIX +"hookMacAddresslowversion2 getMacAddress param = " + param.args[0]);
Log.e(TAG,HOOK_PREFIX + getStackTrace(new Exception()));
}
});
}catch (Throwable e) {
Log.e(TAG,"hookMacAddresslowversion2", e);
}
}
3.新建xposed配置
在src/main/目录下新建一个Assets Folder,并在Assets Folder中创建xposed_init文件,xposed_init文件中写入Main类的完成名称,例如:com.w.myhook.Main
4.在AndroidManifest.xml中声明xposed meta-data
<meta-data android:name="xposedmodule"
android:value="true"/>
<meta-data android:name="xposedminversion"
android:value="53"/>
<meta-data android:name="xposeddescription"
android:value="myAppHook"/>
5.配置xposed库依赖
compileOnly'de.robv.android.xposed:api:82'
compileOnly'de.robv.android.xposed:api:82:sources'
6.编译运行
三,安装MyHook模块到VirtualXposed
1. 启动VirtualXposed后,点击底部的按钮 - 添加应用 - 选择MyHook - 点击安装 - 选择VirtualXposed
2,2.返回VirtualXposed首页,向上滑动打开抽屉,启动Xposed Installer,开启getmachook模块
3.重启VirtualXposed
不需要重启手机,只需要将VirtualXposed APP的进程重启即可
四,安装需要检测的APP
可以直接从手机SD卡中安装,也可以像第三步的第1步安装MyHook那样把需要检测的APP安装到VirtualXposed,这里就不再赘述了,注:安装APP后不需要再添加模块或重启VirtualXposed了
五,运行被检测的APP
返回VirtualXposed首页,向上滑动打开抽屉,点击运行需要检测的APP.
过滤日志关键字getmachook,就可以看到mac地址的调用情况和调用堆栈.
demo代码地址
https://github.com/crazydigua/getmachook