前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >安卓虚拟定位

安卓虚拟定位

作者头像
大A
发布2023-02-14 19:24:48
2.5K0
发布2023-02-14 19:24:48
举报
文章被收录于专栏:爱打音游的大A

前言

  安卓虚拟定位技术已经出现很多年了,对于现在来说并不是什么新鲜技术,但是实际上我自己并没有使用过,因为暂时没有需求。然而最近需求来了,想找个现成的工具居然要我开会员,无奈只好自己学习一下相关的知识。

无Root虚拟定位

  很多人(包括我自己)可能想当然的认为安卓上的虚拟定位必须依赖于Root权限,其实不然,在非Root的情况下也能实现一定程度上的虚拟定位,那就是借助开发者模式中的模拟位置功能。可以参考这篇文章

  开发者模式中提供了模拟位置的接口,能够自己开发一个用于模拟位置的app,只要在Manifest中声明权限"android.permission.ACCESS_MOCK_LOCATION"后,即可在开发者选项-选择模拟位置信息应用中选择这个app,具体任何模拟位置则由app中的实现决定,我暂时没有亲自试过,可以知道的是,使用这种方法能够实现百度地图的虚拟定位,但是对于其他很多主流app是无法生效的,所以其实算是比较鸡肋,因为这个功能原来就是设计给开发者使用的。

Root虚拟定位

  在有Root的情况下,理论上虚拟定位能够对所有app生效。不讨论某些大厂的极端情况,一般来说,应用获取位置信息的来源有3个:

  1. 移动网络
  2. WIFI
  3. GPS

  我们只要能够篡改这三个来源的数据就能实现虚拟定位的功能。我们需要知道的就是与这三个来源相关的所有API,并对其进行合理的篡改。参考这篇文章,我们可以知道很多相关的重要接口以及篡改思路,并且文末有个xposed插件,可以实现企业微信的虚拟定位。但是由于代码中写死了企业微信的包名,所以只能对企业微信生效,其实现在有LSPosed可以指定模块只对特定的app生效,所以已经没必要用以往的包名限定写法来写xposed插件了。这边我将其hook的对象包名改成com.tencent.mm即微信,测试后证明了该插件经久不衰,即使时隔多年也依然能对最新版本的微信生效后,我阅读了它的源码,并参考其主要hook逻辑,实现了对应的frida版本,虽然没有100%对所有的API进行hook,但是已经能够生效。

代码如下:

代码语言:javascript
复制
var Latitude = 30
var Longitude = 120

Java.perform(()=>{
    var telMng = Java.use("android.telephony.TelephonyManager")
    var ArrayList = Java.use("java.util.ArrayList")
    telMng.getCellLocation.implementation = function(){
        console.log("getCellLocation")
        return null
    }

    telMng.getNeighboringCellInfo.implementation = function(){
        console.log("getNeighboringCellInfo")
        return null
    }

    telMng.getAllCellInfo.implementation = function(){
        console.log("getAllCellInfo")
        return null
    }

    telMng.getPhoneCount.implementation = function(){
        console.log("getPhoneCount")
        return 1
    }

    var phoneStateListener = Java.use("android.telephony.PhoneStateListener")
    phoneStateListener.onCellLocationChanged.implementation = function(){
        console.log("onCellLocationChanged")
    }

    // phoneStateListener.onCellInfoChanged.implementation = function(){
    //     console.log("onCellInfoChanged")
    //     return this.onCellInfoChanged.apply(this,arguments)
    // }

    var WifiManager = Java.use("android.net.wifi.WifiManager")
    WifiManager.getScanResults.implementation = function(){
        console.log("getScanResults")
        return ArrayList.$new()
    }

    WifiManager.getWifiState.implementation = function(){
        console.log("getWifiState")
        return 1
    }

    WifiManager.isWifiEnabled.implementation = function(){
        console.log("isWifiEnabled")
        return true
    }


    var WifiInfo = Java.use("android.net.wifi.WifiInfo")
    WifiInfo.getMacAddress.implementation = function(){
        console.log("getMacAddress")
        return "00-00-00-00-00-00-00-00"
    }

    WifiInfo.getSSID.implementation = function(){
        console.log("getSSID")
        return null
    }

    WifiInfo.getBSSID.implementation = function(){
        console.log("getBSSID")
        return "00-00-00-00-00-00-00-00"
    }

    var NetworkInfo = Java.use("android.net.NetworkInfo")
    NetworkInfo.getTypeName.implementation = function(){
        console.log("getTypeName")
        return "WIFI"
    }

    NetworkInfo.isConnectedOrConnecting.implementation = function(){
        console.log("isConnectedOrConnecting")
        return true
    }

    NetworkInfo.isConnected.implementation = function(){
        console.log("isConnected")
        return true
    }

    NetworkInfo.isAvailable.implementation = function(){
        console.log("isAvailable")
        return true
    }

    var CellInfo = Java.use("android.telephony.CellInfo")
    CellInfo.isRegistered.implementation = function(){
        console.log("isRegistered")
        return true
    }

    var LocationManager = Java.use("android.location.LocationManager")
    var Location = Java.use("android.location.Location")
    LocationManager.getLastLocation.implementation = function(){
        console.log("getLastLocation")
        var location = Location.$new(LocationManager.GPS_PROVIDER.value)
        location.setLatitude(Latitude)
        location.setLongitude(Longitude)
        location.setAccuracy(100)
        location.setTime(new Date().getTime())
        return location
    }

    LocationManager.getLastKnownLocation.implementation = function(){
        console.log("getLastKnownLocation")
        var location = Location.$new(LocationManager.GPS_PROVIDER.value)
        location.setLatitude(Latitude)
        location.setLongitude(Longitude)
        location.setAccuracy(100)
        location.setTime(new Date().getTime())
        return location
    }    

    LocationManager.getProviders.overload('boolean').implementation = function(){
        console.log("getProviders1")
        var array = ArrayList.$new()
        array.add("gps")
        return array
    }

    LocationManager.getProviders.overload('android.location.Criteria', 'boolean').implementation = function(){
        console.log("getProviders2")
        var array = ArrayList.$new()
        array.add("gps")
        return array
    }

    LocationManager.getBestProvider.implementation = function(){
        console.log("getBestProvider")
        return "gps"
    }

    LocationManager.addGpsStatusListener.implementation = function(args){
        console.log("addGpsStatusListener")
        var ret = this.addGpsStatusListener(args)
        if(args != null){
            args.onGpsStatusChanged(1)
            args.onGpsStatusChanged(3)
        }
        return ret
    }

    LocationManager.addNmeaListener.overload('android.location.GpsStatus$NmeaListener').implementation = function(){
        console.log("addNmeaListener")
        return false
    }

    // LocationManager.getGpsStatus.implementation = function(){
    //     console.log("getGpsStatus")
    // }
    
})
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-03-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 无Root虚拟定位
  • Root虚拟定位
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档