原理:创建一个动态库利用oc的runtime特性替换定位相关回调方法伪造GPS坐标,然后将动态库注入微信。
伪造GPS坐标
原理图:
替换CLLocationManager的setDelegate:方法,将CLLocationManager的delegate替换为我们自定义的WMLocationProxy代理类,WMLocationProxy持有真正的CLLocationManager的delegate。
1
2
3
4
5
6
| - (void)wm_setDelegate:(id)delegate {
WMLocationProxy *proxy = [[WMLocationProxy alloc] init];
proxy.oLMDelegate = delegate;
self.proxy = proxy;
[self wm_setDelegate:proxy];
}
|
在WMLocationProxy中转发CLLocationManagerDelegate的方法时先替换位置坐标,然后再转发给CLLocationManagerDelegate。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| - (void)forwardInvocation:(NSInvocation *)anInvocation {
if (self.oLMDelegate && [self.oLMDelegate respondsToSelector:anInvocation.selector]) {
if (anInvocation.selector == @selector(locationManager:didUpdateToLocation:fromLocation:)) {
CLLocation *originLocation;
[anInvocation getArgument:&originLocation atIndex:3];
CLLocation *newLocation = [self makeFakeLocationWithOriginLocation:originLocation];
[anInvocation setArgument:&newLocation atIndex:3];
}
if (anInvocation.selector == @selector(locationManager:didUpdateLocations:)) {
__unsafe_unretained NSArray *locations;
[anInvocation getArgument:&locations atIndex:3];
if (locations.count > 0) {
CLLocation *originLocation = locations[0];
CLLocation *fakeLocation = [self makeFakeLocationWithOriginLocation:originLocation];
NSArray *fakeLocations = @[fakeLocation];
self.orginLocations = fakeLocations;
[anInvocation setArgument:&fakeLocations atIndex:3];
}
}
[anInvocation invokeWithTarget:self.oLMDelegate];
}
}
|
动态库(Dynamic library)注入
iOS8发布之后Xcode允许创建动态库,我们可以创建一个动态库和原ipa文件合并重新打包ipa。具体参考iOSDylibInjectionDemo
stackoverflow关于动态库的问题可以看看