iOS 15及以上
CLLocation
新增了sourceInformation
(信息来源)属性,该属性为CLLocationSourceInformation
对象。
CLLocationSourceInformation
属性:
-
isSimulatedBySoftware
如果检测到该位置是由软件模拟器(如Xcode
)生成的,则设置为YES
。 -
isProducedByAccessory
如果该位置是由外部附件(如CarPlay
或MFi
附件)生成的,则设置为YES
。
iOS15以下
项目中使用的高德定位,所以高德为例。
连续定位数据通过- (void)amapLocationManager:(AMapLocationManager *)manager didUpdateLocation:(CLLocation *)location reGeocode:(AMapLocationReGeocode *)reGeocode;
方法返回。
通过软件修改
/**
虽然第三方app可以修改位置,只是修改了经纬度,但是其他数据并没有修改,比如海拔垂直精度等数据,我们可以从这些参数入手
NSLog(@"定位信息:%lf,%lf,%lf,%lf,%lf,%lf,%lf",location.coordinate.latitude,location.coordinate.longitude,location.horizontalAccuracy,location.verticalAccuracy,location.altitude,location.course,location.courseAccuracy,location.speed);
Xcode:22.281960,114.163171,5.000000,-1.000000,0.000000,-1.000000,-1.000000,-1.000000
爱思助手:30.879535,120.934785,5.000000,-1.000000,0.000000,-1.000000,-1.000000,-1.000000
*/
NSLog(@"定位信息:%lf,%lf,%lf,%lf,%lf,%lf,%lf",location.coordinate.latitude,location.coordinate.longitude,location.horizontalAccuracy,location.verticalAccuracy,location.altitude,location.course,location.speed);
if (-1.0 == location.verticalAccuracy&&0.0 == location.altitude) {
NSLog(@"虚拟定位");
}
外设硬件
原理
内容摘抄至未越狱iPhone修改定位/iPhone虚拟定位/iPhone模拟定位,苹果MFi外设。
它主要是利用了苹果的通用外设协议,集成MFi芯片,注册成为外置的GPS设备,然后更新系统位置,能够对包括微信在内的所有应用生效。更具体一点说,硬件需要集成苹果的MFi芯片,然后利用了iAP2中的两种协议:External Accessory Protocol和Location Information,大概原理如下:
(1)模拟定位的App 使用 EA协议跟外设连接。这个App集成了地图SDK,主要用途就是方便用户进行搜索或者地图点选来获取想要虚拟定位的GPS信息,然后通过EA通道使用自定义的数据协议把用户选好的GPS信息发送给硬件。
(2)硬件从EA通道接收到GPS信息之后,根据iAP2中的Location Information协议把GPS信息进行编码,发送给iOS系统。
(3)iOS系统接收到硬件通过Location Information协议过来的GPS信息之后,就会把整个系统底层的定位信息更新,这样包括微信在内的所有应用的定位都修改成了刚刚选择的模拟定位点了。
苹果为什么要开放这样一个可以修改系统定位的外设协议呢?
1133568-132844258643a205.jpg从这段苹果官方文档的描述可以看到,主要目的是为了提高定位精度,提升某些场合的用户体验。比如汽车的GPS模块定位精度要比iPhone高,如果能够把汽车的GPS信息发给iPhone,那iPhone上的导航体验就会好很多。
当然上面这种通过MFi芯片进行模拟定位的硬件,肯定是过不了苹果的MFi认证的。只能够去黑市购买MFi芯片,然后开发走线下渠道销售,App也上不了App Store,只能通过企业证书分发。
预防
内容摘抄至iOS 外接设备虚拟GPS心得。
使用EADSessionController类,苹果不支持获取所有外设的信息,只能获取签过协议的外设信息,所以首先需要找到外设的协议,将要禁止使用的外设的协议添加到info.plist文件的Supported external accessory protocols中,然后通过EADSessionController类的connectedAccessories方法获取是否链接了要禁止使用的外设,如果监测到,则说明正在使用禁止的外设。(只有知道要禁止的外设协议才可以禁止外设)
外设的协议是一个反向域名组成的字符串,由硬件的生产厂商定义的;这里讲一下我是如何拿到与app连接的外设协议,首先通过上面app下载链接将其ipa包下载下来,然后将ipa后缀改成zip,解压,右键选择“显示包内容”,找到info.plist文件,在plist文件下的Supported external accessory protocols值就是该外设的协议,将这个值添加到自己app的plist文件中即可。
检测方法:
#import <ExternalAccessory/ExternalAccessory.h>
//外设链接
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_accessoryDidConnect:) name:EAAccessoryDidConnectNotification object:nil];
//外设断开
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_accessoryDidDisconnect:) name:EAAccessoryDidDisconnectNotification object:nil];
//监听
[[EAAccessoryManager sharedAccessoryManager] registerForLocalNotifications];
//外设数据
[[EAAccessoryManager sharedAccessoryManager] connectedAccessories];
demo链接:EADemo
高德
AMapLocationManager
属性detectRiskOfFakeLocation
。
///检测是否存在虚拟定位风险,默认为NO,不检测。 \n注意:设置为YES时,单次定位通过 AMapLocatingCompletionBlock 的error给出虚拟定位风险提示;连续定位通过 amapLocationManager:didFailWithError: 方法的error给出虚拟定位风险提示。error格式为 error.domain==AMapLocationErrorDomain; error.code==AMapLocationErrorRiskOfFakeLocation; \n附带的error的详细信息参考 error.localizedDescription 中的描述以及 error.userInfo 中的信息(error.userInfo.AMapLocationRiskyLocateResult 表示有虚拟风险的定位结果; error.userInfo.AMapLocationAccessoryInfo 表示外接辅助设备信息)。
@property (nonatomic, assign) BOOL detectRiskOfFakeLocation;
测试了下,不起作用。
参考文章
苹果虚拟定位技术原理和检测
IOS 越狱插件-虚拟定位、WIFI修改
ios开发上班打卡防虚拟定位篡改
iOS 外接设备虚拟GPS心得
如何设置iOS虚拟定位
未越狱iPhone修改定位/iPhone虚拟定位/iPhone模拟定位,苹果MFi外设
网友评论