Android之基于Xposed的模拟位置模块实现

作者: CaptainXero | 来源:发表于2016-09-13 17:25 被阅读9045次

    引言

    前段时间看到朋友圈有人在短时间内发了几条状态,定位都在不同国家的首都。问了一下,才知道用了一款能够模拟位置的软件。最近学习Xposed框架,就试着利用Xposed框架开发了一款能够模拟安卓手机位置的应用模块。

    开发环境

    • 测试机:Android 4.4
    • Xposed框架
    • AndroidStudio

    实现原理

    1.Android手机定位原理

    手机常用的定位方式有:

    • 卫星定位(GPS,北斗,伽利略,Glonass)
    • 移动基站定位
    • WiFi辅助定位
    • AGPS定位
    * 卫星定位

    GPS(Global Positioning System)即全球定位系统,是由美国建立的一个卫星导航定位系统,利用该系统,用户可以在全球范围内实现全天候、连续、实时的三维导航定位和测速;另外,利用该系统,用户还能够进行高精度的时间传递和高精度的精密定位。

    * 基站定位

    移动电话测量不同基站的下行导频信号,得到不同基站下行导频的TOA(到达时刻)或 TDOA(到达时间差),根据该测量结果并结合基站的坐标,一般采用三角公式估计算法,就能够计算出移动电话的位置。实际的位置估计算法需要考虑多基站(3个或3个以上)定位的情况,因此算法要复杂很多。一般而言,移动台测量的基站数目越多,测量精度越高,定位性能改善越明显。

    * WiFi定位
    • 每一个无线AP(路由器)都有一个全球唯一的MAC地址,并且一般来说无线AP在一段时间内不会移动;
    • 设备在开启Wi-Fi的情况下,无线路由器默认都会进行SSID广播(除非用户手动配置关闭该功能),在广播帧包含了该路由器的MAC地址;
    • 采集装置可以通过接收周围AP发送的广播信息获取周围AP的MAC信息和信号强度信息,将这些信息上传到服务器,经过服务器的计算,保存为“MAC-经纬度”的映射,当采集的信息足够多时候就在服务器上建立了一张巨大的WiFi信息网络;
    • 当一个设备处在这样的网络中时,可以将收集到的这些能够标示AP的数据发送到位置服务器,服务器检索出每一个AP的地理位置,并结合每个信号的强弱程度,计算出设备的地理位置并返回到用户设备,其计算方式和基站定位位置计算方式相似,也是利用三点定位或多点定位技术;
    • 位置服务商要不断更新、补充自己的数据库,以保证数据的准确性。当某些WiFi信息不在数据库中时,可以根据附近其他的WiFi位置信息推断出未知WiFi的位置信息,并上传服务器。
    * AGPS定位

    AGPS(AssistedGPS:辅助全球卫星定位系统)是结合GSM/GPRS与传统卫星定位,利用基地台代送辅助卫星信息,以缩减GPS芯片获取卫星信号的延迟时间,受遮盖的室内也能借基地台讯号弥补,减轻GPS芯片对卫星的依赖度。AGPS利用手机基站的信号,辅以连接远程定位服务器的方式下载卫星星历 (英语:Almanac Data),再配合传统的GPS卫星接受器,让定位的速度更快。是一种结合网络基站信息和GPS信息对移动台进行定位的技术,既利用全球卫星定位系统GPS,又利用移动基站,解决了GPS覆盖的问题,可以在2代的G、C网络和3G网络中使用。

    1.伪装定位思路

    在了解到上述手机定位原理后,结合平时对手机的使用我们可以得知手机定位最常用的几种方式分别是:

    • WiFi
    • GPS定位
    • 基站定位

    Xposed的便利之处就是提供方法使得我们可以改变系统函数和应用中的函数执行前和执行后的结果。所以设想是否可以利用XPosed框架提供的功能编写一个Hook模块,勾取系统调用中和定位相关的函数并篡改返回值呢?

    2.相关函数

    经过查阅资料和阅读安卓源码,粗略找到以下几个类和相关的方法和定位有关,并对其进行Hook操作。下面是我进行Hook的类及其中的方法名:

    • android.telephony.TelephonyManager
      • getCellLocation
      • getPhoneCount
      • getNeighboringCellInfo
      • getAllCellInfo
    • android.telephony.PhoneStateListener
      • onCellLocationChanged
      • onCellInfoChanged
    • android.net.wifi.WifiManager
      • getScanResults
      • getWifiState
      • isWifiEnabled
    • android.net.wifi.WifiInfo
      • getMacAddress
      • getSSID
      • getBSSID
    • android.net.NetworkInfo
      • getTypeName
      • isConnectedOrConnecting
      • isConnected
      • isAvailable
    • android.telephony.CellInfo
      • isRegistered
    • LocationManager.class
      • getLastLocation
      • getLastKnownLocation
      • getProviders
      • getBestProvider
      • addGpsStatusListener
      • addNmeaListener
    • android.location.LocationManager
      • getGpsStatus

    3.解释

    由于上述方法太多,这里只解释基本的思想。这些方法的作用及参数和返回值都能在Android开发手册中找到,逐条hook并修改返回值即可。我们要做的其实就是利用Hook手段,让手机认为gps是目前最好的位置提供器,并修改其返回值为我们想要的位置,从而达到伪装位置的目的。但是为什么上面列出如此众多的方法需要我们Hook呢?这是因为手机中的定位是一连串比较复杂的过程,是一套各参数匹配的过程。任何一个相关函数的返回值和最终我们填入的结果不吻合,都可能导致伪装定位的失败。所以我们要做的就是找到并Hook定位流程相关的方法并拦截修改返回值。
    附上:Android开发手册

    4.效果截图

    选择伪装地点

    上图是我将核心Hook模块实现后利用百度地图做了一个简单的欺骗位置小软件。


    伪装微信定位

    5.核心Hook模块代码

    package com.example.administrator.hook;
    
    import android.location.Criteria;
    import android.location.GpsStatus;
    import android.location.Location;
    import android.location.LocationListener;
    import android.location.LocationManager;
    import android.os.Build;
    import android.os.SystemClock;
    import android.telephony.CellIdentityCdma;
    import android.telephony.CellIdentityGsm;
    import android.telephony.CellIdentityLte;
    import android.telephony.CellIdentityWcdma;
    import android.telephony.CellInfoCdma;
    import android.telephony.CellInfoGsm;
    import android.telephony.CellInfoLte;
    import android.telephony.CellInfoWcdma;
    import android.telephony.CellLocation;
    import android.telephony.gsm.GsmCellLocation;
    
    import java.lang.reflect.Method;
    import java.lang.reflect.Modifier;
    import java.util.ArrayList;
    import java.util.List;
    
    import de.robv.android.xposed.XC_MethodHook;
    import de.robv.android.xposed.XposedBridge;
    import de.robv.android.xposed.XposedHelpers;
    
    /**
     * Created by CaptainXero on 2016/8/31 0031.
     */
    
    
    
    public class HookUtils {
        public static void HookAndChange(ClassLoader classLoader, final double latitude, final double longtitude, final int lac, final int cid) {
    
            XposedHelpers.findAndHookMethod("android.telephony.TelephonyManager", classLoader,
                    "getCellLocation", new XC_MethodHook() {
                        @Override
                        protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                            GsmCellLocation gsmCellLocation = new GsmCellLocation();
                            gsmCellLocation.setLacAndCid(lac, cid);
                            param.setResult(gsmCellLocation);
                        }
                    });
    
            XposedHelpers.findAndHookMethod("android.telephony.PhoneStateListener", classLoader,
                    "onCellLocationChanged", CellLocation.class, new XC_MethodHook() {
                        @Override
                        protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                            GsmCellLocation gsmCellLocation = new GsmCellLocation();
                            gsmCellLocation.setLacAndCid(lac, cid);
                            param.setResult(gsmCellLocation);
                        }
                    });
    
            if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) {
                XposedHelpers.findAndHookMethod("android.telephony.TelephonyManager", classLoader,
                        "getPhoneCount", new XC_MethodHook() {
                            @Override
                            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                                param.setResult(1);
                            }
                        });
            }
    
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
                XposedHelpers.findAndHookMethod("android.telephony.TelephonyManager", classLoader,
                        "getNeighboringCellInfo", new XC_MethodHook() {
                            @Override
                            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                                param.setResult(new ArrayList<>());
                            }
                        });
            }
    
            if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN) {
                XposedHelpers.findAndHookMethod("android.telephony.TelephonyManager", classLoader,
                        "getAllCellInfo", new XC_MethodHook() {
                            @Override
                            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                                param.setResult(getCell(460, 0, lac, cid, 0, 0));
                            }
                        });
                XposedHelpers.findAndHookMethod("android.telephony.PhoneStateListener", classLoader,
                        "onCellInfoChanged", List.class, new XC_MethodHook() {
                            @Override
                            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                                param.setResult(getCell(460, 0, lac, cid, 0,0));
                            }
                        });
            }
    
            XposedHelpers.findAndHookMethod("android.net.wifi.WifiManager", classLoader, "getScanResults", new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    param.setResult(new ArrayList<>());
                }
            });
    
            XposedHelpers.findAndHookMethod("android.net.wifi.WifiManager", classLoader, "getWifiState", new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    param.setResult(1);
                }
            });
    
            XposedHelpers.findAndHookMethod("android.net.wifi.WifiManager", classLoader, "isWifiEnabled", new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    param.setResult(true);
                }
            });
    
            XposedHelpers.findAndHookMethod("android.net.wifi.WifiInfo", classLoader, "getMacAddress", new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    param.setResult("00-00-00-00-00-00-00-00");
                }
            });
    
            XposedHelpers.findAndHookMethod("android.net.wifi.WifiInfo", classLoader, "getSSID", new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    param.setResult("null");
                }
            });
    
            XposedHelpers.findAndHookMethod("android.net.wifi.WifiInfo", classLoader, "getBSSID", new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    param.setResult("00-00-00-00-00-00-00-00");
                }
            });
    
    
            XposedHelpers.findAndHookMethod("android.net.NetworkInfo", classLoader,
                    "getTypeName", new XC_MethodHook() {
                        @Override
                        protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                            param.setResult("WIFI");
                        }
                    });
            XposedHelpers.findAndHookMethod("android.net.NetworkInfo", classLoader,
                    "isConnectedOrConnecting", new XC_MethodHook() {
                        @Override
                        protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                            param.setResult(true);
                        }
                    });
    
            XposedHelpers.findAndHookMethod("android.net.NetworkInfo", classLoader,
                    "isConnected", new XC_MethodHook() {
                        @Override
                        protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                            param.setResult(true);
                        }
                    });
    
            XposedHelpers.findAndHookMethod("android.net.NetworkInfo", classLoader,
                    "isAvailable", new XC_MethodHook() {
                        @Override
                        protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                            param.setResult(true);
                        }
                    });
    
            XposedHelpers.findAndHookMethod("android.telephony.CellInfo", classLoader,
                    "isRegistered", new XC_MethodHook() {
                        @Override
                        protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                            param.setResult(true);
                        }
                    });
    
            XposedHelpers.findAndHookMethod(LocationManager.class, "getLastLocation", new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    Location l = new Location(LocationManager.GPS_PROVIDER);
                    l.setLatitude(latitude);
                    l.setLongitude(longtitude);
                    l.setAccuracy(100f);
                    l.setTime(System.currentTimeMillis());
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                        l.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
                    }
                    param.setResult(l);
                }
            });
    
            XposedHelpers.findAndHookMethod(LocationManager.class, "getLastKnownLocation", String.class, new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    Location l = new Location(LocationManager.GPS_PROVIDER);
                    l.setLatitude(latitude);
                    l.setLongitude(longtitude);
                    l.setAccuracy(100f);
                    l.setTime(System.currentTimeMillis());
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                        l.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
                    }
                    param.setResult(l);
                }
            });
    
    
            XposedBridge.hookAllMethods(LocationManager.class, "getProviders", new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    ArrayList<String> arrayList = new ArrayList<>();
                    arrayList.add("gps");
                    param.setResult(arrayList);
                }
            });
    
            XposedHelpers.findAndHookMethod(LocationManager.class, "getBestProvider", Criteria.class, Boolean.TYPE, new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    param.setResult("gps");
                }
            });
    
            XposedHelpers.findAndHookMethod(LocationManager.class, "addGpsStatusListener", GpsStatus.Listener.class, new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    if (param.args[0] != null) {
                        XposedHelpers.callMethod(param.args[0], "onGpsStatusChanged", 1);
                        XposedHelpers.callMethod(param.args[0], "onGpsStatusChanged", 3);
                    }
                }
            });
    
            XposedHelpers.findAndHookMethod(LocationManager.class, "addNmeaListener", GpsStatus.NmeaListener.class, new XC_MethodHook() {
                @Override
                protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                    param.setResult(false);
                }
            });
    
            XposedHelpers.findAndHookMethod("android.location.LocationManager", classLoader,
                    "getGpsStatus", GpsStatus.class, new XC_MethodHook() {
                        @Override
                        protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                            GpsStatus gss = (GpsStatus) param.getResult();
                            if (gss == null)
                                return;
    
                            Class<?> clazz = GpsStatus.class;
                            Method m = null;
                            for (Method method : clazz.getDeclaredMethods()) {
                                if (method.getName().equals("setStatus")) {
                                    if (method.getParameterTypes().length > 1) {
                                        m = method;
                                        break;
                                    }
                                }
                            }
                            if (m == null)
                                return;
    
                            //access the private setStatus function of GpsStatus
                            m.setAccessible(true);
    
                            //make the apps belive GPS works fine now
                            int svCount = 5;
                            int[] prns = {1, 2, 3, 4, 5};
                            float[] snrs = {0, 0, 0, 0, 0};
                            float[] elevations = {0, 0, 0, 0, 0};
                            float[] azimuths = {0, 0, 0, 0, 0};
                            int ephemerisMask = 0x1f;
                            int almanacMask = 0x1f;
    
                            //5 satellites are fixed
                            int usedInFixMask = 0x1f;
    
                            XposedHelpers.callMethod(gss, "setStatus", svCount, prns, snrs, elevations, azimuths, ephemerisMask, almanacMask, usedInFixMask);
                            param.args[0] = gss;
                            param.setResult(gss);
                            try {
                                m.invoke(gss, svCount, prns, snrs, elevations, azimuths, ephemerisMask, almanacMask, usedInFixMask);
                                param.setResult(gss);
                            } catch (Exception e) {
                                XposedBridge.log(e);
                            }
                        }
                    });
    
            for (Method method : LocationManager.class.getDeclaredMethods()) {
                if (method.getName().equals("requestLocationUpdates")
                        && !Modifier.isAbstract(method.getModifiers())
                        && Modifier.isPublic(method.getModifiers())) {
                    XposedBridge.hookMethod(method, new XC_MethodHook() {
                        @Override
                        protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                            if (param.args.length >= 4 && (param.args[3] instanceof LocationListener)) {
    
                                LocationListener ll = (LocationListener) param.args[3];
    
                                Class<?> clazz = LocationListener.class;
                                Method m = null;
                                for (Method method : clazz.getDeclaredMethods()) {
                                    if (method.getName().equals("onLocationChanged") && !Modifier.isAbstract(method.getModifiers())) {
                                        m = method;
                                        break;
                                    }
                                }
                                Location l = new Location(LocationManager.GPS_PROVIDER);
                                l.setLatitude(latitude);
                                l.setLongitude(longtitude);
                                l.setAccuracy(10.00f);
                                l.setTime(System.currentTimeMillis());
                                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                                    l.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
                                }
                                XposedHelpers.callMethod(ll, "onLocationChanged", l);
                                try {
                                    if (m != null) {
                                        m.invoke(ll, l);
                                    }
                                } catch (Exception e) {
                                    XposedBridge.log(e);
                                }
                            }
                        }
                    });
                }
    
                if (method.getName().equals("requestSingleUpdate ")
                        && !Modifier.isAbstract(method.getModifiers())
                        && Modifier.isPublic(method.getModifiers())) {
                    XposedBridge.hookMethod(method, new XC_MethodHook() {
                        @Override
                        protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                            if (param.args.length >= 3 && (param.args[1] instanceof LocationListener)) {
    
                                LocationListener ll = (LocationListener) param.args[3];
    
                                Class<?> clazz = LocationListener.class;
                                Method m = null;
                                for (Method method : clazz.getDeclaredMethods()) {
                                    if (method.getName().equals("onLocationChanged") && !Modifier.isAbstract(method.getModifiers())) {
                                        m = method;
                                        break;
                                    }
                                }
    
                                try {
                                    if (m != null) {
                                        Location l = new Location(LocationManager.GPS_PROVIDER);
                                        l.setLatitude(latitude);
                                        l.setLongitude(longtitude);
                                        l.setAccuracy(100f);
                                        l.setTime(System.currentTimeMillis());
                                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                                            l.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
                                        }
                                        m.invoke(ll, l);
                                    }
                                } catch (Exception e) {
                                    XposedBridge.log(e);
                                }
                            }
                        }
                    });
                }
            }
        }
    
        private static ArrayList getCell(int mcc, int mnc, int lac, int cid, int sid, int networkType) {
            ArrayList arrayList = new ArrayList();
            CellInfoGsm cellInfoGsm = (CellInfoGsm) XposedHelpers.newInstance(CellInfoGsm.class);
            XposedHelpers.callMethod(cellInfoGsm, "setCellIdentity", XposedHelpers.newInstance(CellIdentityGsm.class, new Object[]{Integer.valueOf(mcc), Integer.valueOf(mnc), Integer.valueOf(
                    lac), Integer.valueOf(cid)}));
            CellInfoCdma cellInfoCdma = (CellInfoCdma) XposedHelpers.newInstance(CellInfoCdma.class);
            XposedHelpers.callMethod(cellInfoCdma, "setCellIdentity", XposedHelpers.newInstance(CellIdentityCdma.class, new Object[]{Integer.valueOf(lac), Integer.valueOf(sid), Integer.valueOf(cid), Integer.valueOf(0), Integer.valueOf(0)}));
            CellInfoWcdma cellInfoWcdma = (CellInfoWcdma) XposedHelpers.newInstance(CellInfoWcdma.class);
            XposedHelpers.callMethod(cellInfoWcdma, "setCellIdentity", XposedHelpers.newInstance(CellIdentityWcdma.class, new Object[]{Integer.valueOf(mcc), Integer.valueOf(mnc), Integer.valueOf(lac), Integer.valueOf(cid), Integer.valueOf(300)}));
            CellInfoLte cellInfoLte = (CellInfoLte) XposedHelpers.newInstance(CellInfoLte.class);
            XposedHelpers.callMethod(cellInfoLte, "setCellIdentity", XposedHelpers.newInstance(CellIdentityLte.class, new Object[]{Integer.valueOf(mcc), Integer.valueOf(mnc), Integer.valueOf(cid), Integer.valueOf(300), Integer.valueOf(lac)}));
            if (networkType == 1 || networkType == 2) {
                arrayList.add(cellInfoGsm);
            } else if (networkType == 13) {
                arrayList.add(cellInfoLte);
            } else if (networkType == 4 || networkType == 5 || networkType == 6 || networkType == 7 || networkType == 12 || networkType == 14) {
                arrayList.add(cellInfoCdma);
            } else if (networkType == 3 || networkType == 8 || networkType == 9 || networkType == 10 || networkType == 15) {
                arrayList.add(cellInfoWcdma);
            }
            return arrayList;
        }
    }
    
    
    

    相关文章

      网友评论

      • zp_xu:你好,正在做这一块的东西,方便可以留个联系方式请教一下吗
      • allenZP:厉害了
      • 我还没有吃饱:感谢LZ的帖子,内个,强迫症想问一下相关函数那块最后的LocationManager.class和android.location.LocationManager,是一个东西吧?还是有什么需要注意的地方?
      • Luat物联网通信模块:可以关注下Luat开源项目,基于Air200 GPRS模块(价格才12块多),基于Lua开发应用软件,超级容易上手。 完美支持mqtt,而且开发点阵LCD 的UI 非常方便,有丰富的底层库,支持中文很方便。
      • 4f8ffd8a2382:你好 楼主 这个hook可以反应经纬度到服务器么 可以留个联系方式么
      • 卓桐:楼主你测试过能不能欺骗百度地图?
        另外你这个是不是要真的打开gps并且gps搜星定位成功以后才能欺骗?
      • 7fb907cf2307:博主你好 在HookUtils.HookAndChange是这样调用的吗?前三个参数 分别是classLoader 经度 纬度 最后两个参数怎么填写
        public class GPSHooker implements IXposedHookLoadPackage {

        @Override
        public void handleLoadPackage( XC_LoadPackage.LoadPackageParam loadPackageParam ) throws Throwable {
        HookUtils.HookAndChange(loadPackageParam.classLoader,24.441652,118.070755,14608,60541);
        }
        }
      • 大肠杆菌1234:博主你好 我按照步骤使用 xposed框架的日志出现illegalexception 网上都说是因为jar包放在了libs中 应该放在lib中
        我已经放在了lib中啊
      • 智能智控:博主 , 有点急 在线等 谢谢!
        大肠杆菌1234:@程序猿_帆Sir 哥们实现了吗
      • 智能智控:博主您好! 我是xposed小白,我想问下ClassLoader classLoader, final double latitude, final double longtitude, final int lac, final int cid 这几个参数,classLoader,lac和cid是什么参数,谢谢博主指导一下,谢谢!!
      • 896f273371cc:博主,这个是在demo里点击一个地方获取经纬度给微信吗? 能不能提供源码看,我正在学习这个 :flushed:
        CaptainXero:@luoqize1 我在文章里附上了hook代码在后面
      • 784efc23beb8:作者 你好 ,陌陌和探探的 模拟暂不支持
        784efc23beb8:就是hook基站,强制性hook附近没有基站,强制执行gps定位吗
        CaptainXero:@784efc23beb8 可能是基于基站定位,需要hook基站编号
      • 7fe6d06c1958:可以分享以下源码吗 谢谢
        CaptainXero:@304182808 目前来看,短时间内进行距离很远的不同地点定位,会被认为是异常状态。是会被冻结账号的,所以不要短时间内进行较大的连续地址变化。另外hook只有执行到相应的API才会触发
        7fe6d06c1958:@CaptainXero 已经成功欺骗到微信的定位,地址任意更改都可以查到当前位置的附近的人,
         两个疑问: 1 这段hook代码要是不加 if (!paramLoadPackageParam.packageName.equals("com.tencent.mm")) {
        return;
        } 的话,即开机就hook 系统会无法启动。
        2 这总hook操作会不会被微信封号处理?
        CaptainXero:@304182808 后面附上的就是全部hook模块代码
      • ba3290405a7c:赞,支持作者,希望可以交流交流,在下在XP框架这块比较小白
        另外可以分享一下源码吗?
        CaptainXero:@nany233 这样吧,忙完这几天我再详细写一个包含地图模块的博客。到时候请关注
        ba3290405a7c:@CaptainXero :sob:抱歉啦, 没成功hook, 但是Xposed有日志, 希望得到你的源码
        729782436@qq.ocm
        CaptainXero:@nany233 您好,我也是刚接触这个。另外后面附上的就是全部的hook代码

      本文标题:Android之基于Xposed的模拟位置模块实现

      本文链接:https://www.haomeiwen.com/subject/eammettx.html