├── .gitattributes ├── .gitignore ├── Assets ├── .gitkeep ├── Dylibs │ └── .gitkeep ├── Frameworks │ └── .gitkeep ├── Resources │ └── .gitkeep ├── app.ipa └── macapp.app │ └── .gitkeep ├── IPAPatch-DummyApp ├── AppDelegate.h ├── AppDelegate.m ├── Info.plist ├── ProjectConfigurationWarning.cpp ├── ProjectConfigurationWarning.hpp └── main.m ├── IPAPatch-MacDummyApp ├── AppDelegate.h ├── AppDelegate.m └── main.m ├── IPAPatch.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings └── xcshareddata │ └── xcschemes │ ├── IPAPatch-DummyApp.xcscheme │ └── IPAPatch.xcscheme ├── IPAPatch ├── IPAPatchBypassAntiDebugging.h ├── IPAPatchBypassAntiDebugging.m ├── IPAPatchEntry.h ├── IPAPatchEntry.m ├── Info.plist └── Vendors │ └── fishhook │ ├── LICENSE │ ├── fishhook.c │ └── fishhook.h ├── IPAPatchFrameworkMac └── IPAPatchFrameworkMac.h ├── LICENSE ├── README.md └── Tools ├── create_ipa.sh ├── options.plist ├── optool ├── patch.sh └── restore-symbol /.gitattributes: -------------------------------------------------------------------------------- 1 | patch.sh linguist-language=Objective-C 2 | IPAPatchBypassAntiDebugging.m linguist-language=Objective-C 3 | IPAPatch/Vendors/* linguist-language=Objective-C -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # IPAPatch 2 | 3 | Temp/ 4 | Product/ 5 | 6 | .DS_Store 7 | 8 | # Xcode 9 | # 10 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 11 | 12 | ## Build generated 13 | build/ 14 | DerivedData/ 15 | 16 | ## Various settings 17 | *.pbxuser 18 | !default.pbxuser 19 | *.mode1v3 20 | !default.mode1v3 21 | *.mode2v3 22 | !default.mode2v3 23 | *.perspectivev3 24 | !default.perspectivev3 25 | xcuserdata/ 26 | 27 | ## Other 28 | *.moved-aside 29 | *.xccheckout 30 | *.xcscmblueprint 31 | 32 | ## Obj-C/Swift specific 33 | *.hmap 34 | *.dSYM.zip 35 | *.dSYM 36 | 37 | # CocoaPods 38 | # 39 | # We recommend against adding the Pods directory to your .gitignore. However 40 | # you should judge for yourself, the pros and cons are mentioned at: 41 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 42 | # 43 | # Pods/ 44 | 45 | # Carthage 46 | # 47 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 48 | # Carthage/Checkouts 49 | 50 | Carthage/Build 51 | 52 | # fastlane 53 | # 54 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 55 | # screenshots whenever they are needed. 56 | # For more information about the recommended setup visit: 57 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 58 | 59 | fastlane/report.xml 60 | fastlane/Preview.html 61 | fastlane/screenshots 62 | fastlane/test_output 63 | -------------------------------------------------------------------------------- /Assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Naituw/IPAPatch/f64030e9805657da8c6f1086933c224fd24ce100/Assets/.gitkeep -------------------------------------------------------------------------------- /Assets/Dylibs/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Naituw/IPAPatch/f64030e9805657da8c6f1086933c224fd24ce100/Assets/Dylibs/.gitkeep -------------------------------------------------------------------------------- /Assets/Frameworks/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Naituw/IPAPatch/f64030e9805657da8c6f1086933c224fd24ce100/Assets/Frameworks/.gitkeep -------------------------------------------------------------------------------- /Assets/Resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Naituw/IPAPatch/f64030e9805657da8c6f1086933c224fd24ce100/Assets/Resources/.gitkeep -------------------------------------------------------------------------------- /Assets/app.ipa: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Naituw/IPAPatch/f64030e9805657da8c6f1086933c224fd24ce100/Assets/app.ipa -------------------------------------------------------------------------------- /Assets/macapp.app/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Naituw/IPAPatch/f64030e9805657da8c6f1086933c224fd24ce100/Assets/macapp.app/.gitkeep -------------------------------------------------------------------------------- /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/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/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-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-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 | #define CODE_SIGN_IDENTITY_STRING STRINGIZE2(CODE_SIGN_IDENTITY) 29 | 30 | static_assert(!strings_equal(TARGET_BUNDLE_ID_STRING, "com.wutian.example"), "You should update the BundleID in Build Settings before patching"); 31 | 32 | static_assert(!strings_equal(CODE_SIGN_IDENTITY_STRING, "-"), "You should set valid codesign team in Build Settings before patching"); 33 | 34 | // ⚠️ 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" 35 | // ⚠️ Note: The BundleDisplayName of DummyApp will used as prefix of the final name. 36 | 37 | #if TARGET_OS_SIMULATOR 38 | #error Simulators is not supported, Please select a real device from Xcode toolbar. 39 | #endif 40 | 41 | #endif /* ProjectConfigurationWarning_hpp */ 42 | -------------------------------------------------------------------------------- /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-MacDummyApp/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // IPAPatch-MacDummyApp 4 | // 5 | // Created by wutian on 2023/1/29. 6 | // Copyright © 2023 Weibo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : NSObject 12 | 13 | @end 14 | 15 | -------------------------------------------------------------------------------- /IPAPatch-MacDummyApp/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // IPAPatch-MacDummyApp 4 | // 5 | // Created by wutian on 2023/1/29. 6 | // Copyright © 2023 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-MacDummyApp/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // IPAPatch-MacDummyApp 4 | // 5 | // Created by 吴天 on 2023/1/29. 6 | // Copyright © 2023 Weibo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, const char * argv[]) { 12 | @autoreleasepool { 13 | // Setup code that might create autoreleased objects goes here. 14 | } 15 | return NSApplicationMain(argc, argv); 16 | } 17 | -------------------------------------------------------------------------------- /IPAPatch.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXAggregateTarget section */ 10 | C6DDBB5C1F51468D00A42BE2 /* IPAPatch */ = { 11 | isa = PBXAggregateTarget; 12 | buildConfigurationList = C6DDBB5D1F51468D00A42BE2 /* Build configuration list for PBXAggregateTarget "IPAPatch" */; 13 | buildPhases = ( 14 | C6DDBB631F5147BA00A42BE2 /* ShellScript */, 15 | ); 16 | dependencies = ( 17 | C6DDBB611F51469300A42BE2 /* PBXTargetDependency */, 18 | ); 19 | name = IPAPatch; 20 | productName = IPAPatch; 21 | }; 22 | /* End PBXAggregateTarget section */ 23 | 24 | /* Begin PBXBuildFile section */ 25 | C63AC1A51E838BB70094B1C5 /* fishhook.c in Sources */ = {isa = PBXBuildFile; fileRef = C63AC1A21E838BB70094B1C5 /* fishhook.c */; }; 26 | C63AC1A61E838BB70094B1C5 /* fishhook.h in Headers */ = {isa = PBXBuildFile; fileRef = C63AC1A31E838BB70094B1C5 /* fishhook.h */; }; 27 | C63AC1AA1E8392210094B1C5 /* IPAPatchBypassAntiDebugging.h in Headers */ = {isa = PBXBuildFile; fileRef = C63AC1A81E8392210094B1C5 /* IPAPatchBypassAntiDebugging.h */; }; 28 | C63AC1AB1E8392210094B1C5 /* IPAPatchBypassAntiDebugging.m in Sources */ = {isa = PBXBuildFile; fileRef = C63AC1A91E8392210094B1C5 /* IPAPatchBypassAntiDebugging.m */; }; 29 | C64288391E7BF9E900C0BBB0 /* ProjectConfigurationWarning.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C64288371E7BF9E900C0BBB0 /* ProjectConfigurationWarning.cpp */; }; 30 | C698B9F82986148600BB5DC9 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = C698B9F72986148600BB5DC9 /* AppDelegate.m */; }; 31 | C698BA022986148700BB5DC9 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = C698BA012986148700BB5DC9 /* main.m */; }; 32 | C698BA0A29861BA800BB5DC9 /* ProjectConfigurationWarning.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C64288371E7BF9E900C0BBB0 /* ProjectConfigurationWarning.cpp */; }; 33 | C698BA1329861E8C00BB5DC9 /* IPAPatchFrameworkMac.h in Headers */ = {isa = PBXBuildFile; fileRef = C698BA1229861E8C00BB5DC9 /* IPAPatchFrameworkMac.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34 | C698BA1C29861ED700BB5DC9 /* IPAPatchEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = C6B263261E7BC9DF009B4DEA /* IPAPatchEntry.m */; }; 35 | C698BA1D29861EDA00BB5DC9 /* IPAPatchBypassAntiDebugging.m in Sources */ = {isa = PBXBuildFile; fileRef = C63AC1A91E8392210094B1C5 /* IPAPatchBypassAntiDebugging.m */; }; 36 | C698BA1E29861EDE00BB5DC9 /* fishhook.c in Sources */ = {isa = PBXBuildFile; fileRef = C63AC1A21E838BB70094B1C5 /* fishhook.c */; }; 37 | C6A353E21F51367500A9E30D /* options.plist in Resources */ = {isa = PBXBuildFile; fileRef = C6A353E11F51367500A9E30D /* options.plist */; }; 38 | C6B263271E7BC9DF009B4DEA /* IPAPatchEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = C6B263251E7BC9DF009B4DEA /* IPAPatchEntry.h */; }; 39 | C6B263281E7BC9DF009B4DEA /* IPAPatchEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = C6B263261E7BC9DF009B4DEA /* IPAPatchEntry.m */; }; 40 | C6B2634D1E7BCB31009B4DEA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = C6B2634C1E7BCB31009B4DEA /* main.m */; }; 41 | C6B263501E7BCB31009B4DEA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = C6B2634F1E7BCB31009B4DEA /* AppDelegate.m */; }; 42 | /* End PBXBuildFile section */ 43 | 44 | /* Begin PBXContainerItemProxy section */ 45 | C698BA1429861E8C00BB5DC9 /* PBXContainerItemProxy */ = { 46 | isa = PBXContainerItemProxy; 47 | containerPortal = C6B262FE1E7BC97B009B4DEA /* Project object */; 48 | proxyType = 1; 49 | remoteGlobalIDString = C698BA0F29861E8B00BB5DC9; 50 | remoteInfo = IPAPatchFrameworkMac; 51 | }; 52 | C6B263601E7BCC65009B4DEA /* PBXContainerItemProxy */ = { 53 | isa = PBXContainerItemProxy; 54 | containerPortal = C6B262FE1E7BC97B009B4DEA /* Project object */; 55 | proxyType = 1; 56 | remoteGlobalIDString = C6B263061E7BC97B009B4DEA; 57 | remoteInfo = IPAPatch; 58 | }; 59 | C6DDBB601F51469300A42BE2 /* PBXContainerItemProxy */ = { 60 | isa = PBXContainerItemProxy; 61 | containerPortal = C6B262FE1E7BC97B009B4DEA /* Project object */; 62 | proxyType = 1; 63 | remoteGlobalIDString = C6B263481E7BCB31009B4DEA; 64 | remoteInfo = "IPAPatch-DummyApp"; 65 | }; 66 | /* End PBXContainerItemProxy section */ 67 | 68 | /* Begin PBXFileReference section */ 69 | C63AC1A21E838BB70094B1C5 /* fishhook.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fishhook.c; sourceTree = ""; }; 70 | C63AC1A31E838BB70094B1C5 /* fishhook.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fishhook.h; sourceTree = ""; }; 71 | C63AC1A41E838BB70094B1C5 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; 72 | C63AC1A81E8392210094B1C5 /* IPAPatchBypassAntiDebugging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IPAPatchBypassAntiDebugging.h; sourceTree = ""; }; 73 | C63AC1A91E8392210094B1C5 /* IPAPatchBypassAntiDebugging.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IPAPatchBypassAntiDebugging.m; sourceTree = ""; }; 74 | C64288371E7BF9E900C0BBB0 /* ProjectConfigurationWarning.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProjectConfigurationWarning.cpp; sourceTree = ""; }; 75 | C64288381E7BF9E900C0BBB0 /* ProjectConfigurationWarning.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ProjectConfigurationWarning.hpp; sourceTree = ""; }; 76 | C698B9F42986148600BB5DC9 /* IPAPatch-MacDummyApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "IPAPatch-MacDummyApp.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 77 | C698B9F62986148600BB5DC9 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 78 | C698B9F72986148600BB5DC9 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 79 | C698BA012986148700BB5DC9 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 80 | C698BA1029861E8B00BB5DC9 /* IPAPatchFrameworkMac.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = IPAPatchFrameworkMac.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 81 | C698BA1229861E8C00BB5DC9 /* IPAPatchFrameworkMac.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IPAPatchFrameworkMac.h; sourceTree = ""; }; 82 | C6A353E11F51367500A9E30D /* options.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = options.plist; sourceTree = ""; }; 83 | C6B263071E7BC97B009B4DEA /* IPAPatchFramework.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = IPAPatchFramework.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 84 | C6B2630B1E7BC97B009B4DEA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 85 | C6B263251E7BC9DF009B4DEA /* IPAPatchEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IPAPatchEntry.h; sourceTree = ""; }; 86 | C6B263261E7BC9DF009B4DEA /* IPAPatchEntry.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IPAPatchEntry.m; sourceTree = ""; }; 87 | C6B263491E7BCB31009B4DEA /* IPAPatch-DummyApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "IPAPatch-DummyApp.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 88 | C6B2634C1E7BCB31009B4DEA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 89 | C6B2634E1E7BCB31009B4DEA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 90 | C6B2634F1E7BCB31009B4DEA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 91 | C6B2635C1E7BCB31009B4DEA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 92 | C6B263621E7BCD03009B4DEA /* patch.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = patch.sh; sourceTree = ""; }; 93 | C6DDBB621F5146AD00A42BE2 /* create_ipa.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = create_ipa.sh; sourceTree = ""; }; 94 | /* End PBXFileReference section */ 95 | 96 | /* Begin PBXFrameworksBuildPhase section */ 97 | C698B9F12986148600BB5DC9 /* Frameworks */ = { 98 | isa = PBXFrameworksBuildPhase; 99 | buildActionMask = 2147483647; 100 | files = ( 101 | ); 102 | runOnlyForDeploymentPostprocessing = 0; 103 | }; 104 | C698BA0D29861E8B00BB5DC9 /* Frameworks */ = { 105 | isa = PBXFrameworksBuildPhase; 106 | buildActionMask = 2147483647; 107 | files = ( 108 | ); 109 | runOnlyForDeploymentPostprocessing = 0; 110 | }; 111 | C6B263031E7BC97B009B4DEA /* Frameworks */ = { 112 | isa = PBXFrameworksBuildPhase; 113 | buildActionMask = 2147483647; 114 | files = ( 115 | ); 116 | runOnlyForDeploymentPostprocessing = 0; 117 | }; 118 | C6B263461E7BCB31009B4DEA /* Frameworks */ = { 119 | isa = PBXFrameworksBuildPhase; 120 | buildActionMask = 2147483647; 121 | files = ( 122 | ); 123 | runOnlyForDeploymentPostprocessing = 0; 124 | }; 125 | /* End PBXFrameworksBuildPhase section */ 126 | 127 | /* Begin PBXGroup section */ 128 | C63AC1A01E838B8E0094B1C5 /* Vendors */ = { 129 | isa = PBXGroup; 130 | children = ( 131 | C63AC1A11E838BB70094B1C5 /* fishhook */, 132 | ); 133 | path = Vendors; 134 | sourceTree = ""; 135 | }; 136 | C63AC1A11E838BB70094B1C5 /* fishhook */ = { 137 | isa = PBXGroup; 138 | children = ( 139 | C63AC1A31E838BB70094B1C5 /* fishhook.h */, 140 | C63AC1A21E838BB70094B1C5 /* fishhook.c */, 141 | C63AC1A41E838BB70094B1C5 /* LICENSE */, 142 | ); 143 | path = fishhook; 144 | sourceTree = ""; 145 | }; 146 | C698B9F52986148600BB5DC9 /* IPAPatch-MacDummyApp */ = { 147 | isa = PBXGroup; 148 | children = ( 149 | C698B9F62986148600BB5DC9 /* AppDelegate.h */, 150 | C698B9F72986148600BB5DC9 /* AppDelegate.m */, 151 | C698BA012986148700BB5DC9 /* main.m */, 152 | ); 153 | path = "IPAPatch-MacDummyApp"; 154 | sourceTree = ""; 155 | }; 156 | C698BA1129861E8B00BB5DC9 /* IPAPatchFrameworkMac */ = { 157 | isa = PBXGroup; 158 | children = ( 159 | C698BA1229861E8C00BB5DC9 /* IPAPatchFrameworkMac.h */, 160 | ); 161 | path = IPAPatchFrameworkMac; 162 | sourceTree = ""; 163 | }; 164 | C6B262FD1E7BC97B009B4DEA = { 165 | isa = PBXGroup; 166 | children = ( 167 | C6B263091E7BC97B009B4DEA /* IPAPatch */, 168 | C6B263291E7BCA86009B4DEA /* Tools */, 169 | C6B2634A1E7BCB31009B4DEA /* IPAPatch-DummyApp */, 170 | C698B9F52986148600BB5DC9 /* IPAPatch-MacDummyApp */, 171 | C698BA1129861E8B00BB5DC9 /* IPAPatchFrameworkMac */, 172 | C6B263081E7BC97B009B4DEA /* Products */, 173 | ); 174 | sourceTree = ""; 175 | }; 176 | C6B263081E7BC97B009B4DEA /* Products */ = { 177 | isa = PBXGroup; 178 | children = ( 179 | C6B263071E7BC97B009B4DEA /* IPAPatchFramework.framework */, 180 | C6B263491E7BCB31009B4DEA /* IPAPatch-DummyApp.app */, 181 | C698B9F42986148600BB5DC9 /* IPAPatch-MacDummyApp.app */, 182 | C698BA1029861E8B00BB5DC9 /* IPAPatchFrameworkMac.framework */, 183 | ); 184 | name = Products; 185 | sourceTree = ""; 186 | }; 187 | C6B263091E7BC97B009B4DEA /* IPAPatch */ = { 188 | isa = PBXGroup; 189 | children = ( 190 | C63AC1A01E838B8E0094B1C5 /* Vendors */, 191 | C6B2630B1E7BC97B009B4DEA /* Info.plist */, 192 | C6B263251E7BC9DF009B4DEA /* IPAPatchEntry.h */, 193 | C6B263261E7BC9DF009B4DEA /* IPAPatchEntry.m */, 194 | C63AC1A81E8392210094B1C5 /* IPAPatchBypassAntiDebugging.h */, 195 | C63AC1A91E8392210094B1C5 /* IPAPatchBypassAntiDebugging.m */, 196 | ); 197 | path = IPAPatch; 198 | sourceTree = ""; 199 | }; 200 | C6B263291E7BCA86009B4DEA /* Tools */ = { 201 | isa = PBXGroup; 202 | children = ( 203 | C6B263621E7BCD03009B4DEA /* patch.sh */, 204 | C6DDBB621F5146AD00A42BE2 /* create_ipa.sh */, 205 | C6A353E11F51367500A9E30D /* options.plist */, 206 | ); 207 | path = Tools; 208 | sourceTree = ""; 209 | }; 210 | C6B2634A1E7BCB31009B4DEA /* IPAPatch-DummyApp */ = { 211 | isa = PBXGroup; 212 | children = ( 213 | C6B2634E1E7BCB31009B4DEA /* AppDelegate.h */, 214 | C6B2634F1E7BCB31009B4DEA /* AppDelegate.m */, 215 | C64288381E7BF9E900C0BBB0 /* ProjectConfigurationWarning.hpp */, 216 | C64288371E7BF9E900C0BBB0 /* ProjectConfigurationWarning.cpp */, 217 | C6B2635C1E7BCB31009B4DEA /* Info.plist */, 218 | C6B2634B1E7BCB31009B4DEA /* Supporting Files */, 219 | ); 220 | path = "IPAPatch-DummyApp"; 221 | sourceTree = ""; 222 | }; 223 | C6B2634B1E7BCB31009B4DEA /* Supporting Files */ = { 224 | isa = PBXGroup; 225 | children = ( 226 | C6B2634C1E7BCB31009B4DEA /* main.m */, 227 | ); 228 | name = "Supporting Files"; 229 | sourceTree = ""; 230 | }; 231 | /* End PBXGroup section */ 232 | 233 | /* Begin PBXHeadersBuildPhase section */ 234 | C698BA0B29861E8B00BB5DC9 /* Headers */ = { 235 | isa = PBXHeadersBuildPhase; 236 | buildActionMask = 2147483647; 237 | files = ( 238 | C698BA1329861E8C00BB5DC9 /* IPAPatchFrameworkMac.h in Headers */, 239 | ); 240 | runOnlyForDeploymentPostprocessing = 0; 241 | }; 242 | C6B263041E7BC97B009B4DEA /* Headers */ = { 243 | isa = PBXHeadersBuildPhase; 244 | buildActionMask = 2147483647; 245 | files = ( 246 | C6B263271E7BC9DF009B4DEA /* IPAPatchEntry.h in Headers */, 247 | C63AC1A61E838BB70094B1C5 /* fishhook.h in Headers */, 248 | C63AC1AA1E8392210094B1C5 /* IPAPatchBypassAntiDebugging.h in Headers */, 249 | ); 250 | runOnlyForDeploymentPostprocessing = 0; 251 | }; 252 | /* End PBXHeadersBuildPhase section */ 253 | 254 | /* Begin PBXNativeTarget section */ 255 | C698B9F32986148600BB5DC9 /* IPAPatch-MacDummyApp */ = { 256 | isa = PBXNativeTarget; 257 | buildConfigurationList = C698BA062986148700BB5DC9 /* Build configuration list for PBXNativeTarget "IPAPatch-MacDummyApp" */; 258 | buildPhases = ( 259 | C698B9F02986148600BB5DC9 /* Sources */, 260 | C698B9F12986148600BB5DC9 /* Frameworks */, 261 | C698B9F22986148600BB5DC9 /* Resources */, 262 | C698BA09298614FC00BB5DC9 /* ShellScript */, 263 | ); 264 | buildRules = ( 265 | ); 266 | dependencies = ( 267 | C698BA1529861E8C00BB5DC9 /* PBXTargetDependency */, 268 | ); 269 | name = "IPAPatch-MacDummyApp"; 270 | productName = "IPAPatch-MacDummyApp"; 271 | productReference = C698B9F42986148600BB5DC9 /* IPAPatch-MacDummyApp.app */; 272 | productType = "com.apple.product-type.application"; 273 | }; 274 | C698BA0F29861E8B00BB5DC9 /* IPAPatchFrameworkMac */ = { 275 | isa = PBXNativeTarget; 276 | buildConfigurationList = C698BA1829861E8C00BB5DC9 /* Build configuration list for PBXNativeTarget "IPAPatchFrameworkMac" */; 277 | buildPhases = ( 278 | C698BA0B29861E8B00BB5DC9 /* Headers */, 279 | C698BA0C29861E8B00BB5DC9 /* Sources */, 280 | C698BA0D29861E8B00BB5DC9 /* Frameworks */, 281 | C698BA0E29861E8B00BB5DC9 /* Resources */, 282 | ); 283 | buildRules = ( 284 | ); 285 | dependencies = ( 286 | ); 287 | name = IPAPatchFrameworkMac; 288 | productName = IPAPatchFrameworkMac; 289 | productReference = C698BA1029861E8B00BB5DC9 /* IPAPatchFrameworkMac.framework */; 290 | productType = "com.apple.product-type.framework"; 291 | }; 292 | C6B263061E7BC97B009B4DEA /* IPAPatchFramework */ = { 293 | isa = PBXNativeTarget; 294 | buildConfigurationList = C6B2631B1E7BC97B009B4DEA /* Build configuration list for PBXNativeTarget "IPAPatchFramework" */; 295 | buildPhases = ( 296 | C6B263021E7BC97B009B4DEA /* Sources */, 297 | C6B263031E7BC97B009B4DEA /* Frameworks */, 298 | C6B263041E7BC97B009B4DEA /* Headers */, 299 | C6B263051E7BC97B009B4DEA /* Resources */, 300 | ); 301 | buildRules = ( 302 | ); 303 | dependencies = ( 304 | ); 305 | name = IPAPatchFramework; 306 | productName = IPAPatch; 307 | productReference = C6B263071E7BC97B009B4DEA /* IPAPatchFramework.framework */; 308 | productType = "com.apple.product-type.framework"; 309 | }; 310 | C6B263481E7BCB31009B4DEA /* IPAPatch-DummyApp */ = { 311 | isa = PBXNativeTarget; 312 | buildConfigurationList = C6B2635D1E7BCB31009B4DEA /* Build configuration list for PBXNativeTarget "IPAPatch-DummyApp" */; 313 | buildPhases = ( 314 | C6B263451E7BCB31009B4DEA /* Sources */, 315 | C6B263461E7BCB31009B4DEA /* Frameworks */, 316 | C6B263471E7BCB31009B4DEA /* Resources */, 317 | C6B263631E7BD0B4009B4DEA /* ShellScript */, 318 | ); 319 | buildRules = ( 320 | ); 321 | dependencies = ( 322 | C6B263611E7BCC65009B4DEA /* PBXTargetDependency */, 323 | ); 324 | name = "IPAPatch-DummyApp"; 325 | productName = "IPAPatch-DummyApp"; 326 | productReference = C6B263491E7BCB31009B4DEA /* IPAPatch-DummyApp.app */; 327 | productType = "com.apple.product-type.application"; 328 | }; 329 | /* End PBXNativeTarget section */ 330 | 331 | /* Begin PBXProject section */ 332 | C6B262FE1E7BC97B009B4DEA /* Project object */ = { 333 | isa = PBXProject; 334 | attributes = { 335 | DefaultBuildSystemTypeForWorkspace = Original; 336 | LastUpgradeCheck = 0830; 337 | ORGANIZATIONNAME = Weibo; 338 | TargetAttributes = { 339 | C698B9F32986148600BB5DC9 = { 340 | CreatedOnToolsVersion = 14.1; 341 | ProvisioningStyle = Automatic; 342 | }; 343 | C698BA0F29861E8B00BB5DC9 = { 344 | CreatedOnToolsVersion = 14.1; 345 | ProvisioningStyle = Automatic; 346 | }; 347 | C6B263061E7BC97B009B4DEA = { 348 | CreatedOnToolsVersion = 8.3; 349 | DevelopmentTeam = DMJXDB9H6Q; 350 | ProvisioningStyle = Automatic; 351 | }; 352 | C6B263481E7BCB31009B4DEA = { 353 | CreatedOnToolsVersion = 8.3; 354 | ProvisioningStyle = Automatic; 355 | }; 356 | C6DDBB5C1F51468D00A42BE2 = { 357 | CreatedOnToolsVersion = 9.0; 358 | DevelopmentTeam = DMJXDB9H6Q; 359 | }; 360 | }; 361 | }; 362 | buildConfigurationList = C6B263011E7BC97B009B4DEA /* Build configuration list for PBXProject "IPAPatch" */; 363 | compatibilityVersion = "Xcode 3.2"; 364 | developmentRegion = English; 365 | hasScannedForEncodings = 0; 366 | knownRegions = ( 367 | English, 368 | en, 369 | Base, 370 | ); 371 | mainGroup = C6B262FD1E7BC97B009B4DEA; 372 | productRefGroup = C6B263081E7BC97B009B4DEA /* Products */; 373 | projectDirPath = ""; 374 | projectRoot = ""; 375 | targets = ( 376 | C6B263481E7BCB31009B4DEA /* IPAPatch-DummyApp */, 377 | C6B263061E7BC97B009B4DEA /* IPAPatchFramework */, 378 | C6DDBB5C1F51468D00A42BE2 /* IPAPatch */, 379 | C698B9F32986148600BB5DC9 /* IPAPatch-MacDummyApp */, 380 | C698BA0F29861E8B00BB5DC9 /* IPAPatchFrameworkMac */, 381 | ); 382 | }; 383 | /* End PBXProject section */ 384 | 385 | /* Begin PBXResourcesBuildPhase section */ 386 | C698B9F22986148600BB5DC9 /* Resources */ = { 387 | isa = PBXResourcesBuildPhase; 388 | buildActionMask = 2147483647; 389 | files = ( 390 | ); 391 | runOnlyForDeploymentPostprocessing = 0; 392 | }; 393 | C698BA0E29861E8B00BB5DC9 /* Resources */ = { 394 | isa = PBXResourcesBuildPhase; 395 | buildActionMask = 2147483647; 396 | files = ( 397 | ); 398 | runOnlyForDeploymentPostprocessing = 0; 399 | }; 400 | C6B263051E7BC97B009B4DEA /* Resources */ = { 401 | isa = PBXResourcesBuildPhase; 402 | buildActionMask = 2147483647; 403 | files = ( 404 | ); 405 | runOnlyForDeploymentPostprocessing = 0; 406 | }; 407 | C6B263471E7BCB31009B4DEA /* Resources */ = { 408 | isa = PBXResourcesBuildPhase; 409 | buildActionMask = 2147483647; 410 | files = ( 411 | C6A353E21F51367500A9E30D /* options.plist in Resources */, 412 | ); 413 | runOnlyForDeploymentPostprocessing = 0; 414 | }; 415 | /* End PBXResourcesBuildPhase section */ 416 | 417 | /* Begin PBXShellScriptBuildPhase section */ 418 | C698BA09298614FC00BB5DC9 /* ShellScript */ = { 419 | isa = PBXShellScriptBuildPhase; 420 | buildActionMask = 2147483647; 421 | files = ( 422 | ); 423 | inputFileListPaths = ( 424 | ); 425 | inputPaths = ( 426 | ); 427 | outputFileListPaths = ( 428 | ); 429 | outputPaths = ( 430 | ); 431 | runOnlyForDeploymentPostprocessing = 0; 432 | shellPath = /bin/sh; 433 | shellScript = "\"${SRCROOT}/Tools/patch.sh\" Mac\n"; 434 | }; 435 | C6B263631E7BD0B4009B4DEA /* ShellScript */ = { 436 | isa = PBXShellScriptBuildPhase; 437 | buildActionMask = 2147483647; 438 | files = ( 439 | ); 440 | inputPaths = ( 441 | ); 442 | outputPaths = ( 443 | ); 444 | runOnlyForDeploymentPostprocessing = 0; 445 | shellPath = /bin/sh; 446 | shellScript = "\"${SRCROOT}/Tools/patch.sh\" iOS\n"; 447 | }; 448 | C6DDBB631F5147BA00A42BE2 /* ShellScript */ = { 449 | isa = PBXShellScriptBuildPhase; 450 | buildActionMask = 2147483647; 451 | files = ( 452 | ); 453 | inputPaths = ( 454 | ); 455 | outputPaths = ( 456 | ); 457 | runOnlyForDeploymentPostprocessing = 0; 458 | shellPath = /bin/sh; 459 | shellScript = "\"${SRCROOT}/Tools/create_ipa.sh\""; 460 | }; 461 | /* End PBXShellScriptBuildPhase section */ 462 | 463 | /* Begin PBXSourcesBuildPhase section */ 464 | C698B9F02986148600BB5DC9 /* Sources */ = { 465 | isa = PBXSourcesBuildPhase; 466 | buildActionMask = 2147483647; 467 | files = ( 468 | C698BA022986148700BB5DC9 /* main.m in Sources */, 469 | C698BA0A29861BA800BB5DC9 /* ProjectConfigurationWarning.cpp in Sources */, 470 | C698B9F82986148600BB5DC9 /* AppDelegate.m in Sources */, 471 | ); 472 | runOnlyForDeploymentPostprocessing = 0; 473 | }; 474 | C698BA0C29861E8B00BB5DC9 /* Sources */ = { 475 | isa = PBXSourcesBuildPhase; 476 | buildActionMask = 2147483647; 477 | files = ( 478 | C698BA1D29861EDA00BB5DC9 /* IPAPatchBypassAntiDebugging.m in Sources */, 479 | C698BA1E29861EDE00BB5DC9 /* fishhook.c in Sources */, 480 | C698BA1C29861ED700BB5DC9 /* IPAPatchEntry.m in Sources */, 481 | ); 482 | runOnlyForDeploymentPostprocessing = 0; 483 | }; 484 | C6B263021E7BC97B009B4DEA /* Sources */ = { 485 | isa = PBXSourcesBuildPhase; 486 | buildActionMask = 2147483647; 487 | files = ( 488 | C63AC1AB1E8392210094B1C5 /* IPAPatchBypassAntiDebugging.m in Sources */, 489 | C6B263281E7BC9DF009B4DEA /* IPAPatchEntry.m in Sources */, 490 | C63AC1A51E838BB70094B1C5 /* fishhook.c in Sources */, 491 | ); 492 | runOnlyForDeploymentPostprocessing = 0; 493 | }; 494 | C6B263451E7BCB31009B4DEA /* Sources */ = { 495 | isa = PBXSourcesBuildPhase; 496 | buildActionMask = 2147483647; 497 | files = ( 498 | C64288391E7BF9E900C0BBB0 /* ProjectConfigurationWarning.cpp in Sources */, 499 | C6B263501E7BCB31009B4DEA /* AppDelegate.m in Sources */, 500 | C6B2634D1E7BCB31009B4DEA /* main.m in Sources */, 501 | ); 502 | runOnlyForDeploymentPostprocessing = 0; 503 | }; 504 | /* End PBXSourcesBuildPhase section */ 505 | 506 | /* Begin PBXTargetDependency section */ 507 | C698BA1529861E8C00BB5DC9 /* PBXTargetDependency */ = { 508 | isa = PBXTargetDependency; 509 | target = C698BA0F29861E8B00BB5DC9 /* IPAPatchFrameworkMac */; 510 | targetProxy = C698BA1429861E8C00BB5DC9 /* PBXContainerItemProxy */; 511 | }; 512 | C6B263611E7BCC65009B4DEA /* PBXTargetDependency */ = { 513 | isa = PBXTargetDependency; 514 | target = C6B263061E7BC97B009B4DEA /* IPAPatchFramework */; 515 | targetProxy = C6B263601E7BCC65009B4DEA /* PBXContainerItemProxy */; 516 | }; 517 | C6DDBB611F51469300A42BE2 /* PBXTargetDependency */ = { 518 | isa = PBXTargetDependency; 519 | target = C6B263481E7BCB31009B4DEA /* IPAPatch-DummyApp */; 520 | targetProxy = C6DDBB601F51469300A42BE2 /* PBXContainerItemProxy */; 521 | }; 522 | /* End PBXTargetDependency section */ 523 | 524 | /* Begin XCBuildConfiguration section */ 525 | C698BA042986148700BB5DC9 /* Debug */ = { 526 | isa = XCBuildConfiguration; 527 | buildSettings = { 528 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 529 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 530 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 531 | CLANG_ENABLE_OBJC_WEAK = YES; 532 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 533 | CLANG_WARN_COMMA = YES; 534 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 535 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 536 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 537 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 538 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 539 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 540 | CLANG_WARN_STRICT_PROTOTYPES = YES; 541 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 542 | CODE_SIGN_ENTITLEMENTS = ""; 543 | CODE_SIGN_STYLE = Automatic; 544 | COMBINE_HIDPI_IMAGES = YES; 545 | CURRENT_PROJECT_VERSION = 1; 546 | DEVELOPMENT_TEAM = ""; 547 | ENABLE_HARDENED_RUNTIME = YES; 548 | GCC_C_LANGUAGE_STANDARD = gnu11; 549 | GCC_PREPROCESSOR_DEFINITIONS = ( 550 | "DEBUG=1", 551 | "$(inherited)", 552 | "TARGET_BUNDLE_ID=$(PRODUCT_BUNDLE_IDENTIFIER)", 553 | "CODE_SIGN_IDENTITY=$(CODE_SIGN_IDENTITY)", 554 | ); 555 | GENERATE_INFOPLIST_FILE = NO; 556 | INFOPLIST_FILE = "IPAPatch-DummyApp/Info.plist"; 557 | INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023 Weibo. All rights reserved."; 558 | INFOPLIST_KEY_NSMainStoryboardFile = Main; 559 | INFOPLIST_KEY_NSPrincipalClass = NSApplication; 560 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 561 | MACOSX_DEPLOYMENT_TARGET = 13.0; 562 | MARKETING_VERSION = 1.0; 563 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 564 | MTL_FAST_MATH = YES; 565 | PRODUCT_BUNDLE_IDENTIFIER = com.wutian.example; 566 | PRODUCT_NAME = "$(TARGET_NAME)"; 567 | SDKROOT = macosx; 568 | SWIFT_EMIT_LOC_STRINGS = YES; 569 | }; 570 | name = Debug; 571 | }; 572 | C698BA052986148700BB5DC9 /* Release */ = { 573 | isa = XCBuildConfiguration; 574 | buildSettings = { 575 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 576 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 577 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 578 | CLANG_ENABLE_OBJC_WEAK = YES; 579 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 580 | CLANG_WARN_COMMA = YES; 581 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 582 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 583 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 584 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 585 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 586 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 587 | CLANG_WARN_STRICT_PROTOTYPES = YES; 588 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 589 | CODE_SIGN_ENTITLEMENTS = ""; 590 | CODE_SIGN_STYLE = Automatic; 591 | COMBINE_HIDPI_IMAGES = YES; 592 | CURRENT_PROJECT_VERSION = 1; 593 | DEVELOPMENT_TEAM = ""; 594 | ENABLE_HARDENED_RUNTIME = YES; 595 | GCC_C_LANGUAGE_STANDARD = gnu11; 596 | GCC_PREPROCESSOR_DEFINITIONS = ( 597 | "TARGET_BUNDLE_ID=$(PRODUCT_BUNDLE_IDENTIFIER)", 598 | "CODE_SIGN_IDENTITY=$(CODE_SIGN_IDENTITY)", 599 | ); 600 | GENERATE_INFOPLIST_FILE = NO; 601 | INFOPLIST_FILE = "IPAPatch-DummyApp/Info.plist"; 602 | INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023 Weibo. All rights reserved."; 603 | INFOPLIST_KEY_NSMainStoryboardFile = Main; 604 | INFOPLIST_KEY_NSPrincipalClass = NSApplication; 605 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 606 | MACOSX_DEPLOYMENT_TARGET = 13.0; 607 | MARKETING_VERSION = 1.0; 608 | MTL_FAST_MATH = YES; 609 | PRODUCT_BUNDLE_IDENTIFIER = com.wutian.example; 610 | PRODUCT_NAME = "$(TARGET_NAME)"; 611 | SDKROOT = macosx; 612 | SWIFT_EMIT_LOC_STRINGS = YES; 613 | }; 614 | name = Release; 615 | }; 616 | C698BA1929861E8C00BB5DC9 /* Debug */ = { 617 | isa = XCBuildConfiguration; 618 | buildSettings = { 619 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 620 | CLANG_ENABLE_OBJC_WEAK = YES; 621 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 622 | CLANG_WARN_COMMA = YES; 623 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 624 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 625 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 626 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 627 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 628 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 629 | CLANG_WARN_STRICT_PROTOTYPES = YES; 630 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 631 | CODE_SIGN_STYLE = Automatic; 632 | COMBINE_HIDPI_IMAGES = YES; 633 | CURRENT_PROJECT_VERSION = 1; 634 | DEFINES_MODULE = YES; 635 | DEVELOPMENT_TEAM = ""; 636 | DYLIB_COMPATIBILITY_VERSION = 1; 637 | DYLIB_CURRENT_VERSION = 1; 638 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 639 | GCC_C_LANGUAGE_STANDARD = gnu11; 640 | GENERATE_INFOPLIST_FILE = YES; 641 | INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023 Weibo. All rights reserved."; 642 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 643 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 644 | MACOSX_DEPLOYMENT_TARGET = 10.15; 645 | MARKETING_VERSION = 1.0; 646 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 647 | MTL_FAST_MATH = YES; 648 | ONLY_ACTIVE_ARCH = NO; 649 | PRODUCT_BUNDLE_IDENTIFIER = com.wutian.IPAPatchMac; 650 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 651 | SDKROOT = macosx; 652 | SKIP_INSTALL = YES; 653 | SWIFT_EMIT_LOC_STRINGS = YES; 654 | }; 655 | name = Debug; 656 | }; 657 | C698BA1A29861E8C00BB5DC9 /* Release */ = { 658 | isa = XCBuildConfiguration; 659 | buildSettings = { 660 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 661 | CLANG_ENABLE_OBJC_WEAK = YES; 662 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 663 | CLANG_WARN_COMMA = YES; 664 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 665 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 666 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 667 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 668 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 669 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 670 | CLANG_WARN_STRICT_PROTOTYPES = YES; 671 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 672 | CODE_SIGN_STYLE = Automatic; 673 | COMBINE_HIDPI_IMAGES = YES; 674 | CURRENT_PROJECT_VERSION = 1; 675 | DEFINES_MODULE = YES; 676 | DEVELOPMENT_TEAM = ""; 677 | DYLIB_COMPATIBILITY_VERSION = 1; 678 | DYLIB_CURRENT_VERSION = 1; 679 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 680 | GCC_C_LANGUAGE_STANDARD = gnu11; 681 | GENERATE_INFOPLIST_FILE = YES; 682 | INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023 Weibo. All rights reserved."; 683 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 684 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 685 | MACOSX_DEPLOYMENT_TARGET = 10.15; 686 | MARKETING_VERSION = 1.0; 687 | MTL_FAST_MATH = YES; 688 | ONLY_ACTIVE_ARCH = NO; 689 | PRODUCT_BUNDLE_IDENTIFIER = com.wutian.IPAPatchMac; 690 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 691 | SDKROOT = macosx; 692 | SKIP_INSTALL = YES; 693 | SWIFT_EMIT_LOC_STRINGS = YES; 694 | }; 695 | name = Release; 696 | }; 697 | C6B263191E7BC97B009B4DEA /* Debug */ = { 698 | isa = XCBuildConfiguration; 699 | buildSettings = { 700 | ALWAYS_SEARCH_USER_PATHS = NO; 701 | CLANG_ANALYZER_NONNULL = YES; 702 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 703 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 704 | CLANG_CXX_LIBRARY = "libc++"; 705 | CLANG_ENABLE_MODULES = YES; 706 | CLANG_ENABLE_OBJC_ARC = YES; 707 | CLANG_WARN_BOOL_CONVERSION = YES; 708 | CLANG_WARN_CONSTANT_CONVERSION = YES; 709 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 710 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 711 | CLANG_WARN_EMPTY_BODY = YES; 712 | CLANG_WARN_ENUM_CONVERSION = YES; 713 | CLANG_WARN_INFINITE_RECURSION = YES; 714 | CLANG_WARN_INT_CONVERSION = YES; 715 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 716 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 717 | CLANG_WARN_UNREACHABLE_CODE = YES; 718 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 719 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 720 | COPY_PHASE_STRIP = NO; 721 | CURRENT_PROJECT_VERSION = 1; 722 | DEBUG_INFORMATION_FORMAT = dwarf; 723 | ENABLE_STRICT_OBJC_MSGSEND = YES; 724 | ENABLE_TESTABILITY = YES; 725 | GCC_C_LANGUAGE_STANDARD = gnu99; 726 | GCC_DYNAMIC_NO_PIC = NO; 727 | GCC_NO_COMMON_BLOCKS = YES; 728 | GCC_OPTIMIZATION_LEVEL = 0; 729 | GCC_PREPROCESSOR_DEFINITIONS = ( 730 | "DEBUG=1", 731 | "$(inherited)", 732 | ); 733 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 734 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 735 | GCC_WARN_UNDECLARED_SELECTOR = YES; 736 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 737 | GCC_WARN_UNUSED_FUNCTION = YES; 738 | GCC_WARN_UNUSED_VARIABLE = YES; 739 | IPHONEOS_DEPLOYMENT_TARGET = 10.3; 740 | MTL_ENABLE_DEBUG_INFO = YES; 741 | ONLY_ACTIVE_ARCH = YES; 742 | SDKROOT = iphoneos; 743 | TARGETED_DEVICE_FAMILY = "1,2"; 744 | VERSIONING_SYSTEM = "apple-generic"; 745 | VERSION_INFO_PREFIX = ""; 746 | }; 747 | name = Debug; 748 | }; 749 | C6B2631A1E7BC97B009B4DEA /* Release */ = { 750 | isa = XCBuildConfiguration; 751 | buildSettings = { 752 | ALWAYS_SEARCH_USER_PATHS = NO; 753 | CLANG_ANALYZER_NONNULL = YES; 754 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 755 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 756 | CLANG_CXX_LIBRARY = "libc++"; 757 | CLANG_ENABLE_MODULES = YES; 758 | CLANG_ENABLE_OBJC_ARC = YES; 759 | CLANG_WARN_BOOL_CONVERSION = YES; 760 | CLANG_WARN_CONSTANT_CONVERSION = YES; 761 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 762 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 763 | CLANG_WARN_EMPTY_BODY = YES; 764 | CLANG_WARN_ENUM_CONVERSION = YES; 765 | CLANG_WARN_INFINITE_RECURSION = YES; 766 | CLANG_WARN_INT_CONVERSION = YES; 767 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 768 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 769 | CLANG_WARN_UNREACHABLE_CODE = YES; 770 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 771 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 772 | COPY_PHASE_STRIP = NO; 773 | CURRENT_PROJECT_VERSION = 1; 774 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 775 | ENABLE_NS_ASSERTIONS = NO; 776 | ENABLE_STRICT_OBJC_MSGSEND = YES; 777 | GCC_C_LANGUAGE_STANDARD = gnu99; 778 | GCC_NO_COMMON_BLOCKS = YES; 779 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 780 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 781 | GCC_WARN_UNDECLARED_SELECTOR = YES; 782 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 783 | GCC_WARN_UNUSED_FUNCTION = YES; 784 | GCC_WARN_UNUSED_VARIABLE = YES; 785 | IPHONEOS_DEPLOYMENT_TARGET = 10.3; 786 | MTL_ENABLE_DEBUG_INFO = NO; 787 | SDKROOT = iphoneos; 788 | TARGETED_DEVICE_FAMILY = "1,2"; 789 | VALIDATE_PRODUCT = YES; 790 | VERSIONING_SYSTEM = "apple-generic"; 791 | VERSION_INFO_PREFIX = ""; 792 | }; 793 | name = Release; 794 | }; 795 | C6B2631C1E7BC97B009B4DEA /* Debug */ = { 796 | isa = XCBuildConfiguration; 797 | buildSettings = { 798 | CODE_SIGN_IDENTITY = ""; 799 | DEFINES_MODULE = NO; 800 | DEVELOPMENT_TEAM = DMJXDB9H6Q; 801 | DYLIB_COMPATIBILITY_VERSION = 1; 802 | DYLIB_CURRENT_VERSION = 1; 803 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 804 | ENABLE_BITCODE = NO; 805 | INFOPLIST_FILE = IPAPatch/Info.plist; 806 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 807 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 808 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 809 | ONLY_ACTIVE_ARCH = NO; 810 | PRODUCT_BUNDLE_IDENTIFIER = com.wutian.IPAPatch; 811 | PRODUCT_NAME = "$(TARGET_NAME)"; 812 | SKIP_INSTALL = YES; 813 | }; 814 | name = Debug; 815 | }; 816 | C6B2631D1E7BC97B009B4DEA /* Release */ = { 817 | isa = XCBuildConfiguration; 818 | buildSettings = { 819 | CODE_SIGN_IDENTITY = ""; 820 | DEFINES_MODULE = NO; 821 | DEVELOPMENT_TEAM = DMJXDB9H6Q; 822 | DYLIB_COMPATIBILITY_VERSION = 1; 823 | DYLIB_CURRENT_VERSION = 1; 824 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 825 | ENABLE_BITCODE = NO; 826 | INFOPLIST_FILE = IPAPatch/Info.plist; 827 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 828 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 829 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 830 | PRODUCT_BUNDLE_IDENTIFIER = com.wutian.IPAPatch; 831 | PRODUCT_NAME = "$(TARGET_NAME)"; 832 | SKIP_INSTALL = YES; 833 | }; 834 | name = Release; 835 | }; 836 | C6B2635E1E7BCB31009B4DEA /* Debug */ = { 837 | isa = XCBuildConfiguration; 838 | buildSettings = { 839 | CLANG_CXX_LANGUAGE_STANDARD = "c++14"; 840 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 841 | CODE_SIGN_STYLE = Automatic; 842 | DEVELOPMENT_TEAM = ""; 843 | ENABLE_BITCODE = NO; 844 | GCC_PREPROCESSOR_DEFINITIONS = ( 845 | "DEBUG=1", 846 | "$(inherited)", 847 | "TARGET_BUNDLE_ID=$(PRODUCT_BUNDLE_IDENTIFIER)", 848 | "CODE_SIGN_IDENTITY=$(CODE_SIGN_IDENTITY)", 849 | ); 850 | INFOPLIST_FILE = "IPAPatch-DummyApp/Info.plist"; 851 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 852 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 853 | PRODUCT_BUNDLE_IDENTIFIER = com.wutian.example; 854 | PRODUCT_NAME = "$(TARGET_NAME)"; 855 | PROVISIONING_PROFILE = ""; 856 | PROVISIONING_PROFILE_SPECIFIER = ""; 857 | SDKROOT = iphoneos; 858 | }; 859 | name = Debug; 860 | }; 861 | C6B2635F1E7BCB31009B4DEA /* Release */ = { 862 | isa = XCBuildConfiguration; 863 | buildSettings = { 864 | CLANG_CXX_LANGUAGE_STANDARD = "c++14"; 865 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 866 | CODE_SIGN_STYLE = Automatic; 867 | DEVELOPMENT_TEAM = ""; 868 | ENABLE_BITCODE = NO; 869 | GCC_PREPROCESSOR_DEFINITIONS = ( 870 | "TARGET_BUNDLE_ID=$(PRODUCT_BUNDLE_IDENTIFIER)", 871 | "CODE_SIGN_IDENTITY=$(CODE_SIGN_IDENTITY)", 872 | ); 873 | INFOPLIST_FILE = "IPAPatch-DummyApp/Info.plist"; 874 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 875 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 876 | PRODUCT_BUNDLE_IDENTIFIER = com.wutian.example; 877 | PRODUCT_NAME = "$(TARGET_NAME)"; 878 | PROVISIONING_PROFILE = ""; 879 | PROVISIONING_PROFILE_SPECIFIER = ""; 880 | SDKROOT = iphoneos; 881 | }; 882 | name = Release; 883 | }; 884 | C6DDBB5E1F51468D00A42BE2 /* Debug */ = { 885 | isa = XCBuildConfiguration; 886 | buildSettings = { 887 | DEVELOPMENT_TEAM = DMJXDB9H6Q; 888 | PRODUCT_NAME = "$(TARGET_NAME)"; 889 | }; 890 | name = Debug; 891 | }; 892 | C6DDBB5F1F51468D00A42BE2 /* Release */ = { 893 | isa = XCBuildConfiguration; 894 | buildSettings = { 895 | DEVELOPMENT_TEAM = DMJXDB9H6Q; 896 | PRODUCT_NAME = "$(TARGET_NAME)"; 897 | }; 898 | name = Release; 899 | }; 900 | /* End XCBuildConfiguration section */ 901 | 902 | /* Begin XCConfigurationList section */ 903 | C698BA062986148700BB5DC9 /* Build configuration list for PBXNativeTarget "IPAPatch-MacDummyApp" */ = { 904 | isa = XCConfigurationList; 905 | buildConfigurations = ( 906 | C698BA042986148700BB5DC9 /* Debug */, 907 | C698BA052986148700BB5DC9 /* Release */, 908 | ); 909 | defaultConfigurationIsVisible = 0; 910 | defaultConfigurationName = Release; 911 | }; 912 | C698BA1829861E8C00BB5DC9 /* Build configuration list for PBXNativeTarget "IPAPatchFrameworkMac" */ = { 913 | isa = XCConfigurationList; 914 | buildConfigurations = ( 915 | C698BA1929861E8C00BB5DC9 /* Debug */, 916 | C698BA1A29861E8C00BB5DC9 /* Release */, 917 | ); 918 | defaultConfigurationIsVisible = 0; 919 | defaultConfigurationName = Release; 920 | }; 921 | C6B263011E7BC97B009B4DEA /* Build configuration list for PBXProject "IPAPatch" */ = { 922 | isa = XCConfigurationList; 923 | buildConfigurations = ( 924 | C6B263191E7BC97B009B4DEA /* Debug */, 925 | C6B2631A1E7BC97B009B4DEA /* Release */, 926 | ); 927 | defaultConfigurationIsVisible = 0; 928 | defaultConfigurationName = Release; 929 | }; 930 | C6B2631B1E7BC97B009B4DEA /* Build configuration list for PBXNativeTarget "IPAPatchFramework" */ = { 931 | isa = XCConfigurationList; 932 | buildConfigurations = ( 933 | C6B2631C1E7BC97B009B4DEA /* Debug */, 934 | C6B2631D1E7BC97B009B4DEA /* Release */, 935 | ); 936 | defaultConfigurationIsVisible = 0; 937 | defaultConfigurationName = Release; 938 | }; 939 | C6B2635D1E7BCB31009B4DEA /* Build configuration list for PBXNativeTarget "IPAPatch-DummyApp" */ = { 940 | isa = XCConfigurationList; 941 | buildConfigurations = ( 942 | C6B2635E1E7BCB31009B4DEA /* Debug */, 943 | C6B2635F1E7BCB31009B4DEA /* Release */, 944 | ); 945 | defaultConfigurationIsVisible = 0; 946 | defaultConfigurationName = Release; 947 | }; 948 | C6DDBB5D1F51468D00A42BE2 /* Build configuration list for PBXAggregateTarget "IPAPatch" */ = { 949 | isa = XCConfigurationList; 950 | buildConfigurations = ( 951 | C6DDBB5E1F51468D00A42BE2 /* Debug */, 952 | C6DDBB5F1F51468D00A42BE2 /* Release */, 953 | ); 954 | defaultConfigurationIsVisible = 0; 955 | defaultConfigurationName = Release; 956 | }; 957 | /* End XCConfigurationList section */ 958 | }; 959 | rootObject = C6B262FE1E7BC97B009B4DEA /* Project object */; 960 | } 961 | -------------------------------------------------------------------------------- /IPAPatch.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /IPAPatch.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /IPAPatch.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildSystemType 6 | Original 7 | PreviewsEnabled 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /IPAPatch.xcodeproj/xcshareddata/xcschemes/IPAPatch-DummyApp.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 9 | 10 | 16 | 22 | 23 | 24 | 25 | 26 | 32 | 33 | 45 | 47 | 53 | 54 | 55 | 56 | 62 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /IPAPatch.xcodeproj/xcshareddata/xcschemes/IPAPatch.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 9 | 10 | 16 | 22 | 23 | 24 | 25 | 26 | 32 | 33 | 44 | 45 | 51 | 52 | 58 | 59 | 60 | 61 | 63 | 64 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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/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 | #if TARGET_OS_OSX 13 | #import 14 | #else 15 | #import 16 | #endif 17 | 18 | @implementation IPAPatchEntry 19 | 20 | + (void)load 21 | { 22 | // DO YOUR WORKS... 23 | 24 | // For Example: 25 | [self for_example_showAlert]; 26 | } 27 | 28 | + (void)for_example_showAlert 29 | { 30 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 31 | 32 | #if TARGET_OS_OSX 33 | __auto_type alert = [[NSAlert alloc] init]; 34 | alert.messageText = @"Hacked"; 35 | alert.informativeText = @"Hacked with IPAPatch"; 36 | [alert addButtonWithTitle:@"OK"]; 37 | [alert runModal]; 38 | #else 39 | UIAlertController * alertController = [UIAlertController alertControllerWithTitle:@"Hacked" message:@"Hacked with IPAPatch" preferredStyle:UIAlertControllerStyleAlert]; 40 | [alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:NULL]]; 41 | UIViewController * controller = [UIApplication sharedApplication].keyWindow.rootViewController; 42 | while (controller.presentedViewController) { 43 | controller = controller.presentedViewController; 44 | } 45 | [controller presentViewController:alertController animated:YES completion:NULL]; 46 | #endif 47 | }); 48 | } 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013, Facebook, Inc. 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // * Redistributions of source code must retain the above copyright notice, 6 | // this list of conditions and the following disclaimer. 7 | // * Redistributions in binary form must reproduce the above copyright notice, 8 | // this list of conditions and the following disclaimer in the documentation 9 | // and/or other materials provided with the distribution. 10 | // * Neither the name Facebook nor the names of its contributors may be used to 11 | // endorse or promote products derived from this software without specific 12 | // prior written permission. 13 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 14 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 17 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 21 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | 24 | #include "fishhook.h" 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #ifdef __LP64__ 40 | typedef struct mach_header_64 mach_header_t; 41 | typedef struct segment_command_64 segment_command_t; 42 | typedef struct section_64 section_t; 43 | typedef struct nlist_64 nlist_t; 44 | #define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT_64 45 | #else 46 | typedef struct mach_header mach_header_t; 47 | typedef struct segment_command segment_command_t; 48 | typedef struct section section_t; 49 | typedef struct nlist nlist_t; 50 | #define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT 51 | #endif 52 | 53 | #ifndef SEG_DATA_CONST 54 | #define SEG_DATA_CONST "__DATA_CONST" 55 | #endif 56 | 57 | struct rebindings_entry { 58 | struct rebinding *rebindings; 59 | size_t rebindings_nel; 60 | struct rebindings_entry *next; 61 | }; 62 | 63 | static struct rebindings_entry *_rebindings_head; 64 | 65 | static int prepend_rebindings(struct rebindings_entry **rebindings_head, 66 | struct rebinding rebindings[], 67 | size_t nel) { 68 | struct rebindings_entry *new_entry = (struct rebindings_entry *) malloc(sizeof(struct rebindings_entry)); 69 | if (!new_entry) { 70 | return -1; 71 | } 72 | new_entry->rebindings = (struct rebinding *) malloc(sizeof(struct rebinding) * nel); 73 | if (!new_entry->rebindings) { 74 | free(new_entry); 75 | return -1; 76 | } 77 | memcpy(new_entry->rebindings, rebindings, sizeof(struct rebinding) * nel); 78 | new_entry->rebindings_nel = nel; 79 | new_entry->next = *rebindings_head; 80 | *rebindings_head = new_entry; 81 | return 0; 82 | } 83 | 84 | #if 0 85 | static int get_protection(void *addr, vm_prot_t *prot, vm_prot_t *max_prot) { 86 | mach_port_t task = mach_task_self(); 87 | vm_size_t size = 0; 88 | vm_address_t address = (vm_address_t)addr; 89 | memory_object_name_t object; 90 | #ifdef __LP64__ 91 | mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT_64; 92 | vm_region_basic_info_data_64_t info; 93 | kern_return_t info_ret = vm_region_64( 94 | task, &address, &size, VM_REGION_BASIC_INFO_64, (vm_region_info_64_t)&info, &count, &object); 95 | #else 96 | mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT; 97 | vm_region_basic_info_data_t info; 98 | kern_return_t info_ret = vm_region(task, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)&info, &count, &object); 99 | #endif 100 | if (info_ret == KERN_SUCCESS) { 101 | if (prot != NULL) 102 | *prot = info.protection; 103 | 104 | if (max_prot != NULL) 105 | *max_prot = info.max_protection; 106 | 107 | return 0; 108 | } 109 | 110 | return -1; 111 | } 112 | #endif 113 | 114 | static void perform_rebinding_with_section(struct rebindings_entry *rebindings, 115 | section_t *section, 116 | intptr_t slide, 117 | nlist_t *symtab, 118 | char *strtab, 119 | uint32_t *indirect_symtab) { 120 | uint32_t *indirect_symbol_indices = indirect_symtab + section->reserved1; 121 | void **indirect_symbol_bindings = (void **)((uintptr_t)slide + section->addr); 122 | 123 | for (uint i = 0; i < section->size / sizeof(void *); i++) { 124 | uint32_t symtab_index = indirect_symbol_indices[i]; 125 | if (symtab_index == INDIRECT_SYMBOL_ABS || symtab_index == INDIRECT_SYMBOL_LOCAL || 126 | symtab_index == (INDIRECT_SYMBOL_LOCAL | INDIRECT_SYMBOL_ABS)) { 127 | continue; 128 | } 129 | uint32_t strtab_offset = symtab[symtab_index].n_un.n_strx; 130 | char *symbol_name = strtab + strtab_offset; 131 | bool symbol_name_longer_than_1 = symbol_name[0] && symbol_name[1]; 132 | struct rebindings_entry *cur = rebindings; 133 | while (cur) { 134 | for (uint j = 0; j < cur->rebindings_nel; j++) { 135 | if (symbol_name_longer_than_1 && strcmp(&symbol_name[1], cur->rebindings[j].name) == 0) { 136 | kern_return_t err; 137 | 138 | if (cur->rebindings[j].replaced != NULL && indirect_symbol_bindings[i] != cur->rebindings[j].replacement) 139 | *(cur->rebindings[j].replaced) = indirect_symbol_bindings[i]; 140 | 141 | /** 142 | * 1. Moved the vm protection modifying codes to here to reduce the 143 | * changing scope. 144 | * 2. Adding VM_PROT_WRITE mode unconditionally because vm_region 145 | * API on some iOS/Mac reports mismatch vm protection attributes. 146 | * -- Lianfu Hao Jun 16th, 2021 147 | **/ 148 | err = vm_protect (mach_task_self (), (uintptr_t)indirect_symbol_bindings, section->size, 0, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_COPY); 149 | if (err == KERN_SUCCESS) { 150 | /** 151 | * Once we failed to change the vm protection, we 152 | * MUST NOT continue the following write actions! 153 | * iOS 15 has corrected the const segments prot. 154 | * -- Lionfore Hao Jun 11th, 2021 155 | **/ 156 | indirect_symbol_bindings[i] = cur->rebindings[j].replacement; 157 | } 158 | goto symbol_loop; 159 | } 160 | } 161 | cur = cur->next; 162 | } 163 | symbol_loop:; 164 | } 165 | } 166 | 167 | static void rebind_symbols_for_image(struct rebindings_entry *rebindings, 168 | const struct mach_header *header, 169 | intptr_t slide) { 170 | Dl_info info; 171 | if (dladdr(header, &info) == 0) { 172 | return; 173 | } 174 | 175 | segment_command_t *cur_seg_cmd; 176 | segment_command_t *linkedit_segment = NULL; 177 | struct symtab_command* symtab_cmd = NULL; 178 | struct dysymtab_command* dysymtab_cmd = NULL; 179 | 180 | uintptr_t cur = (uintptr_t)header + sizeof(mach_header_t); 181 | for (uint i = 0; i < header->ncmds; i++, cur += cur_seg_cmd->cmdsize) { 182 | cur_seg_cmd = (segment_command_t *)cur; 183 | if (cur_seg_cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) { 184 | if (strcmp(cur_seg_cmd->segname, SEG_LINKEDIT) == 0) { 185 | linkedit_segment = cur_seg_cmd; 186 | } 187 | } else if (cur_seg_cmd->cmd == LC_SYMTAB) { 188 | symtab_cmd = (struct symtab_command*)cur_seg_cmd; 189 | } else if (cur_seg_cmd->cmd == LC_DYSYMTAB) { 190 | dysymtab_cmd = (struct dysymtab_command*)cur_seg_cmd; 191 | } 192 | } 193 | 194 | if (!symtab_cmd || !dysymtab_cmd || !linkedit_segment || 195 | !dysymtab_cmd->nindirectsyms) { 196 | return; 197 | } 198 | 199 | // Find base symbol/string table addresses 200 | uintptr_t linkedit_base = (uintptr_t)slide + linkedit_segment->vmaddr - linkedit_segment->fileoff; 201 | nlist_t *symtab = (nlist_t *)(linkedit_base + symtab_cmd->symoff); 202 | char *strtab = (char *)(linkedit_base + symtab_cmd->stroff); 203 | 204 | // Get indirect symbol table (array of uint32_t indices into symbol table) 205 | uint32_t *indirect_symtab = (uint32_t *)(linkedit_base + dysymtab_cmd->indirectsymoff); 206 | 207 | cur = (uintptr_t)header + sizeof(mach_header_t); 208 | for (uint i = 0; i < header->ncmds; i++, cur += cur_seg_cmd->cmdsize) { 209 | cur_seg_cmd = (segment_command_t *)cur; 210 | if (cur_seg_cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) { 211 | if (strcmp(cur_seg_cmd->segname, SEG_DATA) != 0 && 212 | strcmp(cur_seg_cmd->segname, SEG_DATA_CONST) != 0) { 213 | continue; 214 | } 215 | for (uint j = 0; j < cur_seg_cmd->nsects; j++) { 216 | section_t *sect = 217 | (section_t *)(cur + sizeof(segment_command_t)) + j; 218 | if ((sect->flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS) { 219 | perform_rebinding_with_section(rebindings, sect, slide, symtab, strtab, indirect_symtab); 220 | } 221 | if ((sect->flags & SECTION_TYPE) == S_NON_LAZY_SYMBOL_POINTERS) { 222 | perform_rebinding_with_section(rebindings, sect, slide, symtab, strtab, indirect_symtab); 223 | } 224 | } 225 | } 226 | } 227 | } 228 | 229 | static void _rebind_symbols_for_image(const struct mach_header *header, 230 | intptr_t slide) { 231 | rebind_symbols_for_image(_rebindings_head, header, slide); 232 | } 233 | 234 | int rebind_symbols_image(void *header, 235 | intptr_t slide, 236 | struct rebinding rebindings[], 237 | size_t rebindings_nel) { 238 | struct rebindings_entry *rebindings_head = NULL; 239 | int retval = prepend_rebindings(&rebindings_head, rebindings, rebindings_nel); 240 | rebind_symbols_for_image(rebindings_head, (const struct mach_header *) header, slide); 241 | if (rebindings_head) { 242 | free(rebindings_head->rebindings); 243 | } 244 | free(rebindings_head); 245 | return retval; 246 | } 247 | 248 | int rebind_symbols(struct rebinding rebindings[], size_t rebindings_nel) { 249 | int retval = prepend_rebindings(&_rebindings_head, rebindings, rebindings_nel); 250 | if (retval < 0) { 251 | return retval; 252 | } 253 | // If this was the first call, register callback for image additions (which is also invoked for 254 | // existing images, otherwise, just run on existing images 255 | if (!_rebindings_head->next) { 256 | _dyld_register_func_for_add_image(_rebind_symbols_for_image); 257 | } else { 258 | uint32_t c = _dyld_image_count(); 259 | for (uint32_t i = 0; i < c; i++) { 260 | _rebind_symbols_for_image(_dyld_get_image_header(i), _dyld_get_image_vmaddr_slide(i)); 261 | } 262 | } 263 | return retval; 264 | } 265 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /IPAPatchFrameworkMac/IPAPatchFrameworkMac.h: -------------------------------------------------------------------------------- 1 | // 2 | // IPAPatchFrameworkMac.h 3 | // IPAPatchFrameworkMac 4 | // 5 | // Created by 吴天 on 2023/1/29. 6 | // Copyright © 2023 Weibo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for IPAPatchFrameworkMac. 12 | FOUNDATION_EXPORT double IPAPatchFrameworkMacVersionNumber; 13 | 14 | //! Project version string for IPAPatchFrameworkMac. 15 | FOUNDATION_EXPORT const unsigned char IPAPatchFrameworkMacVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | - **Generate distributable .ipa files** 42 | 43 | You can distribute your patch/work to your friends very easily, with IPAPatch generated modified version of .ipa files 44 | 45 | > *Modified version of Facebook.ipa created by IPAPatch* 46 | > 47 | > ![](http://wx1.sinaimg.cn/large/bebedbb5ly1fiyawu5q36j20gt07fgmr.jpg) 48 | 49 | ## Instructions 50 | 51 | 1. **Clone or Download This Project** 52 | 53 | Download this project to your local disk 54 | 55 | 2. **Prepare Decrypted IPA File** 56 | 57 | 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 58 | 59 | 3. **Replace Placeholder IPA** 60 | 61 | 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. 62 | 63 | 4. **Place External Resources/Frameworks (Optional)** 64 | 65 | Follow types of external file are supported: 66 | - **Frameworks**: 67 | - External frameworks can be placed at `IPAPatch/Assets/Frameworks` folder. 68 | - Frameworks will be linked automatically. 69 | - For example `IPAPatch/Assets/Frameworks/RevealServer.framework` 70 | - **Dynamic Libraries**: 71 | - External dynamic libraries can be placed at `IPAPatch/Assets/Dylibs` folder. 72 | - Libraries will be linked automatically 73 | - **Resources/Bundles**: 74 | - Other resources or bundles can be placed at `IPAPatch/Assets/Resources` 75 | - Resources will be copied directly to the main bundle of original app 76 | 77 | 5. **Configure Build Settings** 78 | 79 | - Open `IPAPatch.xcodeproj` 80 | - In the Project Editor, Select Target `IPAPatch-DummyApp` 81 | - `Display Name` defaults to "💊", this is used as prefix of the final display name. 82 | - Change `Bundle Identifier` to match your provisioning profiles 83 | - Fix signing issues if any. 84 | 85 | 6. **Configure IPPatch Options** 86 | 87 | - You can config IPAPatch's behavior with `Tools/options.plist` 88 | 89 | | Name | Description | Default | 90 | | --- | --- | --- | 91 | | RESTORE_SYMBOLS | When `YES`, IPAPatch will try to restore symbol table from Mach-O for debugging propose (with tools from https://github.com/tobefuturer/restore-symbol, also thanks to @henrayluo and @dannion) | NO | 92 | | CREATE_IPA_FILE | When `YES`, IPAPatch will generate a ipa file on each build. Genrated file is located at `SRCROOT/Product` | NO | 93 | | IGNORE_UI_SUPPORTED_DEVICES | When `YES`, IPAPatch will delete `UISupportedDevices` from source app's `Info.plist` | NO | 94 | | REMOVE_WATCHPLACEHOLDER | When `YES`, IPAPatch will remove `com.apple.WatchPlaceholder` folder from source app's bundle | YES | 95 | | USE_ORIGINAL_ENTITLEMENTS | When `YES`, IPAPatch will use source app's entitlements to resign, you need to make sure your Provisioning Profile matches the entitlements, or you need to disable `AMFI` on target device | NO | 96 | 97 | 7. **Code Your Patch** 98 | 99 | 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). 100 | 101 | 8. **Build and Run** 102 | 103 | 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. 104 | 105 | ## Example 106 | 107 | I created some demo project, which shows you how to use `IPAPatch`: 108 | 109 | - Reveal + Youtube: 110 | - https://github.com/Naituw/IPAPatch/releases/tag/1.0 111 | - Cycript + Youtube (Idea from @phpmaple): 112 | - https://github.com/Naituw/IPAPatch/releases/tag/1.0.1 113 | 114 | ## FAQ 115 | 116 | - Q: Library not loaded with reason: `mach-o, but wrong architecture` ? 117 | - A: Try set `IPAPatch` target's `Valid Architectures` to match your ipa binary's architecture. 118 | 119 | - Q: process launch failed: Unspecified (Disabled) ? 120 | - A: The ipa file use with IPAPatch must be decrypted, See step.2 of Instructions. 121 | 122 | - Q: dyld: Symbol not found: XXX, Referenced from: XXX, Expected in: XXX/libswiftXXX.dylib 123 | - The swift version the framework you injecting use, is incompatible with the version of your Xcode 124 | 125 | ## License 126 | 127 | #### IPAPatch 128 | 129 |    IPAPatch is licensed under the MIT license. 130 | 131 | Copyright (c) 2017-present Wu Tian . 132 | 133 | Permission is hereby granted, free of charge, to any person obtaining a copy 134 | of this software and associated documentation files (the "Software"), to deal 135 | in the Software without restriction, including without limitation the rights 136 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 137 | copies of the Software, and to permit persons to whom the Software is 138 | furnished to do so, subject to the following conditions: 139 | 140 | The above copyright notice and this permission notice shall be included in 141 | all copies or substantial portions of the Software. 142 | 143 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 144 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 145 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 146 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 147 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 148 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 149 | THE SOFTWARE. 150 | 151 | 152 | #### OPTOOL 153 | 154 | Copyright (c) 2014, Alex Zielenski 155 | All rights reserved. 156 | 157 | Redistribution and use in source and binary forms, with or without 158 | modification, are permitted provided that the following conditions are met: 159 | 160 | * Redistributions of source code must retain the above copyright notice, this 161 | list of conditions and the following disclaimer. 162 | 163 | * Redistributions in binary form must reproduce the above copyright notice, 164 | this list of conditions and the following disclaimer in the documentation 165 | and/or other materials provided with the distribution. 166 | 167 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 168 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 169 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 170 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 171 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 172 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 173 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 174 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 175 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 176 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 177 | 178 | 179 | #### fishhook 180 | 181 | Copyright (c) 2013, Facebook, Inc. 182 | All rights reserved. 183 | Redistribution and use in source and binary forms, with or without 184 | modification, are permitted provided that the following conditions are met: 185 | * Redistributions of source code must retain the above copyright notice, 186 | this list of conditions and the following disclaimer. 187 | * Redistributions in binary form must reproduce the above copyright notice, 188 | this list of conditions and the following disclaimer in the documentation 189 | and/or other materials provided with the distribution. 190 | * Neither the name Facebook nor the names of its contributors may be used to 191 | endorse or promote products derived from this software without specific 192 | prior written permission. 193 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 194 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 195 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 196 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 197 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 198 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 199 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 200 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 201 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 202 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 203 | 204 | -------------------------------------------------------------------------------- /Tools/create_ipa.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # create_ipa.sh 4 | # IPAPatch 5 | # 6 | # Created by 吴天 on 2017/8/26. 7 | # Copyright © 2017年 Weibo. All rights reserved. 8 | 9 | OPTIONS_PATH="${SRCROOT}/Tools/options.plist" 10 | TARGET_APP_PATH="$BUILT_PRODUCTS_DIR/IPAPatch-DummyApp.app" 11 | TARGET_DISPLAY_NAME=$(/usr/libexec/PlistBuddy -c "Print CFBundleDisplayName" "$TARGET_APP_PATH/Info.plist") 12 | 13 | CREATE_IPA_FILE=$(/usr/libexec/PlistBuddy -c "Print CREATE_IPA_FILE" "${OPTIONS_PATH}") 14 | 15 | if [ "$CREATE_IPA_FILE" = true ]; then 16 | 17 | IPA_PRODUCT_PATH="${SRCROOT}/Product" 18 | IPA_PRODUCT_PAYLOAD_PATH="${IPA_PRODUCT_PATH}/Payload" 19 | 20 | rm -rf "${IPA_PRODUCT_PATH}" || true 21 | 22 | mkdir -p "${IPA_PRODUCT_PATH}" 23 | mkdir -p "${IPA_PRODUCT_PAYLOAD_PATH}" 24 | 25 | cp -rf "$TARGET_APP_PATH" "$IPA_PRODUCT_PAYLOAD_PATH" 26 | 27 | cd "$IPA_PRODUCT_PATH" 28 | 29 | zip -qr "${TARGET_DISPLAY_NAME}.ipa" "Payload/" 30 | 31 | rm -rf "$IPA_PRODUCT_PAYLOAD_PATH" 32 | 33 | fi 34 | -------------------------------------------------------------------------------- /Tools/options.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | RESTORE_SYMBOLS 6 | 7 | CREATE_IPA_FILE 8 | 9 | IGNORE_UI_SUPPORTED_DEVICES 10 | 11 | REMOVE_WATCHPLACEHOLDER 12 | 13 | USE_ORIGINAL_ENTITLEMENTS 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Tools/optool: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Naituw/IPAPatch/f64030e9805657da8c6f1086933c224fd24ce100/Tools/optool -------------------------------------------------------------------------------- /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 | PLATFORM="$1" 29 | 30 | TEMP_PATH="${SRCROOT}/Temp" 31 | OPTIONS_PATH="${SRCROOT}/Tools/options.plist" 32 | ASSETS_PATH="${SRCROOT}/Assets" 33 | TARGET_IPA_PATH="${ASSETS_PATH}/app.ipa" 34 | TARGET_MAC_APP_PATH="${ASSETS_PATH}/macapp.app" 35 | FRAMEWORKS_TO_INJECT_PATH="${ASSETS_PATH}/Frameworks" 36 | RESOURCES_TO_INJECT_PATH="${ASSETS_PATH}/Resources" 37 | DYLIBS_TO_INJECT_PATH="${ASSETS_PATH}/Dylibs" 38 | 39 | DUMMY_DISPLAY_NAME="" # To be found in Step 0 40 | TARGET_BUNDLE_ID="" # To be found in Step 0 41 | RESTORE_SYMBOLS=false 42 | REMOVE_WATCHPLACEHOLDER=false 43 | USE_ORIGINAL_ENTITLEMENTS=false 44 | TEMP_APP_PATH="" # To be found in Step 1 45 | TARGET_APP_PATH="" # To be found in Step 3 46 | TARGET_APP_CONTENTS_PATH="" # To be found in Step 3 47 | TARGET_APP_FRAMEWORKS_PATH="" # To be found in Step 5 48 | 49 | 50 | # --------------------------------------------------- 51 | # 0. Prepare Working Enviroment 52 | 53 | rm -rf "$TEMP_PATH" || true 54 | mkdir -p "$TEMP_PATH" || true 55 | 56 | DUMMY_DISPLAY_NAME=$(/usr/libexec/PlistBuddy -c "Print CFBundleDisplayName" "${SRCROOT}/$TARGET_NAME/Info.plist") 57 | echo "DUMMY_DISPLAY_NAME: $DUMMY_DISPLAY_NAME" 58 | 59 | RESTORE_SYMBOLS=$(/usr/libexec/PlistBuddy -c "Print RESTORE_SYMBOLS" "${OPTIONS_PATH}") 60 | IGNORE_UI_SUPPORTED_DEVICES=$(/usr/libexec/PlistBuddy -c "Print IGNORE_UI_SUPPORTED_DEVICES" "${OPTIONS_PATH}") 61 | REMOVE_WATCHPLACEHOLDER=$(/usr/libexec/PlistBuddy -c "Print REMOVE_WATCHPLACEHOLDER" "${OPTIONS_PATH}") 62 | USE_ORIGINAL_ENTITLEMENTS=$(/usr/libexec/PlistBuddy -c "Print USE_ORIGINAL_ENTITLEMENTS" "${OPTIONS_PATH}") 63 | 64 | echo "RESTORE_SYMBOLS: $RESTORE_SYMBOLS" 65 | echo "CREATE_IPA_FILE: $CREATE_IPA_FILE" 66 | echo "IGNORE_UI_SUPPORTED_DEVICES: $IGNORE_UI_SUPPORTED_DEVICES" 67 | 68 | TARGET_BUNDLE_ID="$PRODUCT_BUNDLE_IDENTIFIER" 69 | echo "TARGET_BUNDLE_ID: $TARGET_BUNDLE_ID" 70 | 71 | 72 | # --------------------------------------------------- 73 | # 1. Extract Target IPA 74 | 75 | if [ $PLATFORM = "Mac" ] 76 | then 77 | echo "Copying Mac App to Temp folder" 78 | cp -rP "$TARGET_MAC_APP_PATH" "$TEMP_PATH" 79 | TEMP_APP_PATH=$(set -- "$TEMP_PATH/"*.app; echo "$1") 80 | else 81 | echo "Extracting iOS App to Temp folder" 82 | unzip -oqq "$TARGET_IPA_PATH" -d "$TEMP_PATH" 83 | TEMP_APP_PATH=$(set -- "$TEMP_PATH/Payload/"*.app; echo "$1") 84 | fi 85 | 86 | echo "TEMP_APP_PATH: $TEMP_APP_PATH" 87 | 88 | # --------------------------------------------------- 89 | # 2 restore symbol and integrate to Mach-O File 90 | 91 | if [ "$RESTORE_SYMBOLS" = true ]; then 92 | 93 | # --------------------------------------------------- 94 | # 2.1 try to thin Mach-O File 95 | 96 | MACH_O_FILE_NAME=`basename $TEMP_APP_PATH .app` 97 | MACH_O_FILE_PATH=$TEMP_APP_PATH/$MACH_O_FILE_NAME 98 | echo "MACH_O_FILE_PATH: $MACH_O_FILE_PATH" 99 | 100 | ARCHS=`lipo -archs $MACH_O_FILE_PATH` 101 | ARCH_COUNT=${#ARCHS[@]} 102 | 103 | if [ $ARCH_COUNT -eq 1 ]; then 104 | echo "skipping lipo -thin: non-fat binary" 105 | else 106 | lipo -thin armv7 $MACH_O_FILE_PATH -o $TEMP_PATH/"$MACH_O_FILE_NAME"_armv7 107 | lipo -thin arm64 $MACH_O_FILE_PATH -o $TEMP_PATH/"$MACH_O_FILE_NAME"_arm64 108 | fi 109 | 110 | # --------------------------------------------------- 111 | # 2.2 try to restore symbol by archs 112 | 113 | # Sources: https://github.com/tobefuturer/restore-symbol 114 | # restore symbol technique 115 | 116 | RESTORE_SYMBOL_TOOL="${SRCROOT}/Tools/restore-symbol" 117 | 118 | if [ $ARCH_COUNT -eq 1 ]; then 119 | "$RESTORE_SYMBOL_TOOL" $MACH_O_FILE_PATH -o $TEMP_PATH/$"$MACH_O_FILE_NAME"_with_symbol 120 | else 121 | "$RESTORE_SYMBOL_TOOL" $TEMP_PATH/$"$MACH_O_FILE_NAME"_armv7 -o $TEMP_PATH/$"$MACH_O_FILE_NAME"_armv7_with_symbol 122 | "$RESTORE_SYMBOL_TOOL" $TEMP_PATH/$"$MACH_O_FILE_NAME"_arm64 -o $TEMP_PATH/$"$MACH_O_FILE_NAME"_arm64_with_symbol 123 | fi 124 | 125 | # --------------------------------------------------- 126 | # 2.3 reintegrate Mach-O File 127 | 128 | if [ $ARCH_COUNT -eq 1 ]; then 129 | echo "skipping lipo -create: non-fat binary" 130 | else 131 | lipo -create $TEMP_PATH/"$MACH_O_FILE_NAME"_armv7_with_symbol $TEMP_PATH/"$MACH_O_FILE_NAME"_arm64_with_symbol -o $TEMP_PATH/"$MACH_O_FILE_NAME"_with_symbol 132 | fi 133 | 134 | rm -f $MACH_O_FILE_PATH 135 | cp $TEMP_PATH/"$MACH_O_FILE_NAME"_with_symbol $MACH_O_FILE_PATH 136 | 137 | fi # [ "$RESTORE_SYMBOLS" ] 138 | 139 | 140 | # --------------------------------------------------- 141 | # 3. Overwrite DummyApp IPA with Target App Contents 142 | 143 | TARGET_APP_PATH="$BUILT_PRODUCTS_DIR/$TARGET_NAME.app" 144 | if [ $PLATFORM = "Mac" ] 145 | then 146 | TARGET_APP_CONTENTS_PATH="$TARGET_APP_PATH/Contents" 147 | else 148 | TARGET_APP_CONTENTS_PATH="$TARGET_APP_PATH" 149 | fi 150 | echo "TARGET_APP_PATH: $TARGET_APP_PATH" 151 | 152 | rm -rf "$TARGET_APP_PATH" || true 153 | mkdir -p "$TARGET_APP_PATH" || true 154 | cp -rfP "$TEMP_APP_PATH/" "$TARGET_APP_PATH/" 155 | 156 | 157 | 158 | 159 | # --------------------------------------------------- 160 | # 4. Inject the Executable We Wrote and Built (IPAPatchFramework.framework) 161 | 162 | APP_BINARY=`plutil -convert xml1 -o - $TARGET_APP_CONTENTS_PATH/Info.plist|grep -A1 Exec|tail -n1|cut -f2 -d\>|cut -f1 -d\<` 163 | if [ $PLATFORM = "Mac" ] 164 | then 165 | APP_BINARY="MacOS/$APP_BINARY" 166 | fi 167 | OPTOOL="${SRCROOT}/Tools/optool" 168 | 169 | mkdir "$TARGET_APP_CONTENTS_PATH/Dylibs" 170 | if [ $PLATFORM = "Mac" ] 171 | then 172 | cp "$BUILT_PRODUCTS_DIR/IPAPatchFrameworkMac.framework/IPAPatchFrameworkMac" "$TARGET_APP_CONTENTS_PATH/Dylibs/IPAPatchFramework" 173 | else 174 | cp "$BUILT_PRODUCTS_DIR/IPAPatchFramework.framework/IPAPatchFramework" "$TARGET_APP_CONTENTS_PATH/Dylibs/IPAPatchFramework" 175 | fi 176 | for file in `ls -1 "$TARGET_APP_CONTENTS_PATH/Dylibs"`; do 177 | echo -n ' ' 178 | 179 | if [ $PLATFORM = "Mac" ] 180 | then 181 | FRAMEWORK_LOAD_PATH="@executable_path/../Dylibs/$file" 182 | else 183 | FRAMEWORK_LOAD_PATH="@executable_path/Dylibs/$file" 184 | fi 185 | 186 | echo "Install Load: $file -> $FRAMEWORK_LOAD_PATH" 187 | "$OPTOOL" install -c load -p "$FRAMEWORK_LOAD_PATH" -t "$TARGET_APP_CONTENTS_PATH/$APP_BINARY" 188 | done 189 | 190 | chmod +x "$TARGET_APP_CONTENTS_PATH/$APP_BINARY" 191 | 192 | 193 | 194 | 195 | # --------------------------------------------------- 196 | # 5. Inject External Files if Exists 197 | 198 | CopySwiftStdLib () { 199 | source_file=$1 200 | target_dir=$2 201 | 202 | otool -L $source_file | while read -r line ; do 203 | if [[ $line = "@rpath/libswift"* ]]; then 204 | re="@rpath\/(libswift[^[:space:]]+.dylib)[[:space:]]"; 205 | if [[ $line =~ $re ]]; then 206 | LIBNAME=${BASH_REMATCH[1]}; 207 | if ! [ -e "$target_dir/$LIBNAME" ]; then 208 | LIB_SOURCE_PATH="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphoneos/${LIBNAME}" 209 | if [ -e $LIB_SOURCE_PATH ]; then 210 | echo "Copying $LIBNAME: $LIB_SOURCE_PATH" 211 | cp -rf "$LIB_SOURCE_PATH" "$target_dir" 212 | 213 | # resolve nested dependecies 214 | CopySwiftStdLib "$target_dir/$LIBNAME" "$target_dir" 215 | fi 216 | fi 217 | fi 218 | fi 219 | done 220 | } 221 | 222 | # 5-1. Inject External Frameworks if Exists 223 | TARGET_APP_FRAMEWORKS_PATH="$TARGET_APP_CONTENTS_PATH/Frameworks" 224 | 225 | echo "Injecting Frameworks from $FRAMEWORKS_TO_INJECT_PATH" 226 | for file in `ls -1 "${FRAMEWORKS_TO_INJECT_PATH}"`; do 227 | extension="${file##*.}" 228 | echo "$file 's extension is $extension" 229 | 230 | if [ "$extension" != "framework" ] 231 | then 232 | continue 233 | fi 234 | 235 | mkdir -p "$TARGET_APP_FRAMEWORKS_PATH" 236 | rsync -av --exclude=".*" "${FRAMEWORKS_TO_INJECT_PATH}/$file" "$TARGET_APP_FRAMEWORKS_PATH" 237 | filename="${file%.*}" 238 | 239 | echo -n ' ' 240 | echo "Install Load: $file -> @executable_path/Frameworks/$file/$filename" 241 | 242 | "$OPTOOL" install -c load -p "@executable_path/Frameworks/$file/$filename" -t "$TARGET_APP_CONTENTS_PATH/$APP_BINARY" 243 | 244 | CopySwiftStdLib "$TARGET_APP_FRAMEWORKS_PATH/$file/$filename" "$TARGET_APP_FRAMEWORKS_PATH" 245 | done 246 | 247 | # 5-2. Inject Dylibs if Exists 248 | echo "Injecting Dylibs from $DYLIBS_TO_INJECT_PATH" 249 | for file in `ls -1 "${DYLIBS_TO_INJECT_PATH}"`; do 250 | if [[ $file = "."* ]]; then 251 | continue 252 | fi 253 | 254 | filename="${file%.*}" 255 | cp "$DYLIBS_TO_INJECT_PATH/$filename" "$TARGET_APP_CONTENTS_PATH/Dylibs/$filename" 256 | 257 | echo -n ' ' 258 | echo "Install Load: $file -> @executable_path/Dylibs/$filename" 259 | 260 | "$OPTOOL" install -c load -p "@executable_path/Dylibs/$filename" -t "$TARGET_APP_CONTENTS_PATH/$APP_BINARY" 261 | 262 | CopySwiftStdLib "$TARGET_APP_CONTENTS_PATH/Dylibs/$filename" "$TARGET_APP_FRAMEWORKS_PATH" 263 | done 264 | 265 | # 5-3. Inject External Resources if Exists 266 | echo "Injecting Resources from $RESOURCES_TO_INJECT_PATH" 267 | rsync -av --exclude=".*" "${RESOURCES_TO_INJECT_PATH}/" "$TARGET_APP_CONTENTS_PATH" 268 | 269 | 270 | 271 | 272 | 273 | 274 | # --------------------------------------------------- 275 | # 6. Remove Plugins/Watch (AppExtensions), To Simplify the Signing Process 276 | 277 | echo "Removing AppExtensions" 278 | rm -rf "$TARGET_APP_CONTENTS_PATH/PlugIns" || true 279 | rm -rf "$TARGET_APP_CONTENTS_PATH/Watch" || true 280 | 281 | if [ "$REMOVE_WATCHPLACEHOLDER" = true ]; then 282 | echo "Removing com.apple.WatchPlaceholder" 283 | rm -rf "$TARGET_APP_CONTENTS_PATH/com.apple.WatchPlaceholder" || true 284 | fi 285 | 286 | 287 | # --------------------------------------------------- 288 | # 7. Update Info.plist for Target App 289 | 290 | echo "Updating BundleID:$PRODUCT_BUNDLE_IDENTIFIER, DisplayName:$TARGET_DISPLAY_NAME" 291 | TARGET_DISPLAY_NAME=$(/usr/libexec/PlistBuddy -c "Print CFBundleDisplayName" "$TARGET_APP_CONTENTS_PATH/Info.plist") 292 | TARGET_DISPLAY_NAME="$DUMMY_DISPLAY_NAME$TARGET_DISPLAY_NAME" 293 | 294 | /usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $PRODUCT_BUNDLE_IDENTIFIER" "$TARGET_APP_CONTENTS_PATH/Info.plist" 295 | /usr/libexec/PlistBuddy -c "Set :CFBundleDisplayName $TARGET_DISPLAY_NAME" "$TARGET_APP_CONTENTS_PATH/Info.plist" 296 | 297 | if [ "$IGNORE_UI_SUPPORTED_DEVICES" = true ]; then 298 | /usr/libexec/PlistBuddy -c "Delete :UISupportedDevices" "$TARGET_APP_CONTENTS_PATH/Info.plist" 299 | fi 300 | 301 | # --------------------------------------------------- 302 | # 8. Code Sign All The Things 303 | 304 | if [ "$USE_ORIGINAL_ENTITLEMENTS" = true ]; then 305 | ENTITLEMENTS="$TEMP_PATH/entitlements.xcent" 306 | codesign -d --entitlements :- "$TARGET_APP_PATH" > "$ENTITLEMENTS" 307 | fi 308 | 309 | echo "Code Signing Dylibs" 310 | if [ "$USE_ORIGINAL_ENTITLEMENTS" = true ]; then 311 | /usr/bin/codesign --force --sign "$EXPANDED_CODE_SIGN_IDENTITY" --entitlements "$ENTITLEMENTS" "$TARGET_APP_CONTENTS_PATH/Dylibs/"* 312 | else 313 | /usr/bin/codesign --force --sign "$EXPANDED_CODE_SIGN_IDENTITY" "$TARGET_APP_CONTENTS_PATH/Dylibs/"* 314 | fi 315 | 316 | 317 | echo "Code Signing Frameworks" 318 | if [ -d "$TARGET_APP_FRAMEWORKS_PATH" ]; then 319 | if [ "$USE_ORIGINAL_ENTITLEMENTS" = true ]; then 320 | echo "/usr/bin/codesign --force --sign $EXPANDED_CODE_SIGN_IDENTITY --entitlements $ENTITLEMENTS $TARGET_APP_FRAMEWORKS_PATH/*" 321 | /usr/bin/codesign --force --sign "$EXPANDED_CODE_SIGN_IDENTITY" --entitlements "$ENTITLEMENTS" "$TARGET_APP_FRAMEWORKS_PATH/"* 322 | else 323 | echo "/usr/bin/codesign --force --sign $EXPANDED_CODE_SIGN_IDENTITY $TARGET_APP_FRAMEWORKS_PATH/*" 324 | /usr/bin/codesign --force --sign "$EXPANDED_CODE_SIGN_IDENTITY" "$TARGET_APP_FRAMEWORKS_PATH/"* 325 | fi 326 | fi 327 | 328 | echo "Code Signing App Binary" 329 | if [ "$USE_ORIGINAL_ENTITLEMENTS" = true ]; then 330 | /usr/bin/codesign --force --sign "$EXPANDED_CODE_SIGN_IDENTITY" --timestamp=none --entitlements "$ENTITLEMENTS" "$TARGET_APP_PATH" 331 | if [ $PLATFORM = "Mac" ] 332 | then 333 | /usr/bin/codesign --force --sign "$EXPANDED_CODE_SIGN_IDENTITY" --timestamp=none --entitlements "$ENTITLEMENTS" "$TARGET_APP_CONTENTS_PATH/MacOS/"* 334 | fi 335 | else 336 | /usr/bin/codesign --force --sign "$EXPANDED_CODE_SIGN_IDENTITY" --timestamp=none "$TARGET_APP_PATH" 337 | if [ $PLATFORM = "Mac" ] 338 | then 339 | /usr/bin/codesign --force --sign "$EXPANDED_CODE_SIGN_IDENTITY" --timestamp=none "$TARGET_APP_CONTENTS_PATH/MacOS/"* 340 | fi 341 | fi 342 | 343 | 344 | 345 | 346 | 347 | # --------------------------------------------------- 348 | # 9. Install 349 | # 350 | # Nothing To Do, Xcode Will Automatically Install the DummyApp We Overwrited 351 | echo "Done" 352 | 353 | -------------------------------------------------------------------------------- /Tools/restore-symbol: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Naituw/IPAPatch/f64030e9805657da8c6f1086933c224fd24ce100/Tools/restore-symbol --------------------------------------------------------------------------------