Android虚拟定位

Android虚拟定位
William C.Android虚拟定位
项目地址
- 下载方式
打开项目,点击右边的releases,听说先点个右上角的Star成功率会更高😁。
进入新的页面可以看到各个历史版本,选择最上面的(也就是最新的)版本的apk文件 单击下载。
原理分析
地图与定位
本APP地图与定位是使用的百度地图开放平台能力,目前国内的三家主流地图应用(百度、腾讯、高德)都有对个人提供免费的SDK。
模拟定位原理
本应用目前使用的是基于开发者模式的位置修改
- 基于开发者模式 的位置修改
实现方式:使用 Android 系统自带的调试 API,模拟 GPS Provider 的结果,从而实现模拟位置的功能。即利用手机自带的位置模拟功能,修改用户获取的位置信息。
Android 系统,在开发者模式中开启允许模拟位置。Android 6.0 以上的系统中开发者模式中去除了”允许模拟器位置“选项,但是增加了”选择模拟位置信息应用“选项。可以通过该选项,选择要开启模拟位置的应用,便可以通过 addTestProvider 进行位置信息模拟。
这是目前最为简单的模拟定位方式,不要求root,缺点就是易于检测。
1 | try { |
- 基于Hook方式 的位置修改
实现方式:对手机 Root 以后,利用 Hook 框架拦截系统或者地图类 SDK 获取位置信息的 API,并用伪造的位置数据替换原有的位置数据,从而实现模拟位置的功能。
以高德地图为例,通过 Xposed 框架对高德地图中获取位置信息的函数进行 Hook,从而达到修改位置信息的目的。
这种方法的缺点就是现在市面上购买的手机难以root。
1 | XposedHelpers.findAndHookMethod(Location.class, "getLongitude", new XC_MethodHook() { |
基于虚拟容器 的位置修改
实现方式:将 APP 安装在虚拟容器内,虚拟容器通过将应用注册到虚拟空间中。以 Xposedvirtual 为例,它是一套插件框架,允许应用以插件的方式运行在其构造的虚拟空间中,并自带 Root 权限和 Xposed Hook 框架,且宿主机无需 Root。这样便可以在任意的设备上利用 Hook 框架拦截系统或者地图类 SDK 获取位置信息的 API,并用伪造的数据替换原有的位置数据,从而实现模拟位置的功能。基于模拟器 的位置修改
实现方式:将 APP 安装在模拟器内,利用模拟器提供的位置修改功能修改模拟器的位置信息,从而实现模拟位置的功能。
以夜神模拟器为例,修改模拟器的位置信息
- 基于修改系统源码 的位置修改
实现方式:修改 Android 系统源码并编译打包,将系统中获取位置信息的 API 暴露出来,暴露的接口可以接收外部自定义的位置信息。当 APP 调用获取位置相关的 API 时,可以通过暴露的接口传入指定的位置信息,从而实现模拟位置的功能。
如何检测模拟定位
基于开发者模式的位置修改检测
- 最暴力,直接检测手机是否打开了开发者模式
1 | private fun checkDeveloperMode() { |
- 检测定位是否来自MockProvider
1 | private fun checkMockLocation() { |
- 检查模拟定位开关
1 | private fun checkMockLocationEnabled() { |
- 检测应用列表,并检测是否有APP申请了模拟定位的权限
android.permission.ACCESS_MOCK_LOCATION。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15private fun checkInstalledAppsForMockPermission() {
val packageManager = packageManager
val installedPackages = packageManager.getInstalledPackages(PackageManager.GET_PERMISSIONS)
val appsWithMockLocation = installedPackages.filter { packageInfo ->
packageInfo.requestedPermissions?.contains("android.permission.ACCESS_MOCK_LOCATION") == true
}
if (appsWithMockLocation.isNotEmpty()) {
textView.append("以下应用拥有模拟定位权限:\n")
appsWithMockLocation.forEach { packageInfo ->
textView.append("- ${packageInfo.packageName}\n")
}
} else {
textView.append("没有应用拥有模拟定位权限\n")
}
}
基于 Hook 方式的位置修改
- 思路:
Hook 方式通常通过 Xposed 或类似框架,拦截和修改系统 API 的返回值,比如 LocationManager、Location 对象的相关方法。因此,检测这种方式主要是识别这些框架的存在和使用。
可以检查系统中是否安装了 Xposed 或 LSPatch 之类的框架,或检测是否存在这些框架的迹象,如特定的系统属性或文件。
检测关键方法是否被 Hook,比如检测 LocationManager 的 getLastKnownLocation() 或 requestLocationUpdates() 的返回值是否被修改过。
- 难易程度:
中等。虽然检测框架的存在相对容易,但如果开发者对 Hook 方法进行了深度隐藏(如通过 LSPatch 无模块显示等),检测难度会增加。
- 注意事项:
要考虑检测方案的兼容性,以免误报合法的系统修改。
如果框架通过高级技术进行隐藏,检测可能会变得非常困难。
基于虚拟容器的位置修改
- 思路:
虚拟容器技术(如 VirtualXposed)通过在虚拟环境中运行应用,拦截和修改系统 API 的返回值,而不需要设备 Root。
可以通过检测应用运行环境是否为虚拟容器来识别,例如检查进程名称、特定的虚拟容器标识文件或特征,或通过系统调用反查虚拟化环境(如查看文件系统特征)。
也可以监控关键系统服务的行为(如 LocationManager),并比对实际设备状态与应用内获取的信息是否一致。
- 难易程度:
中等。虚拟容器环境可能存在一些独特的特征,通过仔细分析可以识别,但不同的虚拟容器实现可能各有差异。
- 注意事项:
虚拟容器的多样性使得需要综合多种检测方法来提高检测的准确性。
容器可能会模拟原生环境,因此要防止虚假阴性(未检测到修改的情况)。
基于模拟器的位置修改
- 思路:
模拟器通常用于开发和测试,具备一系列的虚拟化特征。可以通过检测设备信息是否与实际设备不符(如硬件信息、传感器信息、系统属性等)来识别模拟器。
检查系统属性(如 ro.product.model、ro.hardware)是否匹配常见的模拟器特征(如 “sdk_gphone_x86” 等)。
检测应用权限,模拟器环境中通常会有不同的权限和系统行为。
- 难易程度:
简单到中等。模拟器的特征比较明显,通常很容易被检测到,但如果模拟器进行了深度仿真和伪装,检测难度会提高。
- 注意事项:
需要兼容不同版本的模拟器,不同的模拟器可能会有不同的表现。
有些模拟器可能已经进行了特征伪装,因此检测策略需要持续更新。
基于修改系统源码的位置修改
- 思路:
修改系统源码是通过修改 Android 系统的底层代码实现的,这种方式直接在系统级别修改 API 的行为,绕过了上层检测机制。
检测这种方式主要通过比对系统的关键组件是否被篡改,或使用信任链来验证系统文件的完整性,如验证签名、哈希值等。
检查系统的 SELinux 配置、验证系统文件的完整性(例如关键二进制文件的校验)也是一种方法。
- 难易程度:
困难。这种方式修改较为隐蔽,且往往在较深的系统层面执行,难以通过常规的应用层检测手段识别。
- 注意事项:
系统源码的修改通常非常隐蔽,除非有明确的系统文件完整性检查,否则很难检测。
可能需要结合设备的系统更新状态、签名验证和系统安全策略进行综合评估。
如何绕过的钉钉检测
目前来看,钉钉打卡的检测方式是基于应用列表的检测,可能是一种黑白名单机制,我们在基于发者模式的位置修改 中,只要把我们APP的包名修改为类似系统APP的应用,就能绕过钉钉检测。
不知道钉钉为什么只做这种粗略的检测方式,但是我们要知道,钉钉如果想检测开基于发者模式的位置修改就一定能检测到,所以要谨慎使用模拟定位软件打卡,强需求还是要以root方式去模拟定位。
补充,钉钉还会检测运行环境,上面提及的基于虚拟容器的位置修改 是绕不过钉钉检测的,但是也不一定全都绕不过,这本质就是一个持久对抗的过程,道高一尺魔高一丈。
TODO
目前还在开发Hook方式的位置修改,作为Xposed模块使用,还没有上线,初步测试以及可以修改微信的定位了。
效果展示:

免责声明
本虚拟定位软件的开发旨在提供技术学习与交流的途径。请勿将本软件用于任何形式的作弊、非法或不道德的活动。用户应自行承担因不当使用本软件而导致的所有后果。开发者不对任何因使用本软件产生的直接或间接损害承担责任。











