• 不需要Root即可Hook别人APP的方法


    不需要Root即可Hook别人APP的方法

    免 Root 进行 Hook 的核心基础框架: asLody 的 VirtualApp

    0.不同 Hook 方式尝试情况

    1. 【×】2017年5月8日:
      使用YAHFA插件的形式,能够Hook指定类指定方法,但是不稳定.加载Hook插件后,待运行的APP运行时就崩溃了.底层JNI层报错了,看不懂是啥异常.
      或许是因为测试手机都是7.0(API 24)的缘故? 因为官方说明是7.0以上的系统是"实验性"支持.
    2. 【√】2017年05月10日:
      尝试通过 VirtualApp 核心 lib 里的 PatchManager 来完成代码的注入.成功的骗过高德地图APP和Daydao APP。手机基站欺骗代码已经能够达到能够使用的级别.
    3. 【√】2017年05月11日:
      要想只使用基站定位(高德定位类型:6),则必须排除WiFi定位(高德定位类型:5)的干扰.
      1. 开流量
      2. 关WiFi
      3. 禁用“WiFi高级设置 - 随时都可扫描”功能
    4. 【?】2017年0?月??日:
      DroidPluginTeam/DroidPlugin: A plugin framework on android,Run any third-party apk without installation, modification or repackage

    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 的方法
    1. 查看 JAVA类 的方式

      X:>javap -s java.awt.Label
      
    2. 查看 Android类 的方式

      javap -s -bootclasspath /android-sdk/platforms/android-8/android.jar -classpath bin/classes android.app.Activity

      例如:

      javap -s -bootclasspath "D:Program FilesAndroidandroid-sdkplatformsandroid-25android.jar" -classpath bin/classes android.app.Activity
    3. 查看 第三方JAR的类 的方式

      javap -s  -classpath "D:AMap_Location.jar" com.amap.api.location.AMapLocation

      例如:

      javap -s -classpath "D:UserProfileDesktopAMapLocationDemoapplibsAMap_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:UserProfileDesktopVirtualHook-masterVirtualAppdemoHookPluginuildoutputsapkdemoHookPlugin-debug.apk"
    SET TMP=/sdcard/io.virtualhook/patch.apk
    adb 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 + "	 MNC = " + mnc + "	 LAC = " + lac + "	 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定位的想法。

    参考文档

    作者:Asion Tang
    凡是没有注明[转载]的文章,本Blog发表的文章版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    将Ubuntu18.04安装到U盘,实现即插即用
    小技巧之 前端自适应
    web笔记之 环境搭建
    C++学习笔记之 单例模式
    推荐一款Markdown编辑器:typora
    C++学习笔记之 类和对象
    C++学习笔记之 函数
    C++学习笔记之 内联函数
    C++学习笔记之 引用
    C++学习笔记之 const
  • 原文地址:https://www.cnblogs.com/AsionTang/p/6837340.html
Copyright © 2020-2023  润新知