diff --git a/README.md b/README.md index fcf70f8..2a5ad38 100644 --- a/README.md +++ b/README.md @@ -26,27 +26,35 @@ 2. Xcode|Clion 集成开发调试环境 3. 特征码搜索 -| App | version | x86 | arm | Download | remark | Author | -|-----------------|---------|-----|-----|---------------------------------------------|--------------------------------------------------------------------------------------------------------------|---------------------| -| TablePlus | 6.* | ✔ | ✔ | https://tableplus.com/ | inject_bin="/Applications/TablePlus.app/Contents/Frameworks/Sparkle.framework/Versions/B/Sparkle" | | -| DevUtils | 1.* | ✔ | ✔ | https://devutils.com/ | | | -| AirBuddy | 2.* | ✔ | ✔ | https://v2.airbuddy.app/download | inject_bin="/Applications/AirBuddy.app/Contents/Frameworks/LetsMove.framework/Versions/A/LetsMove" | | -| Navicat Premium | 17.* | ✔ | ✔ | App Store | inject_bin="/Applications/Navicat Premium.app/Contents/Frameworks/EE.framework/Versions/A/EE" | QiuChenlyOpenSource | -| Paste | 4.1.3 | ✘ | ✔ | App Store | | LeeeMooo | -| Transmit | 5.* | ✔ | ✔ | https://panic.com/transmit/#download | | | -| AnyGo | 7.* | ✔ | ✔ | https://itoolab.com/gps-location-changer/ | | | -| Downie | 4.* | ✔ | ✔ | https://software.charliemonroe.net/downie/ | inject_bin="/Applications/Permute 3.app/Contents/Frameworks/Licensing.framework/Versions/A/Licensing" | | -| Permute | 3.* | ✔ | ✔ | https://software.charliemonroe.net/permute/ | inject_bin="/Applications/Downie 4.app/Contents/Frameworks/Licensing.framework/Versions/A/Licensing" | | -| ProxyMan | 5.2 | ✔ | ✔ | https://proxyman.io/ | inject_bin="/Applications/Proxyman.app/Contents/Frameworks/HexFiend.framework/Versions/A/HexFiend" | | -| Movist Pro | 2.* | ✔ | ✔ | https://movistprime.com/ | inject_bin="/Applications/Movist Pro.app/Contents/Frameworks/MediaKeyTap.framework/Versions/A/MediaKeyTap" | | -| Surge | 5.7.* | ✔ | ✔ | https://nssurge.com/ | inject_bin="/Applications/Surge.app/Contents/Frameworks/MMMarkdown.framework/Versions/A/MMMarkdown" | | -| Infuse | 7.7.* | ✔ | ✔ | App Store | inject_bin="/Applications/Infuse.app/Contents/Frameworks/Differentiator.framework/Versions/A/Differentiator" | | -| MacUpdater | 3. | ✔ | ✔ | https://www.corecode.io/macupdater/#download | inject_bin="/Applications/MacUpdater.app/Contents/Frameworks/Sparkle.framework/Versions/B/Sparkle" | | +
+ 点击这里展开/收起 + +| App | version | x86 | arm | Download | remark | Author | +|-----------------|---------|-----|-----|----------------------------------------------|----------------------------------------------------------------------------------------------------------------------|---------------------| +| TablePlus | 6.* | ✔ | ✔ | https://tableplus.com/ | inject_bin="/Applications/TablePlus.app/Contents/Frameworks/Sparkle.framework/Versions/B/Sparkle" | | +| DevUtils | 1.* | ✔ | ✔ | https://devutils.com/ | | | +| AirBuddy | 2.* | ✔ | ✔ | https://v2.airbuddy.app/download | inject_bin="/Applications/AirBuddy.app/Contents/Frameworks/LetsMove.framework/Versions/A/LetsMove" | | +| Navicat Premium | 17.* | ✔ | ✔ | App Store | inject_bin="/Applications/Navicat Premium.app/Contents/Frameworks/EE.framework/Versions/A/EE" | QiuChenlyOpenSource | +| Paste | 4.1.3 | ✘ | ✔ | App Store | | LeeeMooo | +| Transmit | 5.* | ✔ | ✔ | https://panic.com/transmit/#download | | | +| AnyGo | 7.* | ✔ | ✔ | https://itoolab.com/gps-location-changer/ | DMCA | | +| Downie | 4.* | ✔ | ✔ | https://software.charliemonroe.net/downie/ | inject_bin="/Applications/Permute 3.app/Contents/Frameworks/Licensing.framework/Versions/A/Licensing" | | +| Permute | 3.* | ✔ | ✔ | https://software.charliemonroe.net/permute/ | inject_bin="/Applications/Downie 4.app/Contents/Frameworks/Licensing.framework/Versions/A/Licensing" | | +| ProxyMan | 5.2 | ✔ | ✔ | https://proxyman.io/ | inject_bin="/Applications/Proxyman.app/Contents/Frameworks/HexFiend.framework/Versions/A/HexFiend" | | +| Movist Pro | 2.* | ✔ | ✔ | https://movistprime.com/ | inject_bin="/Applications/Movist Pro.app/Contents/Frameworks/MediaKeyTap.framework/Versions/A/MediaKeyTap" | | +| Surge | 5.7.* | ✔ | ✔ | https://nssurge.com/ | DMCA | | +| Infuse | 7.7.* | ✔ | ✔ | App Store | inject_bin="/Applications/Infuse.app/Contents/Frameworks/Differentiator.framework/Versions/A/Differentiator" | | +| MacUpdater | 3. | ✔ | ✔ | https://www.corecode.io/macupdater/#download | inject_bin="/Applications/MacUpdater.app/Contents/Frameworks/Sparkle.framework/Versions/B/Sparkle" | | +| CleanShotX | 4. | ✔ | ✘ | https://updates.getcleanshot.com/v3/ | DMCA | | +| ForkLift | 4. | ✔ | ✔ | https://binarynights.com/ | inject_bin="/Applications/ForkLift.app/Contents/Frameworks/UniversalDetector.framework/Versions/A/UniversalDetector" | | + +
+ ## Usage -[download latest release](https://github.com/marlkiller/dylib_dobby_hook_private/releases/download/latest/dylib_dobby_hook.tar.gz) +[download latest release](https://github.com/marlkiller/dylib_dobby_hook/releases/download/latest/dylib_dobby_hook.tar.gz) ```shell tar -xzvf dylib_dobby_hook.tar.gz cd script diff --git a/dylib_dobby_hook.xcodeproj/project.pbxproj b/dylib_dobby_hook.xcodeproj/project.pbxproj index b41cd82..87888ac 100644 --- a/dylib_dobby_hook.xcodeproj/project.pbxproj +++ b/dylib_dobby_hook.xcodeproj/project.pbxproj @@ -27,11 +27,9 @@ B55407272B653DCB005C08E6 /* NavicatPremiumHack.m in Sources */ = {isa = PBXBuildFile; fileRef = B55407262B653DCB005C08E6 /* NavicatPremiumHack.m */; }; B554D7BC2B63F2A300B7EFEA /* DevUtilsHack.m in Sources */ = {isa = PBXBuildFile; fileRef = B554D7BB2B63F2A300B7EFEA /* DevUtilsHack.m */; }; B580D3CA2BE3579300979568 /* LightRoomHack.m in Sources */ = {isa = PBXBuildFile; fileRef = B580D3C72BE3579300979568 /* LightRoomHack.m */; }; - B580D3CB2BE3579300979568 /* AnyGoHack.m in Sources */ = {isa = PBXBuildFile; fileRef = B580D3C82BE3579300979568 /* AnyGoHack.m */; }; - B580D3CC2BE3579300979568 /* SurgeHack.m in Sources */ = {isa = PBXBuildFile; fileRef = B580D3C92BE3579300979568 /* SurgeHack.m */; }; B58160172BE88569001DDB9B /* encryp_utils.m in Sources */ = {isa = PBXBuildFile; fileRef = B58160112BE88569001DDB9B /* encryp_utils.m */; }; B581601B2BE88569001DDB9B /* encryp_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = B58160162BE88569001DDB9B /* encryp_utils.h */; }; - B5CFE84D2BE9F03200CF8D9E /* iMazingHack.m in Sources */ = {isa = PBXBuildFile; fileRef = B5CFE84C2BE9F03200CF8D9E /* iMazingHack.m */; }; + B5D0C0BB2C4B553500881398 /* ForkLiftHack.m in Sources */ = {isa = PBXBuildFile; fileRef = B5D0C0BA2C4B553500881398 /* ForkLiftHack.m */; }; B5D2ED3F2BC0252D0030CBCA /* DevHack.m in Sources */ = {isa = PBXBuildFile; fileRef = B5D2ED3E2BC0252D0030CBCA /* DevHack.m */; }; B5F06B1D2BEF591E0079E68D /* InfuseHack.m in Sources */ = {isa = PBXBuildFile; fileRef = B5F06B1C2BEF591E0079E68D /* InfuseHack.m */; }; B5FE3B862BA2A571001AE437 /* TransmitHack.m in Sources */ = {isa = PBXBuildFile; fileRef = B5FE3B842BA2A571001AE437 /* TransmitHack.m */; }; @@ -79,11 +77,9 @@ B56968C62BEA4E2A0022FAC6 /* libdylib_dobby_hook.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libdylib_dobby_hook.dylib; sourceTree = ""; }; B56968C72BEA4E4D0022FAC6 /* cmake_debugger.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = cmake_debugger.sh; sourceTree = ""; }; B580D3C72BE3579300979568 /* LightRoomHack.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LightRoomHack.m; sourceTree = ""; }; - B580D3C82BE3579300979568 /* AnyGoHack.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AnyGoHack.m; sourceTree = ""; }; - B580D3C92BE3579300979568 /* SurgeHack.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SurgeHack.m; sourceTree = ""; }; B58160112BE88569001DDB9B /* encryp_utils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = encryp_utils.m; sourceTree = ""; }; B58160162BE88569001DDB9B /* encryp_utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = encryp_utils.h; sourceTree = ""; }; - B5CFE84C2BE9F03200CF8D9E /* iMazingHack.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = iMazingHack.m; sourceTree = ""; }; + B5D0C0BA2C4B553500881398 /* ForkLiftHack.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ForkLiftHack.m; sourceTree = ""; }; B5D2ED3E2BC0252D0030CBCA /* DevHack.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DevHack.m; sourceTree = ""; }; B5F06B1C2BEF591E0079E68D /* InfuseHack.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InfuseHack.m; sourceTree = ""; }; B5FE3B842BA2A571001AE437 /* TransmitHack.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TransmitHack.m; sourceTree = ""; }; @@ -184,12 +180,9 @@ isa = PBXGroup; children = ( B5F06B1C2BEF591E0079E68D /* InfuseHack.m */, - B5CFE84C2BE9F03200CF8D9E /* iMazingHack.m */, 38D1AC312B54D1CC00E6CB9E /* AirBuddyHack.m */, 38D1AC2B2B54D03B00E6CB9E /* HackProtocol.h */, - B580D3C82BE3579300979568 /* AnyGoHack.m */, B580D3C72BE3579300979568 /* LightRoomHack.m */, - B580D3C92BE3579300979568 /* SurgeHack.m */, B5FE3B842BA2A571001AE437 /* TransmitHack.m */, 382A25842B6918DF0083F28C /* PasteHack.m */, 38B83E302B5505B300919735 /* TablePlusHack.m */, @@ -327,15 +320,12 @@ 382A25862B6918DF0083F28C /* PasteHack.m in Sources */, B554D7BC2B63F2A300B7EFEA /* DevUtilsHack.m in Sources */, B5F06B1D2BEF591E0079E68D /* InfuseHack.m in Sources */, - B580D3CC2BE3579300979568 /* SurgeHack.m in Sources */, B55407272B653DCB005C08E6 /* NavicatPremiumHack.m in Sources */, 3816BBB92B54FF090051CF39 /* MemoryUtils.m in Sources */, 38B83E312B5505B300919735 /* TablePlusHack.m in Sources */, B580D3CA2BE3579300979568 /* LightRoomHack.m in Sources */, - B580D3CB2BE3579300979568 /* AnyGoHack.m in Sources */, B5FECEAE2BC4FC29008916D6 /* common_ret.m in Sources */, 38D1AC2A2B54CA4D00E6CB9E /* Constant.m in Sources */, - B5CFE84D2BE9F03200CF8D9E /* iMazingHack.m in Sources */, B502BD5D2BCFB35200DAD97F /* MovistProHack.m in Sources */, B5FE3B862BA2A571001AE437 /* TransmitHack.m in Sources */, ); diff --git a/dylib_dobby_hook/apps/AnyGoHack.m b/dylib_dobby_hook/apps/AnyGoHack.m deleted file mode 100644 index 7271edf..0000000 --- a/dylib_dobby_hook/apps/AnyGoHack.m +++ /dev/null @@ -1,192 +0,0 @@ -// -// AnyGoHack.m -// dylib_dobby_hook -// -// Created by 马治武 on 2024/3/17. -// - -#import -#import "Constant.h" -#import "dobby.h" -#import "MemoryUtils.h" -#import -#include -#import "HackProtocol.h" - -@interface AnyGoHack : NSObject - -@end - - -@implementation AnyGoHack - -- (NSString *)getAppName { - return @"com.itoolab.AnyGo"; -} - -- (NSString *)getSupportAppVersion { - // 7.0.0 - return @"7."; -} - -+ (int)hk_isInChina { - NSLog(@">>>>>> Swizzled hk_isInChina method called"); - NSLog(@">>>>>> self.className : %@", self.className); - return 0; -} -- (BOOL)hk_isRegistered { - NSLog(@">>>>>> Swizzled hk_isRegistered method called"); - return YES; -} - - -- (BOOL)hk_isOverDevicesLimit { - NSLog(@">>>>>> Swizzled hk_isOverDevicesLimit method called"); - return NO; -} - - -- (id)hk_device { - NSLog(@">>>>>> Swizzled hk_device method called"); - NSString *className = @"IOSDevice"; - Class class = objc_getClass([className UTF8String]); - return [[class alloc] init]; -} - -- (void)hk_checkRegisterValid:(uint64_t)arg1 { - NSLog(@">>>>>> Swizzled hk_checkRegisterValid method called"); - NSLog(@">>>>>> self.className : %@", self.className); - return ; -} - -- (NSString *) hk_emailText { - NSLog(@">>>>>> Swizzled hk_emailText method called"); - return [Constant G_EMAIL_ADDRESS] ; -} - -- (NSString *) hk_codeText { - NSLog(@">>>>>> Swizzled hk_codeText method called"); - NSUUID *uuid = [NSUUID UUID]; - NSString *uuidString = [uuid UUIDString]; - return uuidString; -} - -// void __cdecl -[RegisterWindow updateUIIsRegister:](RegisterWindow *self, SEL a2, char a3) -//- (int)hk_updateUIIsRegister:(int)arg1 withA3:(int)a3 { -// NSLog(@">>>>>> Swizzled hk_updateUIIsRegister method called"); -// NSLog(@">>>>>> self.className : %@", self.className); -// return [self hk_updateUIIsRegister:arg1 withA3:a3]; -//} - -- (BOOL)hack { -#if defined(__arm64__) || defined(__aarch64__) -#elif defined(__x86_64__) -#endif - - // if ([GlobalFunction isForTest] == 0x0 && [GlobalFunction isInChina] != 0x0) { - [MemoryUtils hookClassMethod: - objc_getClass("GlobalFunction") - originalSelector:NSSelectorFromString(@"isInChina") - swizzledClass:[self class] - swizzledSelector:@selector(hk_isInChina) - ]; -// rax = [RegisterManager shareManager]; -// r14 = [rax isRegistered]; -// [rax release]; -// rax = [r13 objectForKey:@"pathType"]; -// rax = [rax retain]; -// var_40 = [rax intValue]; -// [rax release]; -// var_48 = r13; -// if (r14 != 0x0) { - [MemoryUtils hookInstanceMethod: - objc_getClass("RegisterManager") - originalSelector:NSSelectorFromString(@"isRegistered") - swizzledClass:[self class] - swizzledSelector:@selector(hk_isRegistered) - ]; - - -// r12 = [[RegisterManager shareManager] retain]; -// var_29 = [r12 isOverDevicesLimit:rax]; -// if (var_29 == 0x0) goto loc_10003a8f1; - - [MemoryUtils hookInstanceMethod: - objc_getClass("RegisterManager") - originalSelector:NSSelectorFromString(@"isOverDevicesLimit:") - swizzledClass:[self class] - swizzledSelector:@selector(hk_isOverDevicesLimit) - ]; - - -// -[RegisterWindow updateUIIsRegister:]: -//0000000100059bb9 push rbp -// [MemoryUtils hookInstanceMethod: -// objc_getClass("RegisterWindow") -// originalSelector:NSSelectorFromString(@"updateUIIsRegister:") -// swizzledClass:[self class] -// swizzledSelector:@selector(hk_updateUIIsRegister:withA3:) -// ]; - [MemoryUtils hookInstanceMethod: - objc_getClass("RegisterManager") - originalSelector:NSSelectorFromString(@"email") - swizzledClass:[self class] - swizzledSelector:@selector(hk_emailText) - ]; - [MemoryUtils hookInstanceMethod: - objc_getClass("RegisterManager") - originalSelector:NSSelectorFromString(@"regCode") - swizzledClass:[self class] - swizzledSelector:@selector(hk_codeText) - ]; - -// [MemoryUtils hookInstanceMethod: -// objc_getClass("RegisterWindow") -// originalSelector:NSSelectorFromString(@"checkRegisterValid:result:") -// swizzledClass:[self class] -// swizzledSelector:@selector(hk_checkRegisterValid:) -// ]; -// [MemoryUtils hookInstanceMethod: -// objc_getClass("MainWindowCtr") -// originalSelector:NSSelectorFromString(@"checkRegisterValid:result:") -// swizzledClass:[self class] -// swizzledSelector:@selector(hk_checkRegisterValid:) -// ]; - - -// objc 反射用法 TEST -// // 调用 RegisterManager 类的 shareManager 方法 -// Class registerManagerClass = NSClassFromString(@"RegisterManager"); -// SEL shareManagerSelector = NSSelectorFromString(@"shareManager"); -// id registerManager = [registerManagerClass performSelector:shareManagerSelector]; -// NSLog(@">>>>>> RegisterManager object: %@", registerManager); -// -// // 获取对象的属性与值 -// unsigned int count; -// objc_property_t *properties = class_copyPropertyList(registerManagerClass, &count); -// -// for (unsigned int i = 0; i < count; i++) { -// objc_property_t property = properties[i]; -// NSString *propertyName = [NSString stringWithUTF8String:property_getName(property)]; -// if ([propertyName isEqualToString:@"isRegister"]) { -// // 找到对应的属性,设置其值 -// [registerManager setValue:@(1) forKey:propertyName]; -// // break; -// } -// id propertyValue = [registerManager valueForKey:propertyName]; -// NSLog(@">>>>>> Property: %@, Value: %@", propertyName, propertyValue); -// } -// -// // 获取对象的方法与返回值类型 -// Method *methods = class_copyMethodList(registerManagerClass, &count); -// for (unsigned int i = 0; i < count; i++) { -// Method method = methods[i]; -// const char *methodName = sel_getName(method_getName(method)); -// // method_getReturnType(method, &dst, sizeof(char));// 获取方法返回类型 -// const char *returnType = method_getTypeEncoding(method);// 获取方法参数类型和返回类型 -// NSLog(@">>>>>> Method Name: %s, Return Type: %s", methodName, returnType); -// } - - return YES; -} -@end diff --git a/dylib_dobby_hook/apps/ForkLiftHack.m b/dylib_dobby_hook/apps/ForkLiftHack.m new file mode 100644 index 0000000..81991b2 --- /dev/null +++ b/dylib_dobby_hook/apps/ForkLiftHack.m @@ -0,0 +1,79 @@ +// +// CleanShotXHack.m +// dylib_dobby_hook +// +// Created by voidm on 2024/7/19. +// + +#import +#import "Constant.h" +#import "MemoryUtils.h" +#import +#import "HackProtocol.h" +#include + + +@interface ForkLiftHack : NSObject + + + +@end + + +@implementation ForkLiftHack + + + +- (NSString *)getAppName { + return @"com.binarynights.ForkLift"; +} + +- (NSString *)getSupportAppVersion { + return @"4."; +} + + + +- (BOOL)hack { + + +// +// ; struct ForkLift.RegistrationData { +// ; let name: Swift.String +// ; let quantity: Swift.Int +// ; let license_type: Swift.Int +// ; let validityDate: Foundation.Date +// ; let signature: Swift.String +// ; let licenseKey: Swift.String? +// ; } +//_$s8ForkLift16RegistrationDataVMn: // nominal type descriptor for ForkLift.RegistrationData +//00000001008327c0 struct __swift_StructDescriptor { ; "RegistrationData", DATA XREF=_$s8ForkLift16RegistrationDataVMa+7 +// struct __swift_ContextDescriptor { // context +// 0x10051, // flags +// _$s8ForkLiftMXM-0x1008327c4, // parent context +// aRegistrationda-0x1008327c8, // name of the type +// _$s8ForkLift16RegistrationDataVMa-0x1008327cc, // type accessor function pointer +// _$s8ForkLift16RegistrationDataVMF-0x1008327d0 // fields +// }, +// 0x6, // number of fields +// 0x2 +//} + // 自定义日期字符串 + NSDictionary *registrationDataDict = @{ + @"name": [Constant G_EMAIL_ADDRESS], + @"quantity": @520, + @"license_type": @1, + @"validityDate": @1753025400, // @"2025-07-20 15:30:00", + @"signature": @"SignatureExample", + @"licenseKey": @"ABC123XYZ" + }; + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:registrationDataDict options:0 error:nil]; + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + [defaults setObject:jsonData forKey:@"registrationData"]; + [defaults synchronize]; + + + return YES; +} + +@end diff --git a/dylib_dobby_hook/apps/SurgeHack.m b/dylib_dobby_hook/apps/SurgeHack.m deleted file mode 100644 index 50f50ac..0000000 --- a/dylib_dobby_hook/apps/SurgeHack.m +++ /dev/null @@ -1,799 +0,0 @@ -// -// SurgeHack.m -// dylib_dobby_hook -// -// Created by 马治武 on 2024/4/4. -// - -#import -#import "Constant.h" -#import "dobby.h" -#import "MemoryUtils.h" -#import -#include -#import "HackProtocol.h" -#include -#import -#import "common_ret.h" -#include -#import -#import "encryp_utils.h" - -@interface NSString (MyExtension) -- (BOOL)sEqualToStringEx:(NSString *)parameter; -@end - -@implementation NSString (MyExtension) - -- (BOOL)sEqualToStringEx:(NSString *)parameter { - return false; -} -@end - -@interface SurgeHack : NSObject - - - -@end - - -@implementation SurgeHack - -static IMP urlWithStringSeletorIMP; -static IMP objectForKeyedSubscriptImp; -static IMP objectForKeyedSubscriptImp2; -static IMP KD_JSONObjectIMP; -static IMP initWithBytesNoCopyMethodIMP; -static IMP dataTaskWithRequestIMP; -static IMP dataTaskWithRequestIMP2; -static IMP componentsJoinedByStringIMP; -static IMP shouldPerformMITMForHostIMP; - -static NSString *publicKey = @"-----BEGIN PUBLIC KEY-----\n" -"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvnU72zbRQFSB7IZ4ob2u\n" -"4YgjsI6507rjwhR5DzxZBPtxuAuQOJnCM6XqrFy0hUazNDUybmVb+abbQlbmHs9C\n" -"MGsYLpYKqJLNFCGy+2CRJxCLrTE35pJ36zIVvdj+1qH2KfyfiEjBc6+F6W3E0TwW\n" -"BMd0ezj1pWYZoCytabmhgvhumWXI0ReOIGLuMrEOAf8zKZBWRRVSW3cLSwq0eQ7u\n" -"ubi5UD5rvkmcDuL+RUQySi4W8vOpteq3ceZmtZVpUAXvUjnXzg/EX94VVfPCWhd1\n" -"Ii4P+EBkaV7SuqFgZiczmkcXin5JrkATnIEf5pi71XWadeVZgFSOrkseCQE+Twta\n" -"9QIDAQAB\n" -"-----END PUBLIC KEY-----\n"; - - -static NSDictionary *policySign; -// 这里常量不能用 NSNumber, 需要 基本类型 -static const NSInteger enterpriseLicense = 0; - - -- (NSString *)getAppName { - // >>>>>> 5.7.1 (2758) - return @"com.nssurge.surge-mac"; -} - -- (NSString *)getSupportAppVersion { - return @"5.7."; -} - - - -- (BOOL)hack { - - // 程序使用ptrace来进行动态调试保护,使得执行lldb的时候出现Process xxxx exited with status = 45 (0x0000002d)错误。 - // 使用 DobbyHook 替换 ptrace函数。 - DobbyHook((void *)ptrace, (void *)my_ptrace, (void *)&orig_ptrace); - - NSString *searchFilePath = [[Constant getCurrentAppPath] stringByAppendingString:@"/Contents/MacOS/Surge"]; - uintptr_t fileOffset =[MemoryUtils getCurrentArchFileOffset: searchFilePath]; - - // deviceId = [EncryptionUtils generateSurgeDeviceId]; - // NSLog(@">>>>>> deviceId: %@",deviceId); - - // NSDictionary *jsonLicense = @{ - // @"deviceID": @"16b8f4bdfd55d29f737427b4ec0c14d7", - // @"type":@"licensed", // trial:licensed:revoked - // @"product": @"SURGEMAC5", - // @"expiresOnDate": @1746350567, - // @"p": @"QU1oHx8IbxU1PvQQ3340JA==" - // }; - // 伪造 License , p[1]=1 -// policySign = @{ -// @"policy": @"ewogICJwIiA6ICJtdmlCeW5KRnI3dVZQcGxONVZoTEd3PT0iLAogICJkZXZpY2VJRCIgOiAiMTZiOGY0YmRmZDU1ZDI5ZjczNzQyN2I0ZWMwYzE0ZDciLAogICJwcm9kdWN0IiA6ICJTVVJHRU1BQzUiLAogICJ0eXBlIiA6ICJsaWNlbnNlZCIsCiAgImV4cGlyZXNPbkRhdGUiIDogMTc0NjM1MDU2Nwp9", -// @"sign": @"a6r7vh1fShggsQgBfghOc6FhXdXsgSrHMhwlwO8HJYMDxch7+H8Q0mAnKdG3yY4J002iTTpgtPcUMctlVWOXLNaHnDEY0lWGnU/oHW5BPBiJ6eqPe/Mf+pqwtG4HTRqGRNUiomru2q7zu4VuYdJFklFffnK7gSLxwxAvV71K8JCkvxb0I+eNuJUSzsRhOJC4HMBmeoq++SBViUANbZhI6u+w5XXVcV3VC0VAfsMrIYItHY8oWE9FjWkB+BnJa6+yXgxfBK89wnsW0gCszAs9Pa1e06QEQ1vHKWmbp8XKP5OwzCLp73vSKyjB4cl9o57qwt9Y+DD1Qsdi1MT0NpWqwA==", -// @"enterprise":@1 -// }; - - // 伪造 License , p[1]=3 - policySign = @{ - @"policy": @"ewogICJwIiA6ICJRVTFvSHg4SWJ4VTFQdlFRMzM0MEpBPT0iLAogICJkZXZpY2VJRCIgOiAiMTZiOGY0YmRmZDU1ZDI5ZjczNzQyN2I0ZWMwYzE0ZDciLAogICJwcm9kdWN0IiA6ICJTVVJHRU1BQzUiLAogICJ0eXBlIiA6ICJsaWNlbnNlZCIsCiAgImV4cGlyZXNPbkRhdGUiIDogMTc0NjM1MDU2Nwp9", - @"sign": @"K7QcxRYpPeIYOUtSHqLr2jfzWKYKlphJen0xUwJLVqwM4Xr/DcDvEgQVyIgV8poF9RnhCg7eruw6wbXzMv9GSfSC/zKm4DUsjPsqtvr4X/+thfUyzVrAJgGUmIGSOR7dFrOvdhbx4h+hsiWR9oYVq+vQfp7xdkF1RD+72QVbhR8PJyBCxja34JklxvDKGDJmsc1FhbkTeXzEBNkSNhD58HRWajIxlAs6sckjbGV/DPrrV8cC3Rok3iytiMcp/KRqtaJYtZk/RMrvxnByszutZ8U9z5ve1mHMdO1BKEnUREtriVZ/kU0I07itV9tpDoJReL9pQiQk93L/WdO9mmtERA==", - @"enterprise":@(enterpriseLicense) - }; - // NSLog(@">>>>>> policySign: %@",policySign); - - // 写入 license attr 信息 - NSData *jsonData = [NSJSONSerialization dataWithJSONObject:policySign options:NSJSONWritingPrettyPrinted error:nil]; - Class KDStorageHelperClass = NSClassFromString(@"KDStorageHelper"); - SEL directoryPathSelector = NSSelectorFromString(@"applicationSupportDirectoryPathWithName:"); - NSString *directoryPath = [KDStorageHelperClass performSelector:directoryPathSelector withObject:@"com.nssurge.surge-mac"]; - const char *directoryUTF8String = [directoryPath UTF8String]; - const void *jsonBytes = [jsonData bytes]; - size_t jsonLength = [jsonData length]; - setxattr(directoryUTF8String, "com.nssurge.surge-mac.nsa.3", jsonBytes, jsonLength, 0, 0); - - - // 伪造 public key - // - NSData initWithBytesNoCopy:length:freeWhenDone: - Class NSDataClass = NSClassFromString(@"NSData"); - SEL initWithBytesNoCopySeletor = NSSelectorFromString(@"initWithBytesNoCopy:length:freeWhenDone:"); - Method initWithBytesNoCopyMethod = class_getInstanceMethod(NSDataClass, initWithBytesNoCopySeletor); - initWithBytesNoCopyMethodIMP = method_getImplementation(initWithBytesNoCopyMethod); - [MemoryUtils hookInstanceMethod: - NSDataClass - originalSelector:initWithBytesNoCopySeletor - swizzledClass:[self class] - swizzledSelector:NSSelectorFromString(@"hk_initWithBytesNoCopy:length:freeWhenDone:") - ]; - - // hook NSURL['+ URLWithString:'] - Class NSURLControllerClass = NSClassFromString(@"NSURL"); - SEL urlWithStringSeletor = NSSelectorFromString(@"URLWithString:"); - Method urlWithStringSeletorMethod = class_getClassMethod(NSURL.class, urlWithStringSeletor); - urlWithStringSeletorIMP = method_getImplementation(urlWithStringSeletorMethod); - [MemoryUtils hookClassMethod: - NSURLControllerClass - originalSelector:urlWithStringSeletor - swizzledClass:[self class] - swizzledSelector:NSSelectorFromString(@"hk_URLWithString:") - ]; - - - // trigger : expiresOnDate 解析 policy,获取 license/device 信息 - // -[NSDictionary objectForKeyedSubscript:]: - // Class NSDictionaryClass = NSClassFromString(@"__NSDictionaryI"); - // SEL objectForKeyedSubscriptSeleter = NSSelectorFromString(@"objectForKeyedSubscript:"); - // Method objectForKeyedSubscriptMethod = class_getInstanceMethod(NSDictionaryClass, objectForKeyedSubscriptSeleter); - // objectForKeyedSubscriptImp = method_getImplementation(objectForKeyedSubscriptMethod); - // [MemoryUtils hookInstanceMethod: - // NSDictionaryClass - // originalSelector:objectForKeyedSubscriptSeleter - // swizzledClass:[self class] - // swizzledSelector:NSSelectorFromString(@"hook_objectForKeyedSubscript:") - // ]; - - //获取授权凭证 0 未授权, 1 试用 xxx,2 授权, arm : 0000000100173b70 - // -[WindowController trialButtonPressed:] sub_1001c643c() == 0x1:0x0 - // 00000001001c643c push rbp ; CODE XREF=sub_10008aad8+635, sub_1000beb1b+34, -[SGMAppDelegate applicationDidFinishLaunching:]+3108, sub_1001b16ab+64, sub_1001b1820+14, sub_1001b1820+24, sub_1001b1820+33, sub_1001b2827+7, sub_1001b2827+26, sub_1001b2827+64, sub_1001b441b+83 - // 00000001001c643d mov rbp, rsp - // 00000001001c6440 mov eax, dword [dword_100860ec0] ; dword_100860ec0 - // 00000001001c6446 pop rbp - // 00000001001c6447 ret - - -//## helper 修复 -//# 通过 dtrace 监控到 surge helper[18720] kill 了 surge [18706] 进程 -//0 243 kill:return 18720 com.nssurge.surge-mac.helper 9 18706 0 -//# 查看 helper 日志 发现 helper 检测了 Framework 下文件签名 -//14156 signing bytes in 3 blob(s) from /Applications/Surge.app/Contents/Frameworks/Sparkle.framework/Versions/Current/Sparkle(x86_64) -//2024-05-12 15:50:49.107835+0800 0x309f28 Debug 0x0 19297 0 com.nssurge.surge-mac.helper: (Security) [com.apple.securityd:cfloadfile] failed to fetch /Applications/Surge.app/Contents/Frameworks/Sparkle.framework/Versions/Current/./_CodeSignature/CodeRequirements-1 error=-10 -//2024-05-12 15:50:49.107869+0800 0x309f28 Debug 0x0 19297 0 com.nssurge.surge-mac.helper: (Security) [com.apple.securityd:staticCode] SecStaticCode network default: YES -//2024-05-12 15:50:49.107900+0800 0x309f28 Debug 0x0 19297 0 com.nssurge.surge-mac.helper: (Security) [com.apple.securityd:notarization] Extracting ticket from bundle: /Applications/Surge.app/Contents/Frameworks/Sparkle.framework/Versions/Current/. - - // arm: SecCodeCnginfo : 000000010027c7b8 - // 3. 网络不可用(如果校验不通过, 会影响下面的 dns 解析) --> 移除文件签名验证 -> -[SGMScriptManagementViewController viewDidAppear]: intrinsic_movaps(xmm0, *(int128_t *)0x100603550) - // 00000001005a78b0 db "SecCodeCngInformateWithPckValidimework/Bmework/S", 0 ; DATA XREF=sub_10027f4e8+168 - - // 00000001006034c0 db "SecCodeCheckValiSecCodeCopySigniSecStaticCodeCreSecStaticCodeChe/Contents/Frameworks/MMMarkdown.framework/MMMarkorks/Bugsnag.fraorks/Sparkle.fra", 0 ; DATA XREF=sub_10030b9a5+33 - // 000000010030b9a5 push rbp ; Objective C Block defined at 0x100747c88, Begin of try block, DATA XREF=0x100747c98 - // 000000010030b9a6 mov rbp, rsp - // 000000010030b9a9 push r15 - // 000000010030b9ab push r14 - // 000000010030b9ad push r13 - // 000000010030b9af push r12 - // 000000010030b9b1 push rbx - // 000000010030b9b2 sub rsp, 0xb8 - // 000000010030b9b9 mov edi, 0x14 ; argument "size" for method imp___stubs__malloc - // 000000010030b9be call imp___stubs__malloc ; malloc - // 000000010030b9c3 mov rbx, rax - // 000000010030b9c6 movaps xmm0, xmmword [aSeccodecheckva] ; "SecCodeCheckValiSecCodeCopySigniSecStaticCodeCreSecStaticCodeChe/Contents/Frameworks/MMMarkdown.framework/MMMarkorks/Bugsnag.fraorks/Sparkle.fra" - // 000000010030b9cd movups xmmword [rax], xmm0 - // 000000010030b9d0 mov dword [rax+0x10], 0x79746964 - // 000000010030b9d7 mov rdi, qword [objc_cls_ref_NSString] ; argument "class" for method imp___stubs__objc_alloc, objc_cls_ref_NSString - // 000000010030b9de call imp___stubs__objc_alloc ; objc_alloc - // 000000010030b9e3 mov rsi, qword [0x10082f6d8] ; @selector(initWithBytes:length:encoding:) - -#if defined(__arm64__) || defined(__aarch64__) - NSString *sub_0x10030b9a5Code = @"FF 43 04 D1 E9 23 0A 6D FC 6F 0B A9 FA 67 0C A9 F8 5F 0D A9 F6 57 0E A9 F4 4F 0F A9 FD 7B 10 A9 FD 03 04 91 80 02 80 52 .. .. 09 94 F3 03 00 AA .. .. 00 .."; -#elif defined(__x86_64__) - NSString *sub_0x10030b9a5Code = @"55 48 89 E5 41 57 41 56 41 55 41 54 53 48 81 EC .. .. .. .. BF .. .. .. .. E8 .. .. .. .. 48 89 C3 0F 28 05 .. .. .. .. 0F 11 00"; -#endif - NSArray *sub_0x10030b9a5Offsets =[MemoryUtils searchMachineCodeOffsets: - searchFilePath - machineCode:sub_0x10030b9a5Code - count:(int)1 - ]; - intptr_t _sub_0x10030b9a5 = [MemoryUtils getPtrFromGlobalOffset:0 targetFunctionOffset:(uintptr_t)[sub_0x10030b9a5Offsets[0] unsignedIntegerValue] reduceOffset:(uintptr_t)fileOffset]; - - // dobby.dylib 动态库 , arm 这里不能写 nil ? EXC_BAD_ACCESS (code=1, address=0x0) - // 所以全局替换成了静态库 .a - DobbyHook((void *)_sub_0x10030b9a5, ret, NULL); - - - // hook DNS 解析 -// Class SGDNSRecordIPv4Class = NSClassFromString(@"SGDNSRecordIPv4"); -// SEL addressWithPortSeletor = NSSelectorFromString(@"addressWithPort:"); -// Method addressWithMethod = class_getInstanceMethod(SGDNSRecordIPv4Class, addressWithPortSeletor); -// addressWithMethodIMP = method_getImplementation(addressWithMethod); -// [MemoryUtils hookInstanceMethod: -// SGDNSRecordIPv4Class -// originalSelector:addressWithPortSeletor -// swizzledClass:[self class] -// swizzledSelector:NSSelectorFromString(@"hook_addressWithPort:arg3:arg4:arg5:") -// ]; - - - // 过滤 mac/v3/ac,mac/v3/resource/jsvm,mac/v3/deactivate/,mac/v3/init/,mac/v3/free-trial,mac/v3/resource/module,mac/v3/resource/jsvm,mac/v3/device?deviceID=%@ - // mac/v3/ac - Class SGRequestHelperClass = NSClassFromString(@"SGRequestHelper"); - SEL dataTaskWithRequestSeletor = NSSelectorFromString(@"dataTaskWithRequest:completionHandler:"); - Method dataTaskWithRequestMethod = class_getInstanceMethod(SGRequestHelperClass, dataTaskWithRequestSeletor); - dataTaskWithRequestIMP = method_getImplementation(dataTaskWithRequestMethod); - [MemoryUtils hookInstanceMethod: - SGRequestHelperClass - originalSelector:dataTaskWithRequestSeletor - swizzledClass:[self class] - swizzledSelector:NSSelectorFromString(@"hook_dataTaskWithRequest:completionHandler:") - ]; - - // -[SGHTTPClient dataTaskWithURLRequest:configuration:completionHandler:] - // mac/v3/xx - Class SGHTTPClientClass = NSClassFromString(@"SGHTTPClient"); - SEL dataTaskWithRequestSeletor2 = NSSelectorFromString(@"dataTaskWithURLRequest:configuration:completionHandler:"); - Method dataTaskWithRequestMethod2 = class_getInstanceMethod(SGHTTPClientClass, dataTaskWithRequestSeletor2); - dataTaskWithRequestIMP2 = method_getImplementation(dataTaskWithRequestMethod2); - [MemoryUtils hookInstanceMethod: - SGHTTPClientClass - originalSelector:dataTaskWithRequestSeletor2 - swizzledClass:[self class] - swizzledSelector:NSSelectorFromString(@"hook_dataTaskWithURLRequest:configuration:completionHandler:") - ]; - - - // 下面俩个 设置菜单会报错,大概是因为没权限调用 Ponte 与 Remote 功能 - [MemoryUtils replaceInstanceMethod: - NSClassFromString(@"SGPonteManager") - originalSelector:NSSelectorFromString(@"updatePonteDeviceListWithCompletionHandler:") - swizzledClass:[self class] - swizzledSelector:@selector(ret) - ]; - [MemoryUtils replaceInstanceMethod: - NSClassFromString(@"SGRemoteNotificationCenter") - originalSelector:NSSelectorFromString(@"setup") - swizzledClass:[self class] - swizzledSelector:@selector(ret) - ]; - - - // 这个判断决定模块(不包括官方内置模块)走本地存储 还是 icloud 存储,得绕过 icloud 存储,不然模块存不了 - // -[NSUbiquitousKeyValueStore defaultStore] - [MemoryUtils replaceClassMethod: - NSClassFromString(@"NSUbiquitousKeyValueStore") - originalSelector:NSSelectorFromString(@"defaultStore") - swizzledClass:[self class] - swizzledSelector:@selector(ret0) - ]; - - // 过滤 https://76.223.12.1/mac/v3/ac 请求 - // arm: /mac/deviceNasystemVedeviceModevice -> 00000001000e1fe8 - // Message from debugger: Terminated due to signal 9 - // queue = 'com.apple.root.default-qos', stop reason = EXC_GUARD (code=4611686022722355231, subcode=0x8fd4dbfade2dead) - // triger : -[SGMOverviewViewController viewDidLoad]: >> dispatch_source_set_event_handler(r15, &var_68); - // 把这个 nop 掉就没必要修复 objectForKeyedSubscript(k) 参数了; mac/v3/ac - // 00000001003044df push rbp ; DATA XREF=-[SGMOverviewViewController viewDidLoad]+1256 - //#if defined(__arm64__) || defined(__aarch64__) - // NSString *sub_0x1003044dfCode = @"FF C3 05 D1 FC 6F 11 A9 FA 67 12 A9 F8 5F 13 A9 F6 57 14 A9 F4 4F 15 A9 FD 7B 16 A9 FD 83 05 91 F6 03 00 AA .. .. 00 .."; - //#elif defined(__x86_64__) - // NSString *sub_0x1003044dfCode = @"55 48 89 E5 41 57 41 56 41 55 41 54 53 48 81 EC .. .. .. .. 48 89 BD .. .. .. .. 48 8B 05 .. .. .. .. 48 8B 00 48 89 45 .. 48 8B 1D .. .. .. .. 4C 8B 35 .. .. .. .. BF .. .. .. .. E8 .. .. .. .. 49 89 C7 0F 28 05 .. .. .. .. 0F 11 00 48 B8 .. .. .. .. .. .. .. .."; - //#endif - // NSArray *sub_0x1003044dfOffsets =[MemoryUtils searchMachineCodeOffsets: - // searchFilePath - // machineCode:sub_0x1003044dfCode - // count:(int)3 - // ]; - // - // for (NSNumber *sub_0x1003044dIt in sub_0x1003044dfOffsets) { - // intptr_t _sub_0x1003044df = [MemoryUtils getPtrFromGlobalOffset:0 targetFunctionOffset:(uintptr_t)[sub_0x1003044dIt unsignedIntegerValue] reduceOffset:(uintptr_t)fileOffset]; - // DobbyHook((void *)_sub_0x1003044df, ret1, nil); - // } - - - // 通过 hook join 函数来伪造 device id - // NSMutableArray componentsJoinedByString - Class NSMutableArrayClass = NSClassFromString(@"NSMutableArray"); - SEL componentsJoinedByStringSeletor = NSSelectorFromString(@"componentsJoinedByString:"); - Method componentsJoinedByStringMethod = class_getInstanceMethod(NSMutableArrayClass, componentsJoinedByStringSeletor); - componentsJoinedByStringIMP = method_getImplementation(componentsJoinedByStringMethod); - [MemoryUtils hookInstanceMethod: - NSMutableArrayClass - originalSelector:componentsJoinedByStringSeletor - swizzledClass:[self class] - swizzledSelector:NSSelectorFromString(@"hook_componentsJoinedByString:") - ]; - - - - // 获取真实的设备 ID - // deviceId rcx 呢 --> sub_1000b7dbd(0x2, r15, @"Device ID: %@", rcx, 0x0, r9, var_140); arm : 0000000100174278 - // void *fun_device = (void *)_sub_0x1001c6ca6; - // deviceId = ((NSString* (*)())fun_device)(); - // NSLog(@">>>>>> device id is %@",deviceId); - - // hook CCCrypt ; 来获取 p 参数的 key 与 iv - DobbyHook((void *) CCCrypt,(void *) hk_CCCrypt, (void **) &original_CCCrypt); - - - // 'SGSocket-346', stop reason = EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) - // p 参数第一位如果是 3, 会走这个地方, 导致程序过段时间奔溃或网络不可用 - // 据说正版的第一位是 3, 但是改成 1 好像也没啥问题, 也不会崩溃,要么 hook 下面的, 要么用 1; -// 000000010000e0fd push rbp ; Objective C Block defined at 0x10073fd58, DATA XREF=0x10073fd68 -// 000000010000e0fe mov rbp, rsp -// 000000010000e101 push r15 -// 000000010000e103 push r14 -// 000000010000e105 push r13 -// 000000010000e107 push r12 -// 000000010000e109 push rbx -// 000000010000e10a sub rsp, 0x628 -// 000000010000e111 mov rax, qword [___stack_chk_guard_10073e278] ; ___stack_chk_guard_10073e278 -// rax = [SGDNSPacket queryPacketWithDomain:@"captive.apple.com" identifier:0x0 queryType:0x100]; - -#if defined(__arm64__) || defined(__aarch64__) - NSString *sub_0x10000e091Code = @"FA 67 BB A9 F8 5F 01 A9 F6 57 02 A9 F4 4F 03 A9 FD 7B 04 A9 FD 03 01 91 FF 83 18 D1 .. .. 00 .."; -#elif defined(__x86_64__) - NSString *sub_0x10000e091Code = @"55 48 89 E5 41 57 41 56 41 55 41 54 53 48 81 EC 28 06 00 00 48 8B 05 .. .. .."; -#endif - NSArray *sub_0x10000e091Offsets =[MemoryUtils searchMachineCodeOffsets: - searchFilePath - machineCode:sub_0x10000e091Code - count:(int)3 - ]; - - for (NSNumber *sub_0x10000e091It in sub_0x10000e091Offsets) { - intptr_t _sub_0x10000e091 = [MemoryUtils getPtrFromGlobalOffset:0 targetFunctionOffset:(uintptr_t)[sub_0x10000e091It unsignedIntegerValue] reduceOffset:(uintptr_t)fileOffset]; - DobbyHook((void *)_sub_0x10000e091, ret, NULL); - } - - - - // TODO: SSL 域名过滤该如何优雅 HOOK ?? -// -[SGHTTPEngine shouldPerformMITMForHost:sourceAddress:isSNI:]: -// -// 0000000100049de7 mov r13, qword [0x100837058] ; @selector(isEqualToString:) // __NSCFString -// if ([rbx isEqualToString:@"api.enterprise.nssurge.com:443"] != 0x0 || -// [rbx isEqualToString:@"www.surge-activation.com:443"] != 0x0 || -// [rbx isEqualToString:@"www.surge-activation.com"] != 0x0 || -// [rbx isEqualToString:@"api.enterprise.nssurge.com"] != 0x0) - // 它可以在任意地方进行hook 并获取/修改 寄存器的上下文 -// DobbyInstrument((void *) 0x00000001000499d9, shouldPerformMITMForHost_handler); - - -// -[SGJournalRecordContainer _shouldHideRequest:takeoverMode:engineIdentifier:URL:]: -// r15 hasSuffix:@".surge-activation.com"] != 0x0 || [r15 isEqual:@"enterprise.nssurge.com"] != 0x0 -// -// 000000010005cdb9 mov r14, qword [0x1008360b8] ; @selector(hasSuffix:), CODE XREF=-[SGJournalRecordContainer _shouldHideRequest:takeoverMode:engineIdentifier:URL:]+642 -// 000000010005cdc0 lea rdx, qword [cfstring__surge_activation_com] ; @".surge-activation.com" -// -// 000000010005cdd7 mov rsi, qword [0x100837008] ; @selector(isEqual:) -// 000000010005cdde lea rdx, qword [cfstring_enterprise_nssurge_com] ; @"enterprise.nssurge.com" - - - - - // license 窗口 - // -[SGMLicenseViewController reload]: - // https://www.surge-activation.com/mac/v3/device?deviceID=ce2500e944650ad7f6e2f580268e5454 - [MemoryUtils hookInstanceMethod: - NSClassFromString(@"SGMEnterprise") - originalSelector:NSSelectorFromString(@"settings") - swizzledClass:[self class] - swizzledSelector:NSSelectorFromString(@"hk_settings") - ]; - - - // 发送消息提醒 - Method raiseEventMethod = class_getClassMethod(NSClassFromString(@"SGEEventCenter"), NSSelectorFromString(@"raiseEvent:content:type:")); - IMP raiseEventMethodIMP = method_getImplementation(raiseEventMethod); - ((void *(*)(id, SEL,id,id,int))raiseEventMethodIMP)( - NSClassFromString(@"SGEEventCenter"), - NSSelectorFromString(@"raiseEvent:content:type:"), - @"WARNNING", - @"Ref: https://github.com/marlkiller/dylib_dobby_hook",1 - ); - - return YES; -} - - -void shouldPerformMITMForHost_handler(void *address, DobbyRegisterContext *ctx) { - SEL tmp = @selector(sEqualToStringEx:); - -#if defined(__arm64__) || defined(__aarch64__) -#elif defined(__x86_64__) - intptr_t r12 = (intptr_t)ctx->general.regs.r12; -// 去 nm 的各种指针, 这样写最好 - ctx->general.regs.r12 = (intptr_t)tmp; -// *(intptr_t*)&ctx->general.regs.r12 = (intptr_t)tmp; - -#endif - -} -// https://github.com/PhD-5/iOSDefectTweak/blob/master/hooks/CCCryptHook.m -// https://github.com/PhD-5/CCCryptHook/blob/master/hooks/CCCrypt.xm -static size_t getIVLength(CCAlgorithm alg) { - switch(alg) { - case kCCAlgorithmAES128: - return kCCBlockSizeAES128; - case kCCAlgorithmDES: - return kCCBlockSizeDES; - case kCCAlgorithm3DES: - return kCCBlockSize3DES; - case kCCAlgorithmCAST: - return kCCBlockSizeCAST; - case kCCAlgorithmRC2: - return kCCBlockSizeRC2; - default: - return 0; - } -} -static CCCryptorStatus (*original_CCCrypt)( - CCOperation op, /* kCCEncrypt, etc. */ - CCAlgorithm alg, /* kCCAlgorithmAES128, etc. */ - CCOptions options, /* kCCOptionPKCS7Padding, etc. */ - const void *key, - size_t keyLength, - const void *iv, /* optional initialization vector */ - const void *dataIn, /* optional per op and alg */ - size_t dataInLength, - void *dataOut, /* data RETURNED here */ - size_t dataOutAvailable, - size_t *dataOutMoved); - -CCCryptorStatus hk_CCCrypt( - CCOperation op, /* kCCEncrypt, etc. */ - CCAlgorithm alg, /* kCCAlgorithmAES128, etc. */ - CCOptions options, /* kCCOptionPKCS7Padding, etc. */ - const void *key, - size_t keyLength, - const void *iv, /* optional initialization vector */ - const void *dataIn, /* optional per op and alg */ - size_t dataInLength, - void *dataOut, /* data RETURNED here */ - size_t dataOutAvailable, - size_t *dataOutMoved) -{ -// 0x1001c7ce7 <+955>: leaq -0x50(%rbp), %rdi -// 0x1001c7ceb <+959>: movq %r14, %rsi // deviceId.getBytes() -// 0x1001c7cee <+962>: movq %rax, %rdx // 32 -// 0x1001c7cf1 <+965>: callq 0x10045fca0 ; // rbp-50 为 key, rbp-40 为 iv ; 这里调用的 sha256 来根据 deviceId 生成key/iv -// ... -// 00000001001c7d63 lea rcx, qword [rbp+-0x50] ; argument "key" for method imp___stubs__CCCrypt -// 00000001001c7d67 mov r8d, 0x20 ; argument "keyLength" for method imp___stubs__CCCrypt -// 00000001001c7d6d mov edi, 0x1 ; argument "op" for method imp___stubs__CCCrypt -// 00000001001c7d72 xor esi, esi ; argument "alg" for method imp___stubs__CCCrypt -// 00000001001c7d74 mov edx, 0x1 ; argument "options" for method imp___stubs__CCCrypt -// 00000001001c7d79 lea r9, qword [rbp+-0x40] ; argument "iv" for method imp___stubs__CCCrypt -// 00000001001c7d7d lea r10, -// 00000001001c7d84 push r10 ; argument "dataOutMoved" for method imp___stubs__CCCrypt -// 00000001001c7d86 push r13 ; argument "dataOutAvailable" for method imp___stubs__CCCrypt -// 00000001001c7d88 push qword [qword_100867b70] ; argument "dataOut" for method imp___stubs__CCCrypt, -// 00000001001c7d8e push rax ; argument "dataInLength" for method imp___stubs__CCCrypt -// 00000001001c7d8f push r14 ; argument "dataIn" for method imp___stubs__CCCrypt -// 00000001001c7d91 call imp___stubs__CCCrypt ; CCCrypt - - // TODO: 没搞明白 p 参数解密后是什么, 以及干嘛的.. -// https://drafts.misty.moe/surge%E7%A0%B4%E8%A7%A3-89fa88c1794d43f6888e43bd30f91bfe#d777e8afaa1041eaa844910d5b519ecf -// AES_CBC_256( -// input: "\x03\x04\x02NSExtension", -// key: SHA256(deviceID), -// iv: SHA256(deviceID)[16:32], -// options: PKCS7Padding) -// 00000000 03 04 02 4e 53 45 78 74 65 6e 73 69 6f 6e 00 |...NSExtension.| -// -// [0] = 3, 为固定header -// [1] = 4, 控制VMess加密 -// [2] = 2, 控制TCP、SS的端口字节数 -// [3:] = "NSExtension", 控制TE plugin加载 - - // 似乎 解密后的 dataOut 第一字节不能是 3,不能是 0 - if (keyLength==32) { - // 0x1001c6921 <+1125>: callq 0x1005df574 ; symbol stub for: CCCrypt - // 0x1001c6926 <+1130>: addq $0x30, %rsp - NSData *keyData = [NSData dataWithBytes:key length:keyLength]; - NSString *keyBase64 = [keyData base64EncodedStringWithOptions:0]; - NSString *keyStr = [[NSString alloc] initWithData:keyData encoding:NSUTF8StringEncoding]; - NSLog(@">>>>>> keyBase64 :%@",keyBase64); - NSLog(@">>>>>> keyStr :%@",keyStr); - - const uint8_t *keyBytes = (const uint8_t *)keyData.bytes; - NSString *keyHex = @""; - for (int i = 0; i < keyLength; i++) { - keyHex = [keyHex stringByAppendingFormat:@"%02x ", keyBytes[i]]; - } - // b7 6a bf 75 99 07 0d 87 1e 59 68 f3 84 4a 79 c0 6a f3 7d 82 af 81 a2 84 39 7e 0a cc f2 83 cb 24 - NSLog(@">>>>>> keyHex: %@", keyHex); - - if (iv!=nil) { - NSData *ivData = [NSData dataWithBytes:iv length:(unsigned int)getIVLength(alg)]; - NSString *ivBase64 = [ivData base64EncodedStringWithOptions:0]; - NSString *ivStr = [[NSString alloc] initWithData:ivData encoding:NSUTF8StringEncoding]; - NSLog(@">>>>>> ivBase64 :%@",ivBase64); - NSLog(@">>>>>> ivStr :%@",ivStr); - - const uint8_t *ivBytes = (const uint8_t *)ivData.bytes; - NSString *ivHex = @""; - for (int i = 0; i < getIVLength(alg); i++) { - ivHex = [ivHex stringByAppendingFormat:@"%02x ", ivBytes[i]]; - } - // 6a f3 7d 82 af 81 a2 84 39 7e 0a cc f2 83 cb 24 - NSLog(@">>>>>> ivHex: %@", ivHex); - } - - NSData *dataInData = [NSData dataWithBytes:dataIn length:dataInLength]; - NSString *dataInBase64 = [dataInData base64EncodedStringWithOptions:0]; - NSString *dataInStr = [[NSString alloc] initWithData:dataInData encoding:NSUTF8StringEncoding]; - NSLog(@">>>>>> dataInBase64 :%@",dataInBase64); - NSLog(@">>>>>> dataInStr :%@",dataInStr); - - } - CCCryptorStatus result = original_CCCrypt(op,alg,options,key,keyLength,iv,dataIn,dataInLength,dataOut,dataOutAvailable,dataOutMoved); - - if (keyLength==32) { - NSData *dataOutData = [NSData dataWithBytes:dataOut length:*dataOutMoved]; - NSString *dataOutBase64 = [dataOutData base64EncodedStringWithOptions:0]; - NSString *dataOutStr = [[NSString alloc] initWithData:dataOutData encoding:NSUTF8StringEncoding]; - NSLog(@">>>>>> dataOutBase64 :%@",dataOutBase64); - NSLog(@">>>>>> dataOutStr :%@",dataOutStr); - - // 读取 hex - unsigned char *dataOutBytes = (unsigned char *)dataOutData.bytes; - NSString *dataOutHex = @""; - for (NSUInteger i = 0; i < *dataOutMoved; i++) { - NSString *byteString = [NSString stringWithFormat:@"%02x ", dataOutBytes[i]]; - dataOutHex = [dataOutHex stringByAppendingString:byteString]; - } - // 03 04 02 4e 53 45 78 74 65 6e 73 69 6f 6e - NSLog(@">>>>>> Memory content at address %p: %@", dataOut, dataOutHex); - // kCCSuccess = 0, - NSLog(@">>>>>> result: %d",result); - - } - return result; -} - - - - -typedef void (^CompletionHandler1)(NSError *error, NSURLResponse *response, NSData *data); -typedef void (^CompletionHandler2)(NSData *data, NSURLResponse *response, NSError *error); - -// Ref: https://github.com/NyaMisty/Surge4Advanced/blob/master/Tweak.x -// __auto_type wrapper = ^(NSError *error, NSDictionary *data) { -// __auto_type resp = [[NSHTTPURLResponse alloc] initWithURL:url statusCode:200 HTTPVersion:@"1.1" headerFields:@{}]; -// NSData *body = [NSJSONSerialization dataWithJSONObject:data options:0 error: &error]; -// completionHandler(body, resp, error); -// }; - -//// fake req -// void (^handler)(NSError *error, NSDictionary *data) = ^(NSError *error, NSDictionary *data){ -// NSDictionary *licInfo = @{ -// @"deviceID": @"deviceID", -// @"expirationDate": @4070880000, // 2099-01-01 00:00:00 -// @"fusDate": @4070880000, -// @"type": @"licensed", -// @"issueDate": [NSNumber numberWithInt:(long)[[NSDate date] timeIntervalSince1970]], -// @"p": @"p", -// }; -// NSData *licInfoData = [NSJSONSerialization dataWithJSONObject:licInfo options:0 error: &error]; -// NSString *licInfoStr = [[NSString alloc] initWithData:licInfoData encoding:NSUTF8StringEncoding]; -// NSString *licInfoBase64 = [licInfoData base64EncodedStringWithOptions:0]; -// wrapper(nil, @{ -// @"license": @{ -// @"policy": licInfoBase64, -// @"sign": @"" -// } -// }); -// }; -// dispatch_async(dispatch_get_main_queue(), ^{ -// handler(nil, nil); -// }); - -// if ([reqUrl hasSuffix:@"ac"]) { // disable refresh req -// [req setURL:[NSURL URLWithString:@"http://127.0.0.1:65536"]]; -// void (^handler)(NSError *error, NSDictionary *data) = ^(NSError *error, NSDictionary *data){ -// wrapper(nil, @{}); -// }; -// dispatch_async(dispatch_get_main_queue(), ^{ -// handler(nil, nil); -// }); -// } - -// completionHandler:(void (^)(NSError *error, NSURLResponse *response, NSData *data))completionHandler -//- (void) hook_dataTaskWithURLRequest:(NSMutableURLRequest*)request configuration:arg2 -// completionHandler:(void (^)(NSError *error, NSURLResponse *response, NSData *data))completionHandler{ -- (void) hook_dataTaskWithURLRequest:(NSMutableURLRequest*)request configuration:arg2 completionHandler:(CompletionHandler1)completionHandler{ - - // Printing description of arg3: - // <__NSGlobalBlock__: 0x100742fa0> - // signature: "v32@?0@"NSError"8@"NSHTTPURLResponse"16@"NSData"24" - // invoke : 0x100108c4a - - NSURL *url = [request URL]; - NSString *urlString = [url absoluteString]; - if ([urlString containsString:@"mac/v3/"] && completionHandler) { - // 在 Objective-C 中,completionHandler 是一种常见的异步编程模式,它通常用于在一个操作完成后执行一些额外的代码或处理结果。 - // po arg2 >> signature: "v32@?0@"NSData"8@"NSURLResponse"16@"NSError"24" - __auto_type wrapper = ^(NSError *error, NSDictionary *data) { - __auto_type resp = [[NSHTTPURLResponse alloc] initWithURL:url statusCode:200 HTTPVersion:@"1.1" headerFields:@{}]; - NSData *body = [NSJSONSerialization dataWithJSONObject:data options:0 error: &error]; - completionHandler(error, resp, body); - }; - - NSDictionary *respBody; - NSString *reqBody; - if ([urlString containsString:@"mac/v3/ac"]) { - respBody =@{ - @"k":@0 - }; - }else{ - respBody =@{ - @"code":@0 - }; - } - reqBody = [[NSString alloc] initWithData:[request HTTPBody] encoding:NSUTF8StringEncoding]; - NSLog(@">>>>>> [hook_dataTaskWithURLRequest] Intercept url: %@, request body: %@, response body: %@",url, reqBody,respBody); - wrapper(nil,respBody); - return; - } - NSLog(@">>>>>> [hook_dataTaskWithURLRequest] Allow to pass url: %@",url); - ((void(*)(id, SEL,id,id,id))dataTaskWithRequestIMP2)(self, _cmd,request,arg2,completionHandler); -} - -- (void) hook_dataTaskWithRequest:(NSMutableURLRequest*)request completionHandler:(CompletionHandler2)completionHandler{ - - // Printing description of arg2: - // <__NSStackBlock__: 0x7ff7bfefd828> - // signature: "v32@?0@"NSData"8@"NSURLResponse"16@"NSError"24" - - NSURL *url = [request URL]; - NSString *urlString = [url absoluteString]; - if ([urlString containsString:@"mac/v3/"] && completionHandler) { - // 在 Objective-C 中,completionHandler 是一种常见的异步编程模式,它通常用于在一个操作完成后执行一些额外的代码或处理结果。 - __auto_type wrapper = ^(NSError *error, NSDictionary *data) { - __auto_type resp = [[NSHTTPURLResponse alloc] initWithURL:url statusCode:200 HTTPVersion:@"1.1" headerFields:@{}]; - NSData *body = [NSJSONSerialization dataWithJSONObject:data options:0 error: &error]; - completionHandler(body, resp,error); - }; - NSDictionary *respBody; - NSString *reqBody; - - if ([urlString containsString:@"mac/v3/init/"]) { - // 如果不是 enterprise, 每次软件启动都会校验这个接口 - respBody = policySign; - } else if ([urlString containsString:@"mac/v3/device"]) { - respBody =@{ - @"account":[Constant G_EMAIL_ADDRESS], - @"license":@"🇨🇳 Voidm.Com" - }; - } else if ([urlString containsString:@"mac/v3/ac"]) { - respBody =@{ - @"k":@0 - }; - }else if ([urlString containsString:@"mac/v3/resource/jsvm"]) { - NSString *jsvm = [NSString stringWithContentsOfFile: - [[Constant getCurrentAppPath] stringByAppendingString:@"/Contents/MacOS/jsvm.js"] - encoding:NSUTF8StringEncoding error:nil - ]; - if (!jsvm) { - NSLog(@">>>>>> /Contents/MacOS/jsvm.js 文件不存在 ???"); - [MemoryUtils exAlart:@"FBI warning" message:@"/Contents/MacOS/jsvm.js 文件不存在 ???"]; - respBody =@{ - @"code": @0 - }; - } else { - respBody =@{ - @"code": @0, - @"data": jsvm, - @"v": @"2024071200000000" - }; - } - - }else if ([urlString containsString:@"mac/v3/resource/module"]) { - NSData *nsData = [NSData dataWithContentsOfFile:[[Constant getCurrentAppPath] stringByAppendingString:@"/Contents/MacOS/modules.json"] - options:NSDataReadingMappedIfSafe error:nil]; - if (!nsData) { - NSLog(@">>>>>> /Contents/MacOS/modules.json 文件不存在 ???"); - [MemoryUtils exAlart:@"FBI warning" message:@"/Contents/MacOS/modules.json 文件不存在 ???"]; - respBody =@{ - @"code": @0 - }; - } else { - id sections = [NSJSONSerialization JSONObjectWithData: - nsData options:NSJSONReadingMutableContainers error:nil - ]; - NSData *jsonData = [NSJSONSerialization dataWithJSONObject:@{ - @"v": @"2024071200000000", - @"sections": sections, - @"u": @"8fce02ae-b82a-40ce-bda5-9cfbcb50d65f" - } options:0 error:nil]; - respBody =@{ - @"code":@0, - @"data": [jsonData base64EncodedStringWithOptions:0] - }; - } - - } else { - // TODO: 暂时未知, 有没有必要 hook 各个请求的 response data - respBody =@{ - @"code":@0 - }; - } - reqBody = [[NSString alloc] initWithData:[request HTTPBody] encoding:NSUTF8StringEncoding]; - NSLog(@">>>>>> [hook_dataTaskWithRequest] Intercept url: %@, request body: %@, response body: %@",url, reqBody,respBody); - wrapper(nil,respBody); - return; - } - // pass: https://api.enterprise.nssurge.com/client/refresh - - NSLog(@">>>>>> [hook_dataTaskWithRequest] Allow to pass url: %@",url); - ((void(*)(id, SEL,id,id))dataTaskWithRequestIMP)(self, _cmd,request,completionHandler); -} - -- (NSString *) hook_componentsJoinedByString:arg1{ - if ([arg1 isEqualToString:@"/"] && [[self valueForKeyPath:@"@count"] isEqualToNumber:@6]) { - NSLog(@">>>>>> device info : %@",self); - // md5("1/2/3/4/5/6") = 16b8f4bdfd55d29f737427b4ec0c14d7 - return @"1/2/3/4/5/6"; - } - return ((NSString*(*)(id, SEL, NSString*))componentsJoinedByStringIMP)(self, _cmd, arg1); -} - - - - -// 这里可以伪造 public key,自签名 -- (NSData *) hk_initWithBytesNoCopy:(void *)bytes length:(NSUInteger)length freeWhenDone:(int)freeWhenDone { - // 0x1001c6638 <+380>: callq 0x1001c6b0b ; ___lldb_unnamed_symbol7189 - //-> 0x1001c663d <+385>: testb %al, %al - if (length == 0x1c3) { - NSLog(@">>>>>> hk_initWithBytesNoCopy input length: %lu", (unsigned long)length); - - // NSString *inputString = [[NSString alloc] initWithBytes:bytes length:length encoding:NSUTF8StringEncoding]; - // 替换公钥 - const char *replacementBytes = [publicKey UTF8String]; - NSUInteger replacementLength = [publicKey lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; - memcpy(bytes, replacementBytes, replacementLength); - length = replacementLength; - } - NSData *ret = ((NSData*(*)(id, SEL,void *,NSUInteger,int))initWithBytesNoCopyMethodIMP)(self, _cmd,bytes,length,freeWhenDone); - return ret; -} - -- (id)hk_settings{ - NSLog(@">>>>>> hk_settings"); - - // -[SGMLicenseViewController reload]: - // call sub_1001b1647 ; sub_1001b1647 - id ret = class_createInstance(objc_getClass("SGMEnterpriseSettings"), 0); - [ret performSelector:NSSelectorFromString(@"setUserID:") withObject:[Constant G_EMAIL_ADDRESS]]; - [ret performSelector:NSSelectorFromString(@"setCompanyName:") withObject:@"Home"]; - [ret performSelector:NSSelectorFromString(@"setCompanyID:") withObject:@"CN"]; - return ret; -} -+ (id)hk_URLWithString:arg1{ - id ret = ((id(*)(id, SEL,id))urlWithStringSeletorIMP)(self, _cmd,arg1); - // >>>>>> hk_URLWithString https://www.surge-activation.com/mac/v3/init/ - if ([arg1 containsString:@"v3"]) { - NSLog(@">>>>>> hk_URLWithString [v3] %@",arg1); - } - return ret; -} - -@end diff --git a/dylib_dobby_hook/apps/iMazingHack.m b/dylib_dobby_hook/apps/iMazingHack.m deleted file mode 100644 index 53ade64..0000000 --- a/dylib_dobby_hook/apps/iMazingHack.m +++ /dev/null @@ -1,396 +0,0 @@ -// -// SurgeHack.m -// dylib_dobby_hook -// -// Created by 马治武 on 2024/4/4. -// -/* -clang++ release.c -o librelease3.dylib -dynamiclib -framework Security -framework CoreFoundation -L. -ltinycrypto -ldobby -arch x86_64 -arch arm64 -https://downloads.imazing.com/mac/iMazing/3.0.2.21053/iMazing_3.0.2.21053.dmg - id666666666666odr - imzb8636f74ac99006crd -*/ - -#import -#import "Constant.h" -#import "dobby.h" -#include -#import "MemoryUtils.h" -#import -#include -#import "HackProtocol.h" -#include -#import -#import "common_ret.h" -#include -#import -#import "encryp_utils.h" -#import -#import -#include -#include -#import -#import -#include -#include -#include -#include -#include -#import -#include - - -@interface iMazingHack : NSObject - - - -@end - - -@implementation iMazingHack - -static intptr_t MainAddr; -static OSStatus (*orig_SecRequirementCreateWithString)(CFStringRef text, SecCSFlags flags, SecRequirementRef _Nullable *requirement); -void * (* orig_SynchronousRequest)(void * selfp, const char * domain, int port, bool ssl, void * req); - -char lic_format[] = -"{" - "\"data\":{" - "\"account\":{" - "\"email\":\"marlkiller@voidm.com\"," - "\"can_purchase\":true," - "\"opt_in\":{" - "\"news_offers\":false," - "\"device_info_upload\":false," - "\"analytics\":false" - "}" - "}," - "\"license\":{" - "\"license_type\":\"business_devices_subscription\"," - "\"status\":\"active\"," - "\"seats\":{" - "\"total\":1000," - "\"available\":999" - "}" - "\"subscription_info\":{" - "\"status\":\"active\"," - "\"amount\":\"12,000\"," - "\"currency\":\"USD\"," - "\"next_bill_time\":1916064000" - "}," - "}," - "\"client\":{" - "\"imazing_client_identifier\":\"%s\"," - "\"uuid\":\"%s\"" - "}," - "\"license_auth_token\":\"%s\"," - "\"tasks_available\":false," - "\"license_token_version\":1" - "}," - "\"iat\":%d," - "\"iss\":\"account.imazing.com\"," - "\"aud\":[" - "\"%s\"" - "]," - "\"exp\":%d" -"}"; - -char manage_page[] = -"HTTP/1.1 200 Ok\r\nContent-Type: application/json\r\n\r\n" -"{" - "\"title\":\"Manage Your iMazing Subscription\"," - "\"message\":\"Your iMazing Subscription is currently managed by Antibiotics.\"" -"}"; - -char license_logout[] = "HTTP/1.1 200 Ok\r\nContent-Type: application/json\r\n\r\n{}"; - -- (NSString *)getAppName { - // >>>>>> AppName is [com.DigiDNA.iMazing3Mac],Version is [3.0.0], myAppCFBundleVersion is [20985]. - return @"com.DigiDNA.iMazing3Mac"; -} - -- (NSString *)getSupportAppVersion { - return @"3."; -} - -static int (*origin_isatty)(int code); -static void (*origin_exit)(int code); -static int (*origin_ioctl)(int code,unsigned long code2,...); - -int my_isatty(int code) { - NSLog(@">>>>>> [AntiAntiDebug] - new_isatty"); - return 0; -} - -void my_exit(int code) { - NSLog(@">>>>>> [AntiAntiDebug] - new_exit"); -} -int my_ioctl(int code,unsigned long code2,...) { - NSLog(@">>>>>> [AntiAntiDebug] - new_ioctl"); - return 1; -} - - -static void* (*orig_dlsym)(void* handle, const char* symbol); -static void* my_dlsym(void* handle, const char* symbol){ - NSLog(@">>>>>> my_dlsym symbol :%s",symbol); - if(strcmp(symbol, "ptrace") == 0){ - NSLog(@">>>>>> [AntiAntiDebug] - dlsym get ptrace symbol"); - return (void*)my_ptrace; - } - return orig_dlsym(handle, symbol); -} - - -static void* (*orig_syscall)(int code, va_list args); -static void* my_syscall(int code, va_list args){ - int request; - va_list newArgs; - va_copy(newArgs, args); - if(code == 26){ - request = (long)args; - if(request == 31){ - NSLog(@">>>>>> [AntiAntiDebug] - syscall call ptrace, and request is PT_DENY_ATTACH"); - return nil; - } - } - return (void*)orig_syscall(code, newArgs); -} -static void* (*orig_dlopen)(const char* filename, int myflags); -static void* my_dlopen(const char* filename, int myflags) { - NSLog(@">>>>>> the dlopen name :%s",filename); - return orig_dlopen(filename, myflags); -} - -- (BOOL)hack { - - NSLog(@">>>>>> iMazingHack init"); -// Error: Exception: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) - -// 标准输出文件描述符是否指向终端 -// DobbyHook((void*)isatty,(void*)&my_isatty,(void**)&origin_isatty); -// DobbyHook((void*)exit,(void*)&my_exit,(void**)&origin_exit); - // 标准输出文件描述符的窗口大小,如果为0则可能是在被调试 -// DobbyHook((void*)ioctl,(void*)&my_ioctl,(void**)&origin_ioctl); - - // 使用 dlsym 函数获取动态链接库中的函数地址 -// DobbyHook((void *)dlsym, (void *)my_dlsym, (void *)&orig_dlsym); - // 系统提供了一个系统调用函数 syscall,上面讲到的 ptrace 也是通过系统调用去实现的 -// DobbyHook((void *)syscall, (void *)my_syscall, (void *)&orig_syscall); - // 使用 dlopen 函数打开动态链接库 -// DobbyHook((void *)dlopen, (void *)my_dlopen, (void *)&orig_dlopen); - - DobbyHook((void *)ptrace, (void *)my_ptrace, (void *)&orig_ptrace); - DobbyHook((void *)sysctl, (void *)my_sysctl, (void *)&orig_sysctl); - DobbyHook((void *)task_swap_exception_ports, (void *)my_task_swap_exception_ports, (void *)&orig_task_swap_exception_ports); - DobbyHook((void *)task_get_exception_ports, (void *)my_task_get_exception_ports, (void *)&orig_task_get_exception_ports); - - -// DobbyHook((void *)SecCodeCopySelf, ret0, NULL); -// DobbyHook((void *)SecStaticCodeCreateWithPath, ret0, NULL); - DobbyHook((void *)SecCodeCheckValidity, ret0, NULL); - DobbyHook((void *)SecStaticCodeCheckValidity, ret0, NULL); - DobbyHook((void *)SecRequirementCreateWithString, hk_SecRequirementCreateWithString, (void **)&orig_SecRequirementCreateWithString); - - - MainAddr = _dyld_get_image_vmaddr_slide(0); - intptr_t SynchronousRequestAddr, VerifyJwtPkAddr; -#ifdef __aarch64__ - SynchronousRequestAddr = 0x10077d59c; // "SynchronousRequest" -> quote -> quote -> quote - VerifyJwtPkAddr = 0x100780098; // "VerifyJwtPk" -> quote -> quote -#elif __x86_64__ - SynchronousRequestAddr = 0x10084e9d0; - VerifyJwtPkAddr = 0x1008514f0; -#endif - - DobbyHook((void *)(MainAddr + SynchronousRequestAddr), (void *)hk_SynchronousRequest, (void **)&orig_SynchronousRequest); - -#ifdef __aarch64__ -char ret_1[] = {0x20, 0x00, 0x80, 0xD2, 0xC0, 0x03, 0x5F, 0xD6}; -char ret_0[] = {0x00, 0x00, 0x80, 0xD2, 0xC0, 0x03, 0x5F, 0xD6}; -#elif __x86_64__ -char ret_1[] = {0x48, 0x31, 0xC0, 0x48, 0xFF, 0xC0, 0xC3}; -char ret_0[] = {0x48, 0x31, 0xC0, 0xC3}; -#endif - - _write_memory((mach_vm_address_t)(MainAddr + VerifyJwtPkAddr), sizeof(ret_1), (vm_offset_t)ret_1); - - pthread_t ptid; - pthread_create(&ptid, NULL, &server, NULL); - - - return YES; -} - -void * server(void * arg) { - const uint16_t port_number = 9001; - int server_fd = socket(AF_INET, SOCK_STREAM, 0); - - struct sockaddr_in *server_sockaddr = init_sockaddr_in(port_number); - struct sockaddr_in *client_sockaddr = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in)); - socklen_t server_socklen = sizeof(*server_sockaddr); - socklen_t client_socklen = sizeof(*client_sockaddr); - - - if (bind(server_fd, (const struct sockaddr *) server_sockaddr, server_socklen) < 0) { - printf("Error! Bind has failed\n"); - exit(0); - } - if (listen(server_fd, 2) < 0) { - printf("Error! Can't listen\n"); - exit(0); - } - - - const size_t buffer_len = 1024; - char *buffer = (char *)malloc(buffer_len * sizeof(char)); - char *response = NULL; - - while (1) { - int client_fd = accept(server_fd, (struct sockaddr *) &client_sockaddr, &client_socklen); - - printf("Connection with `%d` has been established and delegated to the process %d.\nWaiting for a query...\n", client_fd, getpid()); - - read(client_fd, buffer, buffer_len); - printf("Received `%s`. Processing... ", buffer); - - response = process_operation(buffer); - bzero(buffer, buffer_len * sizeof(char)); - - send(client_fd, response, strlen(response), 0); - printf("Responded with `%s`. Waiting for a new query...\n", response); - free(response); - - printf("Closing session with `%d`. Bye!\n", client_fd); - close(client_fd); - } - free(buffer); - return NULL; -} - -struct sockaddr_in* init_sockaddr_in(uint16_t port_number) { - struct sockaddr_in *socket_address = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in)); - memset(socket_address, 0, sizeof(*socket_address)); - socket_address -> sin_family = AF_INET; - socket_address -> sin_addr.s_addr = htonl(INADDR_ANY); - socket_address -> sin_port = htons(port_number); - return socket_address; -} - - -char* process_operation(char *input) { - char *path = (char *)malloc(100); - char *output = (char *)malloc(100); - for (int i = 0; ; i++) { - if (*(input+i) == '\r') { - *(path+i) = '\0'; - break; - } - *(path+i) = *(input+i); - } - printf("path: '%s'\n", path); - if (strcmp(path, "GET / HTTP/1.1") == 0) { - printf("Received empty path......\n"); - strcpy(output, "HTTP/1.1 200 Ok\r\n"); - } else if (strcmp(path, "POST /v1/auth/license_auth_token_logout HTTP/1.1") == 0) { - printf("Received token_logout......\n"); - output = (char *)realloc(output, 512); - strcpy(output, license_logout); - } else if (strcmp(path, "POST /v1/licenses/send_manage_license_email HTTP/1.1") == 0) { - printf("Received manage_license......\n"); - output = (char *)realloc(output, 512); - strcpy(output, manage_page); - } else if (strcmp(path, "POST /v1/auth/license_code_login HTTP/1.1") == 0 || strcmp(path, "POST /v1/auth/license_auth_token_login HTTP/1.1") == 0){ - char *client_uuid = (char *)malloc(50); // len = 36 - char *client_identifier = (char *)malloc(50); // len = 19 - int in_len = strlen(input); - for (int i = 0; i < in_len; i++) { - unsigned cur_hash = 0, b = 267; - while (input[i] != '\n' && input[i] != ':') { - cur_hash += input[i]; - cur_hash *= b; - i++; - } - // uuid: 4137240225 - // imazing_client_identifier: 804052081 - if (cur_hash == 4137240225) { - strncpy(client_uuid, input+i+2, 36); - } else if (cur_hash == 804052081) { - strncpy(client_identifier, input+i+2, 19); - } - while (input[i] != '\0' && input[i] != '\n') i++; - } - - char *audience = (char *)malloc(100); - strcpy(audience, client_uuid); - audience[36] = '-'; - strcat(audience, client_identifier); - - unsigned char *aud_hash = (unsigned char *)malloc(50); - CC_SHA256(audience, strlen(audience), aud_hash); - free(audience); - - char *aud = (char *)malloc(100), hex_ch[] = "0123456789abcdef"; - for (int i = 0; i < 32; i++) { - aud[2*i] = hex_ch[aud_hash[i] >> 4]; - aud[2*i+1] = hex_ch[aud_hash[i] & 15]; - } - aud[64] = '\0'; - - char auth_token[] = "imzlat1111222233334444555566667777888899990000aaaabbbbccccddddeeeeffff"; - unsigned long cur_time = time(NULL); - - char *data = (char *)malloc(2048); - snprintf(data, 2048, lic_format, client_identifier, client_uuid, auth_token, cur_time, aud, cur_time+259200); - free(client_uuid), free(client_identifier), free(aud); - -// char *payload = (char *)malloc(2048); - - - NSData *inputData = [NSData dataWithBytes:data length:strlen(data)]; - NSString *base64String = [inputData base64EncodedStringWithOptions:0]; - const char *payload = [base64String UTF8String]; -// char *payload = malloc(strlen(base64Chars) + 1); -// base64_encode(strlen(data), (unsigned char *)data, payload); - - free(data); - - output = (char *)realloc(output, 3072); - snprintf(output, 3072, "HTTP/1.1 200 Ok\r\nContent-Type: application/json\r\n\r\n{\"license_token\":\"eyJhbGciOiJFZERTQSJ9.%s.abcd\"}", payload); - free(payload); - } - - free(path); - - return output; // need to free! -} - -int _write_memory(mach_vm_address_t address, mach_vm_address_t count, vm_offset_t bytes) { - int kr = 0; - kr |= mach_vm_protect(mach_task_self(), address, count, FALSE, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_COPY); - kr |= mach_vm_write(mach_task_self(), address, bytes, count); - kr |= mach_vm_protect(mach_task_self(), address, count, FALSE, VM_PROT_READ | VM_PROT_EXECUTE); - return (kr); -} -void * hk_SynchronousRequest(void * selfp, const char * domain, int port, bool ssl, void * req) { -#ifdef debug - printf(">>>>>>>> outgoing: %s \n", domain); -#endif - if (strcmp(domain, "api.imazing.com") == 0) { -#ifdef debug - printf("======== blocking outgoing to api.imazing.com ....\n"); -#endif - return orig_SynchronousRequest(selfp, "127.0.0.1", 9001, 0, req); - } - return orig_SynchronousRequest(selfp, domain, port, ssl, req); -} - -OSStatus hk_SecRequirementCreateWithString(CFStringRef text, SecCSFlags flags, SecRequirementRef _Nullable *requirement) { - OSStatus status; - CFStringRef requirementString = CFSTR("certificate leaf = H\"B231060196247A36C3094AC947BA60E226B848BF\""); - status = orig_SecRequirementCreateWithString(requirementString, flags, requirement); - CFRelease(requirementString); - return status; -} - -@end diff --git a/script/auto_hack.sh b/script/auto_hack.sh index 4a0b2b8..c395736 100644 --- a/script/auto_hack.sh +++ b/script/auto_hack.sh @@ -54,7 +54,7 @@ hack_app "Movist Pro" "/Applications/Movist Pro.app/Contents/Frameworks/MediaKey hack_app "AirBuddy" "/Applications/AirBuddy.app/Contents/Frameworks/LetsMove.framework/Versions/A/LetsMove" hack_app "Infuse" "/Applications/Infuse.app/Contents/Frameworks/Differentiator.framework/Versions/A/Differentiator" hack_app "MacUpdater" "/Applications/MacUpdater.app/Contents/Frameworks/Sparkle.framework/Versions/B/Sparkle" +hack_app "ForkLift" "/Applications/ForkLift.app/Contents/Frameworks/UniversalDetector.framework/Versions/A/UniversalDetector" -hack_app "Surge" "/Applications/Surge.app/Contents/Frameworks/MMMarkdown.framework/Versions/A/MMMarkdown" "surge_hack.sh" diff --git a/tools/mac_patch_helper b/tools/mac_patch_helper index f415c1d..98c0d70 100755 Binary files a/tools/mac_patch_helper and b/tools/mac_patch_helper differ diff --git a/tools/patch.json b/tools/patch.json index 1b5e3d9..6ac3a66 100644 --- a/tools/patch.json +++ b/tools/patch.json @@ -13,6 +13,16 @@ "clear_certificate":[ "/Applications/Surge.app/Contents/Library/LaunchServices/com.nssurge.surge-mac.helper" ] + }, + "ForkLift":{ + "TODO// patch":{ + "/Applications/ForkLift.app/Contents/Library/LaunchServices/com.binarynights.ForkLiftHelper":{ + + } + }, + "clear_certificate":[ + "/Applications/ForkLift.app/Contents/Library/LaunchServices/com.binarynights.ForkLiftHelper" + ] } }