├── ZXHookAttack ├── ZXHookAttack │ ├── TargetApp │ │ ├── put ipa or app here │ │ └── ZXHookDetection.app │ │ │ ├── PkgInfo │ │ │ ├── ZXHookDetection │ │ │ ├── embedded.mobileprovision │ │ │ ├── Base.lproj │ │ │ ├── Main.storyboardc │ │ │ │ ├── Info.plist │ │ │ │ ├── BYZ-38-t0r-view-8bC-Xf-vdC.nib │ │ │ │ └── UIViewController-BYZ-38-t0r.nib │ │ │ └── LaunchScreen.storyboardc │ │ │ │ ├── Info.plist │ │ │ │ ├── 01J-lp-oVM-view-Ze5-6b-2t3.nib │ │ │ │ └── UIViewController-01J-lp-oVM.nib │ │ │ ├── Frameworks │ │ │ └── ZXHookFramework.framework │ │ │ │ ├── Info.plist │ │ │ │ ├── ZXHookFramework │ │ │ │ └── _CodeSignature │ │ │ │ └── CodeResources │ │ │ ├── Info.plist │ │ │ └── _CodeSignature │ │ │ └── CodeResources │ ├── Target.plist │ ├── icon.png │ ├── Scripts │ │ └── quick-resign.sh │ ├── Info.plist │ └── Config │ │ └── MDConfig.plist ├── LatestBuild ├── ZXHookAttack.xcodeproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── project.pbxproj └── ZXHookAttackDylib │ ├── ZXHookAttackDylib-Prefix.pch │ ├── ZXHookAttackDylib.m │ ├── StatHook.h │ ├── Config │ ├── MDMethodTrace.h │ ├── MDConfigManager.h │ ├── MDCycriptManager.h │ ├── ANYMethodLog.h │ ├── MDConfigManager.m │ ├── MDMethodTrace.m │ ├── MDCycriptManager.m │ └── ANYMethodLog.m │ ├── Tools │ ├── LLDBTools.h │ └── LLDBTools.mm │ ├── ZXHookAttackDylib.h │ ├── StatHook.m │ ├── Logos │ ├── ZXHookAttackDylib.xm │ └── ZXHookAttackDylib.mm │ ├── fishhook │ ├── fishhook.h │ └── fishhook.c │ └── AntiAntiDebug │ └── AntiAntiDebug.m ├── .gitattributes ├── ZXHookDetection ├── ZXHookDetection │ ├── Assets.xcassets │ │ ├── Contents.json │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── ViewController.h │ ├── main.m │ ├── AppDelegate.h │ ├── ZXHookDetection │ │ ├── NSDictionary+ZXDetection.h │ │ ├── ZXHookDetection.h │ │ ├── NSDictionary+ZXDetection.m │ │ └── ZXHookDetection.m │ ├── ViewController.m │ ├── Info.plist │ ├── Base.lproj │ │ ├── Main.storyboard │ │ └── LaunchScreen.storyboard │ └── AppDelegate.m ├── ZXHookDetection.xcodeproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ │ └── xcschemes │ │ └── ZXHookDetection.xcscheme ├── ZXHookFramework │ ├── ZXMyFramework.h │ ├── ZXHookFramework.h │ ├── Info.plist │ ├── ZXMyFramework.m │ ├── fishhook.h │ └── fishhook.c ├── ZXHookDetectionTests │ ├── Info.plist │ └── ZXHookDetectionTests.m ├── ZXHookDetectionUITests │ ├── Info.plist │ └── ZXHookDetectionUITests.m └── ZXHookFrameworkTests │ ├── Info.plist │ └── ZXHookFrameworkTests.m ├── LICENSE ├── .gitignore └── README.md /ZXHookAttack/ZXHookAttack/TargetApp/put ipa or app here: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttack/TargetApp/ZXHookDetection.app/PkgInfo: -------------------------------------------------------------------------------- 1 | APPL???? -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttack/Target.plist: -------------------------------------------------------------------------------- 1 | /Users/lzx/Desktop/程序/ZXHookAttack/ZXHookAttack/TargetApp/ZXHookDetection.app/Info.plist -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttack/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmileZXLee/ZXHookDetection/HEAD/ZXHookAttack/ZXHookAttack/icon.png -------------------------------------------------------------------------------- /ZXHookAttack/LatestBuild: -------------------------------------------------------------------------------- 1 | /Users/lzx/Library/Developer/Xcode/DerivedData/ZXHookAttack-ghzakqhavjhkjygszuflbvzoqffs/Build/Products/Debug-iphoneos -------------------------------------------------------------------------------- /ZXHookDetection/ZXHookDetection/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttack/TargetApp/ZXHookDetection.app/ZXHookDetection: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmileZXLee/ZXHookDetection/HEAD/ZXHookAttack/ZXHookAttack/TargetApp/ZXHookDetection.app/ZXHookDetection -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttack/TargetApp/ZXHookDetection.app/embedded.mobileprovision: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmileZXLee/ZXHookDetection/HEAD/ZXHookAttack/ZXHookAttack/TargetApp/ZXHookDetection.app/embedded.mobileprovision -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttack/TargetApp/ZXHookDetection.app/Base.lproj/Main.storyboardc/Info.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmileZXLee/ZXHookDetection/HEAD/ZXHookAttack/ZXHookAttack/TargetApp/ZXHookDetection.app/Base.lproj/Main.storyboardc/Info.plist -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttack.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttack/TargetApp/ZXHookDetection.app/Base.lproj/LaunchScreen.storyboardc/Info.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmileZXLee/ZXHookDetection/HEAD/ZXHookAttack/ZXHookAttack/TargetApp/ZXHookDetection.app/Base.lproj/LaunchScreen.storyboardc/Info.plist -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttack/TargetApp/ZXHookDetection.app/Frameworks/ZXHookFramework.framework/Info.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmileZXLee/ZXHookDetection/HEAD/ZXHookAttack/ZXHookAttack/TargetApp/ZXHookDetection.app/Frameworks/ZXHookFramework.framework/Info.plist -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttack/TargetApp/ZXHookDetection.app/Frameworks/ZXHookFramework.framework/ZXHookFramework: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmileZXLee/ZXHookDetection/HEAD/ZXHookAttack/ZXHookAttack/TargetApp/ZXHookDetection.app/Frameworks/ZXHookFramework.framework/ZXHookFramework -------------------------------------------------------------------------------- /ZXHookDetection/ZXHookDetection.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttack/TargetApp/ZXHookDetection.app/Base.lproj/Main.storyboardc/BYZ-38-t0r-view-8bC-Xf-vdC.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmileZXLee/ZXHookDetection/HEAD/ZXHookAttack/ZXHookAttack/TargetApp/ZXHookDetection.app/Base.lproj/Main.storyboardc/BYZ-38-t0r-view-8bC-Xf-vdC.nib -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttack/TargetApp/ZXHookDetection.app/Base.lproj/Main.storyboardc/UIViewController-BYZ-38-t0r.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmileZXLee/ZXHookDetection/HEAD/ZXHookAttack/ZXHookAttack/TargetApp/ZXHookDetection.app/Base.lproj/Main.storyboardc/UIViewController-BYZ-38-t0r.nib -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttack/TargetApp/ZXHookDetection.app/Base.lproj/LaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmileZXLee/ZXHookDetection/HEAD/ZXHookAttack/ZXHookAttack/TargetApp/ZXHookDetection.app/Base.lproj/LaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttack/TargetApp/ZXHookDetection.app/Base.lproj/LaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmileZXLee/ZXHookDetection/HEAD/ZXHookAttack/ZXHookAttack/TargetApp/ZXHookDetection.app/Base.lproj/LaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttackDylib/ZXHookAttackDylib-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'ZXHookAttackDylib' target in the 'ZXHookAttackDylib' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #import "/opt/theos/Prefix.pch" //path/to/theos/Prefix.pch 8 | #endif 9 | -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttack.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ZXHookDetection/ZXHookDetection.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ZXHookDetection/ZXHookDetection/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // ZXHookDetection 4 | // 5 | // Created by 李兆祥 on 2019/4/20. 6 | // Copyright © 2019 李兆祥. All rights reserved. 7 | // https://github.com/SmileZXLee/ZXHookDetection 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /ZXHookDetection/ZXHookFramework/ZXMyFramework.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZXMyLib.h 3 | // ZXHookDetection 4 | // 5 | // Created by 李兆祥 on 2019/4/21. 6 | // Copyright © 2019 李兆祥. All rights reserved. 7 | // https://github.com/SmileZXLee/ZXHookDetection 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface ZXMyFramework : NSObject 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /ZXHookDetection/ZXHookDetection/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // ZXHookDetection 4 | // 5 | // Created by 李兆祥 on 2019/4/20. 6 | // Copyright © 2019 李兆祥. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ZXHookDetection/ZXHookDetection/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // ZXHookDetection 4 | // 5 | // Created by 李兆祥 on 2019/4/20. 6 | // Copyright © 2019 李兆祥. All rights reserved. 7 | // https://github.com/SmileZXLee/ZXHookDetection 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /ZXHookDetection/ZXHookDetection/ZXHookDetection/NSDictionary+ZXDetection.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSDictionary+ZXDetection.h 3 | // ZXHookDetection 4 | // 5 | // Created by 李兆祥 on 2019/4/20. 6 | // Copyright © 2019 李兆祥. All rights reserved. 7 | // https://github.com/SmileZXLee/ZXHookDetection 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface NSDictionary (ZXDetection) 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttackDylib/ZXHookAttackDylib.m: -------------------------------------------------------------------------------- 1 | // weibo: http://weibo.com/xiaoqing28 2 | // blog: http://www.alonemonkey.com 3 | // 4 | // ZXHookAttackDylib.m 5 | // ZXHookAttackDylib 6 | // 7 | // Created by 李兆祥 on 2019/4/20. 8 | // Copyright (c) 2019 李兆祥. All rights reserved. 9 | // https://github.com/SmileZXLee/ZXHookDetection 10 | 11 | #import "ZXHookAttackDylib.h" 12 | #import 13 | #import 14 | #import 15 | #import 16 | 17 | -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttackDylib/StatHook.h: -------------------------------------------------------------------------------- 1 | // 2 | // StatHook.h 3 | // ZXHookAttackDylib 4 | // 5 | // Created by 李兆祥 on 2019/4/21. 6 | // Copyright © 2019 李兆祥. All rights reserved. 7 | // https://github.com/SmileZXLee/ZXHookDetection 8 | 9 | static char *JailbrokenPathArr[] = {"/Applications/Cydia.app","/usr/sbin/sshd","/bin/bash","/etc/apt","/Library/MobileSubstrate","/User/Applications/"}; 10 | 11 | #import 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | @interface StatHook : NSObject 15 | +(void)statHook; 16 | @end 17 | 18 | NS_ASSUME_NONNULL_END 19 | -------------------------------------------------------------------------------- /ZXHookDetection/ZXHookDetection/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // ZXHookDetection 4 | // 5 | // Created by 李兆祥 on 2019/4/20. 6 | // Copyright © 2019 李兆祥. All rights reserved. 7 | // https://github.com/SmileZXLee/ZXHookDetection 8 | 9 | #import "ViewController.h" 10 | 11 | @interface ViewController () 12 | 13 | @end 14 | 15 | @implementation ViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | NSString *aesKey = @"TEST_AES_KEY"; 20 | NSLog(@"aesKey--%@",aesKey); 21 | self.view.backgroundColor = [UIColor greenColor]; 22 | } 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /ZXHookDetection/ZXHookDetection/ZXHookDetection/ZXHookDetection.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZXHookDetection.h 3 | // ZXHookDetection 4 | // 5 | // Created by 李兆祥 on 2019/4/20. 6 | // Copyright © 2019 李兆祥. All rights reserved. 7 | // https://github.com/SmileZXLee/ZXHookDetection 8 | 9 | #import 10 | #import 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface ZXHookDetection : NSObject 14 | + (BOOL)isJailbroken1; 15 | + (BOOL)isJailbroken2; 16 | + (BOOL)isJailbroken3; 17 | + (BOOL)isExternalLibs; 18 | + (BOOL)isLegalPublicKey:(NSString *)publicKey; 19 | @end 20 | 21 | NS_ASSUME_NONNULL_END 22 | -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttack/Scripts/quick-resign.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Usage 4 | # Must be an absolute path 5 | 6 | # ./quick-resign.sh [insert] "origin.ipa path" "resign.ipa path" 7 | 8 | INSERT_DYLIB=NO 9 | INPUT_PATH=$1 10 | OUTPUT_PATH=$2 11 | 12 | if [[ $1 == "insert" ]];then 13 | INSERT_DYLIB=YES 14 | INPUT_PATH=$2 15 | OUTPUT_PATH=$3 16 | fi 17 | 18 | if [[ ! $OUTPUT_PATH ]];then 19 | OUTPUT_PATH=$PWD 20 | fi 21 | 22 | cp -rf $INPUT_PATH ../TargetApp/ 23 | cd ../../ 24 | xcodebuild MONKEYDEV_INSERT_DYLIB=$INSERT_DYLIB | xcpretty 25 | cd LatestBuild 26 | ./createIPA.command 27 | cp -rf Target.ipa $OUTPUT_PATH 28 | exit 0 -------------------------------------------------------------------------------- /ZXHookDetection/ZXHookFramework/ZXHookFramework.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZXHookFramework.h 3 | // ZXHookFramework 4 | // 5 | // Created by 李兆祥 on 2019/4/21. 6 | // Copyright © 2019 李兆祥. All rights reserved. 7 | // https://github.com/SmileZXLee/ZXHookDetection 8 | 9 | #import 10 | 11 | //! Project version number for ZXHookFramework. 12 | FOUNDATION_EXPORT double ZXHookFrameworkVersionNumber; 13 | 14 | //! Project version string for ZXHookFramework. 15 | FOUNDATION_EXPORT const unsigned char ZXHookFrameworkVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttackDylib/Config/MDMethodTrace.h: -------------------------------------------------------------------------------- 1 | // weibo: http://weibo.com/xiaoqing28 2 | // blog: http://www.alonemonkey.com 3 | // 4 | // MDMethodTrace.h 5 | // MonkeyDev 6 | // 7 | // Created by AloneMonkey on 2017/9/7. 8 | // Copyright © 2017年 AloneMonkey. All rights reserved. 9 | // 10 | 11 | #ifndef MethodTrace_h 12 | #define MethodTrace_h 13 | 14 | #import 15 | 16 | @interface MDMethodTrace : NSObject 17 | 18 | + (void)addClassTrace:(NSString*) className; 19 | 20 | + (void)addClassTrace:(NSString *)className methodName:(NSString*) methodName; 21 | 22 | + (void)addClassTrace:(NSString *)className methodList:(NSArray*) methodList; 23 | 24 | @end 25 | 26 | #endif /* MethodTrace_h */ 27 | -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttackDylib/Tools/LLDBTools.h: -------------------------------------------------------------------------------- 1 | // weibo: http://weibo.com/xiaoqing28 2 | // blog: http://www.alonemonkey.com 3 | // 4 | // LLDBTools.h 5 | // MonkeyDev 6 | // 7 | // Created by AloneMonkey on 2018/3/8. 8 | // Copyright © 2018年 AloneMonkey. All rights reserved. 9 | // 10 | 11 | #import 12 | #import 13 | 14 | //(lldb) po pviews() 15 | 16 | NSString* pvc(void); 17 | 18 | NSString* pviews(void); 19 | 20 | NSString* pactions(vm_address_t address); 21 | 22 | NSString* pblock(vm_address_t address); 23 | 24 | NSString* methods(const char * classname); 25 | 26 | NSString* ivars(vm_address_t address); 27 | 28 | NSString* choose(const char* classname); 29 | 30 | NSString* vmmap(); 31 | -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttackDylib/ZXHookAttackDylib.h: -------------------------------------------------------------------------------- 1 | // weibo: http://weibo.com/xiaoqing28 2 | // blog: http://www.alonemonkey.com 3 | // 4 | // ZXHookAttackDylib.h 5 | // ZXHookAttackDylib 6 | // 7 | // Created by 李兆祥 on 2019/4/20. 8 | // Copyright (c) 2019 李兆祥. All rights reserved. 9 | // https://github.com/SmileZXLee/ZXHookDetection 10 | 11 | #import 12 | 13 | #define INSERT_SUCCESS_WELCOME @"\n 🎉!!!congratulations!!!🎉\n👍----------------insert dylib success----------------👍" 14 | 15 | @interface CustomViewController 16 | 17 | @property (nonatomic, copy) NSString* newProperty; 18 | 19 | + (void)classMethod; 20 | 21 | - (NSString*)getMyName; 22 | 23 | - (void)newMethod:(NSString*) output; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttackDylib/Config/MDConfigManager.h: -------------------------------------------------------------------------------- 1 | // weibo: http://weibo.com/xiaoqing28 2 | // blog: http://www.alonemonkey.com 3 | // 4 | // MDConfigManager.h 5 | // MonkeyDev 6 | // 7 | // Created by AloneMonkey on 2018/4/24. 8 | // Copyright © 2018年 AloneMonkey. All rights reserved. 9 | // 10 | 11 | #import 12 | 13 | #define MDCONFIG_CYCRIPT_KEY @"Cycript" 14 | #define MDCONFIG_TRACE_KEY @"MethodTrace" 15 | #define MDCONFIG_ENABLE_KEY @"ENABLE" 16 | #define MDCONFIG_CLASS_LIST @"CLASS_LIST" 17 | #define MDCONFIG_LOADATLAUNCH_KEY @"LoadAtLaunch" 18 | 19 | @interface MDConfigManager : NSObject 20 | 21 | + (instancetype)sharedInstance; 22 | 23 | - (NSDictionary*)readConfigByKey:(NSString*) key; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttackDylib/StatHook.m: -------------------------------------------------------------------------------- 1 | // 2 | // StatHook.m 3 | // ZXHookAttackDylib 4 | // 5 | // Created by 李兆祥 on 2019/4/21. 6 | // Copyright © 2019 李兆祥. All rights reserved. 7 | // https://github.com/SmileZXLee/ZXHookDetection 8 | 9 | #import "StatHook.h" 10 | #import "fishhook.h" 11 | @implementation StatHook 12 | static int (*orig_stat)(char *c, struct stat *s); 13 | int hook_stat(char *c, struct stat *s){ 14 | for (int i = 0;i < sizeof(JailbrokenPathArr) / sizeof(char *);i++) { 15 | if(0 == strcmp(c, JailbrokenPathArr[i])){ 16 | return 0; 17 | } 18 | } 19 | return orig_stat(c,s); 20 | } 21 | +(void)statHook{ 22 | struct rebinding stat_rebinding = {"stat", hook_stat, (void *)&orig_stat}; 23 | rebind_symbols((struct rebinding[1]){stat_rebinding}, 1); 24 | } 25 | @end 26 | -------------------------------------------------------------------------------- /ZXHookDetection/ZXHookDetectionTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /ZXHookDetection/ZXHookDetectionUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /ZXHookDetection/ZXHookFrameworkTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /ZXHookDetection/ZXHookFramework/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | 22 | 23 | -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttack/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFiles 10 | 11 | ZXHookAttack/icon.png 12 | 13 | CFBundleIdentifier 14 | $(PRODUCT_BUNDLE_IDENTIFIER) 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | $(PRODUCT_NAME) 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | 1.0 23 | CFBundleVersion 24 | 1 25 | 26 | 27 | -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttackDylib/Config/MDCycriptManager.h: -------------------------------------------------------------------------------- 1 | // weibo: http://weibo.com/xiaoqing28 2 | // blog: http://www.alonemonkey.com 3 | // 4 | // MDCycriptManager.h 5 | // MonkeyDev 6 | // 7 | // Created by AloneMonkey on 2018/3/8. 8 | // Copyright © 2018年 AloneMonkey. All rights reserved. 9 | // 10 | 11 | #ifndef __OPTIMIZE__ 12 | 13 | #import 14 | 15 | #define PORT 6666 16 | 17 | @interface MDCycriptManager : NSObject 18 | 19 | + (instancetype)sharedInstance; 20 | 21 | 22 | /** 23 | Download script by config.plist 24 | 25 | @param update Force update of all scripts 26 | */ 27 | -(void)loadCycript:(BOOL) update; 28 | 29 | /** 30 | eval javascript by cycript 31 | 32 | @param cycript javascript string 33 | @param error error happened 34 | @return eval result 35 | */ 36 | -(NSString*)evaluateCycript:(NSString*) cycript error:(NSError **) error; 37 | 38 | @end 39 | 40 | #endif -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttackDylib/Config/ANYMethodLog.h: -------------------------------------------------------------------------------- 1 | // 2 | // ANYMethodLog.h 3 | // ANYMethodLog 4 | // 5 | // Created by qiuhaodong on 2017/1/14. 6 | // Copyright © 2017年 qiuhaodong. All rights reserved. 7 | // 8 | // https://github.com/qhd/ANYMethodLog.git 9 | // 10 | 11 | #import 12 | 13 | typedef BOOL (^ConditionBlock)(SEL sel); 14 | typedef void (^BeforeBlock)(id target, SEL sel, NSArray *args, int deep); 15 | typedef void (^AfterBlock)(id target, SEL sel, NSArray *args, NSTimeInterval interval, int deep, id retValue); 16 | 17 | @interface ANYMethodLog : NSObject 18 | 19 | /** 20 | 打印对象的方法调用 21 | 22 | @param aClass 要打印的类 23 | @param condition 根据此 block 来决定是否追踪方法(sel 是方法名) 24 | @param before 方法调用前会调用该 block(target 是检测的对象,sel 是方法名,args 是参数列表) 25 | @param after 方法调用后会调用该 block(interval 是执行方法的耗时) 26 | */ 27 | + (void)logMethodWithClass:(Class)aClass 28 | condition:(ConditionBlock) condition 29 | before:(BeforeBlock) before 30 | after:(AfterBlock) after; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /ZXHookDetection/ZXHookDetectionTests/ZXHookDetectionTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZXHookDetectionTests.m 3 | // ZXHookDetectionTests 4 | // 5 | // Created by 李兆祥 on 2019/4/20. 6 | // Copyright © 2019 李兆祥. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ZXHookDetectionTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation ZXHookDetectionTests 16 | 17 | - (void)setUp { 18 | // Put setup code here. This method is called before the invocation of each test method in the class. 19 | } 20 | 21 | - (void)tearDown { 22 | // Put teardown code here. This method is called after the invocation of each test method in the class. 23 | } 24 | 25 | - (void)testExample { 26 | // This is an example of a functional test case. 27 | // Use XCTAssert and related functions to verify your tests produce the correct results. 28 | } 29 | 30 | - (void)testPerformanceExample { 31 | // This is an example of a performance test case. 32 | [self measureBlock:^{ 33 | // Put the code you want to measure the time of here. 34 | }]; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /ZXHookDetection/ZXHookFrameworkTests/ZXHookFrameworkTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZXHookFrameworkTests.m 3 | // ZXHookFrameworkTests 4 | // 5 | // Created by 李兆祥 on 2019/4/21. 6 | // Copyright © 2019 李兆祥. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ZXHookFrameworkTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation ZXHookFrameworkTests 16 | 17 | - (void)setUp { 18 | // Put setup code here. This method is called before the invocation of each test method in the class. 19 | } 20 | 21 | - (void)tearDown { 22 | // Put teardown code here. This method is called after the invocation of each test method in the class. 23 | } 24 | 25 | - (void)testExample { 26 | // This is an example of a functional test case. 27 | // Use XCTAssert and related functions to verify your tests produce the correct results. 28 | } 29 | 30 | - (void)testPerformanceExample { 31 | // This is an example of a performance test case. 32 | [self measureBlock:^{ 33 | // Put the code you want to measure the time of here. 34 | }]; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 李兆祥 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttackDylib/Config/MDConfigManager.m: -------------------------------------------------------------------------------- 1 | // weibo: http://weibo.com/xiaoqing28 2 | // blog: http://www.alonemonkey.com 3 | // 4 | // MDConfigManager.m 5 | // MonkeyDev 6 | // 7 | // Created by AloneMonkey on 2018/4/24. 8 | // Copyright © 2018年 AloneMonkey. All rights reserved. 9 | // 10 | 11 | #define CONFIG_FILE_NAME @"MDConfig" 12 | 13 | #import "MDConfigManager.h" 14 | 15 | @implementation MDConfigManager{ 16 | NSString* _filepath; 17 | } 18 | 19 | + (instancetype)sharedInstance{ 20 | static MDConfigManager *sharedInstance = nil; 21 | if (!sharedInstance){ 22 | sharedInstance = [[MDConfigManager alloc] init]; 23 | } 24 | return sharedInstance; 25 | } 26 | 27 | - (BOOL)isActive{ 28 | _filepath = [[NSBundle mainBundle] pathForResource:CONFIG_FILE_NAME ofType:@"plist"]; 29 | if(_filepath == nil){ 30 | return NO; 31 | } 32 | return YES; 33 | } 34 | 35 | - (NSDictionary*) readConfigByKey:(NSString*) key{ 36 | if([self isActive]){ 37 | NSDictionary* contentDict = [NSDictionary dictionaryWithContentsOfFile:_filepath]; 38 | if([contentDict.allKeys containsObject:key]){ 39 | return contentDict[key]; 40 | }else{ 41 | return nil; 42 | } 43 | }else{ 44 | return nil; 45 | } 46 | } 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /ZXHookDetection/ZXHookDetectionUITests/ZXHookDetectionUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZXHookDetectionUITests.m 3 | // ZXHookDetectionUITests 4 | // 5 | // Created by 李兆祥 on 2019/4/20. 6 | // Copyright © 2019 李兆祥. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ZXHookDetectionUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation ZXHookDetectionUITests 16 | 17 | - (void)setUp { 18 | // Put setup code here. This method is called before the invocation of each test method in the class. 19 | 20 | // In UI tests it is usually best to stop immediately when a failure occurs. 21 | self.continueAfterFailure = NO; 22 | 23 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 24 | [[[XCUIApplication alloc] init] launch]; 25 | 26 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 27 | } 28 | 29 | - (void)tearDown { 30 | // Put teardown code here. This method is called after the invocation of each test method in the class. 31 | } 32 | 33 | - (void)testExample { 34 | // Use recording to get started writing UI tests. 35 | // Use XCTAssert and related functions to verify your tests produce the correct results. 36 | } 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttackDylib/Logos/ZXHookAttackDylib.xm: -------------------------------------------------------------------------------- 1 | // See http://iphonedevwiki.net/index.php/Logos 2 | // https://github.com/SmileZXLee/ZXHookDetection 3 | #import 4 | #import "fishhook.h" 5 | #import "StatHook.h" 6 | %ctor{ 7 | [StatHook statHook]; 8 | NSLog(@"AttackHookLoaded"); 9 | } 10 | @interface ViewController:UIViewController 11 | 12 | @end 13 | %hook ViewController 14 | 15 | -(void)viewDidLoad{ 16 | 17 | self.view.backgroundColor = [UIColor redColor]; 18 | } 19 | %end 20 | 21 | %hook NSBundle 22 | -(id)bundleIdentifier{ 23 | NSArray *address = [NSThread callStackReturnAddresses]; 24 | Dl_info info = {0}; 25 | if(dladdr((void *)[address[2] longLongValue], &info) == 0) { 26 | return %orig; 27 | } 28 | NSString *path = [NSString stringWithUTF8String:info.dli_fname]; 29 | if ([path hasPrefix:NSBundle.mainBundle.bundlePath]) { 30 | NSLog(@"getBundleIdentifier"); 31 | return @"cn.newBundelId"; 32 | } else { 33 | return %orig; 34 | } 35 | } 36 | %end 37 | 38 | //绕过使用NSFileManager判断特定文件是否存在的越狱检测,此时直接返回NO势必会影响程序中对这个方法的正常使用,因此可以先打印一下path,然后判断如果path是用来判断是否越狱则返回NO,否则按照正常逻辑返回 39 | %hook NSFileManager 40 | - (BOOL)fileExistsAtPath:(NSString *)path{ 41 | for (int i = 0;i < sizeof(JailbrokenPathArr) / sizeof(char *);i++) { 42 | NSString *jPath = [NSString stringWithUTF8String:JailbrokenPathArr[i]]; 43 | if([path isEqualToString:jPath]){ 44 | return NO; 45 | } 46 | } 47 | return YES; 48 | } 49 | %end 50 | 51 | -------------------------------------------------------------------------------- /ZXHookDetection/ZXHookDetection/ZXHookDetection/NSDictionary+ZXDetection.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSDictionary+ZXDetection.m 3 | // ZXHookDetection 4 | // 5 | // Created by 李兆祥 on 2019/4/20. 6 | // Copyright © 2019 李兆祥. All rights reserved. 7 | // 测试用的 8 | 9 | #import "NSDictionary+ZXDetection.h" 10 | #import 11 | #include 12 | #import 13 | #import 14 | #import 15 | #import 16 | @implementation NSDictionary (ZXDetection) 17 | +(void)load{ 18 | Class dictCls = objc_getClass("__NSDictionaryM"); 19 | Method orgMethod = class_getInstanceMethod(dictCls, @selector(setObject:forKey:)); 20 | Method swizMethod = class_getInstanceMethod(dictCls, @selector(sw_setObject:forKey:)); 21 | method_exchangeImplementations(orgMethod, swizMethod); 22 | char *env = getenv("DYLD_INSERT_LIBRARIES"); 23 | NSString *res = [NSString stringWithFormat:@"%s",env]; 24 | char *env2 = getenv("XPC_SERVICE_NAME"); 25 | NSString *res2 = [NSString stringWithFormat:@"%s",env2]; 26 | NSLog(@"res2--%@",res2); 27 | NSLog(@"res--%@",res); 28 | 29 | } 30 | 31 | -(void)sw_setObject:(id)obj forKey:(id)key{ 32 | if(![obj isKindOfClass:[objc_getClass("FBSSceneImpl") class]]){ 33 | //NSLog(@"anObject :%@ key: %@ ",obj,key); 34 | } 35 | if([key isKindOfClass:[NSString class]] && [key isEqualToString:@"XPC_SERVICE_NAME"]){ 36 | if([obj containsString:@"cn.zxlee.ZXHookDetection"]){ 37 | 38 | } 39 | 40 | } 41 | 42 | [self sw_setObject:obj forKey:key]; 43 | } 44 | @end 45 | -------------------------------------------------------------------------------- /ZXHookDetection/ZXHookDetection/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /ZXHookDetection/ZXHookDetection/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /ZXHookDetection/ZXHookDetection/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | 31 | # CocoaPods 32 | # 33 | # We recommend against adding the Pods directory to your .gitignore. However 34 | # you should judge for yourself, the pros and cons are mentioned at: 35 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 36 | # 37 | # Pods/ 38 | # 39 | # Add this line if you want to avoid checking in source code from the Xcode workspace 40 | # *.xcworkspace 41 | 42 | # Carthage 43 | # 44 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 45 | # Carthage/Checkouts 46 | 47 | Carthage/Build 48 | 49 | # fastlane 50 | # 51 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 52 | # screenshots whenever they are needed. 53 | # For more information about the recommended setup visit: 54 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 55 | 56 | fastlane/report.xml 57 | fastlane/Preview.html 58 | fastlane/screenshots/**/*.png 59 | fastlane/test_output 60 | 61 | # Code Injection 62 | # 63 | # After new code Injection tools there's a generated folder /iOSInjectionProject 64 | # https://github.com/johnno1962/injectionforxcode 65 | 66 | iOSInjectionProject/ 67 | # Ignore System File 68 | .DS_Store 69 | Thumbs.db 70 | -------------------------------------------------------------------------------- /ZXHookDetection/ZXHookDetection/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttack/Config/MDConfig.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | MethodTrace 6 | 7 | ENABLE 8 | 9 | CLASS_LIST 10 | 11 | BaseMsgContentViewController 12 | 13 | CMessageMgr 14 | 15 | AsyncOnAddMsg:MsgWrap: 16 | onRevokeMsg: 17 | 18 | 19 | 20 | Cycript 21 | 22 | nslog 23 | 24 | LoadAtLaunch 25 | 26 | priority 27 | 0 28 | content 29 | NSLog = function() { var types = 'v', args = [], count = arguments.length; for (var i = 0; i != count; ++i) { types += '@'; args.push(arguments[i]); } new Functor(dlsym(RTLD_DEFAULT, "NSLog"), types).apply(null, args); } 30 | 31 | ms 32 | 33 | LoadAtLaunch 34 | 35 | priority 36 | 1 37 | url 38 | https://raw.githubusercontent.com/AloneMonkey/MDCycript/master/MS.cy 39 | 40 | hook 41 | 42 | LoadAtLaunch 43 | 44 | priority 45 | 2 46 | content 47 | try{ 48 | var oldm = {}; 49 | HookMessage(CustomViewController, @selector(showChangeLog:), function(log) { 50 | NSLog("hooked by cycript!!!"); 51 | return oldm->call(this,log); 52 | }, oldm); 53 | }catch(err){ 54 | NSLog(err.toString()) 55 | } 56 | 57 | md 58 | 59 | LoadAtLaunch 60 | 61 | priority 62 | 3 63 | url 64 | https://raw.githubusercontent.com/AloneMonkey/MDCycript/master/md.cy 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttack/TargetApp/ZXHookDetection.app/Frameworks/ZXHookFramework.framework/_CodeSignature/CodeResources: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | files 6 | 7 | Info.plist 8 | 9 | GqYWse08orwGDq1r3yMFHn1s+a4= 10 | 11 | 12 | files2 13 | 14 | rules 15 | 16 | ^.* 17 | 18 | ^.*\.lproj/ 19 | 20 | optional 21 | 22 | weight 23 | 1000 24 | 25 | ^.*\.lproj/locversion.plist$ 26 | 27 | omit 28 | 29 | weight 30 | 1100 31 | 32 | ^Base\.lproj/ 33 | 34 | weight 35 | 1010 36 | 37 | ^version.plist$ 38 | 39 | 40 | rules2 41 | 42 | .*\.dSYM($|/) 43 | 44 | weight 45 | 11 46 | 47 | ^(.*/)?\.DS_Store$ 48 | 49 | omit 50 | 51 | weight 52 | 2000 53 | 54 | ^.* 55 | 56 | ^.*\.lproj/ 57 | 58 | optional 59 | 60 | weight 61 | 1000 62 | 63 | ^.*\.lproj/locversion.plist$ 64 | 65 | omit 66 | 67 | weight 68 | 1100 69 | 70 | ^Base\.lproj/ 71 | 72 | weight 73 | 1010 74 | 75 | ^Info\.plist$ 76 | 77 | omit 78 | 79 | weight 80 | 20 81 | 82 | ^PkgInfo$ 83 | 84 | omit 85 | 86 | weight 87 | 20 88 | 89 | ^embedded\.provisionprofile$ 90 | 91 | weight 92 | 20 93 | 94 | ^version\.plist$ 95 | 96 | weight 97 | 20 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttack/TargetApp/ZXHookDetection.app/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildMachineOSBuild 6 | 18F96h 7 | CFBundleDevelopmentRegion 8 | en 9 | CFBundleExecutable 10 | ZXHookDetection 11 | CFBundleIdentifier 12 | cn.zxlee.ZXHookDetection 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ZXHookDetection 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSupportedPlatforms 22 | 23 | iPhoneOS 24 | 25 | CFBundleVersion 26 | 1 27 | DTCompiler 28 | com.apple.compilers.llvm.clang.1_0 29 | DTPlatformBuild 30 | 16E226 31 | DTPlatformName 32 | iphoneos 33 | DTPlatformVersion 34 | 12.2 35 | DTSDKBuild 36 | 16E226 37 | DTSDKName 38 | iphoneos12.2 39 | DTXcode 40 | 1020 41 | DTXcodeBuild 42 | 10E125 43 | LSRequiresIPhoneOS 44 | 45 | MinimumOSVersion 46 | 10.0 47 | UIDeviceFamily 48 | 49 | 1 50 | 2 51 | 52 | UILaunchStoryboardName 53 | LaunchScreen 54 | UIMainStoryboardFile 55 | Main 56 | UIRequiredDeviceCapabilities 57 | 58 | armv7 59 | 60 | UISupportedInterfaceOrientations 61 | 62 | UIInterfaceOrientationPortrait 63 | UIInterfaceOrientationLandscapeLeft 64 | UIInterfaceOrientationLandscapeRight 65 | 66 | UISupportedInterfaceOrientations~ipad 67 | 68 | UIInterfaceOrientationPortrait 69 | UIInterfaceOrientationPortraitUpsideDown 70 | UIInterfaceOrientationLandscapeLeft 71 | UIInterfaceOrientationLandscapeRight 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /ZXHookDetection/ZXHookFramework/ZXMyFramework.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZXMyLib.m 3 | // ZXHookDetection 4 | // 5 | // Created by 李兆祥 on 2019/4/21. 6 | // Copyright © 2019 李兆祥. All rights reserved. 7 | // https://github.com/SmileZXLee/ZXHookDetection 8 | 9 | #import "ZXMyFramework.h" 10 | #import 11 | #import 12 | #import "fishhook.h" 13 | #pragma mark 受保护的方法数组 14 | static char *DefendSelStrs[] = {"viewDidLoad","bundleIdentifier"}; 15 | 16 | @implementation ZXMyFramework 17 | void (* orig_exchangeImple)(Method _Nonnull m1, Method _Nonnull m2); 18 | IMP _Nonnull (* orig_setImple)(Method _Nonnull m, IMP _Nonnull imp); 19 | IMP _Nonnull (* getIMP)(Method _Nonnull m); 20 | 21 | +(void)load{ 22 | NSLog(@"ZXMyFrameworkLoaded!"); 23 | NSString *bundleId = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"]; 24 | NSLog(@"bundleId--%@",bundleId); 25 | if(TARGET_IPHONE_SIMULATOR)return; 26 | struct rebinding exchange_rebinding; 27 | exchange_rebinding.name = "method_exchangeImplementations"; 28 | exchange_rebinding.replacement = hook_exchangeImple; 29 | exchange_rebinding.replaced=(void *)&orig_exchangeImple; 30 | 31 | struct rebinding setImple_rebinding; 32 | setImple_rebinding.name = "method_setImplementation"; 33 | setImple_rebinding.replacement = hook_setImple; 34 | setImple_rebinding.replaced=(void *)&orig_setImple; 35 | 36 | struct rebinding rebindings[]={exchange_rebinding,setImple_rebinding}; 37 | rebind_symbols(rebindings, 2); 38 | } 39 | 40 | void hook_exchangeImple(Method _Nonnull orig_method, Method _Nonnull changed_method){ 41 | if(orig_method){ 42 | SEL sel = method_getName(orig_method); 43 | bool in_def = in_defend_sel((char *)[NSStringFromSelector(sel) UTF8String]); 44 | if(in_def){ 45 | NSLog(@"尝试hook受保护的方法:[%@],已禁止",NSStringFromSelector(sel)); 46 | return; 47 | } 48 | } 49 | orig_exchangeImple(orig_method,changed_method); 50 | } 51 | void hook_setImple(Method _Nonnull method, IMP _Nonnull imp){ 52 | if(method){ 53 | SEL sel = method_getName(method); 54 | bool in_def = in_defend_sel((char *)[NSStringFromSelector(sel) UTF8String]); 55 | if(in_def){ 56 | NSLog(@"尝试hook受保护的方法:[%@],已禁止",NSStringFromSelector(sel)); 57 | return; 58 | } 59 | } 60 | orig_setImple(method,imp); 61 | } 62 | 63 | #pragma mark 判断被交换的方法是否是受保护的方法 64 | bool in_defend_sel(char *selStr){ 65 | for (int i = 0;i < sizeof(DefendSelStrs) / sizeof(char *);i++) { 66 | if(0 == strcmp(selStr, DefendSelStrs[i])){ 67 | return true; 68 | } 69 | } 70 | return false; 71 | } 72 | @end 73 | -------------------------------------------------------------------------------- /ZXHookDetection/ZXHookDetection/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // ZXHookDetection 4 | // 5 | // Created by 李兆祥 on 2019/4/20. 6 | // Copyright © 2019 李兆祥. All rights reserved. 7 | // https://github.com/SmileZXLee/ZXHookDetection 8 | 9 | #import "AppDelegate.h" 10 | #import "ZXHookDetection.h" 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | //添加检测 20 | BOOL isJailbroken1 = [ZXHookDetection isJailbroken1]; 21 | BOOL isJailbroken2 = [ZXHookDetection isJailbroken2]; 22 | BOOL isJailbroken3 = [ZXHookDetection isJailbroken3]; 23 | BOOL isExternalLibs = [ZXHookDetection isExternalLibs]; 24 | BOOL isLegalLPublicKey = [ZXHookDetection isLegalPublicKey:@"4Y2YPWFYNQ"]; 25 | NSLog(@"isJailbroken1--%d",isJailbroken1); 26 | NSLog(@"isJailbroken2--%d",isJailbroken2); 27 | NSLog(@"isJailbroken3--%d",isJailbroken3); 28 | NSLog(@"isExternalLibs--%d",isExternalLibs); 29 | NSLog(@"isLegalLPublicKey--%d",isLegalLPublicKey); 30 | return YES; 31 | } 32 | 33 | 34 | - (void)applicationWillResignActive:(UIApplication *)application { 35 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 36 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 37 | } 38 | 39 | 40 | - (void)applicationDidEnterBackground:(UIApplication *)application { 41 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 42 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 43 | } 44 | 45 | 46 | - (void)applicationWillEnterForeground:(UIApplication *)application { 47 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 48 | } 49 | 50 | 51 | - (void)applicationDidBecomeActive:(UIApplication *)application { 52 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 53 | } 54 | 55 | 56 | - (void)applicationWillTerminate:(UIApplication *)application { 57 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 58 | } 59 | 60 | 61 | @end 62 | -------------------------------------------------------------------------------- /ZXHookDetection/ZXHookFramework/fishhook.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013, Facebook, Inc. 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // * Redistributions of source code must retain the above copyright notice, 6 | // this list of conditions and the following disclaimer. 7 | // * Redistributions in binary form must reproduce the above copyright notice, 8 | // this list of conditions and the following disclaimer in the documentation 9 | // and/or other materials provided with the distribution. 10 | // * Neither the name Facebook nor the names of its contributors may be used to 11 | // endorse or promote products derived from this software without specific 12 | // prior written permission. 13 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 14 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 17 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 21 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | 24 | #ifndef fishhook_h 25 | #define fishhook_h 26 | 27 | #include 28 | #include 29 | 30 | #if !defined(FISHHOOK_EXPORT) 31 | #define FISHHOOK_VISIBILITY __attribute__((visibility("hidden"))) 32 | #else 33 | #define FISHHOOK_VISIBILITY __attribute__((visibility("default"))) 34 | #endif 35 | 36 | #ifdef __cplusplus 37 | extern "C" { 38 | #endif //__cplusplus 39 | 40 | /* 41 | * A structure representing a particular intended rebinding from a symbol 42 | * name to its replacement 43 | */ 44 | struct rebinding { 45 | const char *name; 46 | void *replacement; 47 | void **replaced; 48 | }; 49 | 50 | /* 51 | * For each rebinding in rebindings, rebinds references to external, indirect 52 | * symbols with the specified name to instead point at replacement for each 53 | * image in the calling process as well as for all future images that are loaded 54 | * by the process. If rebind_functions is called more than once, the symbols to 55 | * rebind are added to the existing list of rebindings, and if a given symbol 56 | * is rebound more than once, the later rebinding will take precedence. 57 | */ 58 | FISHHOOK_VISIBILITY 59 | int rebind_symbols(struct rebinding rebindings[], size_t rebindings_nel); 60 | 61 | /* 62 | * Rebinds as above, but only in the specified image. The header should point 63 | * to the mach-o header, the slide should be the slide offset. Others as above. 64 | */ 65 | FISHHOOK_VISIBILITY 66 | int rebind_symbols_image(void *header, 67 | intptr_t slide, 68 | struct rebinding rebindings[], 69 | size_t rebindings_nel); 70 | 71 | #ifdef __cplusplus 72 | } 73 | #endif //__cplusplus 74 | 75 | #endif //fishhook_h 76 | 77 | -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttackDylib/fishhook/fishhook.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013, Facebook, Inc. 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // * Redistributions of source code must retain the above copyright notice, 6 | // this list of conditions and the following disclaimer. 7 | // * Redistributions in binary form must reproduce the above copyright notice, 8 | // this list of conditions and the following disclaimer in the documentation 9 | // and/or other materials provided with the distribution. 10 | // * Neither the name Facebook nor the names of its contributors may be used to 11 | // endorse or promote products derived from this software without specific 12 | // prior written permission. 13 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 14 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 17 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 21 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | 24 | #ifndef fishhook_h 25 | #define fishhook_h 26 | 27 | #include 28 | #include 29 | 30 | #if !defined(FISHHOOK_EXPORT) 31 | #define FISHHOOK_VISIBILITY __attribute__((visibility("hidden"))) 32 | #else 33 | #define FISHHOOK_VISIBILITY __attribute__((visibility("default"))) 34 | #endif 35 | 36 | #ifdef __cplusplus 37 | extern "C" { 38 | #endif //__cplusplus 39 | 40 | /* 41 | * A structure representing a particular intended rebinding from a symbol 42 | * name to its replacement 43 | */ 44 | struct rebinding { 45 | const char *name; 46 | void *replacement; 47 | void **replaced; 48 | }; 49 | 50 | /* 51 | * For each rebinding in rebindings, rebinds references to external, indirect 52 | * symbols with the specified name to instead point at replacement for each 53 | * image in the calling process as well as for all future images that are loaded 54 | * by the process. If rebind_functions is called more than once, the symbols to 55 | * rebind are added to the existing list of rebindings, and if a given symbol 56 | * is rebound more than once, the later rebinding will take precedence. 57 | */ 58 | FISHHOOK_VISIBILITY 59 | int rebind_symbols(struct rebinding rebindings[], size_t rebindings_nel); 60 | 61 | /* 62 | * Rebinds as above, but only in the specified image. The header should point 63 | * to the mach-o header, the slide should be the slide offset. Others as above. 64 | */ 65 | FISHHOOK_VISIBILITY 66 | int rebind_symbols_image(void *header, 67 | intptr_t slide, 68 | struct rebinding rebindings[], 69 | size_t rebindings_nel); 70 | 71 | #ifdef __cplusplus 72 | } 73 | #endif //__cplusplus 74 | 75 | #endif //fishhook_h 76 | 77 | -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttackDylib/Config/MDMethodTrace.m: -------------------------------------------------------------------------------- 1 | // weibo: http://weibo.com/xiaoqing28 2 | // blog: http://www.alonemonkey.com 3 | // 4 | // MDMethodTrace.m 5 | // MonkeyDev 6 | // 7 | // Created by AloneMonkey on 2017/9/6. 8 | // Copyright © 2017年 AloneMonkey. All rights reserved. 9 | // 10 | 11 | #import "ANYMethodLog.h" 12 | #import "MDMethodTrace.h" 13 | #import 14 | #import 15 | #import "MDConfigManager.h" 16 | 17 | #define MDLog(fmt, ...) NSLog((@"[MethodTrace] " fmt), ##__VA_ARGS__) 18 | 19 | @implementation MDMethodTrace : NSObject 20 | 21 | +(void)addClassTrace:(NSString *)className{ 22 | [self addClassTrace:className methodList:nil]; 23 | } 24 | 25 | +(void)addClassTrace:(NSString *)className methodName:(NSString *)methodName{ 26 | [self addClassTrace:className methodList:@[methodName]]; 27 | } 28 | 29 | +(void)addClassTrace:(NSString *)className methodList:(NSArray *)methodList{ 30 | Class targetClass = objc_getClass([className UTF8String]); 31 | if(targetClass != nil){ 32 | [ANYMethodLog logMethodWithClass:NSClassFromString(className) condition:^BOOL(SEL sel) { 33 | return (methodList == nil || methodList.count == 0) ? YES : [methodList containsObject:NSStringFromSelector(sel)]; 34 | } before:^(id target, SEL sel, NSArray *args, int deep) { 35 | NSString *selector = NSStringFromSelector(sel); 36 | NSMutableString *selectorString = [NSMutableString new]; 37 | if([selector containsString:@":"]){ 38 | NSArray *selectorArrary = [selector componentsSeparatedByString:@":"]; 39 | selectorArrary = [selectorArrary filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"length > 0"]]; 40 | for (int i = 0; i < selectorArrary.count; i++) { 41 | [selectorString appendFormat:@"%@:%@ ", selectorArrary[i], args[i]]; 42 | } 43 | }else{ 44 | [selectorString appendString:selector]; 45 | } 46 | 47 | NSMutableString *deepString = [NSMutableString new]; 48 | for (int i = 0; i < deep; i++) { 49 | [deepString appendString:@"-"]; 50 | } 51 | NSLog(@"%@[%@ %@]", deepString , target, selectorString); 52 | } after:^(id target, SEL sel, NSArray *args, NSTimeInterval interval,int deep, id retValue) { 53 | NSMutableString *deepString = [NSMutableString new]; 54 | for (int i = 0; i < deep; i++) { 55 | [deepString appendString:@"-"]; 56 | } 57 | NSLog(@"%@ret:%@", deepString, retValue); 58 | }]; 59 | }else{ 60 | MDLog(@"canot find class %@", className); 61 | } 62 | } 63 | 64 | @end 65 | 66 | static __attribute__((constructor)) void entry(){ 67 | MDConfigManager * configManager = [MDConfigManager sharedInstance]; 68 | NSDictionary* content = [configManager readConfigByKey:MDCONFIG_TRACE_KEY]; 69 | 70 | if(content && [content valueForKey:MDCONFIG_ENABLE_KEY] && [content[MDCONFIG_ENABLE_KEY] boolValue]){ 71 | NSDictionary* classListDictionary = [content valueForKey:MDCONFIG_CLASS_LIST]; 72 | if(classListDictionary && classListDictionary.count > 0){ 73 | for (NSString* className in classListDictionary.allKeys) { 74 | Class targetClass = objc_getClass([className UTF8String]); 75 | if(targetClass != nil){ 76 | id methodList = [classListDictionary valueForKey:className]; 77 | if([methodList isKindOfClass:[NSArray class]]){ 78 | [MDMethodTrace addClassTrace:className methodList:methodList]; 79 | }else{ 80 | [MDMethodTrace addClassTrace:className]; 81 | } 82 | }else{ 83 | MDLog(@"Canot find class %@", className); 84 | } 85 | } 86 | } 87 | }else{ 88 | MDLog(@"Method Trace is disabled"); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttackDylib/AntiAntiDebug/AntiAntiDebug.m: -------------------------------------------------------------------------------- 1 | // weibo: http://weibo.com/xiaoqing28 2 | // blog: http://www.alonemonkey.com 3 | // 4 | // AntiAntiDebug.m 5 | // MonkeyDev 6 | // 7 | // Created by AloneMonkey on 2016/12/10. 8 | // Copyright © 2017年 MonkeyDev. All rights reserved. 9 | // 10 | 11 | #if TARGET_OS_SIMULATOR 12 | #error Do not support the simulator, please use the real iPhone Device. 13 | #endif 14 | 15 | #import "fishhook.h" 16 | #import 17 | #import 18 | 19 | typedef int (*ptrace_ptr_t)(int _request,pid_t _pid, caddr_t _addr,int _data); 20 | typedef void* (*dlsym_ptr_t)(void * __handle, const char* __symbol); 21 | typedef int (*syscall_ptr_t)(int, ...); 22 | typedef int (*sysctl_ptr_t)(int *,u_int, void*, size_t*,void*, size_t); 23 | 24 | 25 | static ptrace_ptr_t orig_ptrace = NULL; 26 | static dlsym_ptr_t orig_dlsym = NULL; 27 | static sysctl_ptr_t orig_sysctl = NULL; 28 | static syscall_ptr_t orig_syscall = NULL; 29 | 30 | int my_ptrace(int _request, pid_t _pid, caddr_t _addr, int _data); 31 | void* my_dlsym(void* __handle, const char* __symbol); 32 | int my_sysctl(int * name, u_int namelen, void * info, size_t * infosize, void * newinfo, size_t newinfosize); 33 | int my_syscall(int code, va_list args); 34 | 35 | int my_ptrace(int _request, pid_t _pid, caddr_t _addr, int _data){ 36 | if(_request != 31){ 37 | return orig_ptrace(_request,_pid,_addr,_data); 38 | } 39 | 40 | NSLog(@"[AntiAntiDebug] - ptrace request is PT_DENY_ATTACH"); 41 | 42 | return 0; 43 | } 44 | 45 | void* my_dlsym(void* __handle, const char* __symbol){ 46 | if(strcmp(__symbol, "ptrace") != 0){ 47 | return orig_dlsym(__handle, __symbol); 48 | } 49 | 50 | NSLog(@"[AntiAntiDebug] - dlsym get ptrace symbol"); 51 | 52 | return my_ptrace; 53 | } 54 | 55 | typedef struct kinfo_proc _kinfo_proc; 56 | 57 | int my_sysctl(int * name, u_int namelen, void * info, size_t * infosize, void * newinfo, size_t newinfosize){ 58 | if(namelen == 4 && name[0] == CTL_KERN && name[1] == KERN_PROC && name[2] == KERN_PROC_PID && info && infosize && ((int)*infosize == sizeof(_kinfo_proc))){ 59 | int ret = orig_sysctl(name, namelen, info, infosize, newinfo, newinfosize); 60 | struct kinfo_proc *info_ptr = (struct kinfo_proc *)info; 61 | if(info_ptr && (info_ptr->kp_proc.p_flag & P_TRACED) != 0){ 62 | NSLog(@"[AntiAntiDebug] - sysctl query trace status."); 63 | info_ptr->kp_proc.p_flag ^= P_TRACED; 64 | if((info_ptr->kp_proc.p_flag & P_TRACED) == 0){ 65 | NSLog(@"trace status reomve success!"); 66 | } 67 | } 68 | return ret; 69 | } 70 | return orig_sysctl(name, namelen, info, infosize, newinfo, newinfosize); 71 | } 72 | 73 | int my_syscall(int code, va_list args){ 74 | int request; 75 | va_list newArgs; 76 | va_copy(newArgs, args); 77 | if(code == 26){ 78 | #ifdef __LP64__ 79 | __asm__( 80 | "ldr %w[result], [fp, #0x10]\n" 81 | : [result] "=r" (request) 82 | : 83 | : 84 | ); 85 | #else 86 | request = va_arg(args, int); 87 | #endif 88 | if(request == 31){ 89 | NSLog(@"[AntiAntiDebug] - syscall call ptrace, and request is PT_DENY_ATTACH"); 90 | return 0; 91 | } 92 | } 93 | return orig_syscall(code, newArgs); 94 | } 95 | 96 | __attribute__((constructor)) static void entry(){ 97 | NSLog(@"[AntiAntiDebug Init]"); 98 | 99 | rebind_symbols((struct rebinding[1]){{"ptrace", my_ptrace, (void*)&orig_ptrace}},1); 100 | 101 | rebind_symbols((struct rebinding[1]){{"dlsym", my_dlsym, (void*)&orig_dlsym}},1); 102 | 103 | //some app will crash with _dyld_debugger_notification 104 | // rebind_symbols((struct rebinding[1]){{"sysctl", my_sysctl, (void*)&orig_sysctl}},1); 105 | 106 | rebind_symbols((struct rebinding[1]){{"syscall", my_syscall, (void*)&orig_syscall}},1); 107 | } 108 | 109 | -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttackDylib/Logos/ZXHookAttackDylib.mm: -------------------------------------------------------------------------------- 1 | #line 1 "/Users/lzx/Desktop/程序/ZXHookAttack/ZXHookAttackDylib/Logos/ZXHookAttackDylib.xm" 2 | 3 | 4 | 5 | #include 6 | #if defined(__clang__) 7 | #if __has_feature(objc_arc) 8 | #define _LOGOS_SELF_TYPE_NORMAL __unsafe_unretained 9 | #define _LOGOS_SELF_TYPE_INIT __attribute__((ns_consumed)) 10 | #define _LOGOS_SELF_CONST const 11 | #define _LOGOS_RETURN_RETAINED __attribute__((ns_returns_retained)) 12 | #else 13 | #define _LOGOS_SELF_TYPE_NORMAL 14 | #define _LOGOS_SELF_TYPE_INIT 15 | #define _LOGOS_SELF_CONST 16 | #define _LOGOS_RETURN_RETAINED 17 | #endif 18 | #else 19 | #define _LOGOS_SELF_TYPE_NORMAL 20 | #define _LOGOS_SELF_TYPE_INIT 21 | #define _LOGOS_SELF_CONST 22 | #define _LOGOS_RETURN_RETAINED 23 | #endif 24 | 25 | @class NSFileManager; @class NSBundle; @class ViewController; 26 | static void (*_logos_orig$_ungrouped$ViewController$viewDidLoad)(_LOGOS_SELF_TYPE_NORMAL ViewController* _LOGOS_SELF_CONST, SEL); static void _logos_method$_ungrouped$ViewController$viewDidLoad(_LOGOS_SELF_TYPE_NORMAL ViewController* _LOGOS_SELF_CONST, SEL); static id (*_logos_orig$_ungrouped$NSBundle$bundleIdentifier)(_LOGOS_SELF_TYPE_NORMAL NSBundle* _LOGOS_SELF_CONST, SEL); static id _logos_method$_ungrouped$NSBundle$bundleIdentifier(_LOGOS_SELF_TYPE_NORMAL NSBundle* _LOGOS_SELF_CONST, SEL); static BOOL (*_logos_orig$_ungrouped$NSFileManager$fileExistsAtPath$)(_LOGOS_SELF_TYPE_NORMAL NSFileManager* _LOGOS_SELF_CONST, SEL, NSString *); static BOOL _logos_method$_ungrouped$NSFileManager$fileExistsAtPath$(_LOGOS_SELF_TYPE_NORMAL NSFileManager* _LOGOS_SELF_CONST, SEL, NSString *); 27 | 28 | #line 3 "/Users/lzx/Desktop/程序/ZXHookAttack/ZXHookAttackDylib/Logos/ZXHookAttackDylib.xm" 29 | #import 30 | #import "fishhook.h" 31 | #import "StatHook.h" 32 | static __attribute__((constructor)) void _logosLocalCtor_6abe01d2(int __unused argc, char __unused **argv, char __unused **envp){ 33 | [StatHook statHook]; 34 | NSLog(@"AttackHookLoaded"); 35 | } 36 | @interface ViewController:UIViewController 37 | 38 | @end 39 | 40 | 41 | static void _logos_method$_ungrouped$ViewController$viewDidLoad(_LOGOS_SELF_TYPE_NORMAL ViewController* _LOGOS_SELF_CONST __unused self, SEL __unused _cmd){ 42 | 43 | self.view.backgroundColor = [UIColor redColor]; 44 | } 45 | 46 | 47 | 48 | static id _logos_method$_ungrouped$NSBundle$bundleIdentifier(_LOGOS_SELF_TYPE_NORMAL NSBundle* _LOGOS_SELF_CONST __unused self, SEL __unused _cmd){ 49 | NSArray *address = [NSThread callStackReturnAddresses]; 50 | Dl_info info = {0}; 51 | if(dladdr((void *)[address[2] longLongValue], &info) == 0) { 52 | return _logos_orig$_ungrouped$NSBundle$bundleIdentifier(self, _cmd); 53 | } 54 | NSString *path = [NSString stringWithUTF8String:info.dli_fname]; 55 | if ([path hasPrefix:NSBundle.mainBundle.bundlePath]) { 56 | NSLog(@"getBundleIdentifier"); 57 | return @"cn.newBundelId"; 58 | } else { 59 | return _logos_orig$_ungrouped$NSBundle$bundleIdentifier(self, _cmd); 60 | } 61 | } 62 | 63 | 64 | 65 | 66 | static BOOL _logos_method$_ungrouped$NSFileManager$fileExistsAtPath$(_LOGOS_SELF_TYPE_NORMAL NSFileManager* _LOGOS_SELF_CONST __unused self, SEL __unused _cmd, NSString * path){ 67 | for (int i = 0;i < sizeof(JailbrokenPathArr) / sizeof(char *);i++) { 68 | NSString *jPath = [NSString stringWithUTF8String:JailbrokenPathArr[i]]; 69 | if([path isEqualToString:jPath]){ 70 | return NO; 71 | } 72 | } 73 | return YES; 74 | } 75 | 76 | 77 | static __attribute__((constructor)) void _logosLocalInit() { 78 | {Class _logos_class$_ungrouped$ViewController = objc_getClass("ViewController"); MSHookMessageEx(_logos_class$_ungrouped$ViewController, @selector(viewDidLoad), (IMP)&_logos_method$_ungrouped$ViewController$viewDidLoad, (IMP*)&_logos_orig$_ungrouped$ViewController$viewDidLoad);Class _logos_class$_ungrouped$NSBundle = objc_getClass("NSBundle"); MSHookMessageEx(_logos_class$_ungrouped$NSBundle, @selector(bundleIdentifier), (IMP)&_logos_method$_ungrouped$NSBundle$bundleIdentifier, (IMP*)&_logos_orig$_ungrouped$NSBundle$bundleIdentifier);Class _logos_class$_ungrouped$NSFileManager = objc_getClass("NSFileManager"); MSHookMessageEx(_logos_class$_ungrouped$NSFileManager, @selector(fileExistsAtPath:), (IMP)&_logos_method$_ungrouped$NSFileManager$fileExistsAtPath$, (IMP*)&_logos_orig$_ungrouped$NSFileManager$fileExistsAtPath$);} } 79 | #line 51 "/Users/lzx/Desktop/程序/ZXHookAttack/ZXHookAttackDylib/Logos/ZXHookAttackDylib.xm" 80 | -------------------------------------------------------------------------------- /ZXHookDetection/ZXHookDetection/ZXHookDetection/ZXHookDetection.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZXHookDetection.m 3 | // ZXHookDetection 4 | // 5 | // Created by 李兆祥 on 2019/4/20. 6 | // Copyright © 2019 李兆祥. All rights reserved. 7 | // https://github.com/SmileZXLee/ZXHookDetection 8 | 9 | #import "ZXHookDetection.h" 10 | #import "fishhook.h" 11 | #import 12 | #include 13 | #import 14 | #import 15 | #import 16 | #import 17 | #import 18 | 19 | static char *JailbrokenPathArr[] = {"/Applications/Cydia.app","/usr/sbin/sshd","/bin/bash","/etc/apt","/Library/MobileSubstrate","/User/Applications/"}; 20 | @implementation ZXHookDetection 21 | #pragma mark - 越狱检测 22 | #pragma mark 使用NSFileManager通过检测一些越狱后的关键文件是否可以访问来判断是否越狱 23 | + (BOOL)isJailbroken1{ 24 | if(TARGET_IPHONE_SIMULATOR)return NO; 25 | for (int i = 0;i < sizeof(JailbrokenPathArr) / sizeof(char *);i++) { 26 | if([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithUTF8String:JailbrokenPathArr[i]]]){ 27 | return YES; 28 | } 29 | } 30 | return NO; 31 | } 32 | #pragma mark 使用stat通过检测一些越狱后的关键文件是否可以访问来判断是否越狱 33 | + (BOOL)isJailbroken2{ 34 | 35 | if(TARGET_IPHONE_SIMULATOR)return NO; 36 | int ret ; 37 | Dl_info dylib_info; 38 | int (*func_stat)(const char *, struct stat *) = stat; 39 | if ((ret = dladdr(func_stat, &dylib_info))) { 40 | NSString *fName = [NSString stringWithUTF8String:dylib_info.dli_fname]; 41 | NSLog(@"fname--%@",fName); 42 | if(![fName isEqualToString:@"/usr/lib/system/libsystem_kernel.dylib"]){ 43 | return YES; 44 | } 45 | } 46 | 47 | for (int i = 0;i < sizeof(JailbrokenPathArr) / sizeof(char *);i++) { 48 | struct stat stat_info; 49 | if (0 == stat(JailbrokenPathArr[i], &stat_info)) { 50 | return YES; 51 | } 52 | } 53 | 54 | return NO; 55 | } 56 | 57 | #pragma mark 通过环境变量DYLD_INSERT_LIBRARIES检测是否越狱 58 | + (BOOL)isJailbroken3{ 59 | if(TARGET_IPHONE_SIMULATOR)return NO; 60 | return !(NULL == getenv("DYLD_INSERT_LIBRARIES")); 61 | } 62 | 63 | #pragma mark - 通过遍历dyld_image检测非法注入的动态库 64 | + (BOOL)isExternalLibs{ 65 | if(TARGET_IPHONE_SIMULATOR)return NO; 66 | int dyld_count = _dyld_image_count(); 67 | for (int i = 0; i < dyld_count; i++) { 68 | const char * imageName = _dyld_get_image_name(i); 69 | NSString *res = [NSString stringWithUTF8String:imageName]; 70 | if([res hasPrefix:@"/var/containers/Bundle/Application"]){ 71 | if([res hasSuffix:@".dylib"]){ 72 | //这边还需要过滤掉自己项目中本身有的动态库 73 | return YES; 74 | } 75 | } 76 | } 77 | return NO; 78 | } 79 | 80 | #pragma mark - 通过检测ipa中的embedded.mobileprovision中的我们打包Mac的公钥来确定是否签名被修改,但是需要注意的是此方法只适用于Ad Hoc或企业证书打包的情况,App Store上应用由苹果私钥统一打包,不存在embedded.mobileprovision文件 81 | + (BOOL)isLegalPublicKey:(NSString *)publicKey{ 82 | if(TARGET_IPHONE_SIMULATOR)return YES; 83 | //来源于https://www.jianshu.com/p/a3fc10c70a29 84 | NSString *embeddedPath = [[NSBundle mainBundle] pathForResource:@"embedded" ofType:@"mobileprovision"]; 85 | NSString *embeddedProvisioning = [NSString stringWithContentsOfFile:embeddedPath encoding:NSASCIIStringEncoding error:nil]; 86 | NSArray *embeddedProvisioningLines = [embeddedProvisioning componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]]; 87 | for (int i = 0; i < embeddedProvisioningLines.count; i++) { 88 | if ([embeddedProvisioningLines[i] rangeOfString:@"application-identifier"].location != NSNotFound) { 89 | NSInteger fromPosition = [embeddedProvisioningLines[i+1] rangeOfString:@""].location+8; 90 | 91 | NSInteger toPosition = [embeddedProvisioningLines[i+1] rangeOfString:@""].location; 92 | NSRange range; 93 | range.location = fromPosition; 94 | range.length = toPosition - fromPosition; 95 | NSString *fullIdentifier = [embeddedProvisioningLines[i+1] substringWithRange:range]; 96 | NSArray *identifierComponents = [fullIdentifier componentsSeparatedByString:@"."]; 97 | NSString *appIdentifier = [identifierComponents firstObject]; 98 | NSLog(@"appIdentifier--%@",appIdentifier); 99 | if (![appIdentifier isEqualToString:publicKey]) { 100 | return NO; 101 | } 102 | } 103 | } 104 | return YES; 105 | } 106 | @end 107 | -------------------------------------------------------------------------------- /ZXHookDetection/ZXHookDetection.xcodeproj/xcshareddata/xcschemes/ZXHookDetection.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 53 | 59 | 60 | 61 | 62 | 63 | 69 | 70 | 71 | 72 | 73 | 74 | 84 | 86 | 92 | 93 | 94 | 95 | 96 | 97 | 103 | 105 | 111 | 112 | 113 | 114 | 116 | 117 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttack/TargetApp/ZXHookDetection.app/_CodeSignature/CodeResources: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | files 6 | 7 | Base.lproj/LaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib 8 | 9 | TmTPa23pLn2rdPQ7FkC0FJSL1t8= 10 | 11 | Base.lproj/LaunchScreen.storyboardc/Info.plist 12 | 13 | n2t8gsDpfE6XkhG31p7IQJRxTxU= 14 | 15 | Base.lproj/LaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib 16 | 17 | fRYoqpoeUk2nBokqCqDapxr9fV4= 18 | 19 | Base.lproj/Main.storyboardc/BYZ-38-t0r-view-8bC-Xf-vdC.nib 20 | 21 | /vUfui32dQlQddJZ1J/C32pxojQ= 22 | 23 | Base.lproj/Main.storyboardc/Info.plist 24 | 25 | MDrKFvFWroTb0+KEbQShBcoBvo4= 26 | 27 | Base.lproj/Main.storyboardc/UIViewController-BYZ-38-t0r.nib 28 | 29 | KVMMURK5cvCXJkw6T34C93zSUFs= 30 | 31 | Frameworks/ZXHookFramework.framework/Info.plist 32 | 33 | GqYWse08orwGDq1r3yMFHn1s+a4= 34 | 35 | Frameworks/ZXHookFramework.framework/ZXHookFramework 36 | 37 | CnWLCyD+GNBcauntAEh/2qBdTsU= 38 | 39 | Frameworks/ZXHookFramework.framework/_CodeSignature/CodeResources 40 | 41 | bsryG0OJJY5eESV3m4fNGiv31Rc= 42 | 43 | Info.plist 44 | 45 | w9lk5sDv/rJQh0IQagIgBqzrpCE= 46 | 47 | PkgInfo 48 | 49 | n57qDP4tZfLD1rCS43W0B4LQjzE= 50 | 51 | embedded.mobileprovision 52 | 53 | OE0OoziHaErvLstF1DcNS7iEpW0= 54 | 55 | 56 | files2 57 | 58 | Base.lproj/LaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib 59 | 60 | hash 61 | 62 | TmTPa23pLn2rdPQ7FkC0FJSL1t8= 63 | 64 | hash2 65 | 66 | iGWP6nvdG/L1KldcIXIABs8r8cl16HdNgIIzZs1r4Rk= 67 | 68 | 69 | Base.lproj/LaunchScreen.storyboardc/Info.plist 70 | 71 | hash 72 | 73 | n2t8gsDpfE6XkhG31p7IQJRxTxU= 74 | 75 | hash2 76 | 77 | HyVdXMU7Ux4/KalAao30mpWOK/lEPT4gvYN09wf31cg= 78 | 79 | 80 | Base.lproj/LaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib 81 | 82 | hash 83 | 84 | fRYoqpoeUk2nBokqCqDapxr9fV4= 85 | 86 | hash2 87 | 88 | ck8o8b9nazTwiAyKop8GqXAsSN3EA8iXFHlOz6BXQU8= 89 | 90 | 91 | Base.lproj/Main.storyboardc/BYZ-38-t0r-view-8bC-Xf-vdC.nib 92 | 93 | hash 94 | 95 | /vUfui32dQlQddJZ1J/C32pxojQ= 96 | 97 | hash2 98 | 99 | SWlwgkqUCnjSgtohizqUp20BCILI5mLgBZAMEb/sEU8= 100 | 101 | 102 | Base.lproj/Main.storyboardc/Info.plist 103 | 104 | hash 105 | 106 | MDrKFvFWroTb0+KEbQShBcoBvo4= 107 | 108 | hash2 109 | 110 | PpvapAjR62rl6Ym4E6hkTgpKmBICxTaQXeUqcpHmmqQ= 111 | 112 | 113 | Base.lproj/Main.storyboardc/UIViewController-BYZ-38-t0r.nib 114 | 115 | hash 116 | 117 | KVMMURK5cvCXJkw6T34C93zSUFs= 118 | 119 | hash2 120 | 121 | cJBuYrobbbuBzo/OFbxTl/I/IAYAYt/PJZX3aB+dYW0= 122 | 123 | 124 | Frameworks/ZXHookFramework.framework/Info.plist 125 | 126 | hash 127 | 128 | GqYWse08orwGDq1r3yMFHn1s+a4= 129 | 130 | hash2 131 | 132 | uaOEpvbsKs4O27yFRpr8gjcCJTozonoVPWstEkGmg0k= 133 | 134 | 135 | Frameworks/ZXHookFramework.framework/ZXHookFramework 136 | 137 | hash 138 | 139 | CnWLCyD+GNBcauntAEh/2qBdTsU= 140 | 141 | hash2 142 | 143 | +s9d0fBtrkp5dkfTsH1s5tE8irlc38iv8fvG7LXnMH4= 144 | 145 | 146 | Frameworks/ZXHookFramework.framework/_CodeSignature/CodeResources 147 | 148 | hash 149 | 150 | bsryG0OJJY5eESV3m4fNGiv31Rc= 151 | 152 | hash2 153 | 154 | bVl1LMjgCllAusjzt6d+OxmErunO5LL6hHsphyGHbO0= 155 | 156 | 157 | embedded.mobileprovision 158 | 159 | hash 160 | 161 | OE0OoziHaErvLstF1DcNS7iEpW0= 162 | 163 | hash2 164 | 165 | f72dkopwqC9EpsJrVgh+etoQzQX4aFZg+E+RuOuUDWE= 166 | 167 | 168 | 169 | rules 170 | 171 | ^.* 172 | 173 | ^.*\.lproj/ 174 | 175 | optional 176 | 177 | weight 178 | 1000 179 | 180 | ^.*\.lproj/locversion.plist$ 181 | 182 | omit 183 | 184 | weight 185 | 1100 186 | 187 | ^Base\.lproj/ 188 | 189 | weight 190 | 1010 191 | 192 | ^version.plist$ 193 | 194 | 195 | rules2 196 | 197 | .*\.dSYM($|/) 198 | 199 | weight 200 | 11 201 | 202 | ^(.*/)?\.DS_Store$ 203 | 204 | omit 205 | 206 | weight 207 | 2000 208 | 209 | ^.* 210 | 211 | ^.*\.lproj/ 212 | 213 | optional 214 | 215 | weight 216 | 1000 217 | 218 | ^.*\.lproj/locversion.plist$ 219 | 220 | omit 221 | 222 | weight 223 | 1100 224 | 225 | ^Base\.lproj/ 226 | 227 | weight 228 | 1010 229 | 230 | ^Info\.plist$ 231 | 232 | omit 233 | 234 | weight 235 | 20 236 | 237 | ^PkgInfo$ 238 | 239 | omit 240 | 241 | weight 242 | 20 243 | 244 | ^embedded\.provisionprofile$ 245 | 246 | weight 247 | 20 248 | 249 | ^version\.plist$ 250 | 251 | weight 252 | 20 253 | 254 | 255 | 256 | 257 | -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttackDylib/fishhook/fishhook.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013, Facebook, Inc. 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // * Redistributions of source code must retain the above copyright notice, 6 | // this list of conditions and the following disclaimer. 7 | // * Redistributions in binary form must reproduce the above copyright notice, 8 | // this list of conditions and the following disclaimer in the documentation 9 | // and/or other materials provided with the distribution. 10 | // * Neither the name Facebook nor the names of its contributors may be used to 11 | // endorse or promote products derived from this software without specific 12 | // prior written permission. 13 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 14 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 17 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 21 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | 24 | #import "fishhook.h" 25 | 26 | #import 27 | #import 28 | #import 29 | #import 30 | #import 31 | #import 32 | #import 33 | 34 | #ifdef __LP64__ 35 | typedef struct mach_header_64 mach_header_t; 36 | typedef struct segment_command_64 segment_command_t; 37 | typedef struct section_64 section_t; 38 | typedef struct nlist_64 nlist_t; 39 | #define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT_64 40 | #else 41 | typedef struct mach_header mach_header_t; 42 | typedef struct segment_command segment_command_t; 43 | typedef struct section section_t; 44 | typedef struct nlist nlist_t; 45 | #define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT 46 | #endif 47 | 48 | #ifndef SEG_DATA_CONST 49 | #define SEG_DATA_CONST "__DATA_CONST" 50 | #endif 51 | 52 | struct rebindings_entry { 53 | struct rebinding *rebindings; 54 | size_t rebindings_nel; 55 | struct rebindings_entry *next; 56 | }; 57 | 58 | static struct rebindings_entry *_rebindings_head; 59 | 60 | static int prepend_rebindings(struct rebindings_entry **rebindings_head, 61 | struct rebinding rebindings[], 62 | size_t nel) { 63 | struct rebindings_entry *new_entry = (struct rebindings_entry *) malloc(sizeof(struct rebindings_entry)); 64 | if (!new_entry) { 65 | return -1; 66 | } 67 | new_entry->rebindings = (struct rebinding *) malloc(sizeof(struct rebinding) * nel); 68 | if (!new_entry->rebindings) { 69 | free(new_entry); 70 | return -1; 71 | } 72 | memcpy(new_entry->rebindings, rebindings, sizeof(struct rebinding) * nel); 73 | new_entry->rebindings_nel = nel; 74 | new_entry->next = *rebindings_head; 75 | *rebindings_head = new_entry; 76 | return 0; 77 | } 78 | 79 | static void perform_rebinding_with_section(struct rebindings_entry *rebindings, 80 | section_t *section, 81 | intptr_t slide, 82 | nlist_t *symtab, 83 | char *strtab, 84 | uint32_t *indirect_symtab) { 85 | uint32_t *indirect_symbol_indices = indirect_symtab + section->reserved1; 86 | void **indirect_symbol_bindings = (void **)((uintptr_t)slide + section->addr); 87 | for (uint i = 0; i < section->size / sizeof(void *); i++) { 88 | uint32_t symtab_index = indirect_symbol_indices[i]; 89 | if (symtab_index == INDIRECT_SYMBOL_ABS || symtab_index == INDIRECT_SYMBOL_LOCAL || 90 | symtab_index == (INDIRECT_SYMBOL_LOCAL | INDIRECT_SYMBOL_ABS)) { 91 | continue; 92 | } 93 | uint32_t strtab_offset = symtab[symtab_index].n_un.n_strx; 94 | char *symbol_name = strtab + strtab_offset; 95 | if (strnlen(symbol_name, 2) < 2) { 96 | continue; 97 | } 98 | struct rebindings_entry *cur = rebindings; 99 | while (cur) { 100 | for (uint j = 0; j < cur->rebindings_nel; j++) { 101 | if (strcmp(&symbol_name[1], cur->rebindings[j].name) == 0) { 102 | if (cur->rebindings[j].replaced != NULL && 103 | indirect_symbol_bindings[i] != cur->rebindings[j].replacement) { 104 | *(cur->rebindings[j].replaced) = indirect_symbol_bindings[i]; 105 | } 106 | indirect_symbol_bindings[i] = cur->rebindings[j].replacement; 107 | goto symbol_loop; 108 | } 109 | } 110 | cur = cur->next; 111 | } 112 | symbol_loop:; 113 | } 114 | } 115 | 116 | static void rebind_symbols_for_image(struct rebindings_entry *rebindings, 117 | const struct mach_header *header, 118 | intptr_t slide) { 119 | Dl_info info; 120 | if (dladdr(header, &info) == 0) { 121 | return; 122 | } 123 | 124 | segment_command_t *cur_seg_cmd; 125 | segment_command_t *linkedit_segment = NULL; 126 | struct symtab_command* symtab_cmd = NULL; 127 | struct dysymtab_command* dysymtab_cmd = NULL; 128 | 129 | uintptr_t cur = (uintptr_t)header + sizeof(mach_header_t); 130 | for (uint i = 0; i < header->ncmds; i++, cur += cur_seg_cmd->cmdsize) { 131 | cur_seg_cmd = (segment_command_t *)cur; 132 | if (cur_seg_cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) { 133 | if (strcmp(cur_seg_cmd->segname, SEG_LINKEDIT) == 0) { 134 | linkedit_segment = cur_seg_cmd; 135 | } 136 | } else if (cur_seg_cmd->cmd == LC_SYMTAB) { 137 | symtab_cmd = (struct symtab_command*)cur_seg_cmd; 138 | } else if (cur_seg_cmd->cmd == LC_DYSYMTAB) { 139 | dysymtab_cmd = (struct dysymtab_command*)cur_seg_cmd; 140 | } 141 | } 142 | 143 | if (!symtab_cmd || !dysymtab_cmd || !linkedit_segment || 144 | !dysymtab_cmd->nindirectsyms) { 145 | return; 146 | } 147 | 148 | // Find base symbol/string table addresses 149 | uintptr_t linkedit_base = (uintptr_t)slide + linkedit_segment->vmaddr - linkedit_segment->fileoff; 150 | nlist_t *symtab = (nlist_t *)(linkedit_base + symtab_cmd->symoff); 151 | char *strtab = (char *)(linkedit_base + symtab_cmd->stroff); 152 | 153 | // Get indirect symbol table (array of uint32_t indices into symbol table) 154 | uint32_t *indirect_symtab = (uint32_t *)(linkedit_base + dysymtab_cmd->indirectsymoff); 155 | 156 | cur = (uintptr_t)header + sizeof(mach_header_t); 157 | for (uint i = 0; i < header->ncmds; i++, cur += cur_seg_cmd->cmdsize) { 158 | cur_seg_cmd = (segment_command_t *)cur; 159 | if (cur_seg_cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) { 160 | if (strcmp(cur_seg_cmd->segname, SEG_DATA) != 0 && 161 | strcmp(cur_seg_cmd->segname, SEG_DATA_CONST) != 0) { 162 | continue; 163 | } 164 | for (uint j = 0; j < cur_seg_cmd->nsects; j++) { 165 | section_t *sect = 166 | (section_t *)(cur + sizeof(segment_command_t)) + j; 167 | if ((sect->flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS) { 168 | perform_rebinding_with_section(rebindings, sect, slide, symtab, strtab, indirect_symtab); 169 | } 170 | if ((sect->flags & SECTION_TYPE) == S_NON_LAZY_SYMBOL_POINTERS) { 171 | perform_rebinding_with_section(rebindings, sect, slide, symtab, strtab, indirect_symtab); 172 | } 173 | } 174 | } 175 | } 176 | } 177 | 178 | static void _rebind_symbols_for_image(const struct mach_header *header, 179 | intptr_t slide) { 180 | rebind_symbols_for_image(_rebindings_head, header, slide); 181 | } 182 | 183 | int rebind_symbols_image(void *header, 184 | intptr_t slide, 185 | struct rebinding rebindings[], 186 | size_t rebindings_nel) { 187 | struct rebindings_entry *rebindings_head = NULL; 188 | int retval = prepend_rebindings(&rebindings_head, rebindings, rebindings_nel); 189 | rebind_symbols_for_image(rebindings_head, (const struct mach_header *) header, slide); 190 | free(rebindings_head); 191 | return retval; 192 | } 193 | 194 | int rebind_symbols(struct rebinding rebindings[], size_t rebindings_nel) { 195 | int retval = prepend_rebindings(&_rebindings_head, rebindings, rebindings_nel); 196 | if (retval < 0) { 197 | return retval; 198 | } 199 | // If this was the first call, register callback for image additions (which is also invoked for 200 | // existing images, otherwise, just run on existing images 201 | if (!_rebindings_head->next) { 202 | _dyld_register_func_for_add_image(_rebind_symbols_for_image); 203 | } else { 204 | uint32_t c = _dyld_image_count(); 205 | for (uint32_t i = 0; i < c; i++) { 206 | _rebind_symbols_for_image(_dyld_get_image_header(i), _dyld_get_image_vmaddr_slide(i)); 207 | } 208 | } 209 | return retval; 210 | } 211 | -------------------------------------------------------------------------------- /ZXHookDetection/ZXHookFramework/fishhook.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013, Facebook, Inc. 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // * Redistributions of source code must retain the above copyright notice, 6 | // this list of conditions and the following disclaimer. 7 | // * Redistributions in binary form must reproduce the above copyright notice, 8 | // this list of conditions and the following disclaimer in the documentation 9 | // and/or other materials provided with the distribution. 10 | // * Neither the name Facebook nor the names of its contributors may be used to 11 | // endorse or promote products derived from this software without specific 12 | // prior written permission. 13 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 14 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 17 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 21 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | 24 | #include "fishhook.h" 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #ifdef __LP64__ 35 | typedef struct mach_header_64 mach_header_t; 36 | typedef struct segment_command_64 segment_command_t; 37 | typedef struct section_64 section_t; 38 | typedef struct nlist_64 nlist_t; 39 | #define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT_64 40 | #else 41 | typedef struct mach_header mach_header_t; 42 | typedef struct segment_command segment_command_t; 43 | typedef struct section section_t; 44 | typedef struct nlist nlist_t; 45 | #define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT 46 | #endif 47 | 48 | #ifndef SEG_DATA_CONST 49 | #define SEG_DATA_CONST "__DATA_CONST" 50 | #endif 51 | 52 | struct rebindings_entry { 53 | struct rebinding *rebindings; 54 | size_t rebindings_nel; 55 | struct rebindings_entry *next; 56 | }; 57 | 58 | static struct rebindings_entry *_rebindings_head; 59 | 60 | static int prepend_rebindings(struct rebindings_entry **rebindings_head, 61 | struct rebinding rebindings[], 62 | size_t nel) { 63 | struct rebindings_entry *new_entry = (struct rebindings_entry *) malloc(sizeof(struct rebindings_entry)); 64 | if (!new_entry) { 65 | return -1; 66 | } 67 | new_entry->rebindings = (struct rebinding *) malloc(sizeof(struct rebinding) * nel); 68 | if (!new_entry->rebindings) { 69 | free(new_entry); 70 | return -1; 71 | } 72 | memcpy(new_entry->rebindings, rebindings, sizeof(struct rebinding) * nel); 73 | new_entry->rebindings_nel = nel; 74 | new_entry->next = *rebindings_head; 75 | *rebindings_head = new_entry; 76 | return 0; 77 | } 78 | 79 | static void perform_rebinding_with_section(struct rebindings_entry *rebindings, 80 | section_t *section, 81 | intptr_t slide, 82 | nlist_t *symtab, 83 | char *strtab, 84 | uint32_t *indirect_symtab) { 85 | uint32_t *indirect_symbol_indices = indirect_symtab + section->reserved1; 86 | void **indirect_symbol_bindings = (void **)((uintptr_t)slide + section->addr); 87 | for (uint i = 0; i < section->size / sizeof(void *); i++) { 88 | uint32_t symtab_index = indirect_symbol_indices[i]; 89 | if (symtab_index == INDIRECT_SYMBOL_ABS || symtab_index == INDIRECT_SYMBOL_LOCAL || 90 | symtab_index == (INDIRECT_SYMBOL_LOCAL | INDIRECT_SYMBOL_ABS)) { 91 | continue; 92 | } 93 | uint32_t strtab_offset = symtab[symtab_index].n_un.n_strx; 94 | char *symbol_name = strtab + strtab_offset; 95 | bool symbol_name_longer_than_1 = symbol_name[0] && symbol_name[1]; 96 | struct rebindings_entry *cur = rebindings; 97 | while (cur) { 98 | for (uint j = 0; j < cur->rebindings_nel; j++) { 99 | if (symbol_name_longer_than_1 && 100 | strcmp(&symbol_name[1], cur->rebindings[j].name) == 0) { 101 | if (cur->rebindings[j].replaced != NULL && 102 | indirect_symbol_bindings[i] != cur->rebindings[j].replacement) { 103 | *(cur->rebindings[j].replaced) = indirect_symbol_bindings[i]; 104 | } 105 | indirect_symbol_bindings[i] = cur->rebindings[j].replacement; 106 | goto symbol_loop; 107 | } 108 | } 109 | cur = cur->next; 110 | } 111 | symbol_loop:; 112 | } 113 | } 114 | 115 | static void rebind_symbols_for_image(struct rebindings_entry *rebindings, 116 | const struct mach_header *header, 117 | intptr_t slide) { 118 | Dl_info info; 119 | if (dladdr(header, &info) == 0) { 120 | return; 121 | } 122 | 123 | segment_command_t *cur_seg_cmd; 124 | segment_command_t *linkedit_segment = NULL; 125 | struct symtab_command* symtab_cmd = NULL; 126 | struct dysymtab_command* dysymtab_cmd = NULL; 127 | 128 | uintptr_t cur = (uintptr_t)header + sizeof(mach_header_t); 129 | for (uint i = 0; i < header->ncmds; i++, cur += cur_seg_cmd->cmdsize) { 130 | cur_seg_cmd = (segment_command_t *)cur; 131 | if (cur_seg_cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) { 132 | if (strcmp(cur_seg_cmd->segname, SEG_LINKEDIT) == 0) { 133 | linkedit_segment = cur_seg_cmd; 134 | } 135 | } else if (cur_seg_cmd->cmd == LC_SYMTAB) { 136 | symtab_cmd = (struct symtab_command*)cur_seg_cmd; 137 | } else if (cur_seg_cmd->cmd == LC_DYSYMTAB) { 138 | dysymtab_cmd = (struct dysymtab_command*)cur_seg_cmd; 139 | } 140 | } 141 | 142 | if (!symtab_cmd || !dysymtab_cmd || !linkedit_segment || 143 | !dysymtab_cmd->nindirectsyms) { 144 | return; 145 | } 146 | 147 | // Find base symbol/string table addresses 148 | uintptr_t linkedit_base = (uintptr_t)slide + linkedit_segment->vmaddr - linkedit_segment->fileoff; 149 | nlist_t *symtab = (nlist_t *)(linkedit_base + symtab_cmd->symoff); 150 | char *strtab = (char *)(linkedit_base + symtab_cmd->stroff); 151 | 152 | // Get indirect symbol table (array of uint32_t indices into symbol table) 153 | uint32_t *indirect_symtab = (uint32_t *)(linkedit_base + dysymtab_cmd->indirectsymoff); 154 | 155 | cur = (uintptr_t)header + sizeof(mach_header_t); 156 | for (uint i = 0; i < header->ncmds; i++, cur += cur_seg_cmd->cmdsize) { 157 | cur_seg_cmd = (segment_command_t *)cur; 158 | if (cur_seg_cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) { 159 | if (strcmp(cur_seg_cmd->segname, SEG_DATA) != 0 && 160 | strcmp(cur_seg_cmd->segname, SEG_DATA_CONST) != 0) { 161 | continue; 162 | } 163 | for (uint j = 0; j < cur_seg_cmd->nsects; j++) { 164 | section_t *sect = 165 | (section_t *)(cur + sizeof(segment_command_t)) + j; 166 | if ((sect->flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS) { 167 | perform_rebinding_with_section(rebindings, sect, slide, symtab, strtab, indirect_symtab); 168 | } 169 | if ((sect->flags & SECTION_TYPE) == S_NON_LAZY_SYMBOL_POINTERS) { 170 | perform_rebinding_with_section(rebindings, sect, slide, symtab, strtab, indirect_symtab); 171 | } 172 | } 173 | } 174 | } 175 | } 176 | 177 | static void _rebind_symbols_for_image(const struct mach_header *header, 178 | intptr_t slide) { 179 | rebind_symbols_for_image(_rebindings_head, header, slide); 180 | } 181 | 182 | int rebind_symbols_image(void *header, 183 | intptr_t slide, 184 | struct rebinding rebindings[], 185 | size_t rebindings_nel) { 186 | struct rebindings_entry *rebindings_head = NULL; 187 | int retval = prepend_rebindings(&rebindings_head, rebindings, rebindings_nel); 188 | rebind_symbols_for_image(rebindings_head, (const struct mach_header *) header, slide); 189 | if (rebindings_head) { 190 | free(rebindings_head->rebindings); 191 | } 192 | free(rebindings_head); 193 | return retval; 194 | } 195 | 196 | int rebind_symbols(struct rebinding rebindings[], size_t rebindings_nel) { 197 | int retval = prepend_rebindings(&_rebindings_head, rebindings, rebindings_nel); 198 | if (retval < 0) { 199 | return retval; 200 | } 201 | // If this was the first call, register callback for image additions (which is also invoked for 202 | // existing images, otherwise, just run on existing images 203 | if (!_rebindings_head->next) { 204 | _dyld_register_func_for_add_image(_rebind_symbols_for_image); 205 | } else { 206 | uint32_t c = _dyld_image_count(); 207 | for (uint32_t i = 0; i < c; i++) { 208 | _rebind_symbols_for_image(_dyld_get_image_header(i), _dyld_get_image_vmaddr_slide(i)); 209 | } 210 | } 211 | return retval; 212 | } 213 | -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttackDylib/Config/MDCycriptManager.m: -------------------------------------------------------------------------------- 1 | // weibo: http://weibo.com/xiaoqing28 2 | // blog: http://www.alonemonkey.com 3 | // 4 | // MDCycriptManager.m 5 | // MonkeyDev 6 | // 7 | // Created by AloneMonkey on 2018/3/8. 8 | // Copyright © 2018年 AloneMonkey. All rights reserved. 9 | // 10 | 11 | #ifndef __OPTIMIZE__ 12 | 13 | #import "MDCycriptManager.h" 14 | #import "MDConfigManager.h" 15 | #import 16 | #import 17 | #import 18 | #import 19 | 20 | #define IOS_CELLULAR @"pdp_ip0" 21 | #define IOS_WIFI @"en0" 22 | #define IP_ADDR_IPv4 @"ipv4" 23 | #define IP_ADDR_IPv6 @"ipv6" 24 | #define MDLog(fmt, ...) NSLog((@"[Cycript] " fmt), ##__VA_ARGS__) 25 | 26 | extern JSGlobalContextRef CYGetJSContext(void); 27 | extern void CydgetMemoryParse(const uint16_t **data, size_t *size); 28 | 29 | NSString * const CYErrorLineKey = @"CYErrorLineKey"; 30 | NSString * const CYErrorNameKey = @"CYErrorNameKey"; 31 | NSString * const CYErrorMessageKey = @"CYErrorMessageKey"; 32 | 33 | @interface MDSettingObject : NSObject 34 | 35 | @property (nonatomic, assign) NSInteger priority; 36 | @property (nonatomic, copy) NSString* url; 37 | @property (nonatomic, copy) NSString* content; 38 | @property (nonatomic, assign) BOOL loadAtLaunch; 39 | 40 | -(instancetype)initWithDicationary:(NSDictionary*) dictionary; 41 | 42 | @end 43 | 44 | @implementation MDSettingObject 45 | 46 | -(instancetype)initWithDicationary:(NSDictionary *)dictionary{ 47 | self = [super init]; 48 | if(self){ 49 | self.priority = [dictionary[@"priority"] integerValue]; 50 | self.url = dictionary[@"url"]; 51 | self.content = dictionary[@"content"]; 52 | self.loadAtLaunch = [dictionary objectForKey:MDCONFIG_LOADATLAUNCH_KEY] && [dictionary[MDCONFIG_LOADATLAUNCH_KEY] boolValue]; 53 | } 54 | return self; 55 | } 56 | 57 | @end 58 | 59 | @interface MDCycriptManager() 60 | 61 | @property (nonatomic, strong) NSDictionary* configItem; 62 | @property (nonatomic, copy) NSString* cycriptDirectory; 63 | @property (nonatomic, strong) NSMutableArray* downloading; 64 | @property (nonatomic, strong) NSMutableDictionary* loadAtLaunchModules; 65 | 66 | @end 67 | 68 | @implementation MDCycriptManager 69 | 70 | + (instancetype)sharedInstance{ 71 | static MDCycriptManager *sharedInstance = nil; 72 | if (!sharedInstance){ 73 | sharedInstance = [[MDCycriptManager alloc] init]; 74 | } 75 | return sharedInstance; 76 | } 77 | 78 | - (instancetype)init 79 | { 80 | self = [super init]; 81 | if (self) { 82 | _loadAtLaunchModules = [NSMutableDictionary dictionary]; 83 | _downloading = [NSMutableArray array]; 84 | [self check]; 85 | [self readConfigFile]; 86 | } 87 | return self; 88 | } 89 | 90 | -(void)check{ 91 | NSString* ip = [self getIPAddress]; 92 | if(ip != nil){ 93 | printf("\nDownload cycript(https://cydia.saurik.com/api/latest/3) then run: ./cycript -r %s:%d\n\n", [ip UTF8String], PORT); 94 | }else{ 95 | printf("\nPlease connect wifi before using cycript!\n\n"); 96 | } 97 | 98 | NSFileManager *fileManager = [NSFileManager defaultManager]; 99 | NSString *documentsPath =[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES) firstObject]; 100 | _cycriptDirectory = [documentsPath stringByAppendingPathComponent:@"cycript"]; 101 | [fileManager createDirectoryAtPath:_cycriptDirectory withIntermediateDirectories:YES attributes:nil error:nil]; 102 | } 103 | 104 | -(NSArray*)sortedArray:(NSDictionary*) dictionary{ 105 | NSMutableArray* result = [NSMutableArray arrayWithCapacity:10]; 106 | 107 | NSArray* sortedArray = [dictionary.allKeys sortedArrayUsingComparator:^NSComparisonResult(NSNumber* _Nonnull number1, NSNumber* _Nonnull number2) { 108 | if ([number1 integerValue] > [number2 integerValue]) 109 | return NSOrderedDescending; 110 | return NSOrderedAscending; 111 | }]; 112 | 113 | for (NSNumber* item in sortedArray) { 114 | [result addObject:dictionary[item]]; 115 | } 116 | 117 | return [result copy]; 118 | } 119 | 120 | -(void)readConfigFile{ 121 | MDConfigManager * configManager = [MDConfigManager sharedInstance]; 122 | _configItem = [configManager readConfigByKey:MDCONFIG_CYCRIPT_KEY]; 123 | } 124 | 125 | -(void)loadCycript:(BOOL) update{ 126 | NSFileManager *fileManager = [NSFileManager defaultManager]; 127 | 128 | if(_configItem && _configItem.count > 0){ 129 | 130 | BOOL download = NO; 131 | 132 | for (NSString* moduleName in _configItem.allKeys) { 133 | MDSettingObject * item = [[MDSettingObject alloc] initWithDicationary:_configItem[moduleName]]; 134 | NSString *fullPath = [[_cycriptDirectory stringByAppendingPathComponent:moduleName] stringByAppendingPathExtension:@"cy"]; 135 | 136 | if(item.url){ 137 | if(![fileManager fileExistsAtPath:fullPath] || update){ 138 | download = YES; 139 | [self.downloading addObject:moduleName]; 140 | [self downLoadUrl:item.url saveName:moduleName]; 141 | } 142 | } 143 | 144 | if(item.content){ 145 | if(![fileManager fileExistsAtPath:fullPath] || update){ 146 | NSString* writeContent = [NSString stringWithFormat:@"(function(exports) { %@ })(exports);", item.content]; 147 | [writeContent writeToFile:fullPath atomically:YES encoding:NSUTF8StringEncoding error:nil]; 148 | } 149 | } 150 | 151 | if(item.loadAtLaunch){ 152 | [_loadAtLaunchModules setObject:fullPath forKey:@(item.priority)]; 153 | } 154 | } 155 | 156 | if(!download){ 157 | [self finishDownload]; 158 | } 159 | } 160 | } 161 | 162 | -(void)finishDownload{ 163 | MDLog(@"Finish download all script!"); 164 | NSArray* sortedArray = [self sortedArray:_loadAtLaunchModules]; 165 | for (NSString* fullPath in sortedArray) { 166 | NSError* error; 167 | [self evaluateCycript:[NSString stringWithFormat:@"require('%@');",fullPath] error:&error]; 168 | if(error.code != 0){ 169 | MDLog(@"%@", error.localizedDescription); 170 | } 171 | } 172 | } 173 | 174 | -(void)downLoadUrl:(NSString*) urlString saveName:(NSString*) filename{ 175 | __weak typeof(self) weakSelf = self; 176 | NSURLSession *session = [NSURLSession sharedSession]; 177 | NSURL *url = [NSURL URLWithString:urlString]; 178 | NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithURL:url completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) { 179 | 180 | if(error){ 181 | MDLog(@"Failed download script [%@]: %@", filename, error.localizedDescription); 182 | }else{ 183 | NSString *fullPath = [[weakSelf.cycriptDirectory stringByAppendingPathComponent:filename] stringByAppendingPathExtension:@"cy"]; 184 | [[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath:fullPath] error:nil]; 185 | 186 | MDLog(@"Successful download script [%@]", filename); 187 | } 188 | 189 | [weakSelf.downloading removeObject:filename]; 190 | 191 | if(!weakSelf.downloading.count){ 192 | [weakSelf finishDownload]; 193 | } 194 | }]; 195 | [downloadTask resume]; 196 | } 197 | 198 | -(NSString *)evaluateCycript:(NSString *)cycript error:(NSError *__autoreleasing *)error{ 199 | return nil; 200 | JSGlobalContextRef context = CYGetJSContext(); 201 | 202 | size_t length = cycript.length; 203 | unichar *buffer = malloc(length * sizeof(unichar)); 204 | [cycript getCharacters:buffer range:NSMakeRange(0, length)]; 205 | const uint16_t *characters = buffer; 206 | CydgetMemoryParse(&characters, &length); 207 | JSStringRef expression = JSStringCreateWithCharacters(characters, length); 208 | 209 | // Evaluate the Javascript 210 | JSValueRef exception = NULL; 211 | JSValueRef result = JSEvaluateScript(context, expression, NULL, NULL, 0, &exception); 212 | JSStringRelease(expression); 213 | 214 | NSString *resultString = nil; 215 | 216 | // If a result was returned, convert it into an NSString 217 | if (result) { 218 | JSStringRef string = JSValueToStringCopy(context, result, &exception); 219 | if (string) { 220 | resultString = (__bridge_transfer NSString *)JSStringCopyCFString(kCFAllocatorDefault, string); 221 | JSStringRelease(string); 222 | } 223 | } 224 | 225 | // If an exception was thrown, convert it into an NSError 226 | if (exception && error) { 227 | JSObjectRef exceptionObject = JSValueToObject(context, exception, NULL); 228 | 229 | NSInteger line = (NSInteger)JSValueToNumber(context, JSObjectGetProperty(context, exceptionObject, JSStringCreateWithUTF8CString("line"), NULL), NULL); 230 | JSStringRef string = JSValueToStringCopy(context, JSObjectGetProperty(context, exceptionObject, JSStringCreateWithUTF8CString("name"), NULL), NULL); 231 | NSString *name = (__bridge_transfer NSString *)JSStringCopyCFString(kCFAllocatorDefault, string); 232 | JSStringRelease(string); 233 | string = JSValueToStringCopy(context, JSObjectGetProperty(context, exceptionObject, JSStringCreateWithUTF8CString("message"), NULL), NULL); 234 | NSString *message = (__bridge_transfer NSString *)JSStringCopyCFString(kCFAllocatorDefault, string); 235 | JSStringRelease(string); 236 | string = JSValueToStringCopy(context, exception, NULL); 237 | NSString *description = (__bridge_transfer NSString *)JSStringCopyCFString(kCFAllocatorDefault, string); 238 | JSStringRelease(string); 239 | 240 | NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; 241 | [userInfo setValue:@(line) forKey:CYErrorLineKey]; 242 | [userInfo setValue:name forKey:CYErrorNameKey]; 243 | [userInfo setValue:message forKey:CYErrorMessageKey]; 244 | [userInfo setValue:description forKey:NSLocalizedDescriptionKey]; 245 | *error = [NSError errorWithDomain:@"CYContextDomain" code:0 userInfo:userInfo]; 246 | } 247 | 248 | return resultString; 249 | } 250 | 251 | - (NSString *)getIPAddress{ 252 | 253 | NSDictionary *addresses = [self getIPAddresses]; 254 | 255 | if([addresses.allKeys containsObject:IOS_WIFI @"/" IP_ADDR_IPv4]){ 256 | return addresses[IOS_WIFI @"/" IP_ADDR_IPv4]; 257 | } 258 | 259 | return nil; 260 | } 261 | 262 | - (NSDictionary *)getIPAddresses{ 263 | NSMutableDictionary *addresses = [NSMutableDictionary dictionaryWithCapacity:8]; 264 | 265 | // retrieve the current interfaces - returns 0 on success 266 | struct ifaddrs *interfaces; 267 | if(!getifaddrs(&interfaces)) { 268 | // Loop through linked list of interfaces 269 | struct ifaddrs *interface; 270 | for(interface=interfaces; interface; interface=interface->ifa_next) { 271 | if(!(interface->ifa_flags & IFF_UP) /* || (interface->ifa_flags & IFF_LOOPBACK) */ ) { 272 | continue; // deeply nested code harder to read 273 | } 274 | const struct sockaddr_in *addr = (const struct sockaddr_in*)interface->ifa_addr; 275 | char addrBuf[ MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) ]; 276 | if(addr && (addr->sin_family==AF_INET || addr->sin_family==AF_INET6)) { 277 | NSString *name = [NSString stringWithUTF8String:interface->ifa_name]; 278 | NSString *type; 279 | if(addr->sin_family == AF_INET) { 280 | if(inet_ntop(AF_INET, &addr->sin_addr, addrBuf, INET_ADDRSTRLEN)) { 281 | type = IP_ADDR_IPv4; 282 | } 283 | } else { 284 | const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*)interface->ifa_addr; 285 | if(inet_ntop(AF_INET6, &addr6->sin6_addr, addrBuf, INET6_ADDRSTRLEN)) { 286 | type = IP_ADDR_IPv6; 287 | } 288 | } 289 | if(type) { 290 | NSString *key = [NSString stringWithFormat:@"%@/%@", name, type]; 291 | addresses[key] = [NSString stringWithUTF8String:addrBuf]; 292 | } 293 | } 294 | } 295 | // Free memory 296 | freeifaddrs(interfaces); 297 | } 298 | return [addresses count] ? addresses : nil; 299 | } 300 | 301 | @end 302 | 303 | #endif 304 | -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttackDylib/Tools/LLDBTools.mm: -------------------------------------------------------------------------------- 1 | // weibo: http://weibo.com/xiaoqing28 2 | // blog: http://www.alonemonkey.com 3 | // 4 | // LLDBTools.m 5 | // MonkeyDev 6 | // 7 | // Created by AloneMonkey on 2018/3/8. 8 | // Copyright © 2018年 AloneMonkey. All rights reserved. 9 | // 10 | 11 | #pragma GCC diagnostic ignored "-Wundeclared-selector" 12 | 13 | #import "LLDBTools.h" 14 | #import 15 | #import 16 | #import 17 | #import 18 | #import 19 | #import 20 | 21 | enum { 22 | BLOCK_HAS_COPY_DISPOSE = (1 << 25), 23 | BLOCK_HAS_CTOR = (1 << 26), // helpers have C++ code 24 | BLOCK_IS_GLOBAL = (1 << 28), 25 | BLOCK_HAS_STRET = (1 << 29), // IFF BLOCK_HAS_SIGNATURE 26 | BLOCK_HAS_SIGNATURE = (1 << 30), 27 | }; 28 | 29 | struct Block_literal_1 { 30 | void *isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock 31 | int flags; 32 | int reserved; 33 | void (*invoke)(void *, ...); 34 | struct Block_descriptor_1 { 35 | unsigned long int reserved; // NULL 36 | unsigned long int size; // sizeof(struct Block_literal_1) 37 | // optional helper functions 38 | void (*copy_helper)(void *dst, void *src); // IFF (1<<25) 39 | void (*dispose_helper)(void *src); // IFF (1<<25) 40 | // required ABI.2010.3.16 41 | const char *signature; // IFF (1<<30) 42 | } *descriptor; 43 | // imported variables 44 | }; 45 | 46 | NSString* decode(NSString* code); 47 | NSArray* choose_inner(const char * classname); 48 | char * protection_bits_to_rwx (vm_prot_t p); 49 | const char * unparse_inheritance (vm_inherit_t i); 50 | char * behavior_to_text (vm_behavior_t b); 51 | 52 | NSString* decode(NSString* code){ 53 | NSDictionary * encodeMap = @{ 54 | @"c": @"char", 55 | @"i": @"int", 56 | @"s": @"short", 57 | @"l": @"long", 58 | @"q": @"long long", 59 | 60 | @"C": @"unsigned char", 61 | @"I": @"unsigned int", 62 | @"S": @"unsigned short", 63 | @"L": @"unsigned long", 64 | @"Q": @"unsigned long long", 65 | 66 | @"f": @"float", 67 | @"d": @"double", 68 | @"B": @"bool", 69 | @"v": @"void", 70 | @"*": @"char *", 71 | @"@": @"id", 72 | @"#": @"Class", 73 | @":": @"SEL" 74 | }; 75 | 76 | if(encodeMap[code]){ 77 | return encodeMap[code]; 78 | }else if([code characterAtIndex:0] == '@'){ 79 | if([code characterAtIndex:1] == '?'){ 80 | return code; 81 | }else if([code characterAtIndex:2] == '<'){ 82 | return [NSString stringWithFormat:@"id%@", [[code substringWithRange:NSMakeRange(2, code.length-3)] stringByReplacingOccurrencesOfString:@"><" withString:@", "]]; 83 | }else{ 84 | return [NSString stringWithFormat:@"%@ *", [code substringWithRange:NSMakeRange(2, code.length-3)]]; 85 | } 86 | }else if([code characterAtIndex:0] == '^'){ 87 | return [NSString stringWithFormat:@"%@ *", decode([code substringFromIndex:1])]; 88 | } 89 | return code; 90 | } 91 | 92 | NSString* pvc(){ 93 | return [[[UIWindow performSelector:@selector(keyWindow)] performSelector:@selector(rootViewController)] performSelector:@selector(_printHierarchy)]; 94 | } 95 | 96 | NSString* pviews(){ 97 | return [[[UIApplication sharedApplication] keyWindow] performSelector:@selector(recursiveDescription)]; 98 | } 99 | 100 | NSString* pactions(vm_address_t address){ 101 | NSMutableString* result = [NSMutableString new]; 102 | UIControl* control = (__bridge UIControl*)(void*)address; 103 | NSArray* targets = [[control allTargets] allObjects]; 104 | for (id item in targets) { 105 | NSArray* actions = [control actionsForTarget:item forControlEvent:0]; 106 | [result appendFormat:@"<%s: 0x%lx>: %@\n", object_getClassName(item), (unsigned long)item, [actions componentsJoinedByString:@","]]; 107 | } 108 | return result; 109 | } 110 | 111 | NSString* pblock(vm_address_t address){ 112 | struct Block_literal_1 real = *((struct Block_literal_1 *)(void*)address); 113 | NSMutableDictionary *dict = (id)[NSMutableDictionary dictionary]; 114 | [dict setObject:(id)[NSNumber numberWithLong:(long)real.invoke] forKey:@"invoke"]; 115 | if (real.flags & BLOCK_HAS_SIGNATURE) { 116 | char *signature; 117 | if (real.flags & BLOCK_HAS_COPY_DISPOSE) { 118 | signature = (char *)(real.descriptor)->signature; 119 | } else { 120 | signature = (char *)(real.descriptor)->copy_helper; 121 | } 122 | 123 | NSMethodSignature *sig = [NSMethodSignature signatureWithObjCTypes:signature]; 124 | NSMutableArray *types = [NSMutableArray array]; 125 | 126 | [types addObject:(id)[NSString stringWithUTF8String:(char *)[sig methodReturnType]]]; 127 | 128 | for (NSUInteger i = 0; i < sig.numberOfArguments; i++) { 129 | char *type = (char *)[sig getArgumentTypeAtIndex:i]; 130 | [types addObject:(id)[NSString stringWithUTF8String:type]]; 131 | } 132 | 133 | [dict setObject:types forKey:@"signature"]; 134 | } 135 | 136 | NSMutableArray* sigArr = dict[@"signature"]; 137 | 138 | if(!sigArr){ 139 | return [NSString stringWithFormat:@"Imp: 0x%lx", (long)dict[@"invoke"]]; 140 | }else{ 141 | NSMutableString* sig = [NSMutableString stringWithFormat:@"%@ ^(", decode(sigArr[0])]; 142 | for (int i = 2; i < sigArr.count; i++) { 143 | if(i == sigArr.count - 1){ 144 | [sig appendFormat:@"%@", decode(sigArr[i])]; 145 | }else{ 146 | [sig appendFormat:@"%@ ,", decode(sigArr[i])]; 147 | } 148 | } 149 | [sig appendString:@");"]; 150 | return [NSString stringWithFormat:@"Imp: 0x%lx Signature: %s", (long)dict[@"invoke"], [sig UTF8String]]; 151 | } 152 | } 153 | 154 | struct CYChoice { 155 | std::set query_; 156 | std::set results_; 157 | }; 158 | 159 | struct CYObjectStruct { 160 | Class isa_; 161 | }; 162 | 163 | static void choose_(task_t task, void *baton, unsigned type, vm_range_t *ranges, unsigned count) { 164 | CYChoice *choice(reinterpret_cast(baton)); 165 | 166 | for (unsigned i(0); i != count; ++i) { 167 | vm_range_t &range(ranges[i]); 168 | void *data(reinterpret_cast(range.address)); 169 | size_t size(range.size); 170 | 171 | if (size < sizeof(CYObjectStruct)) 172 | continue; 173 | 174 | uintptr_t *pointers(reinterpret_cast(data)); 175 | #ifdef __arm64__ 176 | Class isa = (__bridge Class)((void *)(pointers[0] & 0x1fffffff8)); 177 | #else 178 | Class isa =(__bridge Class)(void *)pointers[0]; 179 | #endif 180 | std::set::const_iterator result(choice->query_.find(isa)); 181 | if (result == choice->query_.end()) 182 | continue; 183 | 184 | size_t needed(class_getInstanceSize(*result)); 185 | // XXX: if (size < needed) 186 | 187 | size_t boundary(496); 188 | #ifdef __LP64__ 189 | boundary *= 2; 190 | #endif 191 | if ((needed <= boundary && (needed + 15) / 16 * 16 != size) || (needed > boundary && (needed + 511) / 512 * 512 != size)) 192 | continue; 193 | choice->results_.insert((__bridge id)(data)); 194 | } 195 | } 196 | 197 | static Class *CYCopyClassList(size_t &size) { 198 | size = objc_getClassList(NULL, 0); 199 | Class *data(reinterpret_cast(malloc(sizeof(Class) * size))); 200 | 201 | for (;;) { 202 | size_t writ(objc_getClassList(data, (int)size)); 203 | if (writ <= size) { 204 | size = writ; 205 | return data; 206 | } 207 | 208 | Class *copy(reinterpret_cast(realloc(data, sizeof(Class) * writ))); 209 | if (copy == NULL) { 210 | free(data); 211 | return NULL; 212 | } 213 | 214 | data = copy; 215 | size = writ; 216 | } 217 | } 218 | 219 | static kern_return_t CYReadMemory(task_t task, vm_address_t address, vm_size_t size, void **data) { 220 | *data = reinterpret_cast(address); 221 | return KERN_SUCCESS; 222 | } 223 | 224 | NSArray* choose_inner(const char * classname){ 225 | 226 | Class _class = NSClassFromString([NSString stringWithUTF8String:classname]); 227 | 228 | vm_address_t *zones = NULL; 229 | unsigned size = 0; 230 | //获取所有的zone信息 堆上的区域 231 | kern_return_t error = malloc_get_all_zones(mach_task_self(), &CYReadMemory, &zones, &size); 232 | assert(error == KERN_SUCCESS); 233 | 234 | size_t number; 235 | Class *classes(CYCopyClassList(number)); 236 | assert(classes != NULL); 237 | 238 | CYChoice choice; 239 | 240 | //找到目标Class 241 | for (size_t i(0); i != number; ++i) 242 | for (Class current(classes[i]); current != Nil; current = class_getSuperclass(current)) 243 | if (current == _class) { 244 | choice.query_.insert(classes[i]); 245 | break; 246 | } 247 | 248 | for (unsigned i(0); i != size; ++i) { 249 | const malloc_zone_t *zone(reinterpret_cast(zones[i])); 250 | if (zone == NULL || zone->introspect == NULL) 251 | continue; 252 | 253 | //枚举堆上的对象 254 | zone->introspect->enumerator(mach_task_self(), &choice, MALLOC_PTR_IN_USE_RANGE_TYPE, zones[i], &CYReadMemory, &choose_); 255 | } 256 | NSMutableArray * result = [[NSMutableArray alloc] init]; 257 | 258 | for (auto iter = choice.results_.begin(); iter != choice.results_.end(); iter++) { 259 | [result addObject:(id)*iter]; 260 | } 261 | return result; 262 | } 263 | 264 | NSString* choose(const char* classname){ 265 | NSMutableString* result = [NSMutableString new]; 266 | NSArray* results = choose_inner(classname); 267 | [result appendFormat:@"Find %lu instance objects in memory!\n" , (unsigned long)results.count]; 268 | for (id item in results) { 269 | [result appendFormat:@"<%s: 0x%llx>\n", object_getClassName(item), (long long)item]; 270 | } 271 | return result; 272 | } 273 | 274 | NSString* methods(const char * classname){ 275 | return [objc_getClass(classname) performSelector:@selector(_shortMethodDescription)]; 276 | } 277 | 278 | NSString* ivars(vm_address_t address){ 279 | id target = (__bridge id)(void*)address; 280 | return [target performSelector:@selector(_ivarDescription)]; 281 | } 282 | 283 | char * protection_bits_to_rwx (vm_prot_t p){ 284 | static char returned[4]; 285 | 286 | returned[0] = (p & VM_PROT_READ ? 'r' : '-'); 287 | returned[1] = (p & VM_PROT_WRITE ? 'w' : '-'); 288 | returned[2] = (p & VM_PROT_EXECUTE ? 'x' : '-'); 289 | returned[3] = '\0'; 290 | 291 | // memory leak here. No biggy 292 | return (strdup(returned)); 293 | } 294 | 295 | const char * unparse_inheritance (vm_inherit_t i){ 296 | switch (i){ 297 | case VM_INHERIT_SHARE: 298 | return "share"; 299 | case VM_INHERIT_COPY: 300 | return "copy"; 301 | case VM_INHERIT_NONE: 302 | return "none"; 303 | default: 304 | return "???"; 305 | } 306 | } 307 | 308 | char * behavior_to_text (vm_behavior_t b){ 309 | switch (b){ 310 | case VM_BEHAVIOR_DEFAULT: return((char*)"default"); 311 | case VM_BEHAVIOR_RANDOM: return((char*)"random"); 312 | case VM_BEHAVIOR_SEQUENTIAL: return((char*)"fwd-seq"); 313 | case VM_BEHAVIOR_RSEQNTL: return((char*)"rev-seq"); 314 | case VM_BEHAVIOR_WILLNEED: return((char*)"will-need"); 315 | case VM_BEHAVIOR_DONTNEED: return((char*)"will-need"); 316 | case VM_BEHAVIOR_FREE: return((char*)"free-nowb"); 317 | case VM_BEHAVIOR_ZERO_WIRED_PAGES: return((char*)"zero-wire"); 318 | case VM_BEHAVIOR_REUSABLE: return((char*)"reusable"); 319 | case VM_BEHAVIOR_REUSE: return((char*)"reuse"); 320 | case VM_BEHAVIOR_CAN_REUSE: return((char*)"canreuse"); 321 | default: return ((char*)"?"); 322 | } 323 | } 324 | 325 | __BEGIN_DECLS 326 | 327 | extern kern_return_t mach_vm_region 328 | ( 329 | vm_map_t target_task, 330 | mach_vm_address_t *address, 331 | mach_vm_size_t *size, 332 | vm_region_flavor_t flavor, 333 | vm_region_info_t info, 334 | mach_msg_type_number_t *infoCnt, 335 | mach_port_t *object_name 336 | ); 337 | 338 | __END_DECLS 339 | 340 | NSString* vmmap(){ 341 | vm_region_basic_info_data_t info, prev_info; 342 | mach_vm_address_t address = 1, prev_address; 343 | mach_vm_size_t size, prev_size; 344 | mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT_64; 345 | mach_port_t object_name; 346 | 347 | int nsubregions = 0; 348 | kern_return_t kr = mach_vm_region(mach_task_self(), &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)&info, &count, &object_name); 349 | 350 | NSMutableString* result = [[NSMutableString alloc] init]; 351 | 352 | if(kr != KERN_SUCCESS){ 353 | [result appendFormat:@"mach_vm_region: Error %d - %s", kr, mach_error_string(kr)]; 354 | return [result copy]; 355 | } 356 | 357 | //保存之前查到的info 358 | memcpy (&prev_info, &info, sizeof (vm_region_basic_info_data_t)); 359 | prev_address = address; 360 | prev_size = size; 361 | nsubregions = 1; 362 | 363 | while (true) { 364 | int print = 0, done = 0; 365 | 366 | address = prev_address + prev_size; 367 | 368 | if (address == 0){ 369 | print = done = 1; 370 | } 371 | 372 | if (!done){ 373 | kr = mach_vm_region (mach_task_self(), &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)&info, &count, &object_name); 374 | 375 | if (kr != KERN_SUCCESS){ 376 | [result appendFormat:@"mach_vm_region failed for address %llu - Error: %x\n",address, (kr)]; 377 | print = done = 1; 378 | } 379 | } 380 | 381 | //等于才是连续的内存,不等于才打印 382 | if (address != prev_address + prev_size) 383 | print = 1; 384 | 385 | //或者权限信息改变了也打印 386 | if ((info.protection != prev_info.protection) 387 | || (info.max_protection != prev_info.max_protection) 388 | || (info.inheritance != prev_info.inheritance) 389 | || (info.shared != prev_info.reserved) 390 | || (info.reserved != prev_info.reserved)) 391 | print = 1; 392 | 393 | if (print){ 394 | char *print_size_unit = NULL; 395 | 396 | mach_vm_size_t print_size = prev_size; 397 | if (print_size > 1024) { print_size /= 1024; print_size_unit = (char*)"K"; } 398 | if (print_size > 1024) { print_size /= 1024; print_size_unit = (char*)"M"; } 399 | if (print_size > 1024) { print_size /= 1024; print_size_unit = (char*)"G"; } 400 | 401 | [result appendFormat:@" %p-%p [%llu%s](%s/%s; %s, %s, %s) %s", 402 | (void*)(prev_address), 403 | (void*)(prev_address + prev_size), 404 | print_size, 405 | print_size_unit, 406 | protection_bits_to_rwx (prev_info.protection), 407 | protection_bits_to_rwx (prev_info.max_protection), 408 | unparse_inheritance (prev_info.inheritance), 409 | prev_info.shared ? "shared" : "private", 410 | prev_info.reserved ? "reserved" : "not-reserved", 411 | behavior_to_text (prev_info.behavior)]; 412 | 413 | if (nsubregions > 1) 414 | [result appendFormat:@" (%d sub-regions)", nsubregions]; 415 | 416 | [result appendFormat:@"\n"]; 417 | prev_address = address; 418 | prev_size = size; 419 | memcpy (&prev_info, &info, sizeof (vm_region_basic_info_data_t)); 420 | nsubregions = 1; 421 | }else{ 422 | prev_size += size; 423 | nsubregions++; 424 | } 425 | 426 | if (done) 427 | break; 428 | } 429 | return [result copy]; 430 | } 431 | 432 | 433 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ZXHookDetection 2 | ### 越狱检测 3 | 1.使用NSFileManager通过检测一些越狱后的关键文件/路径是否可以访问来判断是否越狱 4 | 常见的文件/路径有 5 | ```objective-c 6 | static char *JailbrokenPathArr[] = {"/Applications/Cydia.app","/usr/sbin/sshd","/bin/bash","/etc/apt","/Library/MobileSubstrate","/User/Applications/"}; 7 | ``` 8 | `[防]`判断是否越狱(使用NSFileManager) 9 | ```objective-c 10 | + (BOOL)isJailbroken1{ 11 | if(TARGET_IPHONE_SIMULATOR)return NO; 12 | for (int i = 0;i < sizeof(JailbrokenPathArr) / sizeof(char *);i++) { 13 | if([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithUTF8String:JailbrokenPathArr[i]]]){ 14 | return YES; 15 | } 16 | } 17 | return NO; 18 | } 19 | ``` 20 | 调用isJailbroken1并将程序运行在越狱设备上,查看打印,检测出是越狱设备 21 | ```objective-c 22 | 2019-04-22 00:54:08.163918 ZXHookDetection[6933:1053473] isJailbroken1--1 23 | ``` 24 | `[攻]`攻击者可以通过hook NSFileManager的fileExistsAtPath方法来绕过检测 25 | ```objective-c 26 | //绕过使用NSFileManager判断特定文件是否存在的越狱检测,此时直接返回NO势必会影响程序中对这个方法的正常使用,因此可以先打印一下path,然后判断如果path是用来判断是否越狱则返回NO,否则按照正常逻辑返回 27 | %hook NSFileManager 28 | - (BOOL)fileExistsAtPath:(NSString *)path{ 29 | if(TARGET_IPHONE_SIMULATOR)return NO; 30 | for (int i = 0;i < sizeof(JailbrokenPathArr) / sizeof(char *);i++) { 31 | NSString *jPath = [NSString stringWithUTF8String:JailbrokenPathArr[i]]; 32 | if([path isEqualToString:jPath]){ 33 | return NO; 34 | } 35 | } 36 | return %orig; 37 | } 38 | %end 39 | ``` 40 | 注入dylib后再次查看打印,已绕过越狱检测 41 | ```objective-c 42 | 2019-04-22 00:58:22.950881 ZXHookDetection[6941:1054289] isJailbroken1--0 43 | ``` 44 | 2.使用C语言函数stat判断文件是否存在(注:stat函数用于获取对应文件信息,返回0则为获取成功,-1为获取失败) 45 | 46 | `[防]`判断是否越狱(使用stat) 47 | ```objective-c 48 | + (BOOL)isJailbroken2{ 49 | if(TARGET_IPHONE_SIMULATOR)return NO; 50 | for (int i = 0;i < sizeof(JailbrokenPathArr) / sizeof(char *);i++) { 51 | struct stat stat_info; 52 | if (0 == stat(JailbrokenPathArr[i], &stat_info)) { 53 | return YES; 54 | } 55 | } 56 | return NO; 57 | } 58 | ``` 59 | 调用isJailbroken2并将程序运行在越狱设备上,查看打印,检测出是越狱设备 60 | ```objective-c 61 | 2019-04-22 00:54:08.164001 ZXHookDetection[6933:1053473] isJailbroken2--1 62 | ``` 63 | `[攻]`使用fishhook可hook C函数,fishhook通过在mac-o文件中查找并替换函数地址达到hook的目的 64 | ```objective-c 65 | static int (*orig_stat)(char *c, struct stat *s); 66 | int hook_stat(char *c, struct stat *s){ 67 | for (int i = 0;i < sizeof(JailbrokenPathArr) / sizeof(char *);i++) { 68 | if(0 == strcmp(c, JailbrokenPathArr[i])){ 69 | return 0; 70 | } 71 | } 72 | return orig_stat(c,s); 73 | } 74 | +(void)statHook{ 75 | struct rebinding stat_rebinding = {"stat", hook_stat, (void *)&orig_stat}; 76 | rebind_symbols((struct rebinding[1]){stat_rebinding}, 1); 77 | } 78 | ``` 79 | 在动态库加载的时候,调用statHook 80 | ```objective-c 81 | %ctor{ 82 | [StatHook statHook]; 83 | } 84 | ``` 85 | 注入dylib后再次查看打印,已绕过越狱检测 86 | ```objective-c 87 | 2019-04-22 00:58:22.950933 ZXHookDetection[6941:1054289] isJailbroken2--0 88 | ``` 89 | `[防]`判断stat的来源是否来自于系统库,因为fishhook通过交换函数地址来实现hook,若hook了stat,则stat来源将指向攻击者注入的动态库中 90 | 因此我们可以完善上方的isJailbroken2判断规则,若stat来源非系统库,则直接返回已越狱 91 | ```objective-c 92 | + (BOOL)isJailbroken2{ 93 | if(TARGET_IPHONE_SIMULATOR)return NO; 94 | int ret ; 95 | Dl_info dylib_info; 96 | int (*func_stat)(const char *, struct stat *) = stat; 97 | if ((ret = dladdr(func_stat, &dylib_info))) { 98 | NSString *fName = [NSString stringWithUTF8String:dylib_info.dli_fname]; 99 | NSLog(@"fname--%@",fName); 100 | if(![fName isEqualToString:@"/usr/lib/system/libsystem_kernel.dylib"]){ 101 | return YES; 102 | } 103 | } 104 | 105 | for (int i = 0;i < sizeof(JailbrokenPathArr) / sizeof(char *);i++) { 106 | struct stat stat_info; 107 | if (0 == stat(JailbrokenPathArr[i], &stat_info)) { 108 | return YES; 109 | } 110 | } 111 | 112 | return NO; 113 | } 114 | ``` 115 | 注入dylib后再次查看打印,检测出stat非来自系统库,自动判定为越狱设备 116 | ```objective-c 117 | 2019-04-22 00:58:22.950933 ZXHookDetection[6941:1054289] isJailbroken2--1 118 | ``` 119 | 3.通过环境变量DYLD_INSERT_LIBRARIES判断是否越狱,若获取到的为NULL,则未越狱 120 | ```objective-c 121 | + (BOOL)isJailbroken3{ 122 | if(TARGET_IPHONE_SIMULATOR)return NO; 123 | return !(NULL == getenv("DYLD_INSERT_LIBRARIES")); 124 | } 125 | ``` 126 | `[攻]`此时依然可以使用fishhook hook函数getenv,攻防方法同上,此处不再赘述。 127 | 128 | *** 129 | 130 | ### 非法动态库注入检测 131 | `[防]`通过遍历dyld_image检测非法注入的动态库 132 | ```objective-c 133 | + (BOOL)isExternalLibs{ 134 | if(TARGET_IPHONE_SIMULATOR)return NO; 135 | int dyld_count = _dyld_image_count(); 136 | for (int i = 0; i < dyld_count; i++) { 137 | const char * imageName = _dyld_get_image_name(i); 138 | NSString *res = [NSString stringWithUTF8String:imageName]; 139 | if([res hasPrefix:@"/var/containers/Bundle/Application"]){ 140 | if([res hasSuffix:@".dylib"]){ 141 | //这边还需要过滤掉自己项目中本身有的动态库 142 | return YES; 143 | } 144 | } 145 | } 146 | return NO; 147 | } 148 | ``` 149 | 攻击者注入dylib之后,已被检测出非法动态库注入 150 | ```objective-c 151 | 2019-04-22 00:58:22.951011 ZXHookDetection[6941:1054289] isExternalLibs--1 152 | ``` 153 | `[攻]`可以hook NSString的hasPrefix方法绕过检测 154 | *** 155 | 156 | ### 关键函数hook检测、阻止hook、hook白名单 157 | #### 攻击者dylib动态库注入总是早于类中的+load方法调用,因此在+load方法中无法进行防护,我们可以先link一个自己的framework,并在framework中+load方法内进行防护 158 | * 创建一个framework,并在其中创建一个名为ZXMyFramework的类,在+load中进行防护操作 159 | * 防护操作基本思路是,我们在攻击者之前hook method_exchangeImplementations与method_setImplementation,使用fishhook进行函数指针交换,并使得我们可以轻松监控所有调用method_exchangeImplementations与method_setImplementation的情况,因Method Swizzle,Cydia Substrate进行方法交换均至少会调用以上两个方法中的一个,因此可以以此检测、阻止重要方法被hook 160 | * 在示例demo中,我们在控制器的viewDidload方法中将当前控制器view的背景色设置为绿色,在hook项目中,通过hook ViewController的viewDidload方法,将控制器view的背景色设置为红色,以便我们可以清晰查看这一流程 161 | 原控制器viewDidload中代码 162 | ```objective-c 163 | - (void)viewDidLoad { 164 | [super viewDidLoad]; 165 | self.view.backgroundColor = [UIColor greenColor]; 166 | } 167 | ``` 168 | 攻击者hook部分代码 169 | ```objective-c 170 | %hook ViewController 171 | 172 | -(void)viewDidLoad{ 173 | 174 | self.view.backgroundColor = [UIColor redColor]; 175 | } 176 | %end 177 | ``` 178 | 注入dylib后运行项目,发现控制器view已变为红色 179 | * 开始防护,在ZXMyFramework的+load方法中,实现method_exchangeImplementations与method_setImplementation的方法交换,以下为ZXMyFramework.m中类的源码 180 | ```objective-c 181 | #pragma mark 受保护的方法数组 182 | static char *DefendSelStrs[] = {"viewDidLoad","bundleIdentifier"}; 183 | 184 | @implementation ZXMyFramework 185 | void (* orig_exchangeImple)(Method _Nonnull m1, Method _Nonnull m2); 186 | IMP _Nonnull (* orig_setImple)(Method _Nonnull m, IMP _Nonnull imp); 187 | IMP _Nonnull (* getIMP)(Method _Nonnull m); 188 | 189 | +(void)load{ 190 | NSLog(@"ZXMyFrameworkLoaded!"); 191 | if(TARGET_IPHONE_SIMULATOR)return; 192 | struct rebinding exchange_rebinding; 193 | exchange_rebinding.name = "method_exchangeImplementations"; 194 | exchange_rebinding.replacement = hook_exchangeImple; 195 | exchange_rebinding.replaced=(void *)&orig_exchangeImple; 196 | 197 | struct rebinding setImple_rebinding; 198 | setImple_rebinding.name = "method_setImplementation"; 199 | setImple_rebinding.replacement = hook_setImple; 200 | setImple_rebinding.replaced=(void *)&orig_setImple; 201 | 202 | struct rebinding rebindings[]={exchange_rebinding,setImple_rebinding}; 203 | rebind_symbols(rebindings, 2); 204 | } 205 | 206 | void hook_exchangeImple(Method _Nonnull orig_method, Method _Nonnull changed_method){ 207 | if(orig_method){ 208 | SEL sel = method_getName(orig_method); 209 | bool in_def = in_defend_sel((char *)[NSStringFromSelector(sel) UTF8String]); 210 | if(in_def){ 211 | NSLog(@"尝试hook受保护的方法:[%@],已禁止",NSStringFromSelector(sel)); 212 | return; 213 | } 214 | } 215 | orig_exchangeImple(orig_method,changed_method); 216 | } 217 | void hook_setImple(Method _Nonnull method, IMP _Nonnull imp){ 218 | if(method){ 219 | SEL sel = method_getName(method); 220 | bool in_def = in_defend_sel((char *)[NSStringFromSelector(sel) UTF8String]); 221 | if(in_def){ 222 | NSLog(@"尝试hook受保护的方法:[%@],已禁止",NSStringFromSelector(sel)); 223 | return; 224 | } 225 | } 226 | orig_setImple(method,imp); 227 | } 228 | 229 | #pragma mark 判断被交换的方法是否是受保护的方法 230 | bool in_defend_sel(char *selStr){ 231 | for (int i = 0;i < sizeof(DefendSelStrs) / sizeof(char *);i++) { 232 | if(0 == strcmp(selStr, DefendSelStrs[i])){ 233 | return true; 234 | } 235 | } 236 | return false; 237 | } 238 | @end 239 | ``` 240 | 上方我们对viewDidLoad和bundleIdentifier方法进行了保护,若发现有代码在试图交换它们的方法,则禁止,若需要交换的方法不在保护的数组中,则放行。 241 | 242 | * 我们开始模拟攻击者开始注入dylib攻击,查看效果 243 | 在攻击者的xm中,我们在动态库初始化的时候打印"AttackHookLoaded",并hook ViewController的viewDidLoad方法和NSBundle的bundleIdentifier方法 244 | ```objective-c 245 | %ctor{ 246 | [StatHook statHook]; 247 | NSLog(@"AttackHookLoaded"); 248 | } 249 | @interface ViewController:UIViewController 250 | 251 | @end 252 | %hook ViewController 253 | 254 | -(void)viewDidLoad{ 255 | 256 | self.view.backgroundColor = [UIColor redColor]; 257 | } 258 | %end 259 | 260 | %hook NSBundle 261 | -(id)bundleIdentifier{ 262 | 263 | NSArray *address = [NSThread callStackReturnAddresses]; 264 | Dl_info info = {0}; 265 | if(dladdr((void *)[address[2] longLongValue], &info) == 0) { 266 | return %orig; 267 | } 268 | NSString *path = [NSString stringWithUTF8String:info.dli_fname]; 269 | if ([path hasPrefix:NSBundle.mainBundle.bundlePath]) { 270 | NSLog(@"getBundleIdentifier"); 271 | return @"cn.newBundelId"; 272 | } else { 273 | return %orig; 274 | } 275 | } 276 | %end 277 | ``` 278 | * 查看防护效果,控制器view的背景色设置为红色已失效,查看打印信息,防护成功! 279 | ```objective-c 280 | 2019-04-22 01:32:22.457211 ZXHookDetection[6971:1059024] ZXMyFrameworkLoaded! 281 | 2019-04-22 01:32:22.546278 ZXHookDetection[6971:1059024] 282 | 🎉!!!congratulations!!!🎉 283 | 👍----------------insert dylib success----------------👍 284 | 2019-04-22 01:32:22.553715 ZXHookDetection[6971:1059024] AttackHookLoaded 285 | 2019-04-22 01:32:22.554384 ZXHookDetection[6971:1059024] 尝试hook受保护的方法:[viewDidLoad],已禁止 286 | 2019-04-22 01:32:22.554525 ZXHookDetection[6971:1059024] 尝试hook受保护的方法:[bundleIdentifier],已禁止 287 | ``` 288 | `[攻]`从上方打印可以看出,我们自己链接的动态库比攻击者注入的动态库早load,我们可以使用otool查看mach-o文件的loadCommand,验证我们的猜想,以下为loadcommand部分信息 289 | ```c 290 | Load command 13 291 | cmd LC_LOAD_DYLIB 292 | cmdsize 76 293 | name @rpath/ZXHookFramework.framework/ZXHookFramework (offset 24) 294 | time stamp 2 Thu Jan 1 08:00:02 1970 295 | current version 1.0.0 296 | compatibility version 1.0.0 297 | Load command 14 298 | cmd LC_LOAD_DYLIB 299 | cmdsize 84 300 | name /System/Library/Frameworks/Foundation.framework/Foundation (offset 24) 301 | time stamp 2 Thu Jan 1 08:00:02 1970 302 | current version 1570.15.0 303 | compatibility version 300.0.0 304 | Load command 15 305 | cmd LC_LOAD_DYLIB 306 | cmdsize 52 307 | name /usr/lib/libobjc.A.dylib (offset 24) 308 | time stamp 2 Thu Jan 1 08:00:02 1970 309 | current version 228.0.0 310 | compatibility version 1.0.0 311 | Load command 16 312 | cmd LC_LOAD_DYLIB 313 | cmdsize 52 314 | name /usr/lib/libSystem.B.dylib (offset 24) 315 | time stamp 2 Thu Jan 1 08:00:02 1970 316 | current version 1252.250.1 317 | compatibility version 1.0.0 318 | Load command 17 319 | cmd LC_LOAD_DYLIB 320 | cmdsize 92 321 | name /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation (offset 24) 322 | time stamp 2 Thu Jan 1 08:00:02 1970 323 | current version 1570.15.0 324 | compatibility version 150.0.0 325 | Load command 18 326 | cmd LC_LOAD_DYLIB 327 | cmdsize 76 328 | name /System/Library/Frameworks/UIKit.framework/UIKit (offset 24) 329 | time stamp 2 Thu Jan 1 08:00:02 1970 330 | current version 61000.0.0 331 | compatibility version 1.0.0 332 | Load command 19 333 | cmd LC_LOAD_DYLIB 334 | cmdsize 80 335 | name @executable_path/Frameworks/libZXHookAttackDylib.dylib (offset 24) 336 | time stamp 2 Thu Jan 1 08:00:02 1970 337 | current version 0.0.0 338 | compatibility version 0.0.0 339 | Load command 20 340 | cmd LC_RPATH 341 | cmdsize 40 342 | path @executable_path/Frameworks (offset 12) 343 | ``` 344 | 显然,ZXHookFramework.framework(防护者)加载早于libZXHookAttackDylib.dylib(攻击者),因此防护有效,因此我们可以通过修改mach-o文件的loadCommand来调整动态库加载顺序,使得libZXHookAttackDylib.dylib加载早于ZXHookFramework.framework即可使防护失效 345 | 346 | *** 347 | 348 | 349 | ### 签名校验 350 | * 通过检测ipa中的embedded.mobileprovision中的我们打包Mac的公钥来确定是否签名被修改,但是需要注意的是此方法只适用于Ad Hoc或企业证书打包的情况,App Store上应用由苹果私钥统一打包,不存在embedded.mobileprovision文件 351 | * 公钥读取写法来源于https://www.jianshu.com/p/a3fc10c70a29 352 | ```objective-c 353 | + (BOOL)isLegalPublicKey:(NSString *)publicKey{ 354 | if(TARGET_IPHONE_SIMULATOR)return YES; 355 | //来源于https://www.jianshu.com/p/a3fc10c70a29 356 | NSString *embeddedPath = [[NSBundle mainBundle] pathForResource:@"embedded" ofType:@"mobileprovision"]; 357 | NSString *embeddedProvisioning = [NSString stringWithContentsOfFile:embeddedPath encoding:NSASCIIStringEncoding error:nil]; 358 | NSArray *embeddedProvisioningLines = [embeddedProvisioning componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]]; 359 | for (int i = 0; i < embeddedProvisioningLines.count; i++) { 360 | if ([embeddedProvisioningLines[i] rangeOfString:@"application-identifier"].location != NSNotFound) { 361 | NSInteger fromPosition = [embeddedProvisioningLines[i+1] rangeOfString:@""].location+8; 362 | 363 | NSInteger toPosition = [embeddedProvisioningLines[i+1] rangeOfString:@""].location; 364 | NSRange range; 365 | range.location = fromPosition; 366 | range.length = toPosition - fromPosition; 367 | NSString *fullIdentifier = [embeddedProvisioningLines[i+1] substringWithRange:range]; 368 | NSArray *identifierComponents = [fullIdentifier componentsSeparatedByString:@"."]; 369 | NSString *appIdentifier = [identifierComponents firstObject]; 370 | NSLog(@"appIdentifier--%@",appIdentifier); 371 | if (![appIdentifier isEqualToString:publicKey]) { 372 | return NO; 373 | } 374 | } 375 | } 376 | return YES; 377 | } 378 | ``` 379 | *** 380 | 381 | ### BundleID检测 382 | * 进行BundleID检测可以有效防止多开 383 | * 获取当前项目的BundleID有多种方法,此处不再赘述,绕过检测则是hook对应的方法,返回原有的BundleID 384 | * 防止攻击者绕过检测,可以在自行link的framework中获取BundleID并进行检测,以在被hook前进行校验 385 | * 可以通过getenv("XPC_SERVICE_NAME")来获取BundleID并进行校验以避免常见的BundleID获取方法被hook 386 | 387 | *** 388 | 389 | ### 其他 390 | * 进行安全检测的类和函数不宜直接使用Defend,Detection,Hook类似的关键字,以避免相应的检测函数直接被hook,hook检测可以放在较隐蔽的地方或不以函数形式体现,可以多位置联合检测 391 | * 若检测到hook行为,不宜直接弹窗,以避免攻击者通过关键字回溯,可以延迟一段时间执行异常函数或默默上报后台等。 392 | * 加密key不要直接写在代码中,在汇编下很容易直接看出来 393 | 394 | 原代码 395 | ```objective-c 396 | - (void)viewDidLoad { 397 | [super viewDidLoad]; 398 | NSString *aesKey = @"TEST_AES_KEY"; 399 | NSLog(@"aesKey--%@",aesKey); 400 | self.view.backgroundColor = [UIColor greenColor]; 401 | } 402 | ``` 403 | 汇编下的代码[部分] 404 | ```assembly 405 | self = X0 ; ViewController *const 406 | _cmd = X1 ; SEL 407 | SUB SP, SP, #0x40 408 | STP X20, X19, [SP,#0x30+var_10] 409 | STP X29, X30, [SP,#0x30+var_s0] 410 | ADD X29, SP, #0x30 411 | MOV X19, self 412 | self = X19 ; ViewController *const 413 | NOP 414 | LDR X8, =_OBJC_CLASS_$_ViewController 415 | STP X0, X8, [SP,#0x30+var_20] 416 | NOP 417 | LDR _cmd, =sel_viewDidLoad ; "viewDidLoad" 418 | ADD X0, SP, #0x30+var_20 419 | BL _objc_msgSendSuper2 420 | ADR X8, cfstr_TestAesKey ; "TEST_AES_KEY" 421 | NOP 422 | aesKey = X8 ; Foundation::NSString::NSString * 423 | STR aesKey, [SP,#0x30+var_30] 424 | ADR X0, cfstr_Aeskey ; "aesKey--%@" 425 | ``` 426 | * 若使用md5或aes等通用加密函数时,关键的加密前的数据或加密key不宜直接当作函数参数传入 427 | 428 | ### 字符串加密&代码混淆 429 | * 字符串加密即关键的常量字符串不直接写死在代码中,而是通过一定的运算计算出来,加大攻击者破解难度 430 | * 代码混淆一般是利用宏进行字符串替换,使得攻击者使用class-dump或ida等工具得出的类名和函数变成无意义的字符串,加大攻击者破解难度 431 | * 推荐使用mj老师的[MJCodeObfuscation](https://github.com/CoderMJLee/MJCodeObfuscation)进行字符串加密与代码混淆,快捷高效 432 | * 注意:大规模使用混淆可能会导致上架审核被拒,建议只处理核心类和方法 433 | 434 | ### 【iOS逆向】iOSApp+springboot后端sign签名+aes加密流程&逆向破解分析示例(class-dump+Logos+monkeyDev+IDA) 435 | * 点击访问👉 [【iOS逆向】iOSApp+springboot后端sign签名+aes加密流程&逆向破解分析示例(class-dump+Logos+monkeyDev+IDA)](https://github.com/SmileZXLee/iOSSignatureAnalysis) 436 | 437 | ### 【iOS逆向】高效Tweak工具函数集,基于theos、monkeyDev 438 | * 点击访问👉 [【iOS逆向】高效Tweak工具函数集,基于theos、monkeyDev](https://github.com/SmileZXLee/ZXHookUtil) 439 | 440 | ### 浅谈http、https与数据加密 441 | * 点击访问👉 [浅谈http、https与数据加密](https://github.com/SmileZXLee/aboutHttp) 442 | 443 | ### 防抓包、http-dns解决方案,防止DNS劫持 444 | * 点击访问👉 [ZXRequestBlock](https://github.com/SmileZXLee/ZXRequestBlock) 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttackDylib/Config/ANYMethodLog.m: -------------------------------------------------------------------------------- 1 | // 2 | // ANYMethodLog.m 3 | // ANYMethodLog 4 | // 5 | // Created by qiuhaodong on 2017/1/14. 6 | // Copyright © 2017年 qiuhaodong. All rights reserved. 7 | // 8 | // https://github.com/qhd/ANYMethodLog.git 9 | // 10 | 11 | /*经实践打印出不同类型占的长度,放此以方便调试查看 12 | +---------------------------+------------+------------+--------+ 13 | | type | value(32) | value(64) | comp | 14 | |---------------------------|------------|------------|--------| 15 | | sizeof(char) | 1 | 1 | | 16 | |---------------------------|------------|------------|--------| 17 | | sizeof(int) | 4 | 4 | | 18 | |---------------------------|------------|------------|--------| 19 | | sizeof(short) | 2 | 2 | | 20 | |---------------------------|------------|------------|--------| 21 | | sizeof(long) | 4 | 8 | * | 22 | |---------------------------|------------|------------|--------| 23 | | sizeof(long long) | 8 | 8 | | 24 | |---------------------------|------------|------------|--------| 25 | | sizeof(unsigned char) | 1 | 1 | | 26 | |---------------------------|------------|------------|--------| 27 | | sizeof(unsigned int) | 4 | 4 | | 28 | |---------------------------|------------|------------|--------| 29 | | sizeof(unsigned short) | 2 | 2 | | 30 | |---------------------------|------------|------------|--------| 31 | | sizeof(unsigned long) | 4 | 8 | * | 32 | |---------------------------|------------|------------|--------| 33 | | sizeof(unsigned long long)| 8 | 8 | | 34 | |---------------------------|------------|------------|--------| 35 | | sizeof(float) | 4 | 4 | | 36 | |---------------------------|------------|------------|--------| 37 | | sizeof(double) | 8 | 8 | | 38 | |---------------------------|------------|------------|--------| 39 | | sizeof(BOOL) | 1 | 1 | | 40 | |---------------------------|------------|------------|--------| 41 | | sizeof(void) | 1 | 1 | | 42 | |---------------------------|------------|------------|--------| 43 | | sizeof(char*) | 4 | 8 | * | 44 | |---------------------------|------------|------------|--------| 45 | | sizeof(id) | 4 | 8 | * | 46 | |---------------------------|------------|------------|--------| 47 | | sizeof(Class) | 4 | 8 | * | 48 | |---------------------------|------------|------------|--------| 49 | | sizeof(SEL) | 4 | 8 | * | 50 | +---------------------------+------------+------------+--------+ 51 | */ 52 | 53 | #import "ANYMethodLog.h" 54 | #import 55 | #import 56 | #import 57 | 58 | #pragma mark - deep 59 | 60 | //调用层次 61 | static int deep = -1; 62 | 63 | #pragma mark - Func Define 64 | 65 | BOOL qhd_isInBlackList(NSString *methodName); 66 | NSDictionary *qhd_canHandleTypeDic(void); 67 | BOOL qhd_isCanHandle(NSString *typeEncode); 68 | SEL qhd_createNewSelector(SEL originalSelector); 69 | BOOL qhd_isStructType(const char *argumentType); 70 | NSString *qhd_structName(const char *argumentType); 71 | BOOL isCGRect (const char *type); 72 | BOOL isCGPoint (const char *type); 73 | BOOL isCGSize (const char *type); 74 | BOOL isCGVector (const char *type); 75 | BOOL isUIOffset (const char *type); 76 | BOOL isUIEdgeInsets (const char *type); 77 | BOOL isCGAffineTransform(const char *type); 78 | BOOL qhd_isCanHook(Method method, const char *returnType); 79 | id getReturnValue(NSInvocation *invocation); 80 | NSArray *qhd_method_arguments(NSInvocation *invocation); 81 | void qhd_forwardInvocation(id target, SEL selector, NSInvocation *invocation); 82 | BOOL qhd_replaceMethod(Class cls, SEL originSelector, char *returnType); 83 | void qhd_logMethod(Class aClass, BOOL(^condition)(SEL sel)); 84 | 85 | #pragma mark - AMLBlock 86 | 87 | @interface AMLBlock : NSObject 88 | 89 | @property (strong, nonatomic) NSString *targetClassName; 90 | @property (copy, nonatomic) ConditionBlock condition; 91 | @property (copy, nonatomic) BeforeBlock before; 92 | @property (copy, nonatomic) AfterBlock after; 93 | 94 | @end 95 | 96 | @implementation AMLBlock 97 | 98 | - (BOOL)runCondition:(SEL)sel { 99 | if (self.condition) { 100 | return self.condition(sel); 101 | } else { 102 | return YES; 103 | } 104 | } 105 | 106 | - (void)rundBefore:(id)target sel:(SEL)sel args:(NSArray *)args deep:(int) deep { 107 | if (self.before) { 108 | self.before(target, sel, args, deep); 109 | } 110 | } 111 | 112 | - (void)rundAfter:(id)target sel:(SEL)sel args:(NSArray *)args interval:(NSTimeInterval)interval deep:(int)deep retValue:(id)retValue{ 113 | if (self.after) { 114 | self.after(target, sel, args, interval, deep, retValue); 115 | } 116 | } 117 | 118 | @end 119 | 120 | 121 | #pragma mark - ANYMethodLog private interface 122 | 123 | @interface ANYMethodLog() 124 | 125 | @property (strong, nonatomic) NSMutableDictionary *blockCache; 126 | 127 | + (instancetype)sharedANYMethodLog; 128 | 129 | - (void)setAMLBlock:(AMLBlock *)block forKey:(NSString *)aKey; 130 | 131 | - (AMLBlock *)blockWithTarget:(id)target; 132 | 133 | @end 134 | 135 | 136 | #pragma mark - C function 137 | 138 | #define SHARED_ANYMETHODLOG [ANYMethodLog sharedANYMethodLog] 139 | 140 | //#define OPEN_TARGET_LOG 141 | 142 | #ifdef OPEN_TARGET_LOG 143 | #define TARGET_LOG(format, ...) NSLog(format, ## __VA_ARGS__) 144 | #else 145 | #define TARGET_LOG(format, ...) 146 | #endif 147 | 148 | 149 | //#define OPEN_DEV_LOG 150 | 151 | #ifdef OPEN_DEV_LOG 152 | #define DEV_LOG(format, ...) NSLog(format, ## __VA_ARGS__) 153 | #else 154 | #define DEV_LOG(format, ...) 155 | #endif 156 | 157 | //是否在默认的黑名单中 158 | BOOL qhd_isInBlackList(NSString *methodName) { 159 | static NSArray *defaultBlackList = nil; 160 | static dispatch_once_t onceToken; 161 | dispatch_once(&onceToken, ^{ 162 | defaultBlackList = @[/*UIViewController的:*/@".cxx_destruct", @"dealloc", @"_isDeallocating", @"release", @"autorelease", @"retain", @"Retain", @"_tryRetain", @"copy", /*UIView的:*/ @"nsis_descriptionOfVariable:", /*NSObject的:*/@"respondsToSelector:", @"class", @"methodSignatureForSelector:", @"allowsWeakReference", @"retainWeakReference", @"init", @"forwardInvocation:"]; 163 | }); 164 | return ([defaultBlackList containsObject:methodName]); 165 | } 166 | 167 | /*reference: https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html#//apple_ref/doc/uid/TP40008048-CH100-SW1 168 | 经实践发现与文档有差别 169 | 1.在64位时@encode(long)跟@encode(long long)的值一样; 170 | 2.在64位时@encode(unsigned long)跟@encode(unsigned long long)的值一样; 171 | 3.在32位时@encode(BOOL)跟@encode(char)一样。 172 | +--------------------+-----------+-----------+ 173 | | type |code(32bit)|code(64bit)| 174 | |--------------------|-----------|-----------| 175 | | BOOL | c | B | 176 | |--------------------|-----------|-----------| 177 | | char | c | c | 178 | |--------------------|-----------|-----------| 179 | | long | l | q | 180 | |--------------------|-----------|-----------| 181 | | long long | q | q | 182 | |--------------------|-----------|-----------| 183 | | unsigned long | L | Q | 184 | |--------------------|-----------|-----------| 185 | | unsigned long long | Q | Q | 186 | +--------------------+-----------+-----------+ 187 | */ 188 | NSDictionary *qhd_canHandleTypeDic() { 189 | static NSDictionary *dic = nil; 190 | static dispatch_once_t onceToken; 191 | dispatch_once(&onceToken, ^{ 192 | dic = @{[NSString stringWithUTF8String:@encode(char)] : @"(char)", 193 | [NSString stringWithUTF8String:@encode(int)] : @"(int)", 194 | [NSString stringWithUTF8String:@encode(short)] : @"(short)", 195 | [NSString stringWithUTF8String:@encode(long)] : @"(long)", 196 | [NSString stringWithUTF8String:@encode(long long)] : @"(long long)", 197 | [NSString stringWithUTF8String:@encode(unsigned char)] : @"(unsigned char))", 198 | [NSString stringWithUTF8String:@encode(unsigned int)] : @"(unsigned int)", 199 | [NSString stringWithUTF8String:@encode(unsigned short)] : @"(unsigned short)", 200 | [NSString stringWithUTF8String:@encode(unsigned long)] : @"(unsigned long)", 201 | [NSString stringWithUTF8String:@encode(unsigned long long)] : @"(unsigned long long)", 202 | [NSString stringWithUTF8String:@encode(float)] : @"(float)", 203 | [NSString stringWithUTF8String:@encode(double)] : @"(double)", 204 | [NSString stringWithUTF8String:@encode(BOOL)] : @"(BOOL)", 205 | [NSString stringWithUTF8String:@encode(void)] : @"(void)", 206 | [NSString stringWithUTF8String:@encode(char *)] : @"(char *)", 207 | [NSString stringWithUTF8String:@encode(id)] : @"(id)", 208 | [NSString stringWithUTF8String:@encode(Class)] : @"(Class)", 209 | [NSString stringWithUTF8String:@encode(SEL)] : @"(SEL)", 210 | [NSString stringWithUTF8String:@encode(CGRect)] : @"(CGRect)", 211 | [NSString stringWithUTF8String:@encode(CGPoint)] : @"(CGPoint)", 212 | [NSString stringWithUTF8String:@encode(CGSize)] : @"(CGSize)", 213 | [NSString stringWithUTF8String:@encode(CGVector)] : @"(CGVector)", 214 | [NSString stringWithUTF8String:@encode(CGAffineTransform)] : @"(CGAffineTransform)", 215 | [NSString stringWithUTF8String:@encode(UIOffset)] : @"(UIOffset)", 216 | [NSString stringWithUTF8String:@encode(UIEdgeInsets)] : @"(UIEdgeInsets)", 217 | @"@?":@"(block)" // block类型 218 | };//TODO:添加其他类型 219 | }); 220 | return dic; 221 | } 222 | 223 | //根据定义的类型的判断是否能处理 224 | BOOL qhd_isCanHandle(NSString *typeEncode) { 225 | return [qhd_canHandleTypeDic().allKeys containsObject:typeEncode]; 226 | } 227 | 228 | //创建一个新的selector 229 | SEL qhd_createNewSelector(SEL originalSelector) { 230 | NSString *oldSelectorName = NSStringFromSelector(originalSelector); 231 | NSString *newSelectorName = [NSString stringWithFormat:@"qhd_%@", oldSelectorName]; 232 | SEL newSelector = NSSelectorFromString(newSelectorName); 233 | return newSelector; 234 | } 235 | 236 | //是否struct类型 237 | BOOL qhd_isStructType(const char *argumentType) { 238 | NSString *typeString = [NSString stringWithUTF8String:argumentType]; 239 | return ([typeString hasPrefix:@"{"] && [typeString hasSuffix:@"}"]); 240 | } 241 | 242 | //struct类型名 243 | NSString *qhd_structName(const char *argumentType) { 244 | NSString *typeString = [NSString stringWithUTF8String:argumentType]; 245 | NSUInteger start = [typeString rangeOfString:@"{"].location; 246 | NSUInteger end = [typeString rangeOfString:@"="].location; 247 | if (end > start) { 248 | return [typeString substringWithRange:NSMakeRange(start + 1, end - start - 1)]; 249 | } else { 250 | return nil; 251 | } 252 | } 253 | 254 | BOOL isCGRect (const char *type) {return [qhd_structName(type) isEqualToString:@"CGRect"];} 255 | BOOL isCGPoint (const char *type) {return [qhd_structName(type) isEqualToString:@"CGPoint"];} 256 | BOOL isCGSize (const char *type) {return [qhd_structName(type) isEqualToString:@"CGSize"];} 257 | BOOL isCGVector (const char *type) {return [qhd_structName(type) isEqualToString:@"CGVector"];} 258 | BOOL isUIOffset (const char *type) {return [qhd_structName(type) isEqualToString:@"UIOffset"];} 259 | BOOL isUIEdgeInsets (const char *type) {return [qhd_structName(type) isEqualToString:@"UIEdgeInsets"];} 260 | BOOL isCGAffineTransform(const char *type) {return [qhd_structName(type) isEqualToString:@"CGAffineTransform"];} 261 | 262 | //检查是否能处理 263 | BOOL qhd_isCanHook(Method method, const char *returnType) { 264 | 265 | //若在黑名单中则不处理 266 | NSString *selectorName = NSStringFromSelector(method_getName(method)); 267 | if (qhd_isInBlackList(selectorName)) { 268 | return NO; 269 | } 270 | 271 | if ([selectorName rangeOfString:@"qhd_"].location != NSNotFound) { 272 | return NO; 273 | } 274 | 275 | NSString *returnTypeString = [NSString stringWithUTF8String:returnType]; 276 | 277 | BOOL isCanHook = YES; 278 | if (!qhd_isCanHandle(returnTypeString)) { 279 | isCanHook = NO; 280 | } 281 | for(int k = 2 ; k < method_getNumberOfArguments(method); k ++) { 282 | char argument[250]; 283 | memset(argument, 0, sizeof(argument)); 284 | method_getArgumentType(method, k, argument, sizeof(argument)); 285 | NSString *argumentString = [NSString stringWithUTF8String:argument]; 286 | if (!qhd_isCanHandle(argumentString)) { 287 | isCanHook = NO; 288 | break; 289 | } 290 | } 291 | return isCanHook; 292 | } 293 | 294 | //获取方法返回值 295 | id getReturnValue(NSInvocation *invocation){ 296 | const char *returnType = invocation.methodSignature.methodReturnType; 297 | if (returnType[0] == 'r') { 298 | returnType++; 299 | } 300 | #define WRAP_GET_VALUE(type) \ 301 | do { \ 302 | type val = 0; \ 303 | [invocation getReturnValue:&val]; \ 304 | return @(val); \ 305 | } while (0) 306 | if (strcmp(returnType, @encode(id)) == 0 || strcmp(returnType, @encode(Class)) == 0 || strcmp(returnType, @encode(void (^)(void))) == 0) { 307 | __autoreleasing id returnObj; 308 | [invocation getReturnValue:&returnObj]; 309 | return returnObj; 310 | } else if (strcmp(returnType, @encode(char)) == 0) { 311 | WRAP_GET_VALUE(char); 312 | } else if (strcmp(returnType, @encode(int)) == 0) { 313 | WRAP_GET_VALUE(int); 314 | } else if (strcmp(returnType, @encode(short)) == 0) { 315 | WRAP_GET_VALUE(short); 316 | } else if (strcmp(returnType, @encode(long)) == 0) { 317 | WRAP_GET_VALUE(long); 318 | } else if (strcmp(returnType, @encode(long long)) == 0) { 319 | WRAP_GET_VALUE(long long); 320 | } else if (strcmp(returnType, @encode(unsigned char)) == 0) { 321 | WRAP_GET_VALUE(unsigned char); 322 | } else if (strcmp(returnType, @encode(unsigned int)) == 0) { 323 | WRAP_GET_VALUE(unsigned int); 324 | } else if (strcmp(returnType, @encode(unsigned short)) == 0) { 325 | WRAP_GET_VALUE(unsigned short); 326 | } else if (strcmp(returnType, @encode(unsigned long)) == 0) { 327 | WRAP_GET_VALUE(unsigned long); 328 | } else if (strcmp(returnType, @encode(unsigned long long)) == 0) { 329 | WRAP_GET_VALUE(unsigned long long); 330 | } else if (strcmp(returnType, @encode(float)) == 0) { 331 | WRAP_GET_VALUE(float); 332 | } else if (strcmp(returnType, @encode(double)) == 0) { 333 | WRAP_GET_VALUE(double); 334 | } else if (strcmp(returnType, @encode(BOOL)) == 0) { 335 | WRAP_GET_VALUE(BOOL); 336 | } else if (strcmp(returnType, @encode(char *)) == 0) { 337 | WRAP_GET_VALUE(const char *); 338 | } else if (strcmp(returnType, @encode(void)) == 0) { 339 | return @"void"; 340 | } else { 341 | NSUInteger valueSize = 0; 342 | NSGetSizeAndAlignment(returnType, &valueSize, NULL); 343 | unsigned char valueBytes[valueSize]; 344 | [invocation getReturnValue:valueBytes]; 345 | 346 | return [NSValue valueWithBytes:valueBytes objCType:returnType]; 347 | } 348 | return nil; 349 | } 350 | 351 | //获取方法参数 352 | NSArray *qhd_method_arguments(NSInvocation *invocation) { 353 | NSMethodSignature *methodSignature = [invocation methodSignature]; 354 | NSMutableArray *argList = (methodSignature.numberOfArguments > 2 ? [NSMutableArray array] : nil); 355 | for (NSUInteger i = 2; i < methodSignature.numberOfArguments; i++) { 356 | const char *argumentType = [methodSignature getArgumentTypeAtIndex:i]; 357 | id arg = nil; 358 | 359 | if (qhd_isStructType(argumentType)) { 360 | #define GET_STRUCT_ARGUMENT(_type)\ 361 | if (is##_type(argumentType)) {\ 362 | _type arg_temp;\ 363 | [invocation getArgument:&arg_temp atIndex:i];\ 364 | arg = NSStringFrom##_type(arg_temp);\ 365 | } 366 | GET_STRUCT_ARGUMENT(CGRect) 367 | else GET_STRUCT_ARGUMENT(CGPoint) 368 | else GET_STRUCT_ARGUMENT(CGSize) 369 | else GET_STRUCT_ARGUMENT(CGVector) 370 | else GET_STRUCT_ARGUMENT(UIOffset) 371 | else GET_STRUCT_ARGUMENT(UIEdgeInsets) 372 | else GET_STRUCT_ARGUMENT(CGAffineTransform) 373 | 374 | if (arg == nil) { 375 | arg = @"{unknown}"; 376 | } 377 | } 378 | #define GET_ARGUMENT(_type)\ 379 | if (0 == strcmp(argumentType, @encode(_type))) {\ 380 | _type arg_temp;\ 381 | [invocation getArgument:&arg_temp atIndex:i];\ 382 | arg = @(arg_temp);\ 383 | } 384 | else GET_ARGUMENT(char) 385 | else GET_ARGUMENT(int) 386 | else GET_ARGUMENT(short) 387 | else GET_ARGUMENT(long) 388 | else GET_ARGUMENT(long long) 389 | else GET_ARGUMENT(unsigned char) 390 | else GET_ARGUMENT(unsigned int) 391 | else GET_ARGUMENT(unsigned short) 392 | else GET_ARGUMENT(unsigned long) 393 | else GET_ARGUMENT(unsigned long long) 394 | else GET_ARGUMENT(float) 395 | else GET_ARGUMENT(double) 396 | else GET_ARGUMENT(BOOL) 397 | else if (0 == strcmp(argumentType, @encode(id))) { 398 | __unsafe_unretained id arg_temp; 399 | [invocation getArgument:&arg_temp atIndex:i]; 400 | arg = arg_temp; 401 | } 402 | else if (0 == strcmp(argumentType, @encode(SEL))) { 403 | SEL arg_temp; 404 | [invocation getArgument:&arg_temp atIndex:i]; 405 | arg = NSStringFromSelector(arg_temp); 406 | } 407 | else if (0 == strcmp(argumentType, @encode(char *))) { 408 | char *arg_temp; 409 | [invocation getArgument:&arg_temp atIndex:i]; 410 | arg = [NSString stringWithUTF8String:arg_temp]; 411 | } 412 | else if (0 == strcmp(argumentType, @encode(void *))) { 413 | void *arg_temp; 414 | [invocation getArgument:&arg_temp atIndex:i]; 415 | arg = (__bridge id _Nonnull)arg_temp; 416 | } 417 | else if (0 == strcmp(argumentType, @encode(Class))) { 418 | Class arg_temp; 419 | [invocation getArgument:&arg_temp atIndex:i]; 420 | arg = arg_temp; 421 | } 422 | 423 | if (!arg) { 424 | arg = @"unknown"; 425 | } 426 | [argList addObject:arg]; 427 | } 428 | return argList; 429 | } 430 | 431 | //forwardInvocation:方法的新IMP 432 | void qhd_forwardInvocation(id target, SEL selector, NSInvocation *invocation) { 433 | NSArray *argList = qhd_method_arguments(invocation); 434 | 435 | SEL originSelector = invocation.selector; 436 | 437 | NSString *originSelectorString = NSStringFromSelector(originSelector); 438 | 439 | //友盟的UMAOCTools会产生问题 440 | if ([originSelectorString rangeOfString:@"hook_"].location != NSNotFound) { 441 | return; 442 | } 443 | 444 | [invocation setSelector:qhd_createNewSelector(originSelector)]; 445 | [invocation setTarget:target]; 446 | 447 | deep++; 448 | 449 | AMLBlock *block = [SHARED_ANYMETHODLOG blockWithTarget:target]; 450 | [block rundBefore:target sel:originSelector args:argList deep:deep]; 451 | 452 | NSDate *start = [NSDate date]; 453 | 454 | [invocation invoke]; 455 | 456 | NSDate *end = [NSDate date]; 457 | NSTimeInterval interval = [end timeIntervalSinceDate:start]; 458 | 459 | [block rundAfter:target sel:originSelector args:argList interval:interval deep:deep retValue:getReturnValue(invocation)]; 460 | 461 | deep--; 462 | } 463 | 464 | //替换方法 465 | BOOL qhd_replaceMethod(Class cls, SEL originSelector, char *returnType) { 466 | Method originMethod = class_getInstanceMethod(cls, originSelector); 467 | if (originMethod == nil) { 468 | return NO; 469 | } 470 | const char *originTypes = method_getTypeEncoding(originMethod); 471 | IMP msgForwardIMP = _objc_msgForward; 472 | #if !defined(__arm64__) 473 | if (qhd_isStructType(returnType)) { 474 | //Reference JSPatch: 475 | //In some cases that returns struct, we should use the '_stret' API: 476 | //http://sealiesoftware.com/blog/archive/2008/10/30/objc_explain_objc_msgSend_stret.html 477 | //NSMethodSignature knows the detail but has no API to return, we can only get the info from debugDescription. 478 | NSMethodSignature *methodSignature = [NSMethodSignature signatureWithObjCTypes:originTypes]; 479 | if ([methodSignature.debugDescription rangeOfString:@"is special struct return? YES"].location != NSNotFound) { 480 | msgForwardIMP = (IMP)_objc_msgForward_stret; 481 | } 482 | } 483 | #endif 484 | 485 | IMP originIMP = method_getImplementation(originMethod); 486 | 487 | if (originIMP == nil || originIMP == msgForwardIMP) { 488 | return NO; 489 | } 490 | 491 | //把原方法的IMP换成_objc_msgForward,使之触发forwardInvocation方法 492 | class_replaceMethod(cls, originSelector, msgForwardIMP, originTypes); 493 | 494 | //把方法forwardInvocation的IMP换成qhd_forwardInvocation 495 | class_replaceMethod(cls, @selector(forwardInvocation:), (IMP)qhd_forwardInvocation, "v@:@"); 496 | 497 | //创建一个新方法,IMP就是原方法的原来的IMP,那么只要在qhd_forwardInvocation调用新方法即可 498 | SEL newSelecotr = qhd_createNewSelector(originSelector); 499 | BOOL isAdd = class_addMethod(cls, newSelecotr, originIMP, originTypes); 500 | if (!isAdd) { 501 | DEV_LOG(@"class_addMethod fail"); 502 | } 503 | 504 | return YES; 505 | } 506 | 507 | void qhd_logMethod(Class aClass, BOOL(^condition)(SEL sel)) { 508 | unsigned int outCount; 509 | Method *methods = class_copyMethodList(aClass,&outCount); 510 | 511 | for (int i = 0; i < outCount; i ++) { 512 | Method tempMethod = *(methods + i); 513 | SEL selector = method_getName(tempMethod); 514 | char *returnType = method_copyReturnType(tempMethod); 515 | 516 | BOOL isCan = qhd_isCanHook(tempMethod, returnType); 517 | 518 | if (isCan && condition) { 519 | isCan = condition(selector); 520 | } 521 | 522 | if (isCan) { 523 | if (qhd_replaceMethod(aClass, selector, returnType)) { 524 | DEV_LOG(@"success hook method:%@ types:%s", NSStringFromSelector(selector), method_getDescription(tempMethod)->types); 525 | } else { 526 | DEV_LOG(@"fail method:%@ types:%s", NSStringFromSelector(selector), method_getDescription(tempMethod)->types); 527 | } 528 | } else { 529 | DEV_LOG(@"can not hook method:%@ types:%s", NSStringFromSelector(selector), method_getDescription(tempMethod)->types); 530 | } 531 | free(returnType); 532 | } 533 | free(methods); 534 | } 535 | 536 | 537 | #pragma mark - ANYMethodLog implementation 538 | 539 | @implementation ANYMethodLog 540 | 541 | + (void)logMethodWithClass:(Class)aClass 542 | condition:(ConditionBlock) condition 543 | before:(BeforeBlock) before 544 | after:(AfterBlock) after { 545 | #ifndef DEBUG 546 | return; 547 | #endif 548 | 549 | if (aClass) { 550 | AMLBlock *block = [[AMLBlock alloc] init]; 551 | block.targetClassName = NSStringFromClass(aClass); 552 | block.condition = condition; 553 | block.before = before; 554 | block.after = after; 555 | [SHARED_ANYMETHODLOG setAMLBlock:block forKey:block.targetClassName]; 556 | } 557 | 558 | qhd_logMethod(aClass, condition); 559 | 560 | //获取元类,处理类方法。(注意获取元类是用object_getClass,而不是class_getSuperclass) 561 | Class metaClass = object_getClass(aClass); 562 | qhd_logMethod(metaClass, condition); 563 | } 564 | 565 | + (instancetype)sharedANYMethodLog { 566 | static ANYMethodLog *_sharedANYMethodLog = nil; 567 | static dispatch_once_t onceToken; 568 | dispatch_once(&onceToken, ^{ 569 | _sharedANYMethodLog = [[self alloc] init]; 570 | _sharedANYMethodLog.blockCache = [NSMutableDictionary dictionary]; 571 | }); 572 | return _sharedANYMethodLog; 573 | } 574 | 575 | - (void)setAMLBlock:(AMLBlock *)block forKey:(NSString *)aKey { 576 | @synchronized (self) { 577 | [self.blockCache setObject:block forKey:aKey]; 578 | } 579 | } 580 | 581 | - (AMLBlock *)blockWithTarget:(id)target { 582 | Class class = [target class]; 583 | AMLBlock *block = [self.blockCache objectForKey:NSStringFromClass(class)]; 584 | while (block == nil) { 585 | class = [class superclass]; 586 | if (class == nil) { 587 | break; 588 | } 589 | block = [self.blockCache objectForKey:NSStringFromClass(class)]; 590 | } 591 | return block; 592 | } 593 | 594 | @end 595 | -------------------------------------------------------------------------------- /ZXHookAttack/ZXHookAttack.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 743C944D226B52C00053D662 /* MDConfig.plist in Resources */ = {isa = PBXBuildFile; fileRef = 743C944C226B52C00053D662 /* MDConfig.plist */; }; 11 | 743C9457226B52C00053D662 /* libZXHookAttackDylib.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 743C9456226B52C00053D662 /* libZXHookAttackDylib.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 12 | 743C945C226B52C00053D662 /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 743C945B226B52C00053D662 /* JavaScriptCore.framework */; }; 13 | 743C945E226B52C00053D662 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 743C945D226B52C00053D662 /* Foundation.framework */; }; 14 | 743C9460226B52C00053D662 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 743C945F226B52C00053D662 /* UIKit.framework */; }; 15 | 743C9465226B52C00053D662 /* ZXHookAttackDylib.mm in Sources */ = {isa = PBXBuildFile; fileRef = 743C9464226B52C00053D662 /* ZXHookAttackDylib.mm */; }; 16 | 743C9468226B52C00053D662 /* MDConfigManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 743C9467226B52C00053D662 /* MDConfigManager.h */; }; 17 | 743C946A226B52C00053D662 /* MDConfigManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 743C9469226B52C00053D662 /* MDConfigManager.m */; }; 18 | 743C946C226B52C00053D662 /* MDCycriptManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 743C946B226B52C00053D662 /* MDCycriptManager.h */; }; 19 | 743C946E226B52C00053D662 /* MDCycriptManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 743C946D226B52C00053D662 /* MDCycriptManager.m */; }; 20 | 743C9470226B52C00053D662 /* MDMethodTrace.h in Headers */ = {isa = PBXBuildFile; fileRef = 743C946F226B52C00053D662 /* MDMethodTrace.h */; }; 21 | 743C9472226B52C00053D662 /* MDMethodTrace.m in Sources */ = {isa = PBXBuildFile; fileRef = 743C9471226B52C00053D662 /* MDMethodTrace.m */; }; 22 | 743C9474226B52C00053D662 /* ANYMethodLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 743C9473226B52C00053D662 /* ANYMethodLog.h */; }; 23 | 743C9476226B52C00053D662 /* ANYMethodLog.m in Sources */ = {isa = PBXBuildFile; fileRef = 743C9475226B52C00053D662 /* ANYMethodLog.m */; }; 24 | 743C9479226B52C00053D662 /* LLDBTools.h in Headers */ = {isa = PBXBuildFile; fileRef = 743C9478226B52C00053D662 /* LLDBTools.h */; }; 25 | 743C947B226B52C00053D662 /* LLDBTools.mm in Sources */ = {isa = PBXBuildFile; fileRef = 743C947A226B52C00053D662 /* LLDBTools.mm */; }; 26 | 743C9480226B52C00053D662 /* AntiAntiDebug.m in Sources */ = {isa = PBXBuildFile; fileRef = 743C947F226B52C00053D662 /* AntiAntiDebug.m */; }; 27 | 743C9483226B52C00053D662 /* fishhook.c in Sources */ = {isa = PBXBuildFile; fileRef = 743C9482226B52C00053D662 /* fishhook.c */; }; 28 | 743C9485226B52C00053D662 /* fishhook.h in Headers */ = {isa = PBXBuildFile; fileRef = 743C9484226B52C00053D662 /* fishhook.h */; }; 29 | 743C9487226B52C00053D662 /* ZXHookAttackDylib.h in Headers */ = {isa = PBXBuildFile; fileRef = 743C9486226B52C00053D662 /* ZXHookAttackDylib.h */; }; 30 | 743C9489226B52C00053D662 /* ZXHookAttackDylib.m in Sources */ = {isa = PBXBuildFile; fileRef = 743C9488226B52C00053D662 /* ZXHookAttackDylib.m */; }; 31 | 743C9497226B94EC0053D662 /* StatHook.h in Headers */ = {isa = PBXBuildFile; fileRef = 743C9495226B94EC0053D662 /* StatHook.h */; }; 32 | 743C9498226B94EC0053D662 /* StatHook.m in Sources */ = {isa = PBXBuildFile; fileRef = 743C9496226B94EC0053D662 /* StatHook.m */; }; 33 | /* End PBXBuildFile section */ 34 | 35 | /* Begin PBXContainerItemProxy section */ 36 | 743C9458226B52C00053D662 /* PBXContainerItemProxy */ = { 37 | isa = PBXContainerItemProxy; 38 | containerPortal = 743C9439226B52C00053D662 /* Project object */; 39 | proxyType = 1; 40 | remoteGlobalIDString = 743C9455226B52C00053D662; 41 | remoteInfo = ZXHookAttackDylib; 42 | }; 43 | /* End PBXContainerItemProxy section */ 44 | 45 | /* Begin PBXCopyFilesBuildPhase section */ 46 | 743C9441226B52C00053D662 /* CopyFiles */ = { 47 | isa = PBXCopyFilesBuildPhase; 48 | buildActionMask = 2147483647; 49 | dstPath = ""; 50 | dstSubfolderSpec = 10; 51 | files = ( 52 | 743C9457226B52C00053D662 /* libZXHookAttackDylib.dylib in CopyFiles */, 53 | ); 54 | runOnlyForDeploymentPostprocessing = 0; 55 | }; 56 | /* End PBXCopyFilesBuildPhase section */ 57 | 58 | /* Begin PBXFileReference section */ 59 | 743C9444226B52C00053D662 /* ZXHookAttack.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ZXHookAttack.app; sourceTree = BUILT_PRODUCTS_DIR; }; 60 | 743C9447226B52C00053D662 /* icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon.png; sourceTree = ""; }; 61 | 743C9448226B52C00053D662 /* Target.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Target.plist; sourceTree = ""; }; 62 | 743C944A226B52C00053D662 /* quick-resign.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; name = "quick-resign.sh"; path = "Scripts/quick-resign.sh"; sourceTree = ""; }; 63 | 743C944C226B52C00053D662 /* MDConfig.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = MDConfig.plist; path = Config/MDConfig.plist; sourceTree = ""; }; 64 | 743C944F226B52C00053D662 /* put ipa or app here */ = {isa = PBXFileReference; lastKnownFileType = text; name = "put ipa or app here"; path = "TargetApp/put ipa or app here"; sourceTree = ""; }; 65 | 743C9450226B52C00053D662 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 66 | 743C9456226B52C00053D662 /* libZXHookAttackDylib.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libZXHookAttackDylib.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; 67 | 743C945B226B52C00053D662 /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; 68 | 743C945D226B52C00053D662 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 69 | 743C945F226B52C00053D662 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 70 | 743C9463226B52C00053D662 /* ZXHookAttackDylib.xm */ = {isa = PBXFileReference; lastKnownFileType = text; name = ZXHookAttackDylib.xm; path = Logos/ZXHookAttackDylib.xm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; 71 | 743C9464226B52C00053D662 /* ZXHookAttackDylib.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = ZXHookAttackDylib.mm; path = Logos/ZXHookAttackDylib.mm; sourceTree = ""; }; 72 | 743C9467226B52C00053D662 /* MDConfigManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MDConfigManager.h; path = Config/MDConfigManager.h; sourceTree = ""; }; 73 | 743C9469226B52C00053D662 /* MDConfigManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = MDConfigManager.m; path = Config/MDConfigManager.m; sourceTree = ""; }; 74 | 743C946B226B52C00053D662 /* MDCycriptManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MDCycriptManager.h; path = Config/MDCycriptManager.h; sourceTree = ""; }; 75 | 743C946D226B52C00053D662 /* MDCycriptManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = MDCycriptManager.m; path = Config/MDCycriptManager.m; sourceTree = ""; }; 76 | 743C946F226B52C00053D662 /* MDMethodTrace.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MDMethodTrace.h; path = Config/MDMethodTrace.h; sourceTree = ""; }; 77 | 743C9471226B52C00053D662 /* MDMethodTrace.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = MDMethodTrace.m; path = Config/MDMethodTrace.m; sourceTree = ""; }; 78 | 743C9473226B52C00053D662 /* ANYMethodLog.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ANYMethodLog.h; path = Config/ANYMethodLog.h; sourceTree = ""; }; 79 | 743C9475226B52C00053D662 /* ANYMethodLog.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = ANYMethodLog.m; path = Config/ANYMethodLog.m; sourceTree = ""; }; 80 | 743C9478226B52C00053D662 /* LLDBTools.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = LLDBTools.h; path = Tools/LLDBTools.h; sourceTree = ""; }; 81 | 743C947A226B52C00053D662 /* LLDBTools.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = LLDBTools.mm; path = Tools/LLDBTools.mm; sourceTree = ""; }; 82 | 743C947D226B52C00053D662 /* ZXHookAttackDylib-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ZXHookAttackDylib-Prefix.pch"; sourceTree = ""; }; 83 | 743C947F226B52C00053D662 /* AntiAntiDebug.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = AntiAntiDebug.m; path = AntiAntiDebug/AntiAntiDebug.m; sourceTree = ""; }; 84 | 743C9482226B52C00053D662 /* fishhook.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = fishhook.c; path = fishhook/fishhook.c; sourceTree = ""; }; 85 | 743C9484226B52C00053D662 /* fishhook.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = fishhook.h; path = fishhook/fishhook.h; sourceTree = ""; }; 86 | 743C9486226B52C00053D662 /* ZXHookAttackDylib.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZXHookAttackDylib.h; sourceTree = ""; }; 87 | 743C9488226B52C00053D662 /* ZXHookAttackDylib.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZXHookAttackDylib.m; sourceTree = ""; }; 88 | 743C9495226B94EC0053D662 /* StatHook.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StatHook.h; sourceTree = ""; }; 89 | 743C9496226B94EC0053D662 /* StatHook.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = StatHook.m; sourceTree = ""; }; 90 | /* End PBXFileReference section */ 91 | 92 | /* Begin PBXFrameworksBuildPhase section */ 93 | 743C943E226B52C00053D662 /* Frameworks */ = { 94 | isa = PBXFrameworksBuildPhase; 95 | buildActionMask = 2147483647; 96 | files = ( 97 | ); 98 | runOnlyForDeploymentPostprocessing = 0; 99 | }; 100 | 743C9453226B52C00053D662 /* Frameworks */ = { 101 | isa = PBXFrameworksBuildPhase; 102 | buildActionMask = 2147483647; 103 | files = ( 104 | 743C945C226B52C00053D662 /* JavaScriptCore.framework in Frameworks */, 105 | 743C9460226B52C00053D662 /* UIKit.framework in Frameworks */, 106 | 743C945E226B52C00053D662 /* Foundation.framework in Frameworks */, 107 | ); 108 | runOnlyForDeploymentPostprocessing = 0; 109 | }; 110 | /* End PBXFrameworksBuildPhase section */ 111 | 112 | /* Begin PBXGroup section */ 113 | 743C9438226B52C00053D662 = { 114 | isa = PBXGroup; 115 | children = ( 116 | 743C9446226B52C00053D662 /* ZXHookAttack */, 117 | 743C9461226B52C00053D662 /* ZXHookAttackDylib */, 118 | 743C945A226B52C00053D662 /* Frameworks */, 119 | 743C9445226B52C00053D662 /* Products */, 120 | ); 121 | sourceTree = ""; 122 | }; 123 | 743C9445226B52C00053D662 /* Products */ = { 124 | isa = PBXGroup; 125 | children = ( 126 | 743C9444226B52C00053D662 /* ZXHookAttack.app */, 127 | 743C9456226B52C00053D662 /* libZXHookAttackDylib.dylib */, 128 | ); 129 | name = Products; 130 | sourceTree = ""; 131 | }; 132 | 743C9446226B52C00053D662 /* ZXHookAttack */ = { 133 | isa = PBXGroup; 134 | children = ( 135 | 743C9447226B52C00053D662 /* icon.png */, 136 | 743C9448226B52C00053D662 /* Target.plist */, 137 | 743C9450226B52C00053D662 /* Info.plist */, 138 | 743C9449226B52C00053D662 /* Scripts */, 139 | 743C944B226B52C00053D662 /* Config */, 140 | 743C944E226B52C00053D662 /* TargetApp */, 141 | ); 142 | path = ZXHookAttack; 143 | sourceTree = ""; 144 | }; 145 | 743C9449226B52C00053D662 /* Scripts */ = { 146 | isa = PBXGroup; 147 | children = ( 148 | 743C944A226B52C00053D662 /* quick-resign.sh */, 149 | ); 150 | name = Scripts; 151 | sourceTree = ""; 152 | }; 153 | 743C944B226B52C00053D662 /* Config */ = { 154 | isa = PBXGroup; 155 | children = ( 156 | 743C944C226B52C00053D662 /* MDConfig.plist */, 157 | ); 158 | name = Config; 159 | sourceTree = ""; 160 | }; 161 | 743C944E226B52C00053D662 /* TargetApp */ = { 162 | isa = PBXGroup; 163 | children = ( 164 | 743C944F226B52C00053D662 /* put ipa or app here */, 165 | ); 166 | name = TargetApp; 167 | sourceTree = ""; 168 | }; 169 | 743C945A226B52C00053D662 /* Frameworks */ = { 170 | isa = PBXGroup; 171 | children = ( 172 | 743C945B226B52C00053D662 /* JavaScriptCore.framework */, 173 | 743C945D226B52C00053D662 /* Foundation.framework */, 174 | 743C945F226B52C00053D662 /* UIKit.framework */, 175 | ); 176 | name = Frameworks; 177 | sourceTree = ""; 178 | }; 179 | 743C9461226B52C00053D662 /* ZXHookAttackDylib */ = { 180 | isa = PBXGroup; 181 | children = ( 182 | 743C9486226B52C00053D662 /* ZXHookAttackDylib.h */, 183 | 743C9488226B52C00053D662 /* ZXHookAttackDylib.m */, 184 | 743C9462226B52C00053D662 /* Logos */, 185 | 743C9466226B52C00053D662 /* Config */, 186 | 743C9477226B52C00053D662 /* Tools */, 187 | 743C947E226B52C00053D662 /* AntiAntiDebug */, 188 | 743C9481226B52C00053D662 /* fishhook */, 189 | 743C947C226B52C00053D662 /* Supporting Files */, 190 | ); 191 | path = ZXHookAttackDylib; 192 | sourceTree = ""; 193 | }; 194 | 743C9462226B52C00053D662 /* Logos */ = { 195 | isa = PBXGroup; 196 | children = ( 197 | 743C9463226B52C00053D662 /* ZXHookAttackDylib.xm */, 198 | 743C9464226B52C00053D662 /* ZXHookAttackDylib.mm */, 199 | 743C9495226B94EC0053D662 /* StatHook.h */, 200 | 743C9496226B94EC0053D662 /* StatHook.m */, 201 | ); 202 | name = Logos; 203 | sourceTree = ""; 204 | }; 205 | 743C9466226B52C00053D662 /* Config */ = { 206 | isa = PBXGroup; 207 | children = ( 208 | 743C9467226B52C00053D662 /* MDConfigManager.h */, 209 | 743C9469226B52C00053D662 /* MDConfigManager.m */, 210 | 743C946B226B52C00053D662 /* MDCycriptManager.h */, 211 | 743C946D226B52C00053D662 /* MDCycriptManager.m */, 212 | 743C946F226B52C00053D662 /* MDMethodTrace.h */, 213 | 743C9471226B52C00053D662 /* MDMethodTrace.m */, 214 | 743C9473226B52C00053D662 /* ANYMethodLog.h */, 215 | 743C9475226B52C00053D662 /* ANYMethodLog.m */, 216 | ); 217 | name = Config; 218 | sourceTree = ""; 219 | }; 220 | 743C9477226B52C00053D662 /* Tools */ = { 221 | isa = PBXGroup; 222 | children = ( 223 | 743C9478226B52C00053D662 /* LLDBTools.h */, 224 | 743C947A226B52C00053D662 /* LLDBTools.mm */, 225 | ); 226 | name = Tools; 227 | sourceTree = ""; 228 | }; 229 | 743C947C226B52C00053D662 /* Supporting Files */ = { 230 | isa = PBXGroup; 231 | children = ( 232 | 743C947D226B52C00053D662 /* ZXHookAttackDylib-Prefix.pch */, 233 | ); 234 | name = "Supporting Files"; 235 | sourceTree = ""; 236 | }; 237 | 743C947E226B52C00053D662 /* AntiAntiDebug */ = { 238 | isa = PBXGroup; 239 | children = ( 240 | 743C947F226B52C00053D662 /* AntiAntiDebug.m */, 241 | ); 242 | name = AntiAntiDebug; 243 | sourceTree = ""; 244 | }; 245 | 743C9481226B52C00053D662 /* fishhook */ = { 246 | isa = PBXGroup; 247 | children = ( 248 | 743C9482226B52C00053D662 /* fishhook.c */, 249 | 743C9484226B52C00053D662 /* fishhook.h */, 250 | ); 251 | name = fishhook; 252 | sourceTree = ""; 253 | }; 254 | /* End PBXGroup section */ 255 | 256 | /* Begin PBXHeadersBuildPhase section */ 257 | 743C9454226B52C00053D662 /* Headers */ = { 258 | isa = PBXHeadersBuildPhase; 259 | buildActionMask = 2147483647; 260 | files = ( 261 | 743C946C226B52C00053D662 /* MDCycriptManager.h in Headers */, 262 | 743C9470226B52C00053D662 /* MDMethodTrace.h in Headers */, 263 | 743C9479226B52C00053D662 /* LLDBTools.h in Headers */, 264 | 743C9487226B52C00053D662 /* ZXHookAttackDylib.h in Headers */, 265 | 743C9468226B52C00053D662 /* MDConfigManager.h in Headers */, 266 | 743C9497226B94EC0053D662 /* StatHook.h in Headers */, 267 | 743C9474226B52C00053D662 /* ANYMethodLog.h in Headers */, 268 | 743C9485226B52C00053D662 /* fishhook.h in Headers */, 269 | ); 270 | runOnlyForDeploymentPostprocessing = 0; 271 | }; 272 | /* End PBXHeadersBuildPhase section */ 273 | 274 | /* Begin PBXNativeTarget section */ 275 | 743C9443226B52C00053D662 /* ZXHookAttack */ = { 276 | isa = PBXNativeTarget; 277 | buildConfigurationList = 743C948F226B52C00053D662 /* Build configuration list for PBXNativeTarget "ZXHookAttack" */; 278 | buildPhases = ( 279 | 743C943D226B52C00053D662 /* Sources */, 280 | 743C943E226B52C00053D662 /* Frameworks */, 281 | 743C943F226B52C00053D662 /* ShellScript */, 282 | 743C9440226B52C00053D662 /* Resources */, 283 | 743C9441226B52C00053D662 /* CopyFiles */, 284 | 743C9442226B52C00053D662 /* ShellScript */, 285 | ); 286 | buildRules = ( 287 | ); 288 | dependencies = ( 289 | 743C9459226B52C00053D662 /* PBXTargetDependency */, 290 | ); 291 | name = ZXHookAttack; 292 | productName = ZXHookAttack; 293 | productReference = 743C9444226B52C00053D662 /* ZXHookAttack.app */; 294 | productType = "com.apple.product-type.application"; 295 | }; 296 | 743C9455226B52C00053D662 /* ZXHookAttackDylib */ = { 297 | isa = PBXNativeTarget; 298 | buildConfigurationList = 743C948C226B52C00053D662 /* Build configuration list for PBXNativeTarget "ZXHookAttackDylib" */; 299 | buildPhases = ( 300 | 743C9451226B52C00053D662 /* ShellScript */, 301 | 743C9452226B52C00053D662 /* Sources */, 302 | 743C9453226B52C00053D662 /* Frameworks */, 303 | 743C9454226B52C00053D662 /* Headers */, 304 | ); 305 | buildRules = ( 306 | ); 307 | dependencies = ( 308 | ); 309 | name = ZXHookAttackDylib; 310 | productName = ZXHookAttackDylib; 311 | productReference = 743C9456226B52C00053D662 /* libZXHookAttackDylib.dylib */; 312 | productType = "com.apple.product-type.library.dynamic"; 313 | }; 314 | /* End PBXNativeTarget section */ 315 | 316 | /* Begin PBXProject section */ 317 | 743C9439226B52C00053D662 /* Project object */ = { 318 | isa = PBXProject; 319 | attributes = { 320 | LastUpgradeCheck = 1020; 321 | ORGANIZATIONNAME = "李兆祥"; 322 | TargetAttributes = { 323 | 743C9443226B52C00053D662 = { 324 | CreatedOnToolsVersion = 10.2; 325 | }; 326 | 743C9455226B52C00053D662 = { 327 | CreatedOnToolsVersion = 10.2; 328 | }; 329 | }; 330 | }; 331 | buildConfigurationList = 743C943C226B52C00053D662 /* Build configuration list for PBXProject "ZXHookAttack" */; 332 | compatibilityVersion = "Xcode 9.3"; 333 | developmentRegion = en; 334 | hasScannedForEncodings = 0; 335 | knownRegions = ( 336 | en, 337 | ); 338 | mainGroup = 743C9438226B52C00053D662; 339 | productRefGroup = 743C9445226B52C00053D662 /* Products */; 340 | projectDirPath = ""; 341 | projectRoot = ""; 342 | targets = ( 343 | 743C9443226B52C00053D662 /* ZXHookAttack */, 344 | 743C9455226B52C00053D662 /* ZXHookAttackDylib */, 345 | ); 346 | }; 347 | /* End PBXProject section */ 348 | 349 | /* Begin PBXResourcesBuildPhase section */ 350 | 743C9440226B52C00053D662 /* Resources */ = { 351 | isa = PBXResourcesBuildPhase; 352 | buildActionMask = 2147483647; 353 | files = ( 354 | 743C944D226B52C00053D662 /* MDConfig.plist in Resources */, 355 | ); 356 | runOnlyForDeploymentPostprocessing = 0; 357 | }; 358 | /* End PBXResourcesBuildPhase section */ 359 | 360 | /* Begin PBXShellScriptBuildPhase section */ 361 | 743C943F226B52C00053D662 /* ShellScript */ = { 362 | isa = PBXShellScriptBuildPhase; 363 | buildActionMask = 2147483647; 364 | files = ( 365 | ); 366 | inputFileListPaths = ( 367 | ); 368 | inputPaths = ( 369 | ); 370 | outputFileListPaths = ( 371 | ); 372 | outputPaths = ( 373 | ); 374 | runOnlyForDeploymentPostprocessing = 0; 375 | shellPath = /bin/sh; 376 | shellScript = /opt/MonkeyDev/Tools/pack.sh; 377 | }; 378 | 743C9442226B52C00053D662 /* ShellScript */ = { 379 | isa = PBXShellScriptBuildPhase; 380 | buildActionMask = 2147483647; 381 | files = ( 382 | ); 383 | inputFileListPaths = ( 384 | ); 385 | inputPaths = ( 386 | ); 387 | outputFileListPaths = ( 388 | ); 389 | outputPaths = ( 390 | ); 391 | runOnlyForDeploymentPostprocessing = 0; 392 | shellPath = /bin/sh; 393 | shellScript = "/opt/MonkeyDev/Tools/pack.sh codesign"; 394 | }; 395 | 743C9451226B52C00053D662 /* ShellScript */ = { 396 | isa = PBXShellScriptBuildPhase; 397 | buildActionMask = 2147483647; 398 | files = ( 399 | ); 400 | inputFileListPaths = ( 401 | ); 402 | inputPaths = ( 403 | ); 404 | outputFileListPaths = ( 405 | ); 406 | outputPaths = ( 407 | ); 408 | runOnlyForDeploymentPostprocessing = 0; 409 | shellPath = /bin/sh; 410 | shellScript = "/opt/MonkeyDev/bin/md --xcbp-logos"; 411 | }; 412 | /* End PBXShellScriptBuildPhase section */ 413 | 414 | /* Begin PBXSourcesBuildPhase section */ 415 | 743C943D226B52C00053D662 /* Sources */ = { 416 | isa = PBXSourcesBuildPhase; 417 | buildActionMask = 2147483647; 418 | files = ( 419 | ); 420 | runOnlyForDeploymentPostprocessing = 0; 421 | }; 422 | 743C9452226B52C00053D662 /* Sources */ = { 423 | isa = PBXSourcesBuildPhase; 424 | buildActionMask = 2147483647; 425 | files = ( 426 | 743C946E226B52C00053D662 /* MDCycriptManager.m in Sources */, 427 | 743C9489226B52C00053D662 /* ZXHookAttackDylib.m in Sources */, 428 | 743C9476226B52C00053D662 /* ANYMethodLog.m in Sources */, 429 | 743C946A226B52C00053D662 /* MDConfigManager.m in Sources */, 430 | 743C947B226B52C00053D662 /* LLDBTools.mm in Sources */, 431 | 743C9465226B52C00053D662 /* ZXHookAttackDylib.mm in Sources */, 432 | 743C9472226B52C00053D662 /* MDMethodTrace.m in Sources */, 433 | 743C9483226B52C00053D662 /* fishhook.c in Sources */, 434 | 743C9498226B94EC0053D662 /* StatHook.m in Sources */, 435 | 743C9480226B52C00053D662 /* AntiAntiDebug.m in Sources */, 436 | ); 437 | runOnlyForDeploymentPostprocessing = 0; 438 | }; 439 | /* End PBXSourcesBuildPhase section */ 440 | 441 | /* Begin PBXTargetDependency section */ 442 | 743C9459226B52C00053D662 /* PBXTargetDependency */ = { 443 | isa = PBXTargetDependency; 444 | target = 743C9455226B52C00053D662 /* ZXHookAttackDylib */; 445 | targetProxy = 743C9458226B52C00053D662 /* PBXContainerItemProxy */; 446 | }; 447 | /* End PBXTargetDependency section */ 448 | 449 | /* Begin XCBuildConfiguration section */ 450 | 743C948A226B52C00053D662 /* Debug */ = { 451 | isa = XCBuildConfiguration; 452 | buildSettings = { 453 | ALWAYS_SEARCH_USER_PATHS = NO; 454 | CLANG_ANALYZER_NONNULL = YES; 455 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 456 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 457 | CLANG_CXX_LIBRARY = "libc++"; 458 | CLANG_ENABLE_MODULES = YES; 459 | CLANG_ENABLE_OBJC_ARC = YES; 460 | CLANG_ENABLE_OBJC_WEAK = YES; 461 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 462 | CLANG_WARN_BOOL_CONVERSION = YES; 463 | CLANG_WARN_COMMA = YES; 464 | CLANG_WARN_CONSTANT_CONVERSION = YES; 465 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 466 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 467 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 468 | CLANG_WARN_EMPTY_BODY = YES; 469 | CLANG_WARN_ENUM_CONVERSION = YES; 470 | CLANG_WARN_INFINITE_RECURSION = YES; 471 | CLANG_WARN_INT_CONVERSION = YES; 472 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 473 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 474 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 475 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 476 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 477 | CLANG_WARN_STRICT_PROTOTYPES = YES; 478 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 479 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 480 | CLANG_WARN_UNREACHABLE_CODE = YES; 481 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 482 | CODE_SIGN_IDENTITY = "iPhone Developer"; 483 | COPY_PHASE_STRIP = NO; 484 | DEBUG_INFORMATION_FORMAT = dwarf; 485 | ENABLE_STRICT_OBJC_MSGSEND = YES; 486 | ENABLE_TESTABILITY = YES; 487 | GCC_C_LANGUAGE_STANDARD = gnu11; 488 | GCC_DYNAMIC_NO_PIC = NO; 489 | GCC_NO_COMMON_BLOCKS = YES; 490 | GCC_OPTIMIZATION_LEVEL = 0; 491 | GCC_PREPROCESSOR_DEFINITIONS = ( 492 | "DEBUG=1", 493 | "$(inherited)", 494 | ); 495 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 496 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 497 | GCC_WARN_UNDECLARED_SELECTOR = YES; 498 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 499 | GCC_WARN_UNUSED_FUNCTION = YES; 500 | GCC_WARN_UNUSED_VARIABLE = YES; 501 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 502 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 503 | MTL_FAST_MATH = YES; 504 | ONLY_ACTIVE_ARCH = YES; 505 | SDKROOT = iphoneos; 506 | }; 507 | name = Debug; 508 | }; 509 | 743C948B226B52C00053D662 /* Release */ = { 510 | isa = XCBuildConfiguration; 511 | buildSettings = { 512 | ALWAYS_SEARCH_USER_PATHS = NO; 513 | CLANG_ANALYZER_NONNULL = YES; 514 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 515 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 516 | CLANG_CXX_LIBRARY = "libc++"; 517 | CLANG_ENABLE_MODULES = YES; 518 | CLANG_ENABLE_OBJC_ARC = YES; 519 | CLANG_ENABLE_OBJC_WEAK = YES; 520 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 521 | CLANG_WARN_BOOL_CONVERSION = YES; 522 | CLANG_WARN_COMMA = YES; 523 | CLANG_WARN_CONSTANT_CONVERSION = YES; 524 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 525 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 526 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 527 | CLANG_WARN_EMPTY_BODY = YES; 528 | CLANG_WARN_ENUM_CONVERSION = YES; 529 | CLANG_WARN_INFINITE_RECURSION = YES; 530 | CLANG_WARN_INT_CONVERSION = YES; 531 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 532 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 533 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 534 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 535 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 536 | CLANG_WARN_STRICT_PROTOTYPES = YES; 537 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 538 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 539 | CLANG_WARN_UNREACHABLE_CODE = YES; 540 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 541 | CODE_SIGN_IDENTITY = "iPhone Developer"; 542 | COPY_PHASE_STRIP = NO; 543 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 544 | ENABLE_NS_ASSERTIONS = NO; 545 | ENABLE_STRICT_OBJC_MSGSEND = YES; 546 | GCC_C_LANGUAGE_STANDARD = gnu11; 547 | GCC_NO_COMMON_BLOCKS = YES; 548 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 549 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 550 | GCC_WARN_UNDECLARED_SELECTOR = YES; 551 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 552 | GCC_WARN_UNUSED_FUNCTION = YES; 553 | GCC_WARN_UNUSED_VARIABLE = YES; 554 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 555 | MTL_ENABLE_DEBUG_INFO = NO; 556 | MTL_FAST_MATH = YES; 557 | SDKROOT = iphoneos; 558 | VALIDATE_PRODUCT = YES; 559 | }; 560 | name = Release; 561 | }; 562 | 743C948D226B52C00053D662 /* Debug */ = { 563 | isa = XCBuildConfiguration; 564 | buildSettings = { 565 | CODE_SIGN_STYLE = Automatic; 566 | DEVELOPMENT_TEAM = 4Y2YPWFYNQ; 567 | DYLIB_COMPATIBILITY_VERSION = 1; 568 | DYLIB_CURRENT_VERSION = 1; 569 | ENABLE_BITCODE = NO; 570 | EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES = "*.nib *.lproj *.gch (*) .DS_Store CVS .svn .git .hg *.xcodeproj *.xcode *.pbproj *.pbxproj"; 571 | EXECUTABLE_PREFIX = lib; 572 | FRAMEWORK_SEARCH_PATHS = ( 573 | "$(inherited)", 574 | "$(MonkeyDevPath)/Frameworks/**", 575 | "$(MonkeyDevPath)/Librarys/**", 576 | "$(MonkeyDevTheosPath)/vendor/lib", 577 | ); 578 | GCC_C_LANGUAGE_STANDARD = gnu99; 579 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 580 | GCC_PREFIX_HEADER = "ZXHookAttackDylib/ZXHookAttackDylib-Prefix.pch"; 581 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 582 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 583 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 584 | HEADER_SEARCH_PATHS = ( 585 | "$(inherited)", 586 | "$(MonkeyDevPath)/include", 587 | "$(MonkeyDevTheosPath)/vendor/include/**", 588 | ); 589 | INSTALL_PATH = "@executable_path/Frameworks/libZXHookAttackDylib.dylib"; 590 | LD_RUNPATH_SEARCH_PATHS = ( 591 | "$(inherited)", 592 | "@executable_path/Frameworks", 593 | ); 594 | LIBRARY_SEARCH_PATHS = ( 595 | "$(inherited)", 596 | "$(MonkeyDevPath)/Frameworks", 597 | "$(MonkeyDevTheosPath)/vendor/lib/**", 598 | ); 599 | MonkeyDevPath = /opt/MonkeyDev; 600 | MonkeyDevTheosPath = /opt/theos; 601 | OTHER_CFLAGS = ( 602 | "$(inherited)", 603 | "-DTHEOS_INSTANCE_NAME=\"\\\"ZXHookAttackDylib\\\"\"", 604 | ); 605 | OTHER_LDFLAGS = ( 606 | "$(inherited)", 607 | "-weak_library", 608 | "/usr/lib/libc++.dylib", 609 | "-weak_library", 610 | "/usr/lib/libstdc++.dylib", 611 | "-weak_library", 612 | "$(MonkeyDevPath)/Frameworks/libsubstrate.dylib", 613 | "-lcycript", 614 | "-framework", 615 | RevealServer, 616 | ); 617 | PRODUCT_NAME = "$(TARGET_NAME)"; 618 | TARGETED_DEVICE_FAMILY = "1,2"; 619 | VALIDATE_PRODUCT = NO; 620 | }; 621 | name = Debug; 622 | }; 623 | 743C948E226B52C00053D662 /* Release */ = { 624 | isa = XCBuildConfiguration; 625 | buildSettings = { 626 | CODE_SIGN_STYLE = Automatic; 627 | COPY_PHASE_STRIP = YES; 628 | DEVELOPMENT_TEAM = 4Y2YPWFYNQ; 629 | DYLIB_COMPATIBILITY_VERSION = 1; 630 | DYLIB_CURRENT_VERSION = 1; 631 | ENABLE_BITCODE = NO; 632 | EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES = "*.nib *.lproj *.gch (*) .DS_Store CVS .svn .git .hg *.xcodeproj *.xcode *.pbproj *.pbxproj"; 633 | EXECUTABLE_PREFIX = lib; 634 | FRAMEWORK_SEARCH_PATHS = ( 635 | "$(inherited)", 636 | "$(MonkeyDevPath)/Frameworks/**", 637 | "$(MonkeyDevPath)/Librarys/**", 638 | "$(MonkeyDevTheosPath)/vendor/lib", 639 | ); 640 | GCC_C_LANGUAGE_STANDARD = gnu99; 641 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 642 | GCC_PREFIX_HEADER = "ZXHookAttackDylib/ZXHookAttackDylib-Prefix.pch"; 643 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 644 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 645 | HEADER_SEARCH_PATHS = ( 646 | "$(inherited)", 647 | "$(MonkeyDevPath)/include", 648 | "$(MonkeyDevTheosPath)/vendor/include/**", 649 | ); 650 | INSTALL_PATH = "@executable_path/Frameworks/libZXHookAttackDylib.dylib"; 651 | LD_RUNPATH_SEARCH_PATHS = ( 652 | "$(inherited)", 653 | "@executable_path/Frameworks", 654 | ); 655 | LIBRARY_SEARCH_PATHS = ( 656 | "$(inherited)", 657 | "$(MonkeyDevPath)/Frameworks", 658 | "$(MonkeyDevTheosPath)/vendor/lib/**", 659 | ); 660 | MonkeyDevPath = /opt/MonkeyDev; 661 | MonkeyDevTheosPath = /opt/theos; 662 | OTHER_CFLAGS = ( 663 | "$(inherited)", 664 | "-DTHEOS_INSTANCE_NAME=\"\\\"ZXHookAttackDylib\\\"\"", 665 | ); 666 | OTHER_LDFLAGS = ( 667 | "$(inherited)", 668 | "-weak_library", 669 | "/usr/lib/libc++.dylib", 670 | "-weak_library", 671 | "/usr/lib/libstdc++.dylib", 672 | "-weak_library", 673 | "$(MonkeyDevPath)/Frameworks/libsubstrate.dylib", 674 | ); 675 | PRODUCT_NAME = "$(TARGET_NAME)"; 676 | TARGETED_DEVICE_FAMILY = "1,2"; 677 | }; 678 | name = Release; 679 | }; 680 | 743C9490226B52C00053D662 /* Debug */ = { 681 | isa = XCBuildConfiguration; 682 | buildSettings = { 683 | CODE_SIGN_STYLE = Automatic; 684 | DEVELOPMENT_TEAM = 4Y2YPWFYNQ; 685 | ENABLE_BITCODE = NO; 686 | INFOPLIST_FILE = ZXHookAttack/Info.plist; 687 | MONKEYDEV_ADD_SUBSTRATE = YES; 688 | MONKEYDEV_CLASS_DUMP = NO; 689 | MONKEYDEV_DEFAULT_BUNDLEID = NO; 690 | MONKEYDEV_INSERT_DYLIB = YES; 691 | MONKEYDEV_RESTORE_SYMBOL = NO; 692 | MONKEYDEV_TARGET_APP = Optional; 693 | PODS_CONFIGURATION_BUILD_DIR = "$BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; 694 | PODS_ROOT = "${SRCROOT}/Pods"; 695 | PRODUCT_BUNDLE_IDENTIFIER = cn.zxlee.ZXHookAttack; 696 | PRODUCT_NAME = "$(TARGET_NAME)"; 697 | TARGETED_DEVICE_FAMILY = "1,2"; 698 | }; 699 | name = Debug; 700 | }; 701 | 743C9491226B52C00053D662 /* Release */ = { 702 | isa = XCBuildConfiguration; 703 | buildSettings = { 704 | CODE_SIGN_STYLE = Automatic; 705 | DEVELOPMENT_TEAM = 4Y2YPWFYNQ; 706 | ENABLE_BITCODE = NO; 707 | INFOPLIST_FILE = ZXHookAttack/Info.plist; 708 | MONKEYDEV_ADD_SUBSTRATE = YES; 709 | MONKEYDEV_CLASS_DUMP = NO; 710 | MONKEYDEV_DEFAULT_BUNDLEID = NO; 711 | MONKEYDEV_INSERT_DYLIB = YES; 712 | MONKEYDEV_RESTORE_SYMBOL = NO; 713 | MONKEYDEV_TARGET_APP = Optional; 714 | PODS_CONFIGURATION_BUILD_DIR = "$BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; 715 | PODS_ROOT = "${SRCROOT}/Pods"; 716 | PRODUCT_BUNDLE_IDENTIFIER = cn.zxlee.ZXHookAttack; 717 | PRODUCT_NAME = "$(TARGET_NAME)"; 718 | TARGETED_DEVICE_FAMILY = "1,2"; 719 | }; 720 | name = Release; 721 | }; 722 | /* End XCBuildConfiguration section */ 723 | 724 | /* Begin XCConfigurationList section */ 725 | 743C943C226B52C00053D662 /* Build configuration list for PBXProject "ZXHookAttack" */ = { 726 | isa = XCConfigurationList; 727 | buildConfigurations = ( 728 | 743C948A226B52C00053D662 /* Debug */, 729 | 743C948B226B52C00053D662 /* Release */, 730 | ); 731 | defaultConfigurationIsVisible = 0; 732 | defaultConfigurationName = Release; 733 | }; 734 | 743C948C226B52C00053D662 /* Build configuration list for PBXNativeTarget "ZXHookAttackDylib" */ = { 735 | isa = XCConfigurationList; 736 | buildConfigurations = ( 737 | 743C948D226B52C00053D662 /* Debug */, 738 | 743C948E226B52C00053D662 /* Release */, 739 | ); 740 | defaultConfigurationIsVisible = 0; 741 | defaultConfigurationName = Release; 742 | }; 743 | 743C948F226B52C00053D662 /* Build configuration list for PBXNativeTarget "ZXHookAttack" */ = { 744 | isa = XCConfigurationList; 745 | buildConfigurations = ( 746 | 743C9490226B52C00053D662 /* Debug */, 747 | 743C9491226B52C00053D662 /* Release */, 748 | ); 749 | defaultConfigurationIsVisible = 0; 750 | defaultConfigurationName = Release; 751 | }; 752 | /* End XCConfigurationList section */ 753 | }; 754 | rootObject = 743C9439226B52C00053D662 /* Project object */; 755 | } 756 | --------------------------------------------------------------------------------