不需要Root即可Hook别人APP的方法
免 Root 进行 Hook 的核心基础框架: asLody 的 VirtualApp
0.不同 Hook 方式尝试情况
- 【×】2017年5月8日:使用YAHFA插件的形式,能够Hook指定类指定方法,但是不稳定.加载Hook插件后,待运行的APP运行时就崩溃了.底层JNI层报错了,看不懂是啥异常.或许是因为测试手机都是7.0(API 24)的缘故? 因为官方说明是7.0以上的系统是"实验性"支持.
- 【√】2017年05月10日:尝试通过 VirtualApp 核心 lib 里的 PatchManager 来完成代码的注入.成功的骗过高德地图APP和Daydao APP。手机基站欺骗代码已经能够达到能够使用的级别.
- 【√】2017年05月11日:要想只使用基站定位(高德定位类型:6),则必须排除WiFi定位(高德定位类型:5)的干扰.
- 开流量
- 关WiFi
- 禁用“WiFi高级设置 - 随时都可扫描”功能
- 【?】2017年0?月??日:
1.基于YAHFA的Hook插件
参考文档
有关methodSig的写法
public static String className = "android.content.res.AssetManager"; public static String methodName = "open"; public static String methodSig = "(Ljava/lang/String;)Ljava/io/InputStream;"; public static InputStream hook(Object thiz, String fileName) { Log.w("YAHFA", "open asset "+fileName); return origin(thiz, fileName); } public static InputStream origin(Object thiz, String msg) { Log.w("YAHFA", "should not be here"); return null; }
methodSig括号内: 方法调用参数
methodSig括号外: 方法返回值查看指定类 signature 的方法
-
查看 JAVA类 的方式
X:\>javap -s java.awt.Label
-
查看 Android类 的方式
javap -s -bootclasspath /android-sdk/platforms/android-8/android.jar -classpath bin/classes android.app.Activity
例如:
javap -s -bootclasspath "D:\Program Files\Android\android-sdk\platforms\android-25\android.jar" -classpath bin/classes android.app.Activity
-
查看 第三方JAR的类 的方式
javap -s -classpath "D:\AMap_Location.jar" com.amap.api.location.AMapLocation
例如:
javap -s -classpath "D:\UserProfile\Desktop\AMapLocationDemo\app\libs\AMap_Location_V3.4.0_20170427.jar" com.amap.api.location.AMapLocation
关键代码片段
类名: com/lody/virtual/client/VClientImpl.java
方法: bindApplicationNoCheck代码: 在方法末尾ClassLoader appClassLoader = mInitialApplication.getClassLoader();String patchApkPath = "/sdcard/io.virtualhook/patch.apk";File libDir = ensureCreated(new File(VEnvironment.getDataUserPackageDirectory(VUserHandle.myUserId(), "patch"), "lib"));NativeLibraryHelperCompat.copyNativeBinaries(new File(patchApkPath), libDir);DexClassLoader dexClassLoader = new DexClassLoader(patchApkPath, VEnvironment.getDalvikCacheDirectory().getAbsolutePath(), libDir.getAbsolutePath(), appClassLoader);new HookMain().doHookDefault(dexClassLoader, appClassLoader);
快速导入APK到手机的批处理.bat
SET LOCAL="D:\UserProfile\Desktop\VirtualHook-master\VirtualApp\demoHookPlugin\build\outputs\apk\demoHookPlugin-debug.apk"SET TMP=/sdcard/io.virtualhook/patch.apkadb push %LOCAL% %TMP%
2.基于 VirtualApp 核心 lib 的 Hook
Hook 基站定位信息
com.lody.virtual.client.hook.proxies.telephony - MethodProxies.java
参照 GetDeviceId 的写法,把以下关键函数都实现一遍:
- getAllCellInfo
- getNeighboringCellInfo
- getCellLocation
例如:
static class getCellLocation extends ReplaceCallingPkgMethodProxy { public getCellLocation() { super("getCellLocation"); } @Override public Object afterCall(Object who, Method method, Object[] args, Object result) throws Throwable { final Object oldResult = super.afterCall(who, method, args, result); if (oldResult.getClass().getSimpleName().equals("Bundle")) { // Debug.waitForDebugger(); final android.os.Bundle cellInfo = (android.os.Bundle) oldResult; try { cellInfo.keySet(); } catch (Exception ex) { ex.printStackTrace(); } //测试基站位置 //cellInfo.putInt("cid", 123306); //cellInfo.putInt("lac", 12338); //cellInfo.putInt("psc", -1); Log.e("----Ye", "getCellLocation old_value2:" + cellInfo); return cellInfo; //Log.i(TAG, " MCC = " + mcc + "\t MNC = " + mnc + "\t LAC = " + lac + "\t CID = " + cellId); } else { //Debug.waitForDebugger(); Log.e("----Ye", "getCellLocation old_value1:" + oldResult); } return oldResult; //TODO:TEST return super.afterCall(who, method, args, result); } @Override public boolean beforeCall(Object who, Method method, Object... args) { MethodParameterUtils.replaceFirstAppPkg(args); return super.beforeCall(who, method, args); } }
Hook 无线WiFi定位
WiFi定位的原理是获取附近扫描到的所有WiFi热点的Mac地址(可选信息) 和 当前连接的WiFi的Mac地址(必要信息)。
因此理论上只要Hook住获取当前连接的WiFi的Mac地址的函数即可.
但是,基于WiFi的Mac地址是个人重要的隐私,所以Android在6.0版本开始就无法通过之前的WiFiManager代码获取到了.
而且,在7.0版本之后连通过直接读取设备底层信息/sys/class/net/wlan0/address
来获取的方式也禁用了.所以,现阶段想完整的Hook住获取Mac地址的函数,需要涉及到: - Android系统函数(WifiManager) = VirtualApp 核心 lib有现成的地方可以Hook
- Java系统函数(NetworkInterface.getNetworkInterfaces) = 需要自己研究如何Hook,没有现成的地方。
结果:暂时放弃Hook住WiFi定位的想法。