├── 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 | ![IPAPatch Logo](http://wx1.sinaimg.cn/large/bebedbb5ly1fdrgg0v1hjj20e205qdgi.jpg) 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 | > Youtube Hacked 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 | > Youtube Debugging 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 | > Youtube Integrated Reveal 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 | --------------------------------------------------------------------------------