├── Assets
├── .gitkeep
├── app.ipa
└── Frameworks
│ └── .gitkeep
├── Tools
├── optool
└── patch.sh
├── .gitattributes
├── IPAPatch.xcodeproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
└── project.pbxproj
├── IPAPatch
├── IPAPatchEntry.h
├── IPAPatchBypassAntiDebugging.h
├── Info.plist
├── IPAPatchEntry.m
├── Vendors
│ └── fishhook
│ │ ├── LICENSE
│ │ ├── fishhook.h
│ │ └── fishhook.c
└── IPAPatchBypassAntiDebugging.m
├── IPAPatch-DummyApp
├── main.m
├── AppDelegate.m
├── AppDelegate.h
├── ProjectConfigurationWarning.cpp
├── ProjectConfigurationWarning.hpp
└── Info.plist
├── LICENSE
├── .gitignore
└── README.md
/Assets/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Assets/app.ipa:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Assets/Frameworks/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Tools/optool:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jamie72/IPAPatch/HEAD/Tools/optool
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | patch.sh linguist-language=Objective-C
2 | IPAPatchBypassAntiDebugging.m linguist-language=Objective-C
3 | IPAPatch/Vendors/* linguist-language=Objective-C
--------------------------------------------------------------------------------
/IPAPatch.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/IPAPatch/IPAPatchEntry.h:
--------------------------------------------------------------------------------
1 | //
2 | // IPAPatchEntry.h
3 | // IPAPatch
4 | //
5 | // Created by wutian on 2017/3/17.
6 | // Copyright © 2017年 Weibo. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface IPAPatchEntry : NSObject
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/IPAPatch/IPAPatchBypassAntiDebugging.h:
--------------------------------------------------------------------------------
1 | //
2 | // IPAPatchBypassAntiDebugging.h
3 | // IPAPatch
4 | //
5 | // Created by wutian on 2017/3/23.
6 | // Copyright © 2017年 Weibo. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface IPAPatchBypassAntiDebugging : NSObject
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/IPAPatch-DummyApp/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // IPAPatch-DummyApp
4 | //
5 | // Created by wutian on 2017/3/17.
6 | // Copyright © 2017年 Weibo. 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 |
--------------------------------------------------------------------------------
/IPAPatch-DummyApp/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // IPAPatch-DummyApp
4 | //
5 | // Created by wutian on 2017/3/17.
6 | // Copyright © 2017年 Weibo. All rights reserved.
7 | //
8 |
9 | // ⚠️ Note: This is placeholder target for installing the ipa file
10 | // DO NOT MODIFY.
11 |
12 | #import "AppDelegate.h"
13 |
14 | @interface AppDelegate ()
15 |
16 | @end
17 |
18 | @implementation AppDelegate
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/IPAPatch-DummyApp/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // IPAPatch-DummyApp
4 | //
5 | // Created by wutian on 2017/3/17.
6 | // Copyright © 2017年 Weibo. All rights reserved.
7 | //
8 |
9 | // ⚠️ Note: This is placeholder target for installing the ipa file
10 | // DO NOT MODIFY.
11 |
12 | #import
13 |
14 | @interface AppDelegate : UIResponder
15 |
16 | @property (strong, nonatomic) UIWindow *window;
17 |
18 |
19 | @end
20 |
21 |
--------------------------------------------------------------------------------
/IPAPatch-DummyApp/ProjectConfigurationWarning.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // ProjectConfigurationWarning.cpp
3 | // IPAPatch
4 | //
5 | // Created by wutian on 2017/3/17.
6 | // Copyright © 2017年 Weibo. All rights reserved.
7 | //
8 | // ⚠️ Note: This is placeholder target for installing the ipa file
9 | // DO NOT MODIFY.
10 |
11 | #include "ProjectConfigurationWarning.hpp"
12 |
13 | // This file is only for warning generation of unconfiguration build settings. see "ProjectConfigurationWarning.hpp"
14 |
--------------------------------------------------------------------------------
/IPAPatch/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
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 | NSPrincipalClass
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Wutian
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.
22 |
--------------------------------------------------------------------------------
/IPAPatch/IPAPatchEntry.m:
--------------------------------------------------------------------------------
1 | //
2 | // IPAPatchEntry.m
3 | // IPAPatch
4 | //
5 | // Created by wutian on 2017/3/17.
6 | // Copyright © 2017年 Weibo. All rights reserved.
7 | //
8 |
9 | #import "IPAPatchEntry.h"
10 | #import
11 |
12 | @implementation IPAPatchEntry
13 |
14 | + (void)load
15 | {
16 | // DO YOUR WORKS...
17 |
18 | // For Example:
19 | [self for_example_showAlert];
20 | }
21 |
22 | + (void)for_example_showAlert
23 | {
24 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
25 | UIAlertController * alertController = [UIAlertController alertControllerWithTitle:@"Hacked" message:@"Hacked with IPAPatch" preferredStyle:UIAlertControllerStyleAlert];
26 | [alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:NULL]];
27 | UIViewController * controller = [UIApplication sharedApplication].keyWindow.rootViewController;
28 | while (controller.presentedViewController) {
29 | controller = controller.presentedViewController;
30 | }
31 | [controller presentViewController:alertController animated:YES completion:NULL];
32 | });
33 | }
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # IPAPatch
2 |
3 | Temp/
4 |
5 | # Xcode
6 | #
7 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
8 |
9 | ## Build generated
10 | build/
11 | DerivedData/
12 |
13 | ## Various settings
14 | *.pbxuser
15 | !default.pbxuser
16 | *.mode1v3
17 | !default.mode1v3
18 | *.mode2v3
19 | !default.mode2v3
20 | *.perspectivev3
21 | !default.perspectivev3
22 | xcuserdata/
23 |
24 | ## Other
25 | *.moved-aside
26 | *.xccheckout
27 | *.xcscmblueprint
28 |
29 | ## Obj-C/Swift specific
30 | *.hmap
31 | *.dSYM.zip
32 | *.dSYM
33 |
34 | # CocoaPods
35 | #
36 | # We recommend against adding the Pods directory to your .gitignore. However
37 | # you should judge for yourself, the pros and cons are mentioned at:
38 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
39 | #
40 | # Pods/
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
59 | fastlane/test_output
60 |
--------------------------------------------------------------------------------
/IPAPatch-DummyApp/ProjectConfigurationWarning.hpp:
--------------------------------------------------------------------------------
1 | //
2 | // ProjectConfigurationWarning.hpp
3 | // IPAPatch
4 | //
5 | // Created by wutian on 2017/3/17.
6 | // Copyright © 2017年 Weibo. All rights reserved.
7 | //
8 |
9 | // ⚠️ Note: This is placeholder target for installing the ipa file
10 | // DO NOT MODIFY.
11 |
12 | // This file is only for warning generation of unconfiguration build settings."
13 |
14 | #ifndef ProjectConfigurationWarning_hpp
15 | #define ProjectConfigurationWarning_hpp
16 |
17 | #include
18 | #include
19 |
20 | // compares two strings in compile time constant fashion
21 | constexpr bool strings_equal(char const * a, char const * b) {
22 | return *a == *b && (*a == '\0' || strings_equal(a + 1, b + 1));
23 | }
24 |
25 | #define STRINGIZE(x) #x
26 | #define STRINGIZE2(x) STRINGIZE(x)
27 | #define TARGET_BUNDLE_ID_STRING STRINGIZE2(TARGET_BUNDLE_ID)
28 |
29 | static_assert(!strings_equal(TARGET_BUNDLE_ID_STRING, "com.wutian.example"), "You Should Update the BundleID in Build Settings before Patching");
30 |
31 | // ⚠️ Note: "com.wutian.example" is placeholder bundleID for the result app, you should change it to your own and fixes the signing issues (if any), in the "IPAPatch-DummyApp - Project - General tab"
32 | // ⚠️ Note: The BundleDisplayName of DummyApp will used as prefix of the final name.
33 |
34 | #if TARGET_OS_SIMULATOR
35 | #error Simulators is not supported, Please select a real device from Xcode toolbar.
36 | #endif
37 |
38 | #endif /* ProjectConfigurationWarning_hpp */
39 |
--------------------------------------------------------------------------------
/IPAPatch-DummyApp/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | 💊
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UIRequiredDeviceCapabilities
26 |
27 | armv7
28 |
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 | UIInterfaceOrientationLandscapeLeft
33 | UIInterfaceOrientationLandscapeRight
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/IPAPatch/Vendors/fishhook/LICENSE:
--------------------------------------------------------------------------------
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.
--------------------------------------------------------------------------------
/IPAPatch/Vendors/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 |
--------------------------------------------------------------------------------
/IPAPatch/IPAPatchBypassAntiDebugging.m:
--------------------------------------------------------------------------------
1 | //
2 | // IPAPatchBypassAntiDebugging.m
3 | // IPAPatch
4 | //
5 | // Created by wutian on 2017/3/23.
6 | // Copyright © 2017年 Weibo. All rights reserved.
7 | //
8 |
9 | #import "IPAPatchBypassAntiDebugging.h"
10 | #import "fishhook.h"
11 | #import
12 | #import
13 |
14 | #define TESTS_BYPASS 0
15 |
16 | // Sources:
17 | // https://www.coredump.gr/articles/ios-anti-debugging-protections-part-1/
18 | // https://www.coredump.gr/articles/ios-anti-debugging-protections-part-2/
19 | // https://www.theiphonewiki.com/wiki/Bugging_Debuggers
20 |
21 | // Bypassing PT_DENY_ATTACH technique
22 |
23 | static void * (*original_dlsym)(void *, const char *);
24 |
25 | int fake_ptrace(int _request, pid_t _pid, caddr_t _addr, int _data)
26 | {
27 | return 0;
28 | }
29 |
30 | void * hooked_dlsym(void * __handle, const char * __symbol)
31 | {
32 | if (strcmp(__symbol, "ptrace") == 0) {
33 | return &fake_ptrace;
34 | }
35 |
36 | return original_dlsym(__handle, __symbol);
37 | }
38 |
39 | static void disable_pt_deny_attach()
40 | {
41 | original_dlsym = dlsym(RTLD_DEFAULT, "dlsym");
42 | rebind_symbols((struct rebinding[1]){{"dlsym", hooked_dlsym}}, 1);
43 | }
44 |
45 | // Bypassing sysctl debugger checking technique
46 |
47 | static int (*original_sysctl)(int *, u_int, void *, size_t *, void *, size_t);
48 |
49 | typedef struct kinfo_proc ipa_kinfo_proc;
50 |
51 | int hooked_sysctl(int * arg0, u_int arg1, void * arg2, size_t * arg3, void * arg4, size_t arg5)
52 | {
53 | bool modify_needed = arg1 == 4 && arg0[0] == CTL_KERN && arg0[1] == KERN_PROC && arg0[2] == KERN_PROC_PID && arg2 && arg3 && (*arg3 == sizeof(ipa_kinfo_proc));
54 |
55 | if (modify_needed) {
56 |
57 | bool original_p_traced = false;
58 | {
59 | ipa_kinfo_proc * pointer = arg2;
60 | ipa_kinfo_proc info = *pointer;
61 | original_p_traced = (info.kp_proc.p_flag & P_TRACED) != 0;
62 | }
63 |
64 | int ret = original_sysctl(arg0, arg1, arg2, arg3, arg4, arg5);
65 |
66 | // keep P_TRACED if input value contains it
67 | if (!original_p_traced) {
68 | ipa_kinfo_proc * pointer = arg2;
69 | ipa_kinfo_proc info = *pointer;
70 | info.kp_proc.p_flag ^= P_TRACED;
71 | *pointer = info;
72 | }
73 |
74 | return ret;
75 |
76 | } else {
77 | return original_sysctl(arg0, arg1, arg2, arg3, arg4, arg5);
78 | }
79 | }
80 |
81 | static void disable_sysctl_debugger_checking()
82 | {
83 | original_sysctl = dlsym(RTLD_DEFAULT, "sysctl");
84 | rebind_symbols((struct rebinding[1]){{"sysctl", hooked_sysctl}}, 1);
85 | }
86 |
87 | #if TESTS_BYPASS
88 | // Tests
89 | static void test_aniti_debugger();
90 | #endif
91 |
92 | @implementation IPAPatchBypassAntiDebugging
93 |
94 | + (void)load
95 | {
96 | disable_pt_deny_attach();
97 | disable_sysctl_debugger_checking();
98 |
99 | #if TESTS_BYPASS
100 | test_aniti_debugger();
101 | #endif
102 | }
103 |
104 | @end
105 |
106 | #if TESTS_BYPASS
107 |
108 | typedef int (*ptrace_ptr_t)(int _request, pid_t _pid, caddr_t _addr, int _data);
109 |
110 | #if !defined(PT_DENY_ATTACH)
111 | #define PT_DENY_ATTACH 31
112 | #endif
113 |
114 | static void test_aniti_debugger()
115 | {
116 | void* handle = dlopen(0, RTLD_GLOBAL | RTLD_NOW);
117 | ptrace_ptr_t ptrace_ptr = dlsym(handle, "ptrace");
118 | ptrace_ptr(PT_DENY_ATTACH, 0, 0, 0);
119 | dlclose(handle);
120 |
121 | int name[4];
122 | struct kinfo_proc info;
123 | size_t info_size = sizeof(info);
124 |
125 | info.kp_proc.p_flag = 0;
126 |
127 | name[0] = CTL_KERN;
128 | name[1] = KERN_PROC;
129 | name[2] = KERN_PROC_PID;
130 | name[3] = getpid();
131 |
132 | if (sysctl(name, 4, &info, &info_size, NULL, 0) == -1) {
133 | perror("sysctl");
134 | exit(-1);
135 | }
136 | bool debugging = ((info.kp_proc.p_flag & P_TRACED) != 0);
137 |
138 | NSCAssert(!debugging, @"Debug checking should be disabled");
139 | }
140 |
141 | #endif // TESTS_BYPASS
142 |
--------------------------------------------------------------------------------
/Tools/patch.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # Copyright (c) 2017-present Wu Tian .
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
13 | # all 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
21 | # THE SOFTWARE.
22 |
23 | # patch.sh
24 | # IPAPatch
25 | #
26 | # Created by wutian on 2017/3/17.
27 |
28 |
29 | TEMP_PATH="${SRCROOT}/Temp"
30 | ASSETS_PATH="${SRCROOT}/Assets"
31 | TARGET_IPA_PATH="${ASSETS_PATH}/app.ipa"
32 | FRAMEWORKS_TO_INJECT_PATH="${ASSETS_PATH}/Frameworks"
33 |
34 | DUMMY_DISPLAY_NAME="" # To be found in Step 0
35 | TARGET_BUNDLE_ID="" # To be found in Step 0
36 | TEMP_APP_PATH="" # To be found in Step 1
37 | TARGET_APP_PATH="" # To be found in Step 2
38 | TARGET_APP_FRAMEWORKS_PATH="" # To be found in Step 4
39 |
40 |
41 |
42 | # ---------------------------------------------------
43 | # 0. Prepare Working Enviroment
44 |
45 | rm -rf "$TEMP_PATH" || true
46 | mkdir -p "$TEMP_PATH" || true
47 |
48 | DUMMY_DISPLAY_NAME=$(/usr/libexec/PlistBuddy -c "Print CFBundleDisplayName" "${SRCROOT}/$TARGET_NAME/Info.plist")
49 | echo "DUMMY_DISPLAY_NAME: $DUMMY_DISPLAY_NAME"
50 |
51 | TARGET_BUNDLE_ID="$PRODUCT_BUNDLE_IDENTIFIER"
52 | echo "TARGET_BUNDLE_ID: $TARGET_BUNDLE_ID"
53 |
54 |
55 | # ---------------------------------------------------
56 | # 1. Extract Target IPA
57 |
58 | unzip -oqq "$TARGET_IPA_PATH" -d "$TEMP_PATH"
59 | TEMP_APP_PATH=$(set -- "$TEMP_PATH/Payload/"*.app; echo "$1")
60 | echo "TEMP_APP_PATH: $TEMP_APP_PATH"
61 |
62 |
63 |
64 |
65 | # ---------------------------------------------------
66 | # 2. Overwrite DummyApp IPA with Target App Contents
67 |
68 | TARGET_APP_PATH="$BUILT_PRODUCTS_DIR/$TARGET_NAME.app"
69 | echo "TARGET_APP_PATH: $TARGET_APP_PATH"
70 |
71 | rm -rf "$TARGET_APP_PATH" || true
72 | mkdir -p "$TARGET_APP_PATH" || true
73 | cp -rf "$TEMP_APP_PATH/" "$TARGET_APP_PATH/"
74 |
75 |
76 |
77 |
78 | # ---------------------------------------------------
79 | # 3. Inject the Executable We Wrote and Built (IPAPatch.framework)
80 |
81 | APP_BINARY=`plutil -convert xml1 -o - $TARGET_APP_PATH/Info.plist|grep -A1 Exec|tail -n1|cut -f2 -d\>|cut -f1 -d\<`
82 | OPTOOL="${SRCROOT}/Tools/optool"
83 |
84 | mkdir "$TARGET_APP_PATH/Dylibs"
85 | cp "$BUILT_PRODUCTS_DIR/IPAPatch.framework/IPAPatch" "$TARGET_APP_PATH/Dylibs/IPAPatch"
86 | for file in `ls -1 "$TARGET_APP_PATH/Dylibs"`; do
87 | echo -n ' '
88 | echo "Install Load: $file -> @executable_path/Dylibs/$file"
89 | "$OPTOOL" install -c load -p "@executable_path/Dylibs/$file" -t "$TARGET_APP_PATH/$APP_BINARY"
90 | done
91 |
92 | chmod +x "$TARGET_APP_PATH/$APP_BINARY"
93 |
94 |
95 |
96 |
97 | # ---------------------------------------------------
98 | # 4. Inject External Frameworks if Exists
99 |
100 | TARGET_APP_FRAMEWORKS_PATH="$BUILT_PRODUCTS_DIR/$TARGET_NAME.app/Frameworks"
101 |
102 | echo "Injecting Frameworks from $FRAMEWORKS_TO_INJECT_PATH"
103 | for file in `ls -1 "${FRAMEWORKS_TO_INJECT_PATH}"`; do
104 | extension="${file##*.}"
105 | echo "$file 's extension is $extension"
106 |
107 | if [ "$extension" != "framework" ]
108 | then
109 | continue
110 | fi
111 |
112 | filename="${file%.*}"
113 |
114 | cp "$FRAMEWORKS_TO_INJECT_PATH/$file/$filename" "$TARGET_APP_PATH/Dylibs/$filename"
115 |
116 | echo -n ' '
117 | echo "Install Load: $file -> @executable_path/Dylibs/$filename"
118 |
119 | echo "TARGET: $TARGET_APP_PATH"
120 |
121 | "$OPTOOL" install -c load -p "@executable_path/Dylibs/$filename" -t "$TARGET_APP_PATH/$APP_BINARY"
122 | done
123 |
124 |
125 |
126 |
127 | # ---------------------------------------------------
128 | # 5. Remove Plugins/Watch (AppExtensions), To Simplify the Signing Process
129 |
130 | rm -rf "$TARGET_APP_PATH/PlugIns" || true
131 | rm -rf "$TARGET_APP_PATH/Watch" || true
132 |
133 |
134 |
135 |
136 | # ---------------------------------------------------
137 | # 7. Update Info.plist for Target App
138 |
139 | TARGET_DISPLAY_NAME=$(/usr/libexec/PlistBuddy -c "Print CFBundleDisplayName" "$TARGET_APP_PATH/Info.plist")
140 | TARGET_DISPLAY_NAME="$DUMMY_DISPLAY_NAME$TARGET_DISPLAY_NAME"
141 |
142 | /usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $PRODUCT_BUNDLE_IDENTIFIER" "$TARGET_APP_PATH/Info.plist"
143 | /usr/libexec/PlistBuddy -c "Set :CFBundleDisplayName $TARGET_DISPLAY_NAME" "$TARGET_APP_PATH/Info.plist"
144 |
145 |
146 |
147 | # ---------------------------------------------------
148 | # 8. Code Sign All The Things
149 |
150 | for DYLIB in "$TARGET_APP_PATH/Dylibs/"*
151 | do
152 | FILENAME=$(basename $DYLIB)
153 | /usr/bin/codesign --force --sign "$EXPANDED_CODE_SIGN_IDENTITY" "$DYLIB"
154 | done
155 |
156 | if [ -d "$TARGET_APP_FRAMEWORKS_PATH" ]; then
157 | for FRAMEWORK in "$TARGET_APP_FRAMEWORKS_PATH/"*
158 | do
159 | FILENAME=$(basename $FRAMEWORK)
160 | /usr/bin/codesign --force --sign "$EXPANDED_CODE_SIGN_IDENTITY" "$FRAMEWORK"
161 | done
162 | fi
163 |
164 | /usr/bin/codesign --force --sign "$EXPANDED_CODE_SIGN_IDENTITY" --timestamp=none "$TARGET_APP_PATH/$APP_BINARY"
165 |
166 |
167 |
168 |
169 | # ---------------------------------------------------
170 | # 9. Install
171 | #
172 | # Nothing To Do, Xcode Will Automatically Install the DummyApp We Overwrited
173 |
174 |
175 |
176 |
--------------------------------------------------------------------------------
/IPAPatch/Vendors/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 = malloc(sizeof(struct rebindings_entry));
64 | if (!new_entry) {
65 | return -1;
66 | }
67 | new_entry->rebindings = 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, 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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | IPAPatch provide a simple way to patch iOS Apps, without needing to jailbreak.
4 |
5 | [ [Features](#features) • [Instructions](#instructions) • [Example](#example) • [FAQ](#faq) • [License](#license) ]
6 |
7 | ## Features
8 |
9 | **IPAPatch** includes an template Xcode project, that provides following features:
10 |
11 | - **Build & Run third-party ipa with your code injected**
12 |
13 | You can run your own code inside ipa file as a dynamic library. So you can change behavior of that app by utilizing Objective-C runtime.
14 |
15 | > *Presented an custom alert in Youtube app*
16 | >
17 | >
18 |
19 | - **Step-by-step Debugging with lldb**
20 |
21 | You can debug third-party apps like your own. For example:
22 |
23 | - Step-by-Step debug your code inside other app
24 | - Set Breakpoints
25 | - Print objects in Xcode console with lldb
26 |
27 |
28 | > *Debugging Youtube with Xcode*
29 | >
30 | >
31 |
32 |
33 | - **Link external frameworks**
34 |
35 | By linking existing frameworks, you can integrate third-party services to apps very easily, such as Reveal.
36 |
37 | > *Inspect Youtube by linking RevealServer.framework*
38 | >
39 | >
40 |
41 | ## Instructions
42 |
43 | 1. **Clone or Download This Project**
44 |
45 | Download this project to your local disk
46 |
47 | 2. **Prepare Decrypted IPA File**
48 |
49 | The IPA file you use need to be decrypted, you can get a decrypted ipa from a jailbroken device or download it directly from an ipa download site, such as http://www.iphonecake.com
50 |
51 | 3. **Replace Placeholder IPA**
52 |
53 | Replace the IPA file located at `IPAPatch/Assets/app.ipa` with yours, this is a placeholder file. The filename should remain `app.ipa` after replacing.
54 |
55 | 4. **Place External Frameworks (Optional)**
56 |
57 | External frameworks can be placed at `IPAPatch/Assets/Frameworks` folder. Frameworks will be linked automatically.
58 |
59 | For example `IPAPatch/Assets/Frameworks/RevealServer.framework`
60 |
61 | 5. **Configure Build Settings**
62 |
63 | - Open `IPAPatch.xcodeproj`
64 | - In the Project Editor, Select Target `IPAPatch-DummyApp`
65 | - `Display Name` defaults to "💊", this is used as prefix of the final display name.
66 | - Change `Bundle Identifier` to match your provisioning profiles
67 | - Fix signing issues if any.
68 |
69 | 6. **Code Your Patch**
70 |
71 | The entry is at `+[IPAPatchEntry load]`, you can write code start from here. To change apps' behavior, You may need to use some method swizzling library, such as [steipete/Aspects](https://github.com/steipete/Aspects).
72 |
73 | 7. **Build and Run**
74 |
75 | Select a real device, and hit the "Run" button at the top-left corner of Xcode. The code your wrote and external frameworks you placed will inject to the ipa file automatically.
76 |
77 | ## Example
78 |
79 | I created some demo project, which shows you how to use `IPAPatch`:
80 |
81 | - Reveal + Youtube:
82 | - https://github.com/Naituw/IPAPatch/releases/tag/1.0
83 | - Cycript + Youtube (Idea from @phpmaple):
84 | - https://github.com/Naituw/IPAPatch/releases/tag/1.0.1
85 |
86 | ## FAQ
87 |
88 | - Q: Library not loaded with reason: `mach-o, but wrong architecture` ?
89 | - A: Try set `IPAPatch` target's `Valid Architectures` to match your ipa binary's architecture.
90 |
91 | - Q: process launch failed: Unspecified (Disabled) ?
92 | - A: The ipa file use with IPAPatch must be decrypted, See step.2 of Instructions.
93 |
94 | ## License
95 |
96 | #### IPAPatch
97 |
98 | IPAPatch is licensed under the MIT license.
99 |
100 | Copyright (c) 2017-present Wu Tian .
101 |
102 | Permission is hereby granted, free of charge, to any person obtaining a copy
103 | of this software and associated documentation files (the "Software"), to deal
104 | in the Software without restriction, including without limitation the rights
105 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
106 | copies of the Software, and to permit persons to whom the Software is
107 | furnished to do so, subject to the following conditions:
108 |
109 | The above copyright notice and this permission notice shall be included in
110 | all copies or substantial portions of the Software.
111 |
112 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
113 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
114 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
115 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
116 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
117 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
118 | THE SOFTWARE.
119 |
120 |
121 | #### OPTOOL
122 |
123 | Copyright (c) 2014, Alex Zielenski
124 | All rights reserved.
125 |
126 | Redistribution and use in source and binary forms, with or without
127 | modification, are permitted provided that the following conditions are met:
128 |
129 | * Redistributions of source code must retain the above copyright notice, this
130 | list of conditions and the following disclaimer.
131 |
132 | * Redistributions in binary form must reproduce the above copyright notice,
133 | this list of conditions and the following disclaimer in the documentation
134 | and/or other materials provided with the distribution.
135 |
136 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
137 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
138 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
139 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
140 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
141 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
142 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
143 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
144 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
145 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
146 |
147 |
148 | #### fishhook
149 |
150 | Copyright (c) 2013, Facebook, Inc.
151 | All rights reserved.
152 | Redistribution and use in source and binary forms, with or without
153 | modification, are permitted provided that the following conditions are met:
154 | * Redistributions of source code must retain the above copyright notice,
155 | this list of conditions and the following disclaimer.
156 | * Redistributions in binary form must reproduce the above copyright notice,
157 | this list of conditions and the following disclaimer in the documentation
158 | and/or other materials provided with the distribution.
159 | * Neither the name Facebook nor the names of its contributors may be used to
160 | endorse or promote products derived from this software without specific
161 | prior written permission.
162 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
163 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
164 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
165 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
166 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
167 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
168 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
169 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
170 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
171 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
172 |
173 |
--------------------------------------------------------------------------------
/IPAPatch.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | C63AC1A51E838BB70094B1C5 /* fishhook.c in Sources */ = {isa = PBXBuildFile; fileRef = C63AC1A21E838BB70094B1C5 /* fishhook.c */; };
11 | C63AC1A61E838BB70094B1C5 /* fishhook.h in Headers */ = {isa = PBXBuildFile; fileRef = C63AC1A31E838BB70094B1C5 /* fishhook.h */; };
12 | C63AC1AA1E8392210094B1C5 /* IPAPatchBypassAntiDebugging.h in Headers */ = {isa = PBXBuildFile; fileRef = C63AC1A81E8392210094B1C5 /* IPAPatchBypassAntiDebugging.h */; };
13 | C63AC1AB1E8392210094B1C5 /* IPAPatchBypassAntiDebugging.m in Sources */ = {isa = PBXBuildFile; fileRef = C63AC1A91E8392210094B1C5 /* IPAPatchBypassAntiDebugging.m */; };
14 | C64288391E7BF9E900C0BBB0 /* ProjectConfigurationWarning.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C64288371E7BF9E900C0BBB0 /* ProjectConfigurationWarning.cpp */; };
15 | C6B263271E7BC9DF009B4DEA /* IPAPatchEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = C6B263251E7BC9DF009B4DEA /* IPAPatchEntry.h */; };
16 | C6B263281E7BC9DF009B4DEA /* IPAPatchEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = C6B263261E7BC9DF009B4DEA /* IPAPatchEntry.m */; };
17 | C6B2634D1E7BCB31009B4DEA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = C6B2634C1E7BCB31009B4DEA /* main.m */; };
18 | C6B263501E7BCB31009B4DEA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = C6B2634F1E7BCB31009B4DEA /* AppDelegate.m */; };
19 | /* End PBXBuildFile section */
20 |
21 | /* Begin PBXContainerItemProxy section */
22 | C6B263601E7BCC65009B4DEA /* PBXContainerItemProxy */ = {
23 | isa = PBXContainerItemProxy;
24 | containerPortal = C6B262FE1E7BC97B009B4DEA /* Project object */;
25 | proxyType = 1;
26 | remoteGlobalIDString = C6B263061E7BC97B009B4DEA;
27 | remoteInfo = IPAPatch;
28 | };
29 | /* End PBXContainerItemProxy section */
30 |
31 | /* Begin PBXFileReference section */
32 | C63AC1A21E838BB70094B1C5 /* fishhook.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fishhook.c; sourceTree = ""; };
33 | C63AC1A31E838BB70094B1C5 /* fishhook.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fishhook.h; sourceTree = ""; };
34 | C63AC1A41E838BB70094B1C5 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = ""; };
35 | C63AC1A81E8392210094B1C5 /* IPAPatchBypassAntiDebugging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IPAPatchBypassAntiDebugging.h; sourceTree = ""; };
36 | C63AC1A91E8392210094B1C5 /* IPAPatchBypassAntiDebugging.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IPAPatchBypassAntiDebugging.m; sourceTree = ""; };
37 | C64288371E7BF9E900C0BBB0 /* ProjectConfigurationWarning.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProjectConfigurationWarning.cpp; sourceTree = ""; };
38 | C64288381E7BF9E900C0BBB0 /* ProjectConfigurationWarning.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ProjectConfigurationWarning.hpp; sourceTree = ""; };
39 | C6B263071E7BC97B009B4DEA /* IPAPatch.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = IPAPatch.framework; sourceTree = BUILT_PRODUCTS_DIR; };
40 | C6B2630B1E7BC97B009B4DEA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
41 | C6B263251E7BC9DF009B4DEA /* IPAPatchEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IPAPatchEntry.h; sourceTree = ""; };
42 | C6B263261E7BC9DF009B4DEA /* IPAPatchEntry.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IPAPatchEntry.m; sourceTree = ""; };
43 | C6B263491E7BCB31009B4DEA /* IPAPatch-DummyApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "IPAPatch-DummyApp.app"; sourceTree = BUILT_PRODUCTS_DIR; };
44 | C6B2634C1E7BCB31009B4DEA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
45 | C6B2634E1E7BCB31009B4DEA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
46 | C6B2634F1E7BCB31009B4DEA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
47 | C6B2635C1E7BCB31009B4DEA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
48 | C6B263621E7BCD03009B4DEA /* patch.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = patch.sh; sourceTree = ""; };
49 | /* End PBXFileReference section */
50 |
51 | /* Begin PBXFrameworksBuildPhase section */
52 | C6B263031E7BC97B009B4DEA /* Frameworks */ = {
53 | isa = PBXFrameworksBuildPhase;
54 | buildActionMask = 2147483647;
55 | files = (
56 | );
57 | runOnlyForDeploymentPostprocessing = 0;
58 | };
59 | C6B263461E7BCB31009B4DEA /* Frameworks */ = {
60 | isa = PBXFrameworksBuildPhase;
61 | buildActionMask = 2147483647;
62 | files = (
63 | );
64 | runOnlyForDeploymentPostprocessing = 0;
65 | };
66 | /* End PBXFrameworksBuildPhase section */
67 |
68 | /* Begin PBXGroup section */
69 | C63AC1A01E838B8E0094B1C5 /* Vendors */ = {
70 | isa = PBXGroup;
71 | children = (
72 | C63AC1A11E838BB70094B1C5 /* fishhook */,
73 | );
74 | path = Vendors;
75 | sourceTree = "";
76 | };
77 | C63AC1A11E838BB70094B1C5 /* fishhook */ = {
78 | isa = PBXGroup;
79 | children = (
80 | C63AC1A31E838BB70094B1C5 /* fishhook.h */,
81 | C63AC1A21E838BB70094B1C5 /* fishhook.c */,
82 | C63AC1A41E838BB70094B1C5 /* LICENSE */,
83 | );
84 | path = fishhook;
85 | sourceTree = "";
86 | };
87 | C6B262FD1E7BC97B009B4DEA = {
88 | isa = PBXGroup;
89 | children = (
90 | C6B263091E7BC97B009B4DEA /* IPAPatch */,
91 | C6B263291E7BCA86009B4DEA /* Tools */,
92 | C6B2634A1E7BCB31009B4DEA /* IPAPatch-DummyApp */,
93 | C6B263081E7BC97B009B4DEA /* Products */,
94 | );
95 | sourceTree = "";
96 | };
97 | C6B263081E7BC97B009B4DEA /* Products */ = {
98 | isa = PBXGroup;
99 | children = (
100 | C6B263071E7BC97B009B4DEA /* IPAPatch.framework */,
101 | C6B263491E7BCB31009B4DEA /* IPAPatch-DummyApp.app */,
102 | );
103 | name = Products;
104 | sourceTree = "";
105 | };
106 | C6B263091E7BC97B009B4DEA /* IPAPatch */ = {
107 | isa = PBXGroup;
108 | children = (
109 | C63AC1A01E838B8E0094B1C5 /* Vendors */,
110 | C6B2630B1E7BC97B009B4DEA /* Info.plist */,
111 | C6B263251E7BC9DF009B4DEA /* IPAPatchEntry.h */,
112 | C6B263261E7BC9DF009B4DEA /* IPAPatchEntry.m */,
113 | C63AC1A81E8392210094B1C5 /* IPAPatchBypassAntiDebugging.h */,
114 | C63AC1A91E8392210094B1C5 /* IPAPatchBypassAntiDebugging.m */,
115 | );
116 | path = IPAPatch;
117 | sourceTree = "";
118 | };
119 | C6B263291E7BCA86009B4DEA /* Tools */ = {
120 | isa = PBXGroup;
121 | children = (
122 | C6B263621E7BCD03009B4DEA /* patch.sh */,
123 | );
124 | path = Tools;
125 | sourceTree = "";
126 | };
127 | C6B2634A1E7BCB31009B4DEA /* IPAPatch-DummyApp */ = {
128 | isa = PBXGroup;
129 | children = (
130 | C6B2634E1E7BCB31009B4DEA /* AppDelegate.h */,
131 | C6B2634F1E7BCB31009B4DEA /* AppDelegate.m */,
132 | C64288381E7BF9E900C0BBB0 /* ProjectConfigurationWarning.hpp */,
133 | C64288371E7BF9E900C0BBB0 /* ProjectConfigurationWarning.cpp */,
134 | C6B2635C1E7BCB31009B4DEA /* Info.plist */,
135 | C6B2634B1E7BCB31009B4DEA /* Supporting Files */,
136 | );
137 | path = "IPAPatch-DummyApp";
138 | sourceTree = "";
139 | };
140 | C6B2634B1E7BCB31009B4DEA /* Supporting Files */ = {
141 | isa = PBXGroup;
142 | children = (
143 | C6B2634C1E7BCB31009B4DEA /* main.m */,
144 | );
145 | name = "Supporting Files";
146 | sourceTree = "";
147 | };
148 | /* End PBXGroup section */
149 |
150 | /* Begin PBXHeadersBuildPhase section */
151 | C6B263041E7BC97B009B4DEA /* Headers */ = {
152 | isa = PBXHeadersBuildPhase;
153 | buildActionMask = 2147483647;
154 | files = (
155 | C6B263271E7BC9DF009B4DEA /* IPAPatchEntry.h in Headers */,
156 | C63AC1A61E838BB70094B1C5 /* fishhook.h in Headers */,
157 | C63AC1AA1E8392210094B1C5 /* IPAPatchBypassAntiDebugging.h in Headers */,
158 | );
159 | runOnlyForDeploymentPostprocessing = 0;
160 | };
161 | /* End PBXHeadersBuildPhase section */
162 |
163 | /* Begin PBXNativeTarget section */
164 | C6B263061E7BC97B009B4DEA /* IPAPatch */ = {
165 | isa = PBXNativeTarget;
166 | buildConfigurationList = C6B2631B1E7BC97B009B4DEA /* Build configuration list for PBXNativeTarget "IPAPatch" */;
167 | buildPhases = (
168 | C6B263021E7BC97B009B4DEA /* Sources */,
169 | C6B263031E7BC97B009B4DEA /* Frameworks */,
170 | C6B263041E7BC97B009B4DEA /* Headers */,
171 | C6B263051E7BC97B009B4DEA /* Resources */,
172 | );
173 | buildRules = (
174 | );
175 | dependencies = (
176 | );
177 | name = IPAPatch;
178 | productName = IPAPatch;
179 | productReference = C6B263071E7BC97B009B4DEA /* IPAPatch.framework */;
180 | productType = "com.apple.product-type.framework";
181 | };
182 | C6B263481E7BCB31009B4DEA /* IPAPatch-DummyApp */ = {
183 | isa = PBXNativeTarget;
184 | buildConfigurationList = C6B2635D1E7BCB31009B4DEA /* Build configuration list for PBXNativeTarget "IPAPatch-DummyApp" */;
185 | buildPhases = (
186 | C6B263451E7BCB31009B4DEA /* Sources */,
187 | C6B263461E7BCB31009B4DEA /* Frameworks */,
188 | C6B263471E7BCB31009B4DEA /* Resources */,
189 | C6B263631E7BD0B4009B4DEA /* ShellScript */,
190 | );
191 | buildRules = (
192 | );
193 | dependencies = (
194 | C6B263611E7BCC65009B4DEA /* PBXTargetDependency */,
195 | );
196 | name = "IPAPatch-DummyApp";
197 | productName = "IPAPatch-DummyApp";
198 | productReference = C6B263491E7BCB31009B4DEA /* IPAPatch-DummyApp.app */;
199 | productType = "com.apple.product-type.application";
200 | };
201 | /* End PBXNativeTarget section */
202 |
203 | /* Begin PBXProject section */
204 | C6B262FE1E7BC97B009B4DEA /* Project object */ = {
205 | isa = PBXProject;
206 | attributes = {
207 | LastUpgradeCheck = 0830;
208 | ORGANIZATIONNAME = Weibo;
209 | TargetAttributes = {
210 | C6B263061E7BC97B009B4DEA = {
211 | CreatedOnToolsVersion = 8.3;
212 | DevelopmentTeam = DMJXDB9H6Q;
213 | ProvisioningStyle = Automatic;
214 | };
215 | C6B263481E7BCB31009B4DEA = {
216 | CreatedOnToolsVersion = 8.3;
217 | DevelopmentTeam = DMJXDB9H6Q;
218 | ProvisioningStyle = Automatic;
219 | };
220 | };
221 | };
222 | buildConfigurationList = C6B263011E7BC97B009B4DEA /* Build configuration list for PBXProject "IPAPatch" */;
223 | compatibilityVersion = "Xcode 3.2";
224 | developmentRegion = English;
225 | hasScannedForEncodings = 0;
226 | knownRegions = (
227 | en,
228 | Base,
229 | );
230 | mainGroup = C6B262FD1E7BC97B009B4DEA;
231 | productRefGroup = C6B263081E7BC97B009B4DEA /* Products */;
232 | projectDirPath = "";
233 | projectRoot = "";
234 | targets = (
235 | C6B263481E7BCB31009B4DEA /* IPAPatch-DummyApp */,
236 | C6B263061E7BC97B009B4DEA /* IPAPatch */,
237 | );
238 | };
239 | /* End PBXProject section */
240 |
241 | /* Begin PBXResourcesBuildPhase section */
242 | C6B263051E7BC97B009B4DEA /* Resources */ = {
243 | isa = PBXResourcesBuildPhase;
244 | buildActionMask = 2147483647;
245 | files = (
246 | );
247 | runOnlyForDeploymentPostprocessing = 0;
248 | };
249 | C6B263471E7BCB31009B4DEA /* Resources */ = {
250 | isa = PBXResourcesBuildPhase;
251 | buildActionMask = 2147483647;
252 | files = (
253 | );
254 | runOnlyForDeploymentPostprocessing = 0;
255 | };
256 | /* End PBXResourcesBuildPhase section */
257 |
258 | /* Begin PBXShellScriptBuildPhase section */
259 | C6B263631E7BD0B4009B4DEA /* ShellScript */ = {
260 | isa = PBXShellScriptBuildPhase;
261 | buildActionMask = 2147483647;
262 | files = (
263 | );
264 | inputPaths = (
265 | );
266 | outputPaths = (
267 | );
268 | runOnlyForDeploymentPostprocessing = 0;
269 | shellPath = /bin/sh;
270 | shellScript = "\"${SRCROOT}/Tools/patch.sh\"";
271 | };
272 | /* End PBXShellScriptBuildPhase section */
273 |
274 | /* Begin PBXSourcesBuildPhase section */
275 | C6B263021E7BC97B009B4DEA /* Sources */ = {
276 | isa = PBXSourcesBuildPhase;
277 | buildActionMask = 2147483647;
278 | files = (
279 | C63AC1AB1E8392210094B1C5 /* IPAPatchBypassAntiDebugging.m in Sources */,
280 | C6B263281E7BC9DF009B4DEA /* IPAPatchEntry.m in Sources */,
281 | C63AC1A51E838BB70094B1C5 /* fishhook.c in Sources */,
282 | );
283 | runOnlyForDeploymentPostprocessing = 0;
284 | };
285 | C6B263451E7BCB31009B4DEA /* Sources */ = {
286 | isa = PBXSourcesBuildPhase;
287 | buildActionMask = 2147483647;
288 | files = (
289 | C64288391E7BF9E900C0BBB0 /* ProjectConfigurationWarning.cpp in Sources */,
290 | C6B263501E7BCB31009B4DEA /* AppDelegate.m in Sources */,
291 | C6B2634D1E7BCB31009B4DEA /* main.m in Sources */,
292 | );
293 | runOnlyForDeploymentPostprocessing = 0;
294 | };
295 | /* End PBXSourcesBuildPhase section */
296 |
297 | /* Begin PBXTargetDependency section */
298 | C6B263611E7BCC65009B4DEA /* PBXTargetDependency */ = {
299 | isa = PBXTargetDependency;
300 | target = C6B263061E7BC97B009B4DEA /* IPAPatch */;
301 | targetProxy = C6B263601E7BCC65009B4DEA /* PBXContainerItemProxy */;
302 | };
303 | /* End PBXTargetDependency section */
304 |
305 | /* Begin XCBuildConfiguration section */
306 | C6B263191E7BC97B009B4DEA /* Debug */ = {
307 | isa = XCBuildConfiguration;
308 | buildSettings = {
309 | ALWAYS_SEARCH_USER_PATHS = NO;
310 | CLANG_ANALYZER_NONNULL = YES;
311 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
312 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
313 | CLANG_CXX_LIBRARY = "libc++";
314 | CLANG_ENABLE_MODULES = YES;
315 | CLANG_ENABLE_OBJC_ARC = YES;
316 | CLANG_WARN_BOOL_CONVERSION = YES;
317 | CLANG_WARN_CONSTANT_CONVERSION = YES;
318 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
319 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
320 | CLANG_WARN_EMPTY_BODY = YES;
321 | CLANG_WARN_ENUM_CONVERSION = YES;
322 | CLANG_WARN_INFINITE_RECURSION = YES;
323 | CLANG_WARN_INT_CONVERSION = YES;
324 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
325 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
326 | CLANG_WARN_UNREACHABLE_CODE = YES;
327 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
328 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
329 | COPY_PHASE_STRIP = NO;
330 | CURRENT_PROJECT_VERSION = 1;
331 | DEBUG_INFORMATION_FORMAT = dwarf;
332 | ENABLE_STRICT_OBJC_MSGSEND = YES;
333 | ENABLE_TESTABILITY = YES;
334 | GCC_C_LANGUAGE_STANDARD = gnu99;
335 | GCC_DYNAMIC_NO_PIC = NO;
336 | GCC_NO_COMMON_BLOCKS = YES;
337 | GCC_OPTIMIZATION_LEVEL = 0;
338 | GCC_PREPROCESSOR_DEFINITIONS = (
339 | "DEBUG=1",
340 | "$(inherited)",
341 | );
342 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
343 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
344 | GCC_WARN_UNDECLARED_SELECTOR = YES;
345 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
346 | GCC_WARN_UNUSED_FUNCTION = YES;
347 | GCC_WARN_UNUSED_VARIABLE = YES;
348 | IPHONEOS_DEPLOYMENT_TARGET = 10.3;
349 | MTL_ENABLE_DEBUG_INFO = YES;
350 | ONLY_ACTIVE_ARCH = YES;
351 | SDKROOT = iphoneos;
352 | TARGETED_DEVICE_FAMILY = "1,2";
353 | VERSIONING_SYSTEM = "apple-generic";
354 | VERSION_INFO_PREFIX = "";
355 | };
356 | name = Debug;
357 | };
358 | C6B2631A1E7BC97B009B4DEA /* Release */ = {
359 | isa = XCBuildConfiguration;
360 | buildSettings = {
361 | ALWAYS_SEARCH_USER_PATHS = NO;
362 | CLANG_ANALYZER_NONNULL = YES;
363 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
364 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
365 | CLANG_CXX_LIBRARY = "libc++";
366 | CLANG_ENABLE_MODULES = YES;
367 | CLANG_ENABLE_OBJC_ARC = YES;
368 | CLANG_WARN_BOOL_CONVERSION = YES;
369 | CLANG_WARN_CONSTANT_CONVERSION = YES;
370 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
371 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
372 | CLANG_WARN_EMPTY_BODY = YES;
373 | CLANG_WARN_ENUM_CONVERSION = YES;
374 | CLANG_WARN_INFINITE_RECURSION = YES;
375 | CLANG_WARN_INT_CONVERSION = YES;
376 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
377 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
378 | CLANG_WARN_UNREACHABLE_CODE = YES;
379 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
380 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
381 | COPY_PHASE_STRIP = NO;
382 | CURRENT_PROJECT_VERSION = 1;
383 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
384 | ENABLE_NS_ASSERTIONS = NO;
385 | ENABLE_STRICT_OBJC_MSGSEND = YES;
386 | GCC_C_LANGUAGE_STANDARD = gnu99;
387 | GCC_NO_COMMON_BLOCKS = YES;
388 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
389 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
390 | GCC_WARN_UNDECLARED_SELECTOR = YES;
391 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
392 | GCC_WARN_UNUSED_FUNCTION = YES;
393 | GCC_WARN_UNUSED_VARIABLE = YES;
394 | IPHONEOS_DEPLOYMENT_TARGET = 10.3;
395 | MTL_ENABLE_DEBUG_INFO = NO;
396 | SDKROOT = iphoneos;
397 | TARGETED_DEVICE_FAMILY = "1,2";
398 | VALIDATE_PRODUCT = YES;
399 | VERSIONING_SYSTEM = "apple-generic";
400 | VERSION_INFO_PREFIX = "";
401 | };
402 | name = Release;
403 | };
404 | C6B2631C1E7BC97B009B4DEA /* Debug */ = {
405 | isa = XCBuildConfiguration;
406 | buildSettings = {
407 | CODE_SIGN_IDENTITY = "";
408 | DEFINES_MODULE = NO;
409 | DEVELOPMENT_TEAM = DMJXDB9H6Q;
410 | DYLIB_COMPATIBILITY_VERSION = 1;
411 | DYLIB_CURRENT_VERSION = 1;
412 | DYLIB_INSTALL_NAME_BASE = "@rpath";
413 | ENABLE_BITCODE = NO;
414 | INFOPLIST_FILE = IPAPatch/Info.plist;
415 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
416 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
417 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
418 | ONLY_ACTIVE_ARCH = NO;
419 | PRODUCT_BUNDLE_IDENTIFIER = com.wutian.IPAPatch;
420 | PRODUCT_NAME = "$(TARGET_NAME)";
421 | SKIP_INSTALL = YES;
422 | };
423 | name = Debug;
424 | };
425 | C6B2631D1E7BC97B009B4DEA /* Release */ = {
426 | isa = XCBuildConfiguration;
427 | buildSettings = {
428 | CODE_SIGN_IDENTITY = "";
429 | DEFINES_MODULE = NO;
430 | DEVELOPMENT_TEAM = DMJXDB9H6Q;
431 | DYLIB_COMPATIBILITY_VERSION = 1;
432 | DYLIB_CURRENT_VERSION = 1;
433 | DYLIB_INSTALL_NAME_BASE = "@rpath";
434 | ENABLE_BITCODE = NO;
435 | INFOPLIST_FILE = IPAPatch/Info.plist;
436 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
437 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
438 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
439 | PRODUCT_BUNDLE_IDENTIFIER = com.wutian.IPAPatch;
440 | PRODUCT_NAME = "$(TARGET_NAME)";
441 | SKIP_INSTALL = YES;
442 | };
443 | name = Release;
444 | };
445 | C6B2635E1E7BCB31009B4DEA /* Debug */ = {
446 | isa = XCBuildConfiguration;
447 | buildSettings = {
448 | CLANG_CXX_LANGUAGE_STANDARD = "c++14";
449 | DEVELOPMENT_TEAM = DMJXDB9H6Q;
450 | ENABLE_BITCODE = NO;
451 | GCC_PREPROCESSOR_DEFINITIONS = (
452 | "DEBUG=1",
453 | "$(inherited)",
454 | "TARGET_BUNDLE_ID=$(PRODUCT_BUNDLE_IDENTIFIER)",
455 | );
456 | INFOPLIST_FILE = "IPAPatch-DummyApp/Info.plist";
457 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
458 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
459 | PRODUCT_BUNDLE_IDENTIFIER = com.wutian.example;
460 | PRODUCT_NAME = "$(TARGET_NAME)";
461 | };
462 | name = Debug;
463 | };
464 | C6B2635F1E7BCB31009B4DEA /* Release */ = {
465 | isa = XCBuildConfiguration;
466 | buildSettings = {
467 | CLANG_CXX_LANGUAGE_STANDARD = "c++14";
468 | DEVELOPMENT_TEAM = DMJXDB9H6Q;
469 | ENABLE_BITCODE = NO;
470 | GCC_PREPROCESSOR_DEFINITIONS = "TARGET_BUNDLE_ID=$(PRODUCT_BUNDLE_IDENTIFIER)";
471 | INFOPLIST_FILE = "IPAPatch-DummyApp/Info.plist";
472 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
473 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
474 | PRODUCT_BUNDLE_IDENTIFIER = com.wutian.example;
475 | PRODUCT_NAME = "$(TARGET_NAME)";
476 | };
477 | name = Release;
478 | };
479 | /* End XCBuildConfiguration section */
480 |
481 | /* Begin XCConfigurationList section */
482 | C6B263011E7BC97B009B4DEA /* Build configuration list for PBXProject "IPAPatch" */ = {
483 | isa = XCConfigurationList;
484 | buildConfigurations = (
485 | C6B263191E7BC97B009B4DEA /* Debug */,
486 | C6B2631A1E7BC97B009B4DEA /* Release */,
487 | );
488 | defaultConfigurationIsVisible = 0;
489 | defaultConfigurationName = Release;
490 | };
491 | C6B2631B1E7BC97B009B4DEA /* Build configuration list for PBXNativeTarget "IPAPatch" */ = {
492 | isa = XCConfigurationList;
493 | buildConfigurations = (
494 | C6B2631C1E7BC97B009B4DEA /* Debug */,
495 | C6B2631D1E7BC97B009B4DEA /* Release */,
496 | );
497 | defaultConfigurationIsVisible = 0;
498 | defaultConfigurationName = Release;
499 | };
500 | C6B2635D1E7BCB31009B4DEA /* Build configuration list for PBXNativeTarget "IPAPatch-DummyApp" */ = {
501 | isa = XCConfigurationList;
502 | buildConfigurations = (
503 | C6B2635E1E7BCB31009B4DEA /* Debug */,
504 | C6B2635F1E7BCB31009B4DEA /* Release */,
505 | );
506 | defaultConfigurationIsVisible = 0;
507 | defaultConfigurationName = Release;
508 | };
509 | /* End XCConfigurationList section */
510 | };
511 | rootObject = C6B262FE1E7BC97B009B4DEA /* Project object */;
512 | }
513 |
--------------------------------------------------------------------------------