Sources/Core/SLSDeviceUtils.m (402 lines of code) (raw):

// // SLSDeviceUtils.m // AliyunLogCommon // // Created by gordon on 2021/5/31. // #import "SLSSystemCapabilities.h" #import "SLSDeviceUtils.h" #import <sys/utsname.h> #if SLS_HAS_UIKIT #import <UIKit/UIKit.h> #else #import <AppKit/AppKit.h> #endif #if SLS_HAS_CORE_TELEPHONY #import <CoreTelephony/CTTelephonyNetworkInfo.h> #import <CoreTelephony/CTCarrier.h> #endif #import <sys/stat.h> #import <dlfcn.h> //#import "reachable/Rechable.h" #import "SLSReachability.h" #include <sys/types.h> #include <sys/sysctl.h> #include <mach/machine.h> @interface SLSDeviceUtils () + (NSString *) getNetworkType; + (NSString *) getReachabilityStatus; @end @implementation SLSDeviceUtils + (NSString *) getDeviceModelIdentifier { struct utsname systemInfo; uname(&systemInfo); return [NSString stringWithCString:systemInfo.machine encoding:NSASCIIStringEncoding]; } + (NSString *)getDeviceModel { struct utsname systemInfo; uname(&systemInfo); NSString *deviceModel = [NSString stringWithCString:systemInfo.machine encoding:NSASCIIStringEncoding]; // iPhone if ([deviceModel isEqualToString:@"iPhone3,1"]) return @"iPhone 4"; if ([deviceModel isEqualToString:@"iPhone3,2"]) return @"iPhone 4"; if ([deviceModel isEqualToString:@"iPhone3,3"]) return @"iPhone 4"; if ([deviceModel isEqualToString:@"iPhone4,1"]) return @"iPhone 4S"; if ([deviceModel isEqualToString:@"iPhone5,1"]) return @"iPhone 5"; if ([deviceModel isEqualToString:@"iPhone5,2"]) return @"iPhone 5 (GSM+CDMA)"; if ([deviceModel isEqualToString:@"iPhone5,3"]) return @"iPhone 5c (GSM)"; if ([deviceModel isEqualToString:@"iPhone5,4"]) return @"iPhone 5c (GSM+CDMA)"; if ([deviceModel isEqualToString:@"iPhone6,1"]) return @"iPhone 5s (GSM)"; if ([deviceModel isEqualToString:@"iPhone6,2"]) return @"iPhone 5s (GSM+CDMA)"; if ([deviceModel isEqualToString:@"iPhone7,1"]) return @"iPhone 6 Plus"; if ([deviceModel isEqualToString:@"iPhone7,2"]) return @"iPhone 6"; if ([deviceModel isEqualToString:@"iPhone8,1"]) return @"iPhone 6s"; if ([deviceModel isEqualToString:@"iPhone8,2"]) return @"iPhone 6s Plus"; if ([deviceModel isEqualToString:@"iPhone8,4"]) return @"iPhone SE"; if ([deviceModel isEqualToString:@"iPhone9,1"]) return @"iPhone 7"; if ([deviceModel isEqualToString:@"iPhone9,2"]) return @"iPhone 7 Plus"; if ([deviceModel isEqualToString:@"iPhone9,3"]) return @"iPhone 7"; if ([deviceModel isEqualToString:@"iPhone9,4"]) return @"iPhone 7 Plus"; if ([deviceModel isEqualToString:@"iPhone10,1"]) return @"iPhone_8"; if ([deviceModel isEqualToString:@"iPhone10,4"]) return @"iPhone_8"; if ([deviceModel isEqualToString:@"iPhone10,2"]) return @"iPhone_8_Plus"; if ([deviceModel isEqualToString:@"iPhone10,5"]) return @"iPhone_8_Plus"; if ([deviceModel isEqualToString:@"iPhone10,3"]) return @"iPhone X"; if ([deviceModel isEqualToString:@"iPhone10,6"]) return @"iPhone X"; if ([deviceModel isEqualToString:@"iPhone11,8"]) return @"iPhone XR"; if ([deviceModel isEqualToString:@"iPhone11,2"]) return @"iPhone XS"; if ([deviceModel isEqualToString:@"iPhone11,6"]) return @"iPhone XS Max"; if ([deviceModel isEqualToString:@"iPhone11,4"]) return @"iPhone XS Max"; if ([deviceModel isEqualToString:@"iPhone12,1"]) return @"iPhone 11"; if ([deviceModel isEqualToString:@"iPhone12,3"]) return @"iPhone 11 Pro"; if ([deviceModel isEqualToString:@"iPhone12,5"]) return @"iPhone 11 Pro Max"; if ([deviceModel isEqualToString:@"iPhone12,8"]) return @"iPhone SE2"; if ([deviceModel isEqualToString:@"iPhone13,1"]) return @"iPhone 12 mini"; if ([deviceModel isEqualToString:@"iPhone13,2"]) return @"iPhone 12"; if ([deviceModel isEqualToString:@"iPhone13,3"]) return @"iPhone 12 Pro"; if ([deviceModel isEqualToString:@"iPhone13,4"]) return @"iPhone 12 Pro Max"; if ([deviceModel isEqualToString:@"iPhone14,4"]) return @"iPhone 13 mini"; if ([deviceModel isEqualToString:@"iPhone14,5"]) return @"iPhone 13"; if ([deviceModel isEqualToString:@"iPhone14,2"]) return @"iPhone 13 Pro"; if ([deviceModel isEqualToString:@"iPhone14,3"]) return @"iPhone 13 Pro Max"; // iPod Touch if ([deviceModel isEqualToString:@"iPod1,1"]) return @"iPod Touch 1G"; if ([deviceModel isEqualToString:@"iPod2,1"]) return @"iPod Touch 2G"; if ([deviceModel isEqualToString:@"iPod3,1"]) return @"iPod Touch 3G"; if ([deviceModel isEqualToString:@"iPod4,1"]) return @"iPod Touch 4G"; if ([deviceModel isEqualToString:@"iPod5,1"]) return @"iPod Touch (5 Gen)"; if ([deviceModel isEqualToString:@"iPod7,1"]) return @"iPod Touch (6 Gen)"; // iPad if ([deviceModel isEqualToString:@"iPad1,1"]) return @"iPad"; if ([deviceModel isEqualToString:@"iPad1,2"]) return @"iPad 3G"; if ([deviceModel isEqualToString:@"iPad2,1"]) return @"iPad 2 (WiFi)"; if ([deviceModel isEqualToString:@"iPad2,2"]) return @"iPad 2"; if ([deviceModel isEqualToString:@"iPad2,3"]) return @"iPad 2 (CDMA)"; if ([deviceModel isEqualToString:@"iPad2,4"]) return @"iPad 2"; if ([deviceModel isEqualToString:@"iPad3,1"]) return @"iPad 3 (WiFi)"; if ([deviceModel isEqualToString:@"iPad3,2"]) return @"iPad 3 (GSM+CDMA)"; if ([deviceModel isEqualToString:@"iPad3,3"]) return @"iPad 3"; if ([deviceModel isEqualToString:@"iPad3,4"]) return @"iPad 4 (WiFi)"; if ([deviceModel isEqualToString:@"iPad3,5"]) return @"iPad 4"; if ([deviceModel isEqualToString:@"iPad3,6"]) return @"iPad 4 (GSM+CDMA)"; if ([deviceModel isEqualToString:@"iPad6,11"]) return @"iPad 5"; if ([deviceModel isEqualToString:@"iPad6,12"]) return @"iPad 5"; if ([deviceModel isEqualToString:@"iPad7,5"]) return @"iPad 6"; if ([deviceModel isEqualToString:@"iPad7,6"]) return @"iPad 6"; if ([deviceModel isEqualToString:@"iPad7,11"]) return @"iPad 7"; if ([deviceModel isEqualToString:@"iPad7,12"]) return @"iPad 7"; if ([deviceModel isEqualToString:@"iPad11,6"]) return @"iPad 8"; if ([deviceModel isEqualToString:@"iPad11,6"]) return @"iPad 8"; if ([deviceModel isEqualToString:@"iPad12,1"]) return @"iPad 9"; if ([deviceModel isEqualToString:@"iPad12,2"]) return @"iPad 9"; // iPad Air if ([deviceModel isEqualToString:@"iPad4,1"]) return @"iPad Air (WiFi)"; if ([deviceModel isEqualToString:@"iPad4,2"]) return @"iPad Air (Cellular)"; if ([deviceModel isEqualToString:@"iPad5,3"]) return @"iPad Air 2"; if ([deviceModel isEqualToString:@"iPad5,4"]) return @"iPad Air 2"; if ([deviceModel isEqualToString:@"iPad11,3"]) return @"iPad Air 3"; if ([deviceModel isEqualToString:@"iPad11,4"]) return @"iPad Air 3"; if ([deviceModel isEqualToString:@"iPad13,1"]) return @"iPad Air 4"; if ([deviceModel isEqualToString:@"iPad13,2"]) return @"iPad Air 4"; // iPad Mini if ([deviceModel isEqualToString:@"iPad2,5"]) return @"iPad Mini (WiFi)"; if ([deviceModel isEqualToString:@"iPad2,6"]) return @"iPad Mini"; if ([deviceModel isEqualToString:@"iPad2,7"]) return @"iPad Mini (GSM+CDMA)"; if ([deviceModel isEqualToString:@"iPad4,4"]) return @"iPad Mini 2 (WiFi)"; if ([deviceModel isEqualToString:@"iPad4,5"]) return @"iPad Mini 2 (Cellular)"; if ([deviceModel isEqualToString:@"iPad4,6"]) return @"iPad Mini 2"; if ([deviceModel isEqualToString:@"iPad4,7"]) return @"iPad Mini 3"; if ([deviceModel isEqualToString:@"iPad4,8"]) return @"iPad Mini 3"; if ([deviceModel isEqualToString:@"iPad4,9"]) return @"iPad Mini 3"; if ([deviceModel isEqualToString:@"iPad5,1"]) return @"iPad Mini 4 (WiFi)"; if ([deviceModel isEqualToString:@"iPad5,2"]) return @"iPad Mini 4 (LTE)"; if ([deviceModel isEqualToString:@"iPad11,1"]) return @"iPad Mini 5"; if ([deviceModel isEqualToString:@"iPad11,2"]) return @"iPad Mini 5"; if ([deviceModel isEqualToString:@"iPad14,1"]) return @"iPad Mini 6"; if ([deviceModel isEqualToString:@"iPad14,2"]) return @"iPad Mini 6"; // iPad Pro if ([deviceModel isEqualToString:@"iPad6,3"]) return @"iPad Pro 9.7"; if ([deviceModel isEqualToString:@"iPad6,4"]) return @"iPad Pro 9.7"; if ([deviceModel isEqualToString:@"iPad7,3"]) return @"iPad Pro 10.5"; if ([deviceModel isEqualToString:@"iPad7,4"]) return @"iPad Pro 10.5"; if ([deviceModel isEqualToString:@"iPad8,1"]) return @"iPad Pro 11"; if ([deviceModel isEqualToString:@"iPad8,2"]) return @"iPad Pro 11"; if ([deviceModel isEqualToString:@"iPad8,3"]) return @"iPad Pro 11"; if ([deviceModel isEqualToString:@"iPad8,4"]) return @"iPad Pro 11"; if ([deviceModel isEqualToString:@"iPad8,9"]) return @"iPad Pro 11 2"; if ([deviceModel isEqualToString:@"iPad8,10"]) return @"iPad Pro 11 2"; if ([deviceModel isEqualToString:@"iPad13,4"]) return @"iPad Pro 11 3"; if ([deviceModel isEqualToString:@"iPad13,5"]) return @"iPad Pro 11 3"; if ([deviceModel isEqualToString:@"iPad13,6"]) return @"iPad Pro 11 3"; if ([deviceModel isEqualToString:@"iPad13,7"]) return @"iPad Pro 11 3"; if ([deviceModel isEqualToString:@"iPad6,7"]) return @"iPad Pro 12.9"; if ([deviceModel isEqualToString:@"iPad6,8"]) return @"iPad Pro 12.9"; if ([deviceModel isEqualToString:@"iPad7,1"]) return @"iPad Pro 12.9 2"; if ([deviceModel isEqualToString:@"iPad7,2"]) return @"iPad Pro 12.9 2"; if ([deviceModel isEqualToString:@"iPad8,5"]) return @"iPad Pro 12.9 3"; if ([deviceModel isEqualToString:@"iPad8,6"]) return @"iPad Pro 12.9 3"; if ([deviceModel isEqualToString:@"iPad8,7"]) return @"iPad Pro 12.9 3"; if ([deviceModel isEqualToString:@"iPad8,8"]) return @"iPad Pro 12.9 3"; if ([deviceModel isEqualToString:@"iPad8,11"]) return @"iPad Pro 12.9 4"; if ([deviceModel isEqualToString:@"iPad8,12"]) return @"iPad Pro 12.9 4"; if ([deviceModel isEqualToString:@"iPad13,8"]) return @"iPad Pro 12.9 5"; if ([deviceModel isEqualToString:@"iPad13,9"]) return @"iPad Pro 12.9 5"; if ([deviceModel isEqualToString:@"iPad13,10"]) return @"iPad Pro 12.9 5"; if ([deviceModel isEqualToString:@"iPad13,11"]) return @"iPad Pro 12.9 5"; // Apple TV if ([deviceModel isEqualToString:@"AppleTV1,1"]) return @"Apple TV 1"; if ([deviceModel isEqualToString:@"AppleTV2,1"]) return @"Apple TV 2"; if ([deviceModel isEqualToString:@"AppleTV3,1"]) return @"Apple TV 3"; if ([deviceModel isEqualToString:@"AppleTV3,2"]) return @"Apple TV 3"; if ([deviceModel isEqualToString:@"AppleTV5,3"]) return @"Apple TV 4"; if ([deviceModel isEqualToString:@"AppleTV6,2"]) return @"Apple TV 4K"; if ([deviceModel isEqualToString:@"AppleTV11,1"]) return @"Apple TV 4K 2"; // Simulator if ([deviceModel isEqualToString:@"i386"]) return @"Simulator"; if ([deviceModel isEqualToString:@"x86_64"]) return @"Simulator"; return deviceModel; } + (NSString *) isJailBreak { //以下检测的过程是越往下,越狱越高级 //获取越狱文件路径 NSString *cydiaPath = @"/Applications/Cydia.app"; NSString *aptPath = @"/private/var/lib/apt/"; if ([[NSFileManager defaultManager] fileExistsAtPath:cydiaPath]) { return @"true"; } if ([[NSFileManager defaultManager] fileExistsAtPath:aptPath]) { return @"true"; } //可能存在hook了NSFileManager方法,此处用底层C stat去检测 struct stat stat_info; if (0 == stat("/Library/MobileSubstrate/MobileSubstrate.dylib", &stat_info)) { return @"true"; } if (0 == stat("/Applications/Cydia.app", &stat_info)) { return @"true"; } if (0 == stat("/var/lib/cydia/", &stat_info)) { return @"true"; } if (0 == stat("/var/cache/apt", &stat_info)) { return @"true"; } //可能存在stat也被hook了,可以看stat是不是出自系统库,有没有被攻击者换掉。这种情况出现的可能性很小 int ret; Dl_info dylib_info; int (*func_stat)(const char *,struct stat *) = stat; if ((ret = dladdr(func_stat, &dylib_info))) { //相等为0,不相等,肯定被攻击 if (strcmp(dylib_info.dli_fname, "/usr/lib/system/libsystem_kernel.dylib")) { return @"true"; } } //通常,越狱机的输出结果会包含字符串:Library/MobileSubstrate/MobileSubstrate.dylib。 //攻击者给MobileSubstrate改名,原理都是通过DYLD_INSERT_LIBRARIES注入动态库。那么可以检测当前程序运行的环境变量 char *env = getenv("DYLD_INSERT_LIBRARIES"); if (env != NULL) { return @"true"; } return @"false"; } + (NSString *)getResolution { #if SLS_HAS_UIKIT CGSize size = [[UIScreen mainScreen] bounds].size; CGFloat scale = [[UIScreen mainScreen] scale]; return [NSString stringWithFormat:@"%.0f*%.0f",size.height * scale, size.width * scale]; #else NSScreen *screen = [NSScreen mainScreen]; NSDictionary *description = [screen deviceDescription]; NSSize size = [[description objectForKey:NSDeviceSize] sizeValue]; return [NSString stringWithFormat:@"%.0f*%.0f",size.height, size.width]; #endif } + (NSString *)getCarrier { #if SLS_HAS_CORE_TELEPHONY #if TARGET_IPHONE_SIMULATOR return @"Unknown"; #endif @try { CTTelephonyNetworkInfo *info = [[CTTelephonyNetworkInfo alloc] init]; CTCarrier *carrier = nil; if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 12.1) { if ([info respondsToSelector:@selector(serviceSubscriberCellularProviders)]) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunguarded-availability-new" carrier = info.serviceSubscriberCellularProviders[info.serviceSubscriberCellularProviders.allKeys.firstObject]; if (nil != carrier && nil != carrier.mobileNetworkCode) { carrier = info.serviceSubscriberCellularProviders[info.serviceSubscriberCellularProviders.allKeys.lastObject]; } #pragma clang diagnostic pop } } if(carrier == nil) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" carrier = info.subscriberCellularProvider; #pragma clang diagnostic pop } if (carrier != nil) { if (!carrier.isoCountryCode) { return @"无运营商"; } else { return [carrier carrierName]; } } else { return @"Unknown"; } } @catch (NSException *exception) { return @"Unknown"; } #else return @"Unknown"; #endif } + (NSString *)getReachabilityStatus { SLSReachability *reachability = [SLSReachability reachabilityWithHostname:@"www.aliyun.com"]; switch ([reachability currentReachabilityStatus]) { case SLSNotReachable: return @"Unknown"; case SLSReachableViaWiFi: return @"Wi-Fi"; break; case SLSReachableViaWWAN: return @"WWAN"; break; default: return @""; } } + (NSString *)getNetworkType { #if SLS_HAS_CORE_TELEPHONY @try { CTTelephonyNetworkInfo *networkInfo = [[CTTelephonyNetworkInfo alloc] init]; NSString *currentStatus = networkInfo.currentRadioAccessTechnology; return currentStatus; } @catch (NSException *exception) { return @"Unknown"; } #else return @"Unknown"; #endif } + (NSString *)getNetworkTypeName { #if SLS_HAS_CORE_TELEPHONY NSString *currentReachabilityStatus = [self getReachabilityStatus]; if(![@"WWAN" isEqual:currentReachabilityStatus]) { return currentReachabilityStatus; } NSString *currentStatus = [self getNetworkType]; if ([currentStatus isEqualToString:CTRadioAccessTechnologyLTE]) { return @"4G"; } if (@available(iOS 14.1, *)) { if ([currentStatus isEqualToString:CTRadioAccessTechnologyNRNSA] || [currentStatus isEqualToString:CTRadioAccessTechnologyNR]) { return @"5G"; } } if ([currentStatus isEqualToString:CTRadioAccessTechnologyWCDMA] || [currentStatus isEqualToString:CTRadioAccessTechnologyHSDPA] || [currentStatus isEqualToString:CTRadioAccessTechnologyHSUPA] || [currentStatus isEqualToString:CTRadioAccessTechnologyCDMAEVDORev0] || [currentStatus isEqualToString:CTRadioAccessTechnologyCDMAEVDORevA] || [currentStatus isEqualToString:CTRadioAccessTechnologyCDMAEVDORevB] || [currentStatus isEqualToString:CTRadioAccessTechnologyeHRPD]) { return @"3G"; } if ([currentStatus isEqualToString:CTRadioAccessTechnologyGPRS] || [currentStatus isEqualToString:CTRadioAccessTechnologyEdge] || [currentStatus isEqualToString:CTRadioAccessTechnologyCDMA1x]) { return @"2G"; } return @"Unknown"; #else return @"Unknown"; #endif } + (NSString *)getNetworkSubTypeName { #if SLS_HAS_CORE_TELEPHONY NSString *currentReachabilityStatus = [self getReachabilityStatus]; if(![@"WWAN" isEqual:currentReachabilityStatus]) { return @"Unknown"; } NSString *currentStatus = [self getNetworkType]; if ([currentStatus isEqualToString:CTRadioAccessTechnologyGPRS]) { return @"GPRS"; } if ([currentStatus isEqualToString:CTRadioAccessTechnologyEdge]) { return @"EDGE"; } if ([currentStatus isEqualToString:CTRadioAccessTechnologyWCDMA]) { return @"WCDMA"; } if ([currentStatus isEqualToString:CTRadioAccessTechnologyHSDPA]) { return @"HSDPA"; } if ([currentStatus isEqualToString:CTRadioAccessTechnologyHSUPA]) { return @"HSUPA"; } if ([currentStatus isEqualToString:CTRadioAccessTechnologyCDMA1x]) { return @"CDMA1x"; } if ([currentStatus isEqualToString:CTRadioAccessTechnologyCDMAEVDORev0]) { return @"EVDOv0"; } if ([currentStatus isEqualToString:CTRadioAccessTechnologyCDMAEVDORevA]) { return @"EVDORevA"; } if ([currentStatus isEqualToString:CTRadioAccessTechnologyCDMAEVDORevB]) { return @"EVDORevB"; } if ([currentStatus isEqualToString:CTRadioAccessTechnologyeHRPD]) { return @"HRPD"; } if ([currentStatus isEqualToString:CTRadioAccessTechnologyLTE]) { return @"LTE"; } if (@available(iOS 14.1, *)) { if ([currentStatus isEqualToString:CTRadioAccessTechnologyNRNSA]) { return @"NRNSA"; } else if ([currentStatus isEqualToString:CTRadioAccessTechnologyNR]) { return @"NR"; } } return @"Unknown"; #else return @"Unknown"; #endif } + (NSString *) getCPUArch { NSMutableString *cpu = [[NSMutableString alloc] init]; size_t size; cpu_type_t type; cpu_subtype_t subtype; size = sizeof(type); sysctlbyname("hw.cputype", &type, &size, NULL, 0); size = sizeof(subtype); sysctlbyname("hw.cpusubtype", &subtype, &size, NULL, 0); if (type == CPU_TYPE_X86_64) { [cpu appendString:@"x86_64"]; } else if (type == CPU_TYPE_X86) { [cpu appendString:@"x86"]; } else if (type == CPU_TYPE_ARM) { [cpu appendString:@"ARM"]; switch (subtype) { case CPU_SUBTYPE_ARM_V6: [cpu appendString:@"v6"]; break; case CPU_SUBTYPE_ARM_V7: [cpu appendString:@"v7"]; break; case CPU_SUBTYPE_ARM_V8: [cpu appendString:@"v8"]; break; default: break; } } else if (type == CPU_TYPE_ARM64) { [cpu appendString:@"ARM64"]; } return [cpu copy]; } @end