From 88c6ff9069deeac450320ee1191cfc61e1dffba5 Mon Sep 17 00:00:00 2001 From: marlkiller Date: Mon, 30 Sep 2024 17:49:44 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dylib_dobby_hook/apps/PaddleBaseHack.m | 2 +- dylib_dobby_hook/dylib_dobby_hook.m | 51 +++++----- dylib_dobby_hook/utils/Constant.h | 19 +--- dylib_dobby_hook/utils/Constant.m | 126 ++++++++++++------------- dylib_dobby_hook/utils/common_ret.m | 13 +-- tools/process_inject | Bin 0 -> 136576 bytes 6 files changed, 101 insertions(+), 110 deletions(-) create mode 100644 tools/process_inject diff --git a/dylib_dobby_hook/apps/PaddleBaseHack.m b/dylib_dobby_hook/apps/PaddleBaseHack.m index 2486e0d..5d06a4f 100644 --- a/dylib_dobby_hook/apps/PaddleBaseHack.m +++ b/dylib_dobby_hook/apps/PaddleBaseHack.m @@ -265,7 +265,7 @@ - (BOOL)hack { swizzledSelector:NSSelectorFromString(@"hook_dataTaskWithRequest:completionHandler:") ]; - if ([[Constant currentAppName] containsString:@"mindmac"]) { + if ([[Constant getCurrentAppName] containsString:@"mindmac"]) { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults setObject:@"Basic" forKey:@"licenseType"]; [defaults setObject:@YES forKey:@"licenseStatusChanged"]; diff --git a/dylib_dobby_hook/dylib_dobby_hook.m b/dylib_dobby_hook/dylib_dobby_hook.m index 7ea175e..8fefbf8 100644 --- a/dylib_dobby_hook/dylib_dobby_hook.m +++ b/dylib_dobby_hook/dylib_dobby_hook.m @@ -13,12 +13,6 @@ @implementation dylib_dobby_hook -#ifdef DEBUG -const bool SHOW_ALARM = true; -#else -const bool SHOW_ALARM = false; -#endif - // INIT TEST START int sum(int a, int b) { return a+b; @@ -43,9 +37,6 @@ void initTest(void){ // INIT TEST END - - - BOOL shouldExcludeCurrentApp(void) { NSArray *excludedPrefixes = @[ @"/System/", @@ -61,6 +52,28 @@ BOOL shouldExcludeCurrentApp(void) { return NO; } + +BOOL canShowAlert(void) { + NSString *path = [[[NSProcessInfo processInfo] arguments] firstObject]; + + // 检查路径 + if ([path hasPrefix:@"/System/Library/"] || [path hasPrefix:@"/usr/bin/"]) { + NSLog(@">>>>>> Path starts with /usr/bin/, UI alert not allowed."); + return NO; + } + + if ([Constant isHelper]) { + NSLog(@">>>>>> Process is a helper, UI alert not allowed."); + return NO; + } +// NSApplicationActivationPolicyRegular: 普通应用,能在 Dock 中显示,接受用户输入。例如:Safari、Mail。 +// NSApplicationActivationPolicyAccessory: 辅助应用,不在 Dock 中显示,但可以在菜单栏中显示图标。通常用于后台工具。 +// NSApplicationActivationPolicyProhibited: 被禁止激活的应用,不显示在 Dock 中,也无法接受输入。常用于后台服务。 + BOOL isForeground = [NSRunningApplication currentApplication].activationPolicy == NSApplicationActivationPolicyRegular; + NSLog(@">>>>>> Is current application canShowAlert: %@", isForeground ? @"YES" : @"NO"); + return isForeground; +} + + (void) load { @@ -72,27 +85,15 @@ + (void) load { return; } - if ([Constant isFirstOpen] && ![Constant isHelper]) { + + BOOL showAlarm = canShowAlert(); + if ([Constant isFirstOpen] && showAlarm) { NSAlert *alert = [[NSAlert alloc] init]; [alert setMessageText:@"Cracked By\n[marlkiller/dylib_dobby_hook]"]; [alert setInformativeText:@"仅供研究学习使用,请勿用于非法用途"]; [alert addButtonWithTitle:@"OK"]; [alert runModal]; } - if (SHOW_ALARM && ![Constant isHelper]) { - NSAlert *alert = [[NSAlert alloc] init]; - [alert setMessageText:@"FBI warning"]; - [alert setInformativeText:@"Please confirm if the app has been backed up.\nIf there are any issues, please restore it yourself!"]; - [alert addButtonWithTitle:@"Confirm"]; - [alert addButtonWithTitle:@"Cancel"]; - NSInteger response = [alert runModal]; - if (response == NSAlertFirstButtonReturn) { - [Constant doHack]; - } else { - return; - } - }else { - [Constant doHack]; - } + [Constant doHack]; } @end diff --git a/dylib_dobby_hook/utils/Constant.h b/dylib_dobby_hook/utils/Constant.h index c5ba4bb..04dbed4 100644 --- a/dylib_dobby_hook/utils/Constant.h +++ b/dylib_dobby_hook/utils/Constant.h @@ -9,22 +9,13 @@ @interface Constant : NSObject -@property (class, nonatomic, strong) NSString *G_EMAIL_ADDRESS; -@property (class, nonatomic, strong) NSString *G_EMAIL_ADDRESS_FMT; -@property (class, nonatomic, strong) NSString *G_DYLIB_NAME; - -@property (class, nonatomic, strong) NSString *currentAppPath; -@property (class, nonatomic, strong) NSString *currentAppName; -@property (class, nonatomic, strong) NSString *currentAppVersion; -@property (class, nonatomic, strong) NSString *currentAppCFBundleVersion; -@property (class, nonatomic, assign) BOOL arm; -@property (class, nonatomic, assign) BOOL helper; - - - -+ (BOOL) isFirstOpen; ++ (NSString *)G_EMAIL_ADDRESS; ++ (NSString *)G_EMAIL_ADDRESS_FMT; ++ (NSString *)G_DYLIB_NAME; ++ (BOOL)isFirstOpen; + (BOOL)isArm; + (BOOL)isHelper; ++ (NSString *)getCurrentAppName; + (NSString *)getCurrentAppPath; + (NSString *)getCurrentAppVersion; + (NSString *)getCurrentAppCFBundleVersion; diff --git a/dylib_dobby_hook/utils/Constant.m b/dylib_dobby_hook/utils/Constant.m index 66c0d45..c004b58 100644 --- a/dylib_dobby_hook/utils/Constant.m +++ b/dylib_dobby_hook/utils/Constant.m @@ -17,51 +17,49 @@ #import "HackProtocolDefault.h" #import "HackHelperProtocolDefault.h" -@implementation Constant // 使用构造函数属性 (constructor attribute) 的方法 // 这个方法会在 main 函数执行之前自动调用 static void __attribute__ ((constructor)) initialize(void){ - - NSLog(@">>>>>> Constant ((constructor)) initialize(void)"); - + printf(">>>>>> Constant ((constructor)) initialize(void)\n"); } +@implementation Constant -static NSString *G_EMAIL_ADDRESS = @"X'rq ol: zneyxvyyre@ibvqz.pbz";; -static NSString *G_EMAIL_ADDRESS_FMT = @"zneyxvyyre@ibvqz.pbz";; -static NSString *G_DYLIB_NAME = @"libdylib_dobby_hook.dylib"; +static NSString *_G_EMAIL_ADDRESS = @"X'rq ol: zneyxvyyre@ibvqz.pbz";; +static NSString *_G_EMAIL_ADDRESS_FMT = @"zneyxvyyre@ibvqz.pbz";; +static NSString *_G_DYLIB_NAME = @"libdylib_dobby_hook.dylib"; -static NSString *currentAppPath; -static NSString *currentAppName; -static NSString *currentAppVersion; -static NSString *currentAppCFBundleVersion; -static BOOL arm; -static BOOL helper; +static NSString *_currentAppPath; +static NSString *_currentAppName; +static NSString *_currentAppVersion; +static NSString *_currentAppCFBundleVersion; +static BOOL _arm; +static BOOL _helper; // 告诉编译器不生成默认的 getter 和 setter 方法 -@dynamic G_EMAIL_ADDRESS; -@dynamic G_EMAIL_ADDRESS_FMT; -@dynamic G_DYLIB_NAME; -@dynamic currentAppPath; -@dynamic currentAppName; -@dynamic currentAppVersion; -@dynamic currentAppCFBundleVersion; -@dynamic arm; -@dynamic helper; +//@dynamic G_EMAIL_ADDRESS; +//@dynamic G_EMAIL_ADDRESS_FMT; +//@dynamic G_DYLIB_NAME; +//@dynamic currentAppPath; +//@dynamic currentAppName; +//@dynamic currentAppVersion; +//@dynamic currentAppCFBundleVersion; +//@dynamic arm; +//@dynamic helper; + (NSString *)G_EMAIL_ADDRESS { - return love69(G_EMAIL_ADDRESS); + return love69(_G_EMAIL_ADDRESS); } + (NSString *)G_EMAIL_ADDRESS_FMT { - return love69(G_EMAIL_ADDRESS_FMT); + return love69(_G_EMAIL_ADDRESS_FMT); } + (NSString *)G_DYLIB_NAME { - return G_DYLIB_NAME; + return _G_DYLIB_NAME; } -+ (NSString *)currentAppName { - return currentAppName; ++ (NSString *)getCurrentAppName { + return _currentAppName; } + (BOOL) isFirstOpen { @@ -86,10 +84,10 @@ + (void)initialize { NSLog(@">>>>>> DobbyGetVersion: %s", DobbyGetVersion()); NSBundle *app = [NSBundle mainBundle]; - currentAppName = [[app bundleIdentifier] copy]; - currentAppVersion =[ [app objectForInfoDictionaryKey:@"CFBundleShortVersionString"] copy]; - currentAppCFBundleVersion = [[app objectForInfoDictionaryKey:@"CFBundleVersion"] copy]; - NSLog(@">>>>>> AppName is [%s],Version is [%s], myAppCFBundleVersion is [%s].", currentAppName.UTF8String, currentAppVersion.UTF8String, currentAppCFBundleVersion.UTF8String); + _currentAppName = [[app bundleIdentifier] copy]; + _currentAppVersion =[ [app objectForInfoDictionaryKey:@"CFBundleShortVersionString"] copy]; + _currentAppCFBundleVersion = [[app objectForInfoDictionaryKey:@"CFBundleVersion"] copy]; + NSLog(@">>>>>> AppName is [%s],Version is [%s], myAppCFBundleVersion is [%s].", _currentAppName.UTF8String, _currentAppVersion.UTF8String, _currentAppCFBundleVersion.UTF8String); NSLog(@">>>>>> App Architecture is: %@", [Constant getSystemArchitecture]); NSLog(@">>>>>> App DebuggerAttached is: %d", [Constant isDebuggerAttached]); NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"Info" ofType:@"plist"]; @@ -99,16 +97,16 @@ + (void)initialize { NSString *NSUserDefaultsPath = [[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:[NSString stringWithFormat:@"Preferences/%@.plist", bundleIdentifier]]; NSLog(@">>>>>> NSUserDefaultsPath is %@", NSUserDefaultsPath); NSRange range = [[Constant getSystemArchitecture] rangeOfString:@"arm" options:NSCaseInsensitiveSearch]; - arm = range.location != NSNotFound; + _arm = range.location != NSNotFound; // 这里不用 copy 的话, clion cmake 编译的产物会内存泄漏,字符串对象乱飞...不知道为什么 // 返回包的完整路径。 - currentAppPath = [[app bundlePath] copy]; - NSLog(@">>>>>> [app bundlePath] %@",currentAppPath); + _currentAppPath = [[app bundlePath] copy]; + NSLog(@">>>>>> [app bundlePath] %@",_currentAppPath); // /Library/PrivilegedHelperTools - if ([currentAppPath isEqualToString:@"/Library/PrivilegedHelperTools"]) { + if ([_currentAppPath isEqualToString:@"/Library/PrivilegedHelperTools"]) { NSLog(@">>>>>> helper is True"); - helper = YES; + _helper = YES; } // 返回应用程序执行文件的路径。 @@ -121,23 +119,23 @@ + (void)initialize { } + (BOOL)isHelper { - return helper; + return _helper; } + (BOOL)isArm { - return arm; + return _arm; } + (NSString *)getCurrentAppPath { - return currentAppPath; + return _currentAppPath; } + (NSString *)getCurrentAppVersion { - return currentAppVersion; + return _currentAppVersion; } // currentAppVersion 有时会影响计算偏移位置, // 所以 cache 偏移用这个 currentAppCFBundleVersion + (NSString *)getCurrentAppCFBundleVersion { - return currentAppCFBundleVersion; + return _currentAppCFBundleVersion; } + (NSString *)getSystemArchitecture { size_t size; @@ -208,31 +206,31 @@ + (BOOL)isSubclassOfClass:(Class)class parentClass:(Class)parentClass { } + (void)doHack { - NSArray *personClasses = [Constant getAllHackClasses]; - - NSLog(@">>>>>> Constant: Initiating doHack operation..."); - for (Class class in personClasses) { - NSLog(@">>>>>> Constant: Processing class - %@", NSStringFromClass(class)); - id it = [[class alloc] init]; - if ([it shouldInject:currentAppName]) { - NSString *supportAppVersion = [it getSupportAppVersion]; - if (supportAppVersion==NULL || - supportAppVersion.length==0 || - currentAppVersion==NULL || - [currentAppVersion hasPrefix:supportAppVersion] ) { - [it hack]; - }else{ - NSAlert *alert = [[NSAlert alloc] init]; - [alert addButtonWithTitle:@"OK"]; - alert.messageText = [NSString stringWithFormat:@"Unsupported current appVersion !!\nSuppert appVersion: [%s]\nCurrent appVersion: [%s]",[it getSupportAppVersion].UTF8String, currentAppVersion.UTF8String];; - [alert runModal]; + + @try { + NSArray *personClasses = [Constant getAllHackClasses]; + NSLog(@">>>>>> Constant: Initiating doHack operation..."); + for (Class class in personClasses) { + NSLog(@">>>>>> Constant: Processing class - %@", NSStringFromClass(class)); + id it = [[class alloc] init]; + if ([it shouldInject:_currentAppName]) { + NSString *supportAppVersion = [it getSupportAppVersion]; + if (supportAppVersion==NULL || + supportAppVersion.length==0 || + _currentAppVersion==NULL || + (_currentAppVersion!=NULL && [_currentAppVersion hasPrefix:supportAppVersion]) ) { + [it hack]; + return; + + }else{ + NSLog(@">>>>>> [ERROR] Unsupported current appVersion !! Suppert appVersion: [%@] Current appVersion: [%@]", + [it getSupportAppVersion], _currentAppVersion); + } } - return; } + NSLog(@">>>>>>> [ERROR] Unsupported current app: [%@]",_currentAppName); + } @catch (NSException *exception) { + NSLog(@">>>>>> [Caught exception]: %@", exception); } - NSAlert *alert = [[NSAlert alloc] init]; - [alert addButtonWithTitle:@"OK"]; - alert.messageText = [NSString stringWithFormat:@"Unsupported current app: [%s]", currentAppName.UTF8String];; - [alert runModal]; } @end diff --git a/dylib_dobby_hook/utils/common_ret.m b/dylib_dobby_hook/utils/common_ret.m index f0e965b..7f7291d 100644 --- a/dylib_dobby_hook/utils/common_ret.m +++ b/dylib_dobby_hook/utils/common_ret.m @@ -13,22 +13,28 @@ #include #import #include -#include + int ret2 (void){ printf(">>>>>> ret2\n"); return 2; } int ret1 (void){ +// uint8_t ret1Hex[6] = {0xB8, 0x01, 0x00, 0x00, 0x00, 0xC3}; // mov eax, 1; ret +// uint8_t ret1HexARM[8] = {0x20, 0x00, 0x80, 0xD2, 0xC0, 0x03, 0x5F, 0xD6}; // mov x0, #1; ret printf(">>>>>> ret1\n"); return 1; } int ret0 (void){ +// uint8_t ret0Hex[3] = {0x31, 0xC0, 0xC3}; // xor eax, eax; ret +// uint8_t ret0HexARM[8] = {0x00, 0x00, 0x80, 0xD2, 0xC0, 0x03, 0x5F, 0xD6}; // mov x0, #0; ret printf(">>>>>> ret0\n"); return 0; } void ret(void){ +// uint8_t retHex[1] = {0xC3}; // ret +// uint8_t retHexARM[4] = {0xC0, 0x03, 0x5F, 0xD6}; // ret printf(">>>>>> ret\n"); } @@ -151,9 +157,4 @@ OSStatus hk_SecCodeCheckValidityWithErrors(SecCodeRef code, SecCSFlags flags, Se return output; } //char *global_dylib_name = "libdylib_dobby_hook.dylib"; -// 注入函数 -int inject_dylib(pid_t pid, const char *lib) { - // Ref: https://juejin.cn/post/7277787934863835171 - return 0; -} diff --git a/tools/process_inject b/tools/process_inject new file mode 100644 index 0000000000000000000000000000000000000000..fd1d71afa53f4420f10aa4ca7be767de358cd780 GIT binary patch literal 136576 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 literal 0 HcmV?d00001