关于青桔电单车插件的编写过程

准备工作


  • 上一篇文章知识: //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

从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

以上列出的仅为本人认为可疑ivarfunc, 经过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

这里我们得知参数一的classBHNearbyParkingSpotCom, 打开对应头文件查看

@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

以上列出的仅为本人觉得可疑的ivarfunc, 通过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>

这里有两个参数, arg1BHMapEntrance从名字上分析应该属于地图类不属于停车点, 所以我们打开第二个参数的类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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,001评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,210评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,874评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,001评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,022评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,005评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,929评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,742评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,193评论 1 309
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,427评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,583评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,305评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,911评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,564评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,731评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,581评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,478评论 2 352