├── 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 |
--------------------------------------------------------------------------------