准备工作
- 上一篇文章知识: //www.greatytc.com/p/fb7343560d39
-
frida-ios-dump
: 用于砸壳 -
class-dump
: 导出头文件 -
lookin
: 用于UI界面的查看 -
theos
: 写Tweak(越狱插件)主要工具 -
vscode
: 写Tweak(越狱插件)主要工具
逆向过程
- 首先使用
frida-ios-dump
对青桔
App进行砸壳
./dump.py 青桔
- 解压砸壳出来的
ipa
文件- 使用
class-dump
导出青桔
App的头文件
class-dump -S -s -H Payload/BlackHorse.app -o ./Header
做好以上工作后就可以开始我们的逆向研究了;
首先使用lookin
查看我们需要页面的vc
类名
从Lookin可以看到这个
vc
的类名为BHHomeController
, 于是直接打开刚才dump出来头文件里对应的文件查看
@interface BHHomeController : UIViewController <...>activityBtnRedDot=_activityBtnRedDot;
- (void)centerPinCom:(id)arg1 didSelectedSearchBubble:(id)arg2;
- (struct CLLocationCoordinate2D)centerScreenCoorinate;
- (void)com:(id)arg1 didNearbyParkingSpotImageClickedWithImageUrlStr:(id)arg2;
- (void)com:(id)arg1 didNearbyParkingSpotSelectedAtIndex:(long long)arg2;
@property(nonatomic) struct CLLocationCoordinate2D findBikeOriginCoor;
@property(nonatomic) struct CLLocationCoordinate2D findParkingSpotOriginCoor;
@property(nonatomic) struct CLLocationCoordinate2D lastQueryCoor;
@property(nonatomic) struct CLLocationCoordinate2D lastQuerySpotCoor;
@property(retain, nonatomic) BHNearbyParkingSpotCom *nearbyparkingSpotCom;
@property(retain, nonatomic) NSArray *parkingSpots;
@property(retain, nonatomic) BHParkingSpot *selectedParkingSpot;
@end
以上列出的仅为本人认为可疑
的ivar
和func
, 经过NSLog
调试输出最终确认为
- (void)com:(id)arg1 didNearbyParkingSpotSelectedAtIndex:(long long)arg2;
这里写一个Tweak对该方法的参数进行打印
%hook BHHomeController
- (void)com:(id)arg1 didNearbyParkingSpotSelectedAtIndex:(long long)arg2 {
NSLog(@"iOSRE: didNearbyParkingSpotSelectedAtIndex: %@ - %@ : %llu", [arg1 class], arg1, arg2);
%orig;
}
%end
就得到了以下输出
iOSRE: didNearbyParkingSpotSelectedAtIndex: BHNearbyParkingSpotCom - <BHNearbyParkingSpotCom: 0x2837531e0> : 1
这里我们得知参数一的class
为BHNearbyParkingSpotCom
, 打开对应头文件查看
@interface BHNearbyParkingSpotCom : NSObject <BHMapEntranceDelegate, BHBizComProtocol>
- (id)annotationsByNearbySpots:(id)arg1 startCoor:(struct CLLocationCoordinate2D)arg2 isShowAnnoCalloutView:(_Bool)arg3;
- (void)didParkingSpotBubbleClicked:(id)arg1;
- (void)mapEntrance:(id)arg1 didSelectAnnotationView:(id)arg2;
- (id)mapEntrance:(id)arg1 viewForAnnotation:(id)arg2;
- (id)mapEntrance:(id)arg1 viewForOverlay:(id)arg2;
@property(nonatomic) __weak ONESBasePointAnnotation *nearestAnno;
@property(retain, nonatomic) NSMutableDictionary *parkingSpotsRegionsDic;
- (void)selectNearestParkingSpot;
- (void)selectParkingSpotByIndex:(long long)arg1;
@property(nonatomic) __weak ONESBasePointAnnotation *selectedAnno;
- (void)showParkingSpotBubbleByParkingSpot:(id)arg1 distance:(id)arg2 walkSecond:(id)arg3 atIndex:(long long)arg4;
- (void)showParkingSpotRegionByParkingSpot:(id)arg1;
- (void)showParkingSpotsRegionByParkingSpots:(id)arg1;
@end
以上列出的仅为本人觉得可疑的ivar
和func
, 通过NSLog
调试输出最终确认为
- (void)mapEntrance:(id)arg1 didSelectAnnotationView:(id)arg2;
于是我们修改Tweak代码, 再次输出这个func
的参数
%hook BHNearbyParkingSpotCom
- (void)mapEntrance:(id)arg1 didSelectAnnotationView:(id)arg2 {
NSLog(@"iOSRE: didSelectAnnotationView: %@ - %@ : %@ - %@", [arg1 class], arg1, [arg2 class], arg2);
%orig;
}
%end
通过上方Tweak我们得到了输出
iOSRE: didSelectAnnotationView: BHMapEntrance - <BHMapEntrance: 0x282df2d60> : ONESBaseAnnotationView - <ONESBaseAnnotationView: 0x281c654a0>
这里有两个参数, arg1
为BHMapEntrance
从名字上分析应该属于地图类不属于停车点, 所以我们打开第二个参数的类ONESBaseAnnotationView
查看
@interface ONESBaseAnnotationView : NSObject <ONESBaseAnnotationViewProtocol>
@property(retain, nonatomic) ONESBasePointAnnotation *annotation;
@end
在这个类里我们发现了一个和上期美团逆向过程中相同的变量名
(没看过的请跳转补充上期文章//www.greatytc.com/p/fb7343560d39)
我们再跳进这个变量的类看看
@interface ONESBasePointAnnotation : NSObject <ONESBaseAnnotation>
@property(nonatomic) struct CLLocationCoordinate2D coordinate;
@end
果不其然发现了定位信息coordinate
梳理一下逻辑:
BHNearbyParkingSpotCom
- (void)mapEntrance:(id)arg1 didSelectAnnotationView:(id)arg2;
arg2
ONESBaseAnnotationView
annotation
coordinate
通过NSLog
输出可以得知这里的内容和上期逆向美团的内容一致, 于是我们可以直接copy
代码过来
%hook BHNearbyParkingSpotCom
- (void)mapEntrance:(id)arg1 didSelectAnnotationView:(id)arg2 {
if ( [arg2 isKindOfClass:[%c(ONESBaseAnnotationView) class]] ) {
id annotation = [arg2 valueForKey:@"annotation"];
id coor = [annotation valueForKey:@"coordinate"];
struct CLLocationCoordinate2D cll;
[coor getValue:&cll];
NSLog(@"iOSRE: arg2: cll: latitude: %f longitude: %f", cll.latitude, cll.longitude);
UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"当前选择位置" message:[NSString stringWithFormat:@"纬度: %f\n经度: %f\n\n建议/bug反馈QQ: 1451925/656469762", cll.longitude, cll.latitude] preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction * setparking = [UIAlertAction actionWithTitle:@"设置为🅿️" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
lat = cll.latitude;
lng = cll.longitude;
}];
UIAlertAction * unSetparking = [UIAlertAction actionWithTitle:@"取消🅿️" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
lat = 0;
lng = 0;
}];
UIAlertAction * copy1 = [UIAlertAction actionWithTitle:@"复制纬度" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
UIPasteboard.generalPasteboard.string = [NSString stringWithFormat:@"%f", cll.latitude];
}];
UIAlertAction * copy2 = [UIAlertAction actionWithTitle:@"复制经度" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
UIPasteboard.generalPasteboard.string = [NSString stringWithFormat:@"%f", cll.longitude];
}];
UIAlertAction * cancel = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
[alert addAction:setparking];
[alert addAction:unSetparking];
[alert addAction:copy1];
[alert addAction:copy2];
[alert addAction:cancel];
[UIApplication.sharedApplication.delegate.window.rootViewController presentViewController:alert animated:YES completion:nil];
}
%orig;
}
最终实现效果如下
点击
设置为🅿️
后我们的定位就在该停车点内啦~
需要该插件和美团插件的可以添加下方我的个人源或者进群下载
Support
个人Cydia源: https://moxcomic.github.io