#import #import #include #import #import #import #import // 获取ip #import // 获取ip #import // 获取ip #import #import #import #import #import // #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000 #import // #endif #import #import #import typedef void (^tryGetValCallback)(id parameter); // iOS版本检查宏 #define iOS14_OR_LATER() (@available(iOS 14, *)) @interface SBLockScreenManager : NSObject - (BOOL)unlockUIFromSource:(int)source withOptions:(id)options; - (void)lockUIFromSource:(int)source withOptions:(id)options; @end NSDictionary *settings; NSUUID* str2uuid(NSString *str) { return [[NSUUID alloc] initWithUUIDString:str]; } NSInteger str2int(NSString *str) { return [str integerValue]; } float str2float(NSString *str) { return [str floatValue]; } double str2double(NSString *str) { return [str doubleValue]; } unsigned long long str2ull(NSString *str) { return [str longLongValue]; } void tryGetVal(NSString *key, tryGetValCallback block) { @try { if (!key || !block || !settings) return; id data = settings[key]; if (data) { block(data); } } @catch (NSException *exception) { NSLog(@"Error in tryGetVal for key %@: %@", key, exception); } } const char* str2chars(NSString *str) { const char *cString = [str UTF8String]; return cString; } %group ohno // #if __IPHONE_OS_VERSION_MAX_ALLOWED < 140000 // #endif // group ohho start // #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000 %hook ATTrackingManager + (ATTrackingManagerAuthorizationStatus)trackingAuthorizationStatus { __block ATTrackingManagerAuthorizationStatus originalStatus = %orig; NSLog(@"start hook trackingAuthorizationStatus"); NSLog(@"[ATTrackingManager Hook] Original trackingAuthorizationStatus: %lu", (unsigned long)originalStatus); // 你可以在这里修改返回值 // 例如,总是返回已授权状态: // return 3; // ATTrackingManagerAuthorizationStatusAuthorized tryGetVal(@"trackingStatus", ^(id parameter) { NSLog(@"[ATTrackingManager Hook] API trackingAuthorizationStatus: %@", parameter); originalStatus = str2int(parameter); }); NSLog(@"[ATTrackingManager Hook] New trackingAuthorizationStatus: %lu", (unsigned long)originalStatus); // 或者,你可以直接返回原始值 return originalStatus; } + (void)requestTrackingAuthorizationWithCompletionHandler:(void (^)(ATTrackingManagerAuthorizationStatus status))completion { NSLog(@"[ATTrackingManager Hook] requestTrackingAuthorizationWithCompletionHandler called"); __block ATTrackingManagerAuthorizationStatus attStatus = 3; tryGetVal(@"trackingStatus", ^(id parameter) { NSLog(@"[ATTrackingManager Hook] API trackingAuthorizationStatus: %@", parameter); attStatus = str2int(parameter); }); // 模拟延迟(真实的授权对话框有延迟) dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ if (completion) { completion(attStatus); } }); // 调用原始方法 // %orig(completion); } %end // #endif %hook ASIdentifierManager -(NSUUID*)advertisingIdentifier { // 修改IDFA NSLog(@"start hook idfa"); __block NSUUID *idfa = %orig; // reloadConfig(); tryGetVal(@"idfa", ^(id parameter) { idfa = str2uuid(parameter); }); NSLog(@"hook idfa: %@", idfa); return idfa; } -(BOOL) isAdvertisingTrackingEnabled { NSLog(@"[ATTrackingManager Hook] isAdvertisingTrackingEnabled called"); __block BOOL res = %orig; tryGetVal(@"trackingStatus", ^(id parameter) { NSLog(@"[ATTrackingManager Hook] API isAdvertisingTrackingEnabled: %@", parameter); NSInteger status = str2int(parameter); res = (status >= 3 ? YES : NO); }); return res; } %end // static BOOL orientationMonitoringEnabled = NO; %hook UIDevice // IDFV -(NSUUID*)identifierForVendor{ NSLog(@"start hook idfv"); __block NSUUID *idfv = %orig; tryGetVal(@"idfv", ^(id parameter) { idfv = str2uuid(parameter); }); NSLog(@"hook idfv: %@", idfv); return idfv; } - (NSString *)name{ NSLog(@"start hook device name"); __block NSString *name = %orig; tryGetVal(@"deviceName", ^(id parameter) { name = parameter; }); NSLog(@"hook device name: %@", name); return name; } - (NSString *)model{ return %orig; } - (NSString *)localizedModel{ return %orig; } - (NSString *)systemName{ return %orig; } - (NSString *)systemVersion{ NSLog(@"start hook system version"); __block NSString *systemVersion = %orig; tryGetVal(@"osVersion", ^(id parameter) { systemVersion = parameter; }); NSLog(@"hook system version: %@", systemVersion); return systemVersion; } - (UIDeviceBatteryState)batteryState { NSLog(@"start hook batteryState"); __block UIDeviceBatteryState res = %orig; tryGetVal(@"batteryState", ^(id parameter) { NSInteger intVal = str2int(parameter); res = (UIDeviceBatteryState)intVal; }); return res; } - (float)batteryLevel { // 随机电量 NSLog(@"start hook batteryLevel"); __block float res = %orig; tryGetVal(@"batteryLevel", ^(id parameter) { res = str2float(parameter); }); return res; } - (UIDeviceOrientation)orientation { return UIDeviceOrientationPortrait; } %end %hook NSProcessInfo - (NSTimeInterval) systemUptime { // 开机时间 NSLog(@"start hook systemUptime"); __block NSTimeInterval res = %orig; tryGetVal(@"systemUptime", ^(id parameter) { double v = str2double(parameter); if(v > -1.0f) { res = v + res; } }); return res; } - (unsigned long long) physicalMemory { // 内存 NSLog(@"start hook physicalMemory"); __block unsigned long long memory = %orig; tryGetVal(@"physicalMemory", ^(id parameter) { unsigned long long t = str2ull(parameter); if(t > 1000) { memory = t; } }); NSLog(@"hook physicalMemory: %llu", memory); return memory; } - (NSUInteger) processorCount { NSLog(@"start hook processorCount"); __block NSUInteger res = %orig; tryGetVal(@"cpuCore", ^(id parameter) { NSUInteger t = str2int(parameter); if(t > 0) { res = t; } }); return res; } - (NSOperatingSystemVersion)operatingSystemVersion { NSOperatingSystemVersion version = %orig; __block NSString *versionString = @""; tryGetVal(@"osVersion", ^(id parameter) { versionString = parameter; }); if (!versionString || ![versionString length]) { return version; } NSArray *components = [versionString componentsSeparatedByString:@"."]; if (components.count == 0 || components.count > 3) { return version; } // 验证每个组件是否为有效数字 for (NSString *component in components) { if (![[NSScanner scannerWithString:component] scanInteger:NULL]) { return version; } } version.majorVersion = [components[0] integerValue]; version.minorVersion = components.count > 1 ? [components[1] integerValue] : 0; version.patchVersion = components.count > 2 ? [components[2] integerValue] : 0; return version; } %end %hook UIWindow - (UIEdgeInsets) safeAreaInsets { NSLog(@"start hook safeAreaInsets"); __block UIEdgeInsets originalInsets = %orig; %log(@"Original safeAreaInsets: %@", NSStringFromUIEdgeInsets(originalInsets)); tryGetVal(@"safeAreaInsets", ^(id parameter) { NSDictionary *dic = parameter; // 修改 safeAreaInsets UIEdgeInsets modifiedInsets = UIEdgeInsetsMake( originalInsets.top = str2double(dic[@"top"]), // 增加顶部安全区域 originalInsets.left = 0, // 增加左侧安全区域 originalInsets.bottom = str2double(dic[@"bottom"]), // 增加底部安全区域 originalInsets.right = 0 // 增加右侧安全区域 ); originalInsets = modifiedInsets; }); %log(@"Modified safeAreaInsets: %@", NSStringFromUIEdgeInsets(originalInsets)); return originalInsets; } %end %hook UIScreen - (CGFloat) brightness { // 随机亮度 NSLog(@"start hook brightness"); __block CGFloat originalBrightness = %orig; tryGetVal(@"screenBrightness", ^(id parameter) { double fat = str2double(parameter); if(fat > -1.0f) { originalBrightness = fat; } }); return originalBrightness; } - (CGRect)bounds { NSLog(@"start hook bounds"); __block CGRect originalBounds = %orig; tryGetVal(@"screenBounds", ^(id parameter) { NSDictionary *dic = parameter; double w = str2double(dic[@"x"]); double h = str2double(dic[@"y"]); CGRect newBounds = { .origin = {.x = 0, .y = 0}, .size = {.width = w, .height = h}, }; originalBounds = newBounds; }); return originalBounds; } - (CGFloat) scale { NSLog(@"start hook scale"); __block CGFloat originalScale = %orig; tryGetVal(@"screenScale", ^(id parameter) { double fat = str2double(parameter); if(fat > -1.0f) { originalScale = fat; } }); return originalScale; } - (CGRect)nativeBounds { NSLog(@"start hook nativeBounds"); __block CGRect originalBounds = %orig; tryGetVal(@"screenBounds", ^(id parameter) { NSDictionary *dic = parameter; double w = str2double(dic[@"nx"]); double h = str2double(dic[@"ny"]); CGRect newBounds = { .origin = {.x = 0, .y = 0}, .size = {.width = w, .height = h}, }; originalBounds = newBounds; }); return originalBounds; } - (BOOL)isCaptured { // 总是返回NO,表示屏幕没有被捕获(镜像) return NO; } - (UIScreen *)mirroredScreen { // 总是返回nil,表示没有镜像屏幕 return nil; } %end %hook AVAudioSession - (float) outputVolume { // 音量 NSLog(@"start hook outputVolume"); __block float originalVolume = %orig; tryGetVal(@"outputVolume", ^(id parameter) { float fat = str2float(parameter); if(fat > -1.0f) { originalVolume = fat; } }); return originalVolume; } %end %hook UIScreenMode - (CGSize)size { // 修改屏幕大小信息 NSLog(@"start hook bounds"); __block CGSize originalSize = %orig; tryGetVal(@"screenBounds", ^(id parameter) { NSDictionary *dic = parameter; double w = str2double(dic[@"x"]); double h = str2double(dic[@"y"]); CGSize newBounds = { .width = w, .height = h }; originalSize = newBounds; }); return originalSize; } %end %hook NSFileManager - (NSDictionary *) attributesOfFileSystemForPath:(NSString *)path error:(NSError **)error { // 磁盘信息 NSLog(@"start hook disk info"); NSDictionary *res = %orig; // int64_t size = [info[NSFileSystemSize] longLongValue]; // 总大小 // int64_t space = [[info objectForKey:NSFileSystemFreeSize] longLongValue]; if ([path isEqualToString:NSHomeDirectory()]) { NSMutableDictionary *modifiedAttributes = [res mutableCopy]; // 修改或添加属性 tryGetVal(@"diskSize", ^(id parameter) { int64_t fat = str2ull(parameter); if(fat > 0) { modifiedAttributes[NSFileSystemSize] = @(fat); // 1 GB } }); tryGetVal(@"diskFreeSize", ^(id parameter) { int64_t fat = str2ull(parameter); if(fat > 0) { modifiedAttributes[NSFileSystemFreeSize] = @(fat); // 1 GB } }); return [modifiedAttributes copy]; } return res; } // 反越狱检测 - (BOOL)fileExistsAtPath:(NSString *)event { NSLog(@"start hook fileExistsAtPath"); NSArray *array = @[@"/Application/Cydia.app", @"/Application/Sileo.app", @"/usr/lib/TweakInject", @"/Library/TweakInject", @"/Library/MobileSubstrate/MobileSubstrate.dylib", @"/bin/bash", @"/usr/sbin/sshd", @"/etc/apt", @"/usr/bin/ssh", @"/private/var/lib/apt", @"/private/var/lib/cydia", @"/private/var/tmp/cydia.log", @"/Applications/WinterBoard.app", @"/var/lib/cydia", @"/private/etc/dpkg/origins/debian", @"/bin.sh", @"/private/etc/apt", @"/etc/ssh/sshd_config", @"/private/etc/ssh/sshd_config", @"/Applications/SBSetttings.app", @"/private/var/mobileLibrary/SBSettingsThemes/", @"/private/var/stash", @"/usr/libexec/sftp-server", @"/usr/libexec/cydia/", @"/usr/sbin/frida-server", @"/usr/bin/cycript", @"/usr/local/bin/cycript", @"/usr/lib/libcycript.dylib", @"/System/Library/LaunchDaemons/com.saurik.Cydia.Startup.plist", @"/System/Library/LaunchDaemons/com.ikey.bbot.plist", @"/Applications/FakeCarrier.app", @"/Library/MobileSubstrate/DynamicLibraries/Veency.plist", @"/Library/MobileSubstrate/DynamicLibraries/LiveClock.plist", @"/usr/libexec/ssh-keysign", @"/usr/libexec/sftp-server", @"/Applications/blackra1n.app", @"/Applications/IntelliScreen.app", @"/Applications/Snoop-itConfig.app", @"/var/lib/dpkg/info", @"/User/Applications"]; NSInteger index = [array indexOfObjectPassingTest:^BOOL(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { BOOL ret = [event hasPrefix:obj]; if (ret) { *stop = YES; } return ret; }]; if (index != NSNotFound) { NSLog(@"9999999==%@=",event); return NO; } return %orig; } %end %hook NSLocale + (NSArray *) preferredLanguages { // 语言 NSLog(@"start hook preferredLanguages"); return @[@"en-US"]; } + (NSLocale *)currentLocale { // 如果你想修改返回的 locale,可以在这里进行修改 // 例如,强制返回一个特定的 locale: NSLog(@"start hook currentLocale"); __block NSLocale *res = %orig; tryGetVal(@"locale", ^(id parameter) { NSString *loc = parameter; res = [[NSLocale alloc] initWithLocaleIdentifier:loc]; }); return res; } + (NSLocale *)systemLocale { NSLog(@"start hook systemLocale"); __block NSLocale *res = %orig; tryGetVal(@"locale", ^(id parameter) { NSString *loc = parameter; res = [[NSLocale alloc] initWithLocaleIdentifier:loc]; }); return res; } %end %hook NSTimeZone + (NSTimeZone *)localTimeZone { // NSTimeZone *originalTimeZone = %orig; // NSLog(@"[HOOK] Local time zone accessed: %@", [originalTimeZone name]); // 如果你想修改返回的时区,可以在这里进行修改 // 例如,强制返回一个特定的时区: NSLog(@"start hook localTimeZone"); __block NSTimeZone *res = %orig; tryGetVal(@"timeZone", ^(id parameter) { NSString *loc = parameter; res = [NSTimeZone timeZoneWithName:loc]; }); return res; // return originalTimeZone; } + (NSTimeZone *)systemTimeZone { NSLog(@"start hook systemTimeZone"); __block NSTimeZone *res = %orig; tryGetVal(@"timeZone", ^(id parameter) { NSString *loc = parameter; res = [NSTimeZone timeZoneWithName:loc]; }); return res; } + (NSTimeZone *)defaultTimeZone { NSLog(@"start hook defaultTimeZone"); __block NSTimeZone *res = %orig; tryGetVal(@"timeZone", ^(id parameter) { NSString *loc = parameter; res = [NSTimeZone timeZoneWithName:loc]; }); return res; } %end // 状态栏 %hook UIStatusBarManager - (CGRect) statusBarFrame { NSLog(@"start hook statusBarFrame"); __block CGRect originalFrame = %orig; tryGetVal(@"safeAreaInsets", ^(id parameter) { NSDictionary *dic = parameter; double barHeight = str2double(dic[@"height"]); CGSize tempSize = {.width = originalFrame.size.width, .height = barHeight}; originalFrame.size = tempSize; }); return originalFrame; } %end %hook NSMutableURLRequest // Maybe server side checks the user agent? - (instancetype)initWithURL:(NSURL *)URL { self = %orig(URL); if (self) { tryGetVal(@"userAgent", ^(id parameter) { [self setValue:parameter forHTTPHeaderField:@"User-Agent"]; }); } return self; } - (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field { __block NSString *_userAgent = value; if ([field isEqualToString:@"User-Agent"]) { // 修改User Agent tryGetVal(@"userAgent", ^(id parameter) { _userAgent = parameter; }); } %orig(_userAgent, field); } %end %hook NSURLSession + (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration { NSLog(@"start hook sessionWithConfiguration"); //if (configuration.HTTPAdditionalHeaders[@"User-Agent"]) { tryGetVal(@"userAgent", ^(id parameter) { configuration.HTTPAdditionalHeaders = @{@"User-Agent": parameter}; }); //} return %orig; } - (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSData *data, NSURLResponse *response, NSError *error))completionHandler { NSMutableURLRequest *mutableRequest = [request mutableCopy]; tryGetVal(@"userAgent", ^(id parameter) { [mutableRequest setValue:parameter forHTTPHeaderField:@"User-Agent"]; }); return %orig(mutableRequest, completionHandler); } %end %hook WKWebView - (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^)(id, NSError *error))completionHandler { NSLog(@"start hook evaluateJavaScript"); %log(@"Evaluating JavaScript: %@", javaScriptString); __block NSString *userAgent = nil; tryGetVal(@"userAgent", ^(id parameter) { userAgent = parameter; }); if(userAgent) { [self setCustomUserAgent:userAgent]; } %orig(javaScriptString, completionHandler); } - (void)setCustomUserAgent:(NSString *)userAgent { __block NSString *_userAgent = userAgent; tryGetVal(@"userAgent", ^(id parameter) { _userAgent = parameter; }); %orig(_userAgent); } - (NSString *)customUserAgent { // 获取原来的 User-Agent __block NSString *userAgent = %orig; tryGetVal(@"userAgent", ^(id parameter) { userAgent = parameter; }); // 返回修改后的 User-Agent return userAgent; } %end %hook CTTelephonyNetworkInfo - (NSDictionary *) serviceCurrentRadioAccessTechnology { NSLog(@"start hook serviceCurrentRadioAccessTechnology"); NSDictionary *originalTechnologies = %orig; %log(@"Original Radio Access Technologies: %@", originalTechnologies); NSMutableDictionary *modifiedProviders = [[NSMutableDictionary alloc] init]; tryGetVal(@"simInfo", ^(id parameter) { NSDictionary *simInfoDic = parameter; for(NSString *service in simInfoDic.allKeys) { NSDictionary *dic = simInfoDic[service]; NSString *wwan = dic[@"wwan"]; if([wwan isEqual:@"5G"]) { [modifiedProviders setValue:@"CTRadioAccessTechnologyNR" forKey:service]; } else { [modifiedProviders setValue:@"CTRadioAccessTechnologyLTE" forKey:service]; } } }); if([modifiedProviders count] > 0) { return [modifiedProviders copy]; } return originalTechnologies; } - (NSDictionary *)serviceSubscriberCellularProviders { NSLog(@"start hook serviceSubscriberCellularProviders"); NSDictionary *originalProviders = %orig; %log(@"Original Cellular Providers: %@", originalProviders); NSMutableDictionary *modifiedProviders = [[NSMutableDictionary alloc] init]; tryGetVal(@"simInfo", ^(id parameter) { NSDictionary *simInfoDic = parameter; for(NSString *service in simInfoDic.allKeys) { NSDictionary *dic = simInfoDic[service]; CTCarrier *carrier = [[CTCarrier alloc] init]; [carrier setValue:dic[@"carrierName"] forKey:@"carrierName"]; [carrier setValue:dic[@"mobileCountryCode"] forKey:@"mobileCountryCode"]; [carrier setValue:dic[@"mobileNetworkCode"] forKey:@"mobileNetworkCode"]; [carrier setValue:dic[@"isoCountryCode"] forKey:@"isoCountryCode"]; [modifiedProviders setValue:carrier forKey:service]; } }); if([modifiedProviders count] > 0) { return [modifiedProviders copy]; } return originalProviders; } %end // 添加随机函数 static double randomRadiansPerSecond() { double randomValue = (double)arc4random() / UINT32_MAX; return (randomValue * 20.0) - 10.0; } // 创建 CMGyroData 的子类 @interface CustomCMGyroData : CMGyroData @property (nonatomic, assign) CMRotationRate customRotationRate; @end @implementation CustomCMGyroData - (CMRotationRate)rotationRate { return self.customRotationRate; } @end // 陀螺仪 %hook CMMotionManager - (void)startGyroUpdatesToQueue:(NSOperationQueue *)queue withHandler:(CMGyroHandler)handler { if (!queue || !handler) return %orig; CMGyroHandler newHandler = ^(CMGyroData *gyroData, NSError *error) { if(gyroData) { CMRotationRate originalRate = gyroData.rotationRate; // 在这里,你可以修改或记录 rotationRate NSLog(@"Gyro RotationRate - x: %f, y: %f, z: %f", originalRate.x, originalRate.y, originalRate.z); } // 设置随机的旋转速率 CMRotationRate randomRate; randomRate.x = randomRadiansPerSecond(); randomRate.y = randomRadiansPerSecond(); randomRate.z = randomRadiansPerSecond(); // 如果你想修改值,可以这样做: // 创建自定义的 CMGyroData 对象 CustomCMGyroData *customGyroData = (CustomCMGyroData *)[[objc_getClass("CMGyroData") alloc] init]; // Objective-C 没有直接的方法来修改 CMGyroData 的值,所以这里我们只是记录 // 设置自定义数据 customGyroData.customRotationRate = randomRate; // 调用原始处理程序,但使用我们的自定义数据 if (handler) { handler((CMGyroData *)customGyroData, error); } }; %orig(queue, newHandler); } %end // int uname(struct utsname *); %hookf(int, uname, struct utsname * systemInfo) { NSLog(@"start hook uname"); int nRet = %orig; tryGetVal(@"productStr", ^(id parameter) { char str_machine_name[100]; [parameter getCString:str_machine_name maxLength:100 encoding:NSUTF8StringEncoding]; strcpy(systemInfo->machine,str_machine_name); }); return nRet; // Call the original implementation of this function } %hookf(int, sysctl, const int *name, u_int namelen, void *oldp, size_t *oldlenp, const void *newp, size_t newlen) { NSLog(@"start hook sysctl"); if(namelen < 2) { return %orig; } if (name[0] == CTL_KERN && name[1] == KERN_BOOTTIME) { int nRet = %orig; if (nRet == 0 && oldp && oldlenp && *oldlenp >= sizeof(struct timeval)) { struct timeval *a = (struct timeval*)oldp; tryGetVal(@"kernBootTime", ^(id parameter) { int kernBootTime = str2int(parameter); a->tv_sec = kernBootTime + a->tv_sec; }); } return nRet; } else if(name[0] == CTL_HW && name[1] == HW_MACHINE) { __block NSString *modelName = @"iPhone14,2"; tryGetVal(@"productStr", ^(id parameter) { if(parameter) { modelName = parameter; } }); const char *spoofedModel = [modelName UTF8String]; if (!spoofedModel) { return %orig; } size_t modelLen = strlen(spoofedModel) + 1; // +1 for null terminator // 查询缓冲区大小 if (!oldp && oldlenp) { *oldlenp = modelLen; return 0; } // 复制数据 if (oldp && oldlenp) { if (*oldlenp < modelLen) { // 缓冲区太小,返回错误 return ENOMEM; } // 安全复制字符串 strlcpy((char*)oldp, spoofedModel, *oldlenp); *oldlenp = modelLen; NSLog(@"sysctl model copied: %@", modelName); return 0; } return EINVAL; } // 其他情况调用原函数 return %orig; } // 安全的字符串复制函数 static BOOL safe_copy_string(void *dst, size_t *dstlen, const char *src) { if (!dst || !dstlen || !src) return NO; size_t srclen = strlen(src); size_t needed = srclen + 1; if (*dstlen < needed) { *dstlen = needed; return NO; } strlcpy(dst, src, *dstlen); *dstlen = srclen; return YES; } %hookf(int, sysctlbyname, const char *name, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { NSLog(@"start hook sysctlbyname"); if (strcmp(name, "hw.machine") == 0) { NSLog(@"start hook sysctlbyname new machine"); int ret = %orig; __block NSString *machine = nil; tryGetVal(@"productStr", ^(id parameter) { if (parameter) { NSString *temp = parameter; machine = [temp copy]; NSLog(@"machine,%@", temp); } }); if (oldp && machine) { NSLog(@"machine,1"); // char str_machine_name[100]; const char *hwMachineCh = [machine UTF8String]; // [parameter getCString:str_machine_name maxLength:100 encoding:NSUTF8StringEncoding]; //strcpy((char *)oldp, hwMachineCh); if (hwMachineCh) { NSLog(@"machine,2,%@", machine); size_t len = strlen(hwMachineCh); if (*oldlenp > len) { strlcpy((char *)oldp, hwMachineCh, *oldlenp); // 使用安全的字符串复制 *oldlenp = len; } //strncpy((char *)oldp, hwMachineCh, strlen(hwMachineCh)); } } return ret; } else if (strcmp(name, "hw.model") == 0) { NSLog(@"start hook sysctlbyname new model"); int ret = %orig; __block NSString *modelStr = nil; tryGetVal(@"hwModel", ^(id parameter) { if (parameter) { NSString *temp = parameter; modelStr = [temp copy]; NSLog(@"model,%@", temp); } }); if (oldp && modelStr) { NSLog(@"model,1"); // char str_machine_name[100]; const char *modelStrCh = [modelStr UTF8String]; // [parameter getCString:str_machine_name maxLength:100 encoding:NSUTF8StringEncoding]; //strcpy((char *)oldp, hwMachineCh); if (modelStrCh) { NSLog(@"model,2"); strncpy((char *)oldp, modelStrCh, strlen(modelStrCh)); } } return ret; } else { NSLog(@"start hook sysctlbyname old"); return %orig; } } // int clock_gettime(clockid_t __clock_id, struct timespec *__tp); %hookf(int, clock_gettime, clockid_t __clock_id, struct timespec *__tp) { NSLog(@"start hook clock_gettime"); int nret = %orig; if(__clock_id == CLOCK_MONOTONIC_RAW) { // __tp->tv_sec = 20; // __tp->tv_nsec = 20; } return nret; } // 修改ip // 辅助函数:创建网络接口 static struct ifaddrs* createInterface(const char* name, const char* ipv4, const char* ipv6) { if (!name || !ipv4 || !ipv6) return NULL; @try { // 创建新接口 struct ifaddrs *new_ifaddr = (struct ifaddrs *)calloc(1, sizeof(struct ifaddrs)); if (!new_ifaddr) return NULL; // 设置接口名称 new_ifaddr->ifa_name = strdup(name); if (!new_ifaddr->ifa_name) { free(new_ifaddr); return NULL; } new_ifaddr->ifa_flags = IFF_UP | IFF_RUNNING; // 创建IPv4地址结构 struct sockaddr_in *addr_in = (struct sockaddr_in *)calloc(1, sizeof(struct sockaddr_in)); if (!addr_in) { free(new_ifaddr->ifa_name); free(new_ifaddr); return NULL; } // 设置IPv4地址 addr_in->sin_family = AF_INET; if (inet_pton(AF_INET, ipv4, &addr_in->sin_addr) != 1) { free(addr_in); free(new_ifaddr->ifa_name); free(new_ifaddr); return NULL; } new_ifaddr->ifa_addr = (struct sockaddr *)addr_in; // 创建IPv6结构 struct ifaddrs *next_ifaddr = (struct ifaddrs *)calloc(1, sizeof(struct ifaddrs)); if (!next_ifaddr) { free(addr_in); free(new_ifaddr->ifa_name); free(new_ifaddr); return NULL; } // 设置IPv6名称 next_ifaddr->ifa_name = strdup(name); if (!next_ifaddr->ifa_name) { free(next_ifaddr); free(addr_in); free(new_ifaddr->ifa_name); free(new_ifaddr); return NULL; } next_ifaddr->ifa_flags = IFF_UP | IFF_RUNNING; // 创建IPv6地址结构 struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)calloc(1, sizeof(struct sockaddr_in6)); if (!addr_in6) { free(next_ifaddr->ifa_name); free(next_ifaddr); free(addr_in); free(new_ifaddr->ifa_name); free(new_ifaddr); return NULL; } // 设置IPv6地址 addr_in6->sin6_family = AF_INET6; if (inet_pton(AF_INET6, ipv6, &addr_in6->sin6_addr) != 1) { free(addr_in6); free(next_ifaddr->ifa_name); free(next_ifaddr); free(addr_in); free(new_ifaddr->ifa_name); free(new_ifaddr); return NULL; } next_ifaddr->ifa_addr = (struct sockaddr *)addr_in6; // 链接接口 new_ifaddr->ifa_next = next_ifaddr; return new_ifaddr; } @catch (NSException *exception) { NSLog(@"Error creating interface: %@", exception); return NULL; } } // 修改现有接口的IP地址 static void modifyInterfaceIP(struct ifaddrs *interface, const char *ipv4, const char *ipv6) { if (!interface || !ipv4 || !ipv6) return; @try { if (interface->ifa_addr) { if (((struct sockaddr_in*)interface->ifa_addr)->sin_family == AF_INET) { struct sockaddr_in *addr = (struct sockaddr_in*)interface->ifa_addr; inet_pton(AF_INET, ipv4, &addr->sin_addr); } else if (((struct sockaddr_in*)interface->ifa_addr)->sin_family == AF_INET6) { struct sockaddr_in6 *addr6 = (struct sockaddr_in6*)interface->ifa_addr; inet_pton(AF_INET6, ipv6, &addr6->sin6_addr); } } } @catch (NSException *exception) { NSLog(@"Error modifying interface IP: %@", exception); } } %hookf(int, getifaddrs, struct ifaddrs **interfaces) { if (!interfaces) return EINVAL; int nRet = %orig; if (nRet != 0) return nRet; @try { // 获取网络配置 __block NSDictionary *networkConfig = nil; tryGetVal(@"networkInterfacesInfo", ^(id parameter) { if ([parameter isKindOfClass:[NSDictionary class]]) { networkConfig = parameter; } }); if (!networkConfig) { return nRet; } // 处理现有接口 struct ifaddrs *interface; bool isHookEn0IpV4 = false; for (interface = *interfaces; interface; interface = interface->ifa_next) { if (!interface->ifa_name) continue; NSString *name = @(interface->ifa_name); if ([name isEqualToString:@"en0"]) { NSDictionary *en0Config = networkConfig[@"en0"]; if (en0Config) { const char *ipv4 = [en0Config[@"ipv4"] UTF8String]; const char *ipv6 = [en0Config[@"ipv6"] UTF8String]; if (ipv4 && ipv6) { modifyInterfaceIP(interface, ipv4, ipv6); isHookEn0IpV4 = true; } } } } // 添加新接口 if (!isHookEn0IpV4) { NSDictionary *en0Config = networkConfig[@"en0"]; if (en0Config) { const char *ipv4 = [en0Config[@"ipv4"] UTF8String]; const char *ipv6 = [en0Config[@"ipv6"] UTF8String]; struct ifaddrs *new_en0 = createInterface("en0", ipv4, ipv6); if (new_en0) { new_en0->ifa_next->ifa_next = *interfaces; *interfaces = new_en0; } } } // 添加pdp_ip0接口 NSDictionary *pdpConfig = networkConfig[@"pdp_ip0"]; if (pdpConfig) { const char *ipv4 = [pdpConfig[@"ipv4"] UTF8String]; const char *ipv6 = [pdpConfig[@"ipv6"] UTF8String]; struct ifaddrs *new_pdp = createInterface("pdp_ip0", ipv4, ipv6); if (new_pdp) { new_pdp->ifa_next->ifa_next = *interfaces; *interfaces = new_pdp; } } } @catch (NSException *exception) { NSLog(@"Error in getifaddrs hook: %@", exception); } return nRet; } /* Boolean SCNetworkReachabilityGetFlags ( SCNetworkReachabilityRef target, SCNetworkReachabilityFlags *flags ) */ %hookf(Boolean, SCNetworkReachabilityGetFlags, SCNetworkReachabilityRef target, SCNetworkReachabilityFlags *flags) { NSLog(@"start hook SCNetworkReachabilityGetFlags"); Boolean result = %orig(target, flags); if (result && flags != NULL) { // 可以在这里修改 flags 的值 // 例如,总是添加 kSCNetworkReachabilityFlagsReachable 标志 *flags |= kSCNetworkReachabilityFlagsReachable; *flags |= kSCNetworkReachabilityFlagsIsWWAN; } return result; } %hookf(BOOL,UIAccessibilityIsClosedCaptioningEnabled) { return YES; } %hookf(BOOL,UIAccessibilityIsMonoAudioEnabled) { return YES; } // group ohho end %end %ctor{ NSLog(@"start hook"); @try { @autoreleasepool { NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier]; //NSLog(@"print -- %@",bundleIdentifier); NSString *bundleId = @"org.xyzshell.NotNil"; NSString *plistPath = [NSString stringWithFormat:@"/var/mobile/Library/Preferences/%@.plist", bundleId]; // 创建文件管理器实例 NSFileManager *fileManager = [NSFileManager defaultManager]; // 检查文件是否存在 BOOL fileExists = [fileManager fileExistsAtPath:plistPath]; if(fileExists) { settings = [[NSDictionary alloc] initWithContentsOfFile:plistPath]; NSArray *pkgs = settings[@"apps"]; if([pkgs indexOfObject:bundleIdentifier] != NSNotFound){ NSLog(@"hooks start %@", bundleIdentifier); // 指定需要运行的执行的分组代码,%init有两种用法,这里只展示一种 [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"kLuxSSFaceKey"]; %init(ohno); } } } } @catch (NSException *exception) { NSLog(@"Error in ctor: %@", exception); } } static void cleanup() { // 清理分配的资源 if (settings) { settings = nil; } // 其他清理工作 } %dtor { cleanup(); }