基于MonkeyDev实现不越狱修改钉钉位置打卡和签到

第一步
安装MonkeyDev
详细教程可参考https://www.jianshu.com/p/8ecbafb8abc0或者https://github.com/AloneMonkey/MonkeyDev/wiki 

第二步获取砸壳后的钉钉APP 
获取方法:
1.如果没有越狱手机,可通过PP助手直接下载钉钉
基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第1张图片 
2.如果有越狱手机,可通过Clutch等命令对APPStore上下载的钉钉进行砸壳Clutch砸壳详细教程可参考https://www. jianshu.com/p/979fe886e28e 
砸壳前越狱手机需要打开SSH通道

第三步

对砸壳后的钉钉进行hook操作
1.有了MonkeyDev就简单多了,首先打开Xcode创建一个MonkeyApp项目

基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第2张图片 

2.进入新建的项目,右键Show in Finder 

基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第3张图片 

3.把通过PP助手下载的ipa包放到上面新建的dingding项目的TargetAPP目录下,(由于我没有越狱手机,此处使用的是PP助手下载的钉钉)

基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第4张图片 

基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第5张图片 
4.需要一台iPhone手机,越狱或者非越狱均可,此处使用非越狱的iPhone,运行项目,安装成功,输入账号密码登录时,钉钉会提示“你当前登录的非官方客端,已禁止该客户端的登录使用。请下载并使用官方客户端”。原因是我们创建项目是的Bundle ID与正版的钉钉的Bundle ID不一致。

基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第6张图片 

5.把项目的Bundle ID改为“ com.laiwang.DingTalk ”,再次运行,登录成功。

基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第7张图片 
基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第8张图片 
基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第9张图片 

6.运行项目是Xcode可能会提示“ The file “ XXX.app ” couldn't be opened because you don't have permission to view it. ” •解决办法:将info.plist的文件中的Executable.file中的文件修改为:$ ( PRODUCT_NAME )改完后记得clear一下再次运行就行了。         

基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第10张图片 

7.核心Hook操作hook代码写在哪里?我们可以hook代码写在项目的xxxDylib.m文件下,我创建的项目名为“ dingding ”,因此我写在“ dingdingDylib.m ”文件下

基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第11张图片 
hook的历程1.说到定位,我们肯定会想起苹果原生的CoreLocation框架,参照MonkeyDev的使用教程,我们对钉钉APP里的CoreLocation进行hook操作,定位的经纬度为深圳南山智园代码如下:

基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第12张图片 

真机一跑,定位变都没变,伤心的很。。。。

2.如果那么简单就没有这篇教程啦哈哈。。,我们可以利用class dump出所有钉钉ipa的所有头文件,从里面找出一点蛛丝马迹。(class-dump安装及获取app头文件教程https://www.jianshu.com/p/d0ebed2d937a?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation)

基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第13张图片 

基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第14张图片 

通过class dump出来的头文件,发现钉钉使用的是高德地图,搜索发现,高德地图是禁止虚拟定位的。查找了几个博客,发现高德地图中有这样一个方法:- ( BOOL ) detectRiskOfFakeLocation返回YES,就检测虚拟定位,NO就不检测,因此我们可以对使用了这个方法的所有类进行hook操作。(搜索出来,一共三个类)

基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第15张图片 

真机跑起来,哈哈,结果照样凉凉!再去高德地图的api搜索看看这个方法,是不是方法有什么需要注意的。于是我搜索了detectRiskOfFakeLocation这个方法。

基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第16张图片 
于是我们把上面的六个全hook了,代码如下:
基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第17张图片 
基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第18张图片 

全部代码如下:
 

[Objective-C] 纯文本查看 复制代码

?

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

CHDeclareClass ( CLLocation )

 

CHOptimizedMethod0 ( self , CLLocationCoordinate2D , CLLocation , coordinate ) {

  return CLLocationCoordinate2DMake ( 22.5955580000 , 114.0056150000 );

}

 

CHConstructor {

    CHLoadLateClass ( CLLocation );

    CHClassHook ( 0 , CLLocation , coordinate );

}

 

CHDeclareClass ( AMapGeoFenceManager );

 

CHMethod ( 0 , BOOL , AMapGeoFenceManager , detectRiskOfFakeLocation ) {

  return NO ;

}

 

CHMethod ( 0 , BOOL , AMapGeoFenceManager , pausesLocationUpdatesAutomatically ) {

  return NO ;

}

 

CHConstructor{

    CHLoadLateClass ( AMapGeoFenceManager );

    CHClassHook ( 0 , AMapGeoFenceManager , detectRiskOfFakeLocation );

    CHClassHook ( 0 , AMapGeoFenceManager , pausesLocationUpdatesAutomatically );

}

 

CHDeclareClass ( AMapLocationManager );

 

CHMethod ( 0 , BOOL , AMapLocationManager , detectRiskOfFakeLocation ) {

  return NO ;

}

 

CHMethod ( 0 , BOOL , AMapLocationManager , pausesLocationUpdatesAutomatically ) {

  return NO ;

}

 

CHConstructor{

    CHLoadLateClass ( AMapLocationManager );

    CHClassHook ( 0 , AMapLocationManager , detectRiskOfFakeLocation );

    CHClassHook ( 0 , AMapLocationManager , pausesLocationUpdatesAutomatically );

}

 

CHDeclareClass ( DTALocationManager );

 

CHMethod ( 0 , BOOL , DTALocationManager , detectRiskOfFakeLocation ) {

  return NO ;

}

 

CHMethod ( 0 , BOOL , DTALocationManager , dt_pausesLocationUpdatesAutomatically ) {

  return NO ;

}

 

CHConstructor{

    CHLoadLateClass ( DTALocationManager );

    CHClassHook ( 0 , DTALocationManager , detectRiskOfFakeLocation );

    CHClassHook ( 0 , DTALocationManager , dt_pausesLocationUpdatesAutomatically );

}



真机跑一跑,打卡签到的位置都是代码写死的经纬度!复制代码的小伙伴不要忘记导入#import 框架,不然Xcode会报错哦,大家可以根据打卡地点修改经纬度。

基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第19张图片 

 

 

 

1.很多小伙伴反应把Bundle ID改为“ com.laiwang.DingTalk ”运行后钉钉依然提示“非官方应用” 
以下是我的操作,由于我没有越狱手机,只能在pp助手下载,下载是注意要下载越狱应用而不是正版应用,下载的是PP助手上钉钉最新版本4.5.15 ,APPStore上的是4.6版本

基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第20张图片    基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第21张图片 
  

2. 注意:真机运行需要开发者证书,把Bundle ID改为“ com.laiwang.DingTalk ”,Version改为对应的“4.5.15”,真机运行成功,没有提示“非官方应用”。

基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第22张图片 



======================================== ===凉凉的分割线

上一个帖子的经纬度是写死在代码里面的,当公司安排出差的时候就有点尴尬了 ,签到的还是公司的位置,决定对其进行简单的改良,可以在钉钉内手动输入经纬度坐标(经纬度自己百度查询)。


一.使用封装好的第三方库DingTalkUI ,此库封装了我上一篇修改定位的代码,我们利用Cocoapods进行导入安装到我们的dingding项目中
1.打开终端,定位到dingding项目所在目录,执行“ pod init”操作

基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第23张图片 


2.进入dingding目录,利用xcode方式打开Podfile文件,规则参照https://github.com/AloneMonkey/MonkeyDevSpecs

基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第24张图片 



3.修改好Podfile文件后进行保存操作,利用终端进入dingding目录进行“pod install”操作,导入DingTalkUI库成功。注意:( 修改Pods->dingdingPodDylib的 Build Settings 下 Build Active Architecture Only Debug改成No。 ) 
基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第25张图片 基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第26张图片 


4.运行dingding项目,安装完第三方库后在(某些不完美越狱的手机)上运行项目闪退,在非越狱手机上正常运行(还没想到解决方法)在越狱手机上报错。。。如下图,找到解决办法请告诉我
基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第27张图片 


5.进行hook操作,给钉钉添加修改经纬度的输入框界面,我们要把输入框添加到主界面上去怎么添加输入框界面呢,此处我们需要对项目进行调试操作在dingdingDylib.m文件中,监听UIApplicationDidBecomeActiveNotification的通知,打印UIApplication   sharedApplication ]. keyWindow . rootViewController的根控制器,点击home键让app进入后台,再切回到前台,发现控制台打印的是“ DTTabBarController ”(此处操作均为登录钉钉账号后)
基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第28张图片    基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第29张图片基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第30张图片 

6.利用class-dump操作,查看DTTabBarController 控制器的头文件,选择对“ -( void )viewDidLayoutSubviews”进行hook操作,详情请参考下图,大家也可以选择在别的方法或者控制器上进行hook操作,不一定要选择 DTTabBarController 控制器。
基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第31张图片 


7.编写经纬度输入框的代码,我选择自定义view操作,右键new file新建一个类ZFXXXButton继承于UIView,详细方法注释请参考图片:
基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第32张图片 基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第33张图片基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第34张图片 基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第35张图片 
8.在dingdingDylib.m中导入#import "ZFXXXButton.h"的,对DTTabBarControllerviewDidLayoutSubviews方法进行hook操作:
基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第36张图片 
9.真机运行dingding项目,不进行经纬度修改,此时我的位置是南山智园,把经纬度修改为天安门广场,修改成功。
基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第37张图片 基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第38张图片基于MonkeyDev实现不越狱修改钉钉位置打卡和签到_第39张图片 



以下是源码:

[Objective-C] 纯文本查看 复制代码

?

001

002

003

004

005

006

007

008

009

010

011

012

013

014

015

016

017

018

019

020

021

022

023

024

025

026

027

028

029

030

031

032

033

034

035

036

037

038

039

040

041

042

043

044

045

046

047

048

049

050

051

052

053

054

055

056

057

058

059

060

061

062

063

064

065

066

067

068

069

070

071

072

073

074

075

076

077

078

079

080

081

082

083

084

085

086

087

088

089

090

091

092

093

094

095

096

097

098

099

100

101

102

103

104

105

106

107

108

109

110

111

#import "ZFXXXButton.h"

//导入第三方库DingtalkPod

#import "DingtalkPod.h"

//宏定义屏幕的宽度和高度

#define KScreenHeight [UIScreen mainScreen].bounds.size.height

#define KScreenWidth [UIScreen mainScreen].bounds.size.width

 

[url=home.php?mod=space&uid=402414]@[/url] interface ZFXXXButton()

//按钮(用于点击弹出经纬度输入框)

@property (nonatomic,strong)UIButton *btn;

//DingtalkPod对象用于修改经纬度操作

@property (nonatomic,strong)DingtalkPod *pod;

[url=home.php?mod=space&uid=262062]@End[/url]

 

 @ implementation ZFXXXButton

 

-(DingtalkPod *) pod{

    if (!_pod) {

        _pod = [[DingtalkPod alloc]init];

    }

    return _pod;

}

//懒加载按钮

- (UIButton *)btn{

    if (!_btn) {

        _btn = [UIButton buttonWithType:UIButtonTypeCustom];

        [_btn setTitle "修改经纬度" forState:UIControlStateNormal];

        [_btn.titleLabel setFont:[UIFont systemFontOfSize:13]];

        _btn.userInteractionEnabled = YES;

        [_btn addTarget:self action: @selector (btnClick:) forControlEvents:UIControlEventTouchUpInside];

    }

    return _btn;

}

//重写initWithFrame:(CGRect)frame方法,把按钮添加到我们自定义的view中

- (instancetype)initWithFrame:(CGRect)frame{

    if (self = [super initWithFrame:frame]) {

//添加按钮

        [self addSubview:self.btn];

//设置透明度

        self.backgroundColor = [[UIColor grayColor] colorWithAlphaComponent:0.5];

    }

    return self;

}

- (void)layoutSubviews{

    [super layoutSubviews];

    CGSize size = self.frame.size;

//设置按钮在view中的位置

    self.btn.frame = CGRectMake(0, 0, size.width , size .height);

}

 

//点击按钮触发该方法

- (void)btnClick:(UIButton*)btn{

    UIAlertController *alert = [UIAlertController alertControllerWithTitle "修改定位" message "请输入经纬度" preferredStyle:UIAlertControllerStyleAlert];

    [alert addAction: [UIAlertAction actionWithTitle "取消" style:UIAlertActionStyleDefault handler :^(UIAlertAction * _Nonnull action) {

    }]];

        //点击确定按钮,修改经纬度

    [alert addAction:[UIAlertAction actionWithTitle"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {

        UITextField *longitudeTextField = alert.textFields.firstObject;

        UITextField *latitudeTextField = alert.textFields.lastObject;

        NSLog(@"经度= %@",longitudeTextField.text) ;

        NSLog(@"纬度= %@",latitudeTextField.text);

       double longitude = [longitudeTextField.text doubleValue];

       double latitude = [latitudeTextField.text doubleValue];

        //调用DingtalkPod的setLocation:方法修改经纬度

        [self.pod setLocation:CLLocationCoordinate2DMake(longitude,latitude)];

    }]];

        //添加经度输入框

    [alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {

        textField.placeholder = @"请输入经度";

        textField.keyboardType = UIKeyboardTypeASCIICapable;

        textField.returnKeyType = UIReturnKeyDone;

    }];

        //添加纬度输入框

    [alert addTextFieldWithConfigurationHandler:^( UITextField * _Nonnull textField) {

        textField.placeholder = @"请输入纬度";

        textField.keyboardType = UIKeyboardTypeASCIICapable;

        textField.returnKeyType = UIReturnKeyDone;

    }];

        //弹出经纬度输入框

    [[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alert animated:YES completion:nil];

}

 

 

# import "ZFXXXButton.h"

#import "dingdingDylib.h"

#import

#import

#import

#import

#import

#define KScreenHeight [UIScreen mainScreen] .bounds.size.height

#define KScreenWidth [UIScreen mainScreen].bounds.size. width

 

 

CHDeclareClass(DTTabBarController)

 

CHOptimizedMethod0(self, void, DTTabBarController, viewDidLayoutSubviews){

    //调用y正版钉钉的viewDidLayoutSubviews方法

    CHSuper0(DTTabBarController, viewDidLayoutSubviews) ;

    //创建ZFXXXButton

    ZFXXXButton *btn = [[ZFXXXButton alloc]initWithFrame:CGRectMake( (KScreenWidth - 80)/2, 20 , 80, 50)];

    //获取DTTabBarController控制器的根控制器的view,把ZFXXXButton添加到view上

    UITabBarController * vc = (UITabBarController*)self;

    UIView *view = vc.selectedViewController.view;

    [view addSubview:btn];

}

 

CHConstructor{

    CHLoadLateClass (DTTabBarController);

    CHClassHook(0, DTTabBarController, viewDidLayoutSubviews);

}

 

 

你可能感兴趣的:(iso)