gengjf025 发表于 2017-2-7 16:02:32

【非越狱环境】钉钉躺床上打卡之WIFI篇

本帖最后由 gengjf025 于 2017-2-8 10:01 编辑

钉钉iOS客户端WIFI修改(非越狱环境)

本文续自上一篇:【非越狱环境】钉钉躺床上打卡之GPS篇(https://www.chinapyg.com/thread-88593-1-1.html)

一、背景最近有朋友公司移动考勤用的是wifi考勤,即公司设置签到的wifi热点之后,员工只有在连接上该热点后才能打考勤成功,就顺手做了点小事情。

二、工具准备见上一篇。
三、分析1、iOS的wifi获取用到的CNCopySupportedInterfaces()和CNCopyCurrentNetworkInfo()两个函数,组合使用获取到一个CFDictionaryRef,能够读取SSID(wifi热点名)、BSSID(路由器的Mac地址)、SSIDDATA(SSID的十六进制);2、很多app会获取当前网络状态,常用的是函数SCNetworkReachabilityGetFlags(),Reachability中会通过该函数判断当前网络是wifi还是其他状态;
知道这些东西之后就可以直接对这几个系统函数动手了,一劳永逸。
四、编码
    我们在上一篇的代码基础上增加wifi信息修改的相关代码,这里使用的是fishhook这个库,为了避免命名冲突,所有函数都加了前缀;1、创建一个wifi信息类DTWifiModel,头文件如下://
//DTWifiModel.h
//DingTalkDylib
//
//
//

#import <Foundation/Foundation.h>
#import <SystemConfiguration/SCNetworkReachability.h>

@interface DTWifiModel : NSObject

// en0
@property (nonatomic, copy) NSString *ifnam;

@property (nonatomic, assign) SCNetworkReachabilityFlags flags;

// WIFI昵称,例如:公司办公wifi、公司客户wifi
@property (nonatomic, copy) NSString *nickName;

// BSSID:路由器的Mac地址
@property (nonatomic, copy) NSString *BSSID;

// SSID:路由器的广播名称
@property (nonatomic, copy) NSString *SSID;

// SSIDDATA:SSID的十六进制
@property (nonatomic, strong) NSData *SSIDDATA;

@property (nonatomic, assign) BOOL isSelected;

- (instancetype)initWithDictionary:(NSDictionary *)dictionary;

- (instancetype)initWith:(NSString *)ifnam dictionary:(NSDictionary *)dictionary;

@end
2、创建wifi信息展示类DTWifiSettingViewController,该类主要用于展示当前连接的wifi、已经设置过的wifi历史,便于切换:核心函数如下:(1)、获取当前wifi信息,获取到之后会额外记录当前网络状态的flags,存出以备后用:- (void)fetchCurrentWifi {
   
    ;
   
    CFArrayRef arrayRef = CNCopySupportedInterfaces();
    NSArray *ifs = (__bridge_transfer NSArray *)arrayRef;
   
    if(ifs && > 0) {
      
      NSString *ifnam = ;
      
      CFDictionaryRef info = CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam);
      
      NSDictionary *dictionary = (__bridge_transfer NSDictionary *)info;
      
      if (dictionary && ) {
            
            DTWifiModel *wifi = [ initWith:ifnam dictionary:dictionary];
            
            wifi.flags = ;
            
            ;
      }
    }
}
(2)、获取当前网络状态,很多app都会先获取网络状态判断是否为wifi连接,一次获取到wifi热点信息之后再记录一次当前网络状态,用于篡改系统函数返回的flags,代码如下:- (SCNetworkReachabilityFlags)fetchCurrentNetworkStatus {
   
    // 创建零地址,0.0.0.0的地址表示查询本机的网络连接状态
    struct sockaddr_in zeroAddress;//sockaddr_in是与sockaddr等价的数据结构
    bzero(&zeroAddress, sizeof(zeroAddress));
    zeroAddress.sin_len = sizeof(zeroAddress);
    zeroAddress.sin_family = AF_INET;//sin_family是地址家族,一般都是“AF_xxx”的形式。通常大多用的是都是AF_INET,代表TCP/IP协议族
   
    SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress); //创建测试连接的引用:
    SCNetworkReachabilityFlags flags;
   
    BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
    CFRelease(defaultRouteReachability);
   
    if (!didRetrieveFlags) {
      NSLog(@"Error. Could not recover network reachability flagsn");
      return 0;
    }
   
    return flags;
}
3、创建类DTWIFIHook,用于hook系统函数:CNCopySupportedInterfaces()、CNCopyCurrentNetworkInfo()和SCNetworkReachabilityGetFlags(),代码如下:// CFArrayRef CNCopySupportedInterfaces      (void)
static CFArrayRef (*orig_CNCopySupportedInterfaces)();

static CFArrayRef jf_CNCopySupportedInterfaces() {
   
    CFArrayRef re = NULL;
   
    DTWifiModel *wifi = ;
   
    if(wifi && wifi.ifnam) {
      
      NSArray *array = ;
      
      re = CFRetain((__bridge CFArrayRef)(array));
    }
   
    if(!re) {
      
      re = orig_CNCopySupportedInterfaces();
    }
   
    return re;
}
// CFDictionaryRef CNCopyCurrentNetworkInfo      (CFStringRef interfaceName)
static CFDictionaryRef (*orig_CNCopyCurrentNetworkInfo)(CFStringRef interfaceName);

static CFDictionaryRef jf_CNCopyCurrentNetworkInfo(CFStringRef interfaceName) {
   
    CFDictionaryRef re = NULL;
   
    DTWifiModel *wifi = ;
   
    if(wifi) {
      
      NSDictionary *dictionary = @{
                                     @"BSSID" : (wifi.BSSID ? wifi.BSSID : @""),
                                     @"SSID" : (wifi.SSID ? wifi.SSID : @""),
                                     @"SSIDDATA" : (wifi.SSIDDATA ? wifi.SSIDDATA : @""),
                                     };
      re = CFRetain((__bridge CFDictionaryRef)(dictionary));
    }
   
    if(!re) {
      
      re = orig_CNCopyCurrentNetworkInfo(interfaceName);
    }
   
    return re;
}
// Boolean SCNetworkReachabilityGetFlags(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags *flags)
static Boolean (*orig_SCNetworkReachabilityGetFlags)(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags *flags);

static Boolean jf_SCNetworkReachabilityGetFlags(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags *flags) {
   
    Boolean re = false;
   
    DTWifiModel *wifi = ;
   
    if(wifi && wifi.flags > 0) {
      
      re = true;
      
      *flags = wifi.flags;
    }
   
    if(!re) {
      
      re = orig_SCNetworkReachabilityGetFlags(target, flags);
    }
   
    return re;
}
+ (void)load {
   
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
      
      _jf_rebind_symbols((struct _jf_rebinding){
            {"CNCopySupportedInterfaces", jf_CNCopySupportedInterfaces, (void *)&orig_CNCopySupportedInterfaces},
            {"CNCopyCurrentNetworkInfo", jf_CNCopyCurrentNetworkInfo, (void *)&orig_CNCopyCurrentNetworkInfo},
            {"SCNetworkReachabilityGetFlags", jf_SCNetworkReachabilityGetFlags, (void *)&orig_SCNetworkReachabilityGetFlags},
      }, 3);
    });
}
五、注入、打包、签名操作步骤同上一篇,安装测试:可以看到即使使用3G网络也可以实现wifi考勤,大功告成;
六、代码地址**** Hidden Message *****
七、结束语谨慎使用!






雲裏霧裏 发表于 2017-2-7 21:54:40

看起來不錯,先收藏,備用了

gengjf025 发表于 2017-2-19 17:07:15

mancong122 发表于 2017-2-19 12:45
你的文章我看到了,我的意思是:如果说签到的wifi网络属于局域网范畴,只能是在该网络下才能访问到指定的 ...

你说的这种情况,还要移动考勤干啥?直接打指纹或者刷卡算了。

Superhero 发表于 2017-2-7 22:09:34

我想有个安卓版。。。。

买不起苹果。。。

hzq999 发表于 2017-2-7 16:48:30

我们单位居然用分享逍客{:huffy:}

gengjf025 发表于 2017-2-7 16:54:00

hzq999 发表于 2017-2-7 16:48
我们单位居然用分享逍客

不管什么app,应该都是通用的,提供的代码是hook的系统函数,与app本身无关

ytyay 发表于 2017-2-7 20:04:24

学习,感谢分享。

0xcb 发表于 2017-2-7 21:38:31

6 钉钉还有动态补丁,我的一直没升级之前的bug钉钉都补上了

jia87921 发表于 2017-2-7 23:16:01

顶楼主啦..希望楼主多发精品好帖啦.....

samvon 发表于 2017-2-8 02:39:46

学习了~~谢谢

orz 发表于 2017-2-8 09:11:22

不错不错。学习了。 。收藏一下。有空也玩玩。
页: [1] 2 3 4 5 6 7 8 9 10
查看完整版本: 【非越狱环境】钉钉躺床上打卡之WIFI篇