不需要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 Files\Android\android-sdk\platforms\android-25\android.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:\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.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 + "\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定位的想法。

參考文檔


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM