iOS虚拟定位技术探究

Author: GeneBlue
Blog:
什么是虚拟定位【iOS虚拟定位技术探究】简而言之 , 利用软硬件更改手机系统的定位数据 , 从而让目标 app 获取错误的定位信息
虚拟定位常用场景

  • 上下班打卡
  • 代购
  • 朋友圈装逼
  • 打车软件司机端抢单
  • 社交类软件 , 附近人 , 把妹 , 钓凯子
凡是和位置相关的应用 , 均有一定的应用场景 , 尽情发挥群众的智慧
虚拟定位原理经过调研 iOS 虚拟定位大概有三类技术路线:
动态库注入iOS 越狱后 , 安装使用具备虚拟定位功能的越狱插件 。 在上帝模式下 , 越狱插件可以肆意劫持系统函数 。 或者在非越狱环境下 , 砸壳目标 app ipa 文件 , 重打包注入动态库 。 这两种方式本质是一致的 , 都是为了 app 进程运行时 , 注入运行动态库 。
劫持 CoreLocation 中以下常用的获取定位信息的函数 , 即可篡改正常的定位数据:
CLLocationManager->delegate()CLLocationManager->initialize()CLLocationManager->setDelegate()CLLocationManager->startMonitoringSignificantLocationChanges()CLLocationManager->startUpdatingHeading()CLLocationManager->startUpdatingLocation()CLLocationManager->stopMonitoringSignificantLocationChanges()CLLocationManager->stopUpdatingHeading()CLLocationManager->stopUpdatingLocation()电脑端软件做过 iOS 开发的同学 , 可以观察一下 xcode 上有一个 Simulate location 的调试功能 , 这是方便 app 开发过程中测试定位代码 。
iOS虚拟定位技术探究文章插图
我们可以使用这个功能来模拟定位 。 不过使用这种方式需要打开电脑 , 开启 xcode , 然后再编写 GPX 文件 , 对于普通用户 , 这个门槛太高了 。 国内的一些 iOS 助手类软件 , 将 Simulate location 功能逆向出来 , 集成到自己的软件上 , 比如下面这个 iTools 软件:
iOS虚拟定位技术探究文章插图
闪电口外设典型产品如位移精灵 , 不但具备虚拟定位能力 , 还具备充电宝功能 , 多种用途 , 很方便啊 , 有木有 。
iOS虚拟定位技术探究文章插图
那这个东西是啥原理呢?
解释起来很简单 , 这也是苹果提供的功能 , 不是啥黑科技 。 通过苹果 MFi(Made For iOS) 认证厂商会获得 MFI Accessory Interface Specification 文档 , 其中描述了 USB 与外设之间的通讯协议 iAP2 , 该协议具备许多丰富的功能:
iOS虚拟定位技术探究文章插图
可以看到其中就有 location 定位功能 , 按照协议格式 , 发送对应位置数据 , 就可以更改定位信息 。 电脑端 xcode 是不是也是使用 iAP2 协议呢?xcode 实现文档没有公开过 , 所以这个是未知的 。
检测方法知道了 , 这三种虚拟定位方式 , 我们只要找到正常定位与虚拟定位之间的差异就可以做到检测了
动态库注入有几个明显特征:
  • 越狱环境 , 安装越狱插件 , 其动态库会被注入到目标进程
  • 非越狱环境下 , 砸壳目标ipa , 注入动态库
  • 劫持(HOOK)定位函数
越狱环境可以检查设备是否越狱 , 非越狱可以检查 app 是否被重打包 。 如此 , 检查定位函数是否被劫持比较关键
函数 HOOK 涉及 OC 语言的动态特性 , 主要利用了 method_exchangeImplementations() 将函数实现替换掉 。 被 HOOK 的函数 , 其 IMP 实现会被劫持到注入的动态库中 , 所以我们检查函数 IMP 实现是否是原始 module 即可判断是否被 HOOK 了 。
- (NSString *) getMethodIMPInfo:(NSString *) className, sel:(NSString *)sel {NSString *ret;Dl_info info;IMP imp = class_getMethodImplementation(objc_getClass([className UTF8String]), sel_registerName([sel UTF8String]));if ( dladdr(imp,}return ret;}NSString *ret = getMethodIMPInfo(@"CLLocationManager", @"delegate");电脑端软件使用电脑端软件虚拟定位时 , app 获取定位信息与正常获取定位信息有差异 。
正常获取定位的时代理方法会被执行 3 次:
2020-09-25 14:37:25.587317+0800 iOSApp[990:275020] 纬度为:22.996662, 经度为:113.3284482020-09-25 14:38:00.158517+0800 iOSApp[990:275020] 高度为:23.0319122020-09-25 14:38:04.869490+0800 iOSApp[990:275020] 水平精确度:65.000000, 垂直精确度:10.0000002020-09-25 14:38:22.238887+0800 iOSApp[990:275020] 纬度为:22.996662, 经度为:113.3284482020-09-25 14:38:23.784470+0800 iOSApp[990:275020] 高度为:23.0319122020-09-25 14:38:25.844754+0800 iOSApp[990:275020] 水平精确度:65.000000, 垂直精确度:10.0000002020-09-25 14:38:26.841710+0800 iOSApp[990:275020] 纬度为:22.996667, 经度为:113.3284472020-09-25 14:38:26.842180+0800 iOSApp[990:275020] 高度为:23.0476932020-09-25 14:38:26.842767+0800 iOSApp[990:275020] 水平精确度:65.000000, 垂直精确度:10.000000