├── .gitignore ├── JBKit.xcodeproj └── project.pbxproj ├── JBKit ├── JBException.cpp ├── JBException.hpp ├── JBExploit.cpp ├── JBExploit.hpp ├── JBExploit_c.cpp ├── JBExploit_c.h ├── JBKit.h ├── JBMacros.h ├── JBOffsets.cpp ├── JBOffsets.hpp ├── JBOffsets_c.cpp ├── JBOffsets_c.h ├── JBPrimitive.cpp ├── JBPrimitive.hpp ├── JBPrimitive_c.cpp ├── JBPrimitive_c.h └── JBTypes.h ├── include ├── launch.h └── xpc │ ├── XPC.apinotes │ ├── activity.h │ ├── availability.h │ ├── base.h │ ├── connection.h │ ├── debug.h │ ├── endpoint.h │ ├── module.modulemap │ ├── private.h │ ├── rich_error.h │ ├── session.h │ └── xpc.h └── lib └── libxpc.tbd /.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | *.patch 3 | *.diff 4 | *.o 5 | *.a 6 | *.la 7 | *.lo 8 | aclocal.m4 9 | autom4te.cache 10 | compile 11 | config.* 12 | configure 13 | depcomp 14 | */.deps 15 | */.libs 16 | Makefile 17 | Makefile.in 18 | install-sh 19 | libtool 20 | ltmain.sh 21 | m4 22 | missing 23 | stamp-h1 24 | xcuserdata 25 | Build 26 | Index 27 | stamp-h2 28 | *.pc 29 | configure~ 30 | project.xcworkspace 31 | xcshareddata 32 | -------------------------------------------------------------------------------- /JBKit.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 56; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 87168C1B2B4C710A00DC6AB9 /* JBKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 87168C1A2B4C710A00DC6AB9 /* JBKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 11 | 87168C232B4C71B400DC6AB9 /* JBExploit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 87168C212B4C71B400DC6AB9 /* JBExploit.cpp */; }; 12 | 87168C242B4C71B400DC6AB9 /* JBExploit.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 87168C222B4C71B400DC6AB9 /* JBExploit.hpp */; settings = {ATTRIBUTES = (Public, ); }; }; 13 | 87168C272B4C71DD00DC6AB9 /* JBPrimitive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 87168C252B4C71DD00DC6AB9 /* JBPrimitive.cpp */; }; 14 | 87168C282B4C71DD00DC6AB9 /* JBPrimitive.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 87168C262B4C71DD00DC6AB9 /* JBPrimitive.hpp */; settings = {ATTRIBUTES = (Public, ); }; }; 15 | 87168C2B2B4C720500DC6AB9 /* JBOffsets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 87168C292B4C720500DC6AB9 /* JBOffsets.cpp */; }; 16 | 87168C2C2B4C720500DC6AB9 /* JBOffsets.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 87168C2A2B4C720500DC6AB9 /* JBOffsets.hpp */; settings = {ATTRIBUTES = (Public, ); }; }; 17 | 87168C322B4C807C00DC6AB9 /* JBException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 87168C302B4C807C00DC6AB9 /* JBException.cpp */; }; 18 | 87168C332B4C807C00DC6AB9 /* JBException.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 87168C312B4C807C00DC6AB9 /* JBException.hpp */; settings = {ATTRIBUTES = (Public, ); }; }; 19 | 87168C342B4C930F00DC6AB9 /* JBTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 87168C2D2B4C75D900DC6AB9 /* JBTypes.h */; settings = {ATTRIBUTES = (Public, ); }; }; 20 | 87168C352B4C931700DC6AB9 /* JBMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 87168C2E2B4C7FF800DC6AB9 /* JBMacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; 21 | 874CABED2B4CA35E0002EC15 /* libxpc.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 874CABEB2B4CA2A80002EC15 /* libxpc.tbd */; }; 22 | 878171D42B4CA7CD00F7399C /* JBExploit_c.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 878171D22B4CA7CD00F7399C /* JBExploit_c.cpp */; }; 23 | 878171D52B4CA7CD00F7399C /* JBExploit_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 878171D32B4CA7CD00F7399C /* JBExploit_c.h */; settings = {ATTRIBUTES = (Public, ); }; }; 24 | 878171D82B4CAA4400F7399C /* JBOffsets_c.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 878171D62B4CAA4400F7399C /* JBOffsets_c.cpp */; }; 25 | 878171D92B4CAA4400F7399C /* JBOffsets_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 878171D72B4CAA4400F7399C /* JBOffsets_c.h */; settings = {ATTRIBUTES = (Public, ); }; }; 26 | 878171DC2B4CAF9500F7399C /* JBPrimitive_c.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 878171DA2B4CAF9500F7399C /* JBPrimitive_c.cpp */; }; 27 | 878171DD2B4CAF9500F7399C /* JBPrimitive_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 878171DB2B4CAF9500F7399C /* JBPrimitive_c.h */; settings = {ATTRIBUTES = (Public, ); }; }; 28 | /* End PBXBuildFile section */ 29 | 30 | /* Begin PBXFileReference section */ 31 | 87168C172B4C710A00DC6AB9 /* JBKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = JBKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 32 | 87168C1A2B4C710A00DC6AB9 /* JBKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JBKit.h; sourceTree = ""; }; 33 | 87168C212B4C71B400DC6AB9 /* JBExploit.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JBExploit.cpp; sourceTree = ""; }; 34 | 87168C222B4C71B400DC6AB9 /* JBExploit.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = JBExploit.hpp; sourceTree = ""; }; 35 | 87168C252B4C71DD00DC6AB9 /* JBPrimitive.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JBPrimitive.cpp; sourceTree = ""; }; 36 | 87168C262B4C71DD00DC6AB9 /* JBPrimitive.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = JBPrimitive.hpp; sourceTree = ""; }; 37 | 87168C292B4C720500DC6AB9 /* JBOffsets.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JBOffsets.cpp; sourceTree = ""; }; 38 | 87168C2A2B4C720500DC6AB9 /* JBOffsets.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = JBOffsets.hpp; sourceTree = ""; }; 39 | 87168C2D2B4C75D900DC6AB9 /* JBTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JBTypes.h; sourceTree = ""; }; 40 | 87168C2E2B4C7FF800DC6AB9 /* JBMacros.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JBMacros.h; sourceTree = ""; }; 41 | 87168C302B4C807C00DC6AB9 /* JBException.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JBException.cpp; sourceTree = ""; }; 42 | 87168C312B4C807C00DC6AB9 /* JBException.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = JBException.hpp; sourceTree = ""; }; 43 | 874CABEB2B4CA2A80002EC15 /* libxpc.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libxpc.tbd; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk/usr/lib/system/libxpc.tbd; sourceTree = DEVELOPER_DIR; }; 44 | 878171D22B4CA7CD00F7399C /* JBExploit_c.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JBExploit_c.cpp; sourceTree = ""; }; 45 | 878171D32B4CA7CD00F7399C /* JBExploit_c.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JBExploit_c.h; sourceTree = ""; }; 46 | 878171D62B4CAA4400F7399C /* JBOffsets_c.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JBOffsets_c.cpp; sourceTree = ""; }; 47 | 878171D72B4CAA4400F7399C /* JBOffsets_c.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JBOffsets_c.h; sourceTree = ""; }; 48 | 878171DA2B4CAF9500F7399C /* JBPrimitive_c.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JBPrimitive_c.cpp; sourceTree = ""; }; 49 | 878171DB2B4CAF9500F7399C /* JBPrimitive_c.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JBPrimitive_c.h; sourceTree = ""; }; 50 | /* End PBXFileReference section */ 51 | 52 | /* Begin PBXFrameworksBuildPhase section */ 53 | 87168C142B4C710A00DC6AB9 /* Frameworks */ = { 54 | isa = PBXFrameworksBuildPhase; 55 | buildActionMask = 2147483647; 56 | files = ( 57 | 874CABED2B4CA35E0002EC15 /* libxpc.tbd in Frameworks */, 58 | ); 59 | runOnlyForDeploymentPostprocessing = 0; 60 | }; 61 | /* End PBXFrameworksBuildPhase section */ 62 | 63 | /* Begin PBXGroup section */ 64 | 87168C0D2B4C710A00DC6AB9 = { 65 | isa = PBXGroup; 66 | children = ( 67 | 87168C192B4C710A00DC6AB9 /* JBKit */, 68 | 87168C182B4C710A00DC6AB9 /* Products */, 69 | 874CABEA2B4CA2A80002EC15 /* Frameworks */, 70 | ); 71 | sourceTree = ""; 72 | }; 73 | 87168C182B4C710A00DC6AB9 /* Products */ = { 74 | isa = PBXGroup; 75 | children = ( 76 | 87168C172B4C710A00DC6AB9 /* JBKit.framework */, 77 | ); 78 | name = Products; 79 | sourceTree = ""; 80 | }; 81 | 87168C192B4C710A00DC6AB9 /* JBKit */ = { 82 | isa = PBXGroup; 83 | children = ( 84 | 87168C1A2B4C710A00DC6AB9 /* JBKit.h */, 85 | 87168C2D2B4C75D900DC6AB9 /* JBTypes.h */, 86 | 87168C2E2B4C7FF800DC6AB9 /* JBMacros.h */, 87 | 87168C2A2B4C720500DC6AB9 /* JBOffsets.hpp */, 88 | 87168C292B4C720500DC6AB9 /* JBOffsets.cpp */, 89 | 878171D72B4CAA4400F7399C /* JBOffsets_c.h */, 90 | 878171D62B4CAA4400F7399C /* JBOffsets_c.cpp */, 91 | 87168C312B4C807C00DC6AB9 /* JBException.hpp */, 92 | 87168C302B4C807C00DC6AB9 /* JBException.cpp */, 93 | 87168C222B4C71B400DC6AB9 /* JBExploit.hpp */, 94 | 87168C212B4C71B400DC6AB9 /* JBExploit.cpp */, 95 | 878171D32B4CA7CD00F7399C /* JBExploit_c.h */, 96 | 878171D22B4CA7CD00F7399C /* JBExploit_c.cpp */, 97 | 87168C262B4C71DD00DC6AB9 /* JBPrimitive.hpp */, 98 | 87168C252B4C71DD00DC6AB9 /* JBPrimitive.cpp */, 99 | 878171DB2B4CAF9500F7399C /* JBPrimitive_c.h */, 100 | 878171DA2B4CAF9500F7399C /* JBPrimitive_c.cpp */, 101 | ); 102 | path = JBKit; 103 | sourceTree = ""; 104 | }; 105 | 874CABEA2B4CA2A80002EC15 /* Frameworks */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | 874CABEB2B4CA2A80002EC15 /* libxpc.tbd */, 109 | ); 110 | name = Frameworks; 111 | sourceTree = ""; 112 | }; 113 | /* End PBXGroup section */ 114 | 115 | /* Begin PBXHeadersBuildPhase section */ 116 | 87168C122B4C710A00DC6AB9 /* Headers */ = { 117 | isa = PBXHeadersBuildPhase; 118 | buildActionMask = 2147483647; 119 | files = ( 120 | 878171D52B4CA7CD00F7399C /* JBExploit_c.h in Headers */, 121 | 87168C242B4C71B400DC6AB9 /* JBExploit.hpp in Headers */, 122 | 878171D92B4CAA4400F7399C /* JBOffsets_c.h in Headers */, 123 | 87168C2C2B4C720500DC6AB9 /* JBOffsets.hpp in Headers */, 124 | 87168C342B4C930F00DC6AB9 /* JBTypes.h in Headers */, 125 | 87168C282B4C71DD00DC6AB9 /* JBPrimitive.hpp in Headers */, 126 | 87168C352B4C931700DC6AB9 /* JBMacros.h in Headers */, 127 | 87168C332B4C807C00DC6AB9 /* JBException.hpp in Headers */, 128 | 878171DD2B4CAF9500F7399C /* JBPrimitive_c.h in Headers */, 129 | 87168C1B2B4C710A00DC6AB9 /* JBKit.h in Headers */, 130 | ); 131 | runOnlyForDeploymentPostprocessing = 0; 132 | }; 133 | /* End PBXHeadersBuildPhase section */ 134 | 135 | /* Begin PBXNativeTarget section */ 136 | 87168C162B4C710A00DC6AB9 /* JBKit */ = { 137 | isa = PBXNativeTarget; 138 | buildConfigurationList = 87168C1E2B4C710A00DC6AB9 /* Build configuration list for PBXNativeTarget "JBKit" */; 139 | buildPhases = ( 140 | 87168C122B4C710A00DC6AB9 /* Headers */, 141 | 87168C132B4C710A00DC6AB9 /* Sources */, 142 | 87168C142B4C710A00DC6AB9 /* Frameworks */, 143 | 87168C152B4C710A00DC6AB9 /* Resources */, 144 | ); 145 | buildRules = ( 146 | ); 147 | dependencies = ( 148 | ); 149 | name = JBKit; 150 | productName = JBKit; 151 | productReference = 87168C172B4C710A00DC6AB9 /* JBKit.framework */; 152 | productType = "com.apple.product-type.framework"; 153 | }; 154 | /* End PBXNativeTarget section */ 155 | 156 | /* Begin PBXProject section */ 157 | 87168C0E2B4C710A00DC6AB9 /* Project object */ = { 158 | isa = PBXProject; 159 | attributes = { 160 | BuildIndependentTargetsInParallel = 1; 161 | LastUpgradeCheck = 1500; 162 | TargetAttributes = { 163 | 87168C162B4C710A00DC6AB9 = { 164 | CreatedOnToolsVersion = 15.0.1; 165 | }; 166 | }; 167 | }; 168 | buildConfigurationList = 87168C112B4C710A00DC6AB9 /* Build configuration list for PBXProject "JBKit" */; 169 | compatibilityVersion = "Xcode 14.0"; 170 | developmentRegion = en; 171 | hasScannedForEncodings = 0; 172 | knownRegions = ( 173 | en, 174 | Base, 175 | ); 176 | mainGroup = 87168C0D2B4C710A00DC6AB9; 177 | productRefGroup = 87168C182B4C710A00DC6AB9 /* Products */; 178 | projectDirPath = ""; 179 | projectRoot = ""; 180 | targets = ( 181 | 87168C162B4C710A00DC6AB9 /* JBKit */, 182 | ); 183 | }; 184 | /* End PBXProject section */ 185 | 186 | /* Begin PBXResourcesBuildPhase section */ 187 | 87168C152B4C710A00DC6AB9 /* Resources */ = { 188 | isa = PBXResourcesBuildPhase; 189 | buildActionMask = 2147483647; 190 | files = ( 191 | ); 192 | runOnlyForDeploymentPostprocessing = 0; 193 | }; 194 | /* End PBXResourcesBuildPhase section */ 195 | 196 | /* Begin PBXSourcesBuildPhase section */ 197 | 87168C132B4C710A00DC6AB9 /* Sources */ = { 198 | isa = PBXSourcesBuildPhase; 199 | buildActionMask = 2147483647; 200 | files = ( 201 | 878171D42B4CA7CD00F7399C /* JBExploit_c.cpp in Sources */, 202 | 87168C232B4C71B400DC6AB9 /* JBExploit.cpp in Sources */, 203 | 878171DC2B4CAF9500F7399C /* JBPrimitive_c.cpp in Sources */, 204 | 878171D82B4CAA4400F7399C /* JBOffsets_c.cpp in Sources */, 205 | 87168C2B2B4C720500DC6AB9 /* JBOffsets.cpp in Sources */, 206 | 87168C272B4C71DD00DC6AB9 /* JBPrimitive.cpp in Sources */, 207 | 87168C322B4C807C00DC6AB9 /* JBException.cpp in Sources */, 208 | ); 209 | runOnlyForDeploymentPostprocessing = 0; 210 | }; 211 | /* End PBXSourcesBuildPhase section */ 212 | 213 | /* Begin XCBuildConfiguration section */ 214 | 87168C1C2B4C710A00DC6AB9 /* Debug */ = { 215 | isa = XCBuildConfiguration; 216 | buildSettings = { 217 | ALWAYS_SEARCH_USER_PATHS = NO; 218 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 219 | CLANG_ANALYZER_NONNULL = YES; 220 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 221 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 222 | CLANG_ENABLE_MODULES = YES; 223 | CLANG_ENABLE_OBJC_ARC = YES; 224 | CLANG_ENABLE_OBJC_WEAK = YES; 225 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 226 | CLANG_WARN_BOOL_CONVERSION = YES; 227 | CLANG_WARN_COMMA = YES; 228 | CLANG_WARN_CONSTANT_CONVERSION = YES; 229 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 230 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 231 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 232 | CLANG_WARN_EMPTY_BODY = YES; 233 | CLANG_WARN_ENUM_CONVERSION = YES; 234 | CLANG_WARN_INFINITE_RECURSION = YES; 235 | CLANG_WARN_INT_CONVERSION = YES; 236 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 237 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 238 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 239 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 240 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 241 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 242 | CLANG_WARN_STRICT_PROTOTYPES = YES; 243 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 244 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 245 | CLANG_WARN_UNREACHABLE_CODE = YES; 246 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 247 | COPY_PHASE_STRIP = NO; 248 | CURRENT_PROJECT_VERSION = 1; 249 | DEBUG_INFORMATION_FORMAT = dwarf; 250 | ENABLE_STRICT_OBJC_MSGSEND = YES; 251 | ENABLE_TESTABILITY = YES; 252 | ENABLE_USER_SCRIPT_SANDBOXING = YES; 253 | GCC_C_LANGUAGE_STANDARD = gnu17; 254 | GCC_DYNAMIC_NO_PIC = NO; 255 | GCC_NO_COMMON_BLOCKS = YES; 256 | GCC_OPTIMIZATION_LEVEL = 0; 257 | GCC_PREPROCESSOR_DEFINITIONS = ( 258 | "DEBUG=1", 259 | "$(inherited)", 260 | ); 261 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 262 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 263 | GCC_WARN_UNDECLARED_SELECTOR = YES; 264 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 265 | GCC_WARN_UNUSED_FUNCTION = YES; 266 | GCC_WARN_UNUSED_VARIABLE = YES; 267 | IPHONEOS_DEPLOYMENT_TARGET = 17.0; 268 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES; 269 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 270 | MTL_FAST_MATH = YES; 271 | ONLY_ACTIVE_ARCH = YES; 272 | SDKROOT = iphoneos; 273 | VERSIONING_SYSTEM = "apple-generic"; 274 | VERSION_INFO_PREFIX = ""; 275 | }; 276 | name = Debug; 277 | }; 278 | 87168C1D2B4C710A00DC6AB9 /* Release */ = { 279 | isa = XCBuildConfiguration; 280 | buildSettings = { 281 | ALWAYS_SEARCH_USER_PATHS = NO; 282 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 283 | CLANG_ANALYZER_NONNULL = YES; 284 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 285 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 286 | CLANG_ENABLE_MODULES = YES; 287 | CLANG_ENABLE_OBJC_ARC = YES; 288 | CLANG_ENABLE_OBJC_WEAK = YES; 289 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 290 | CLANG_WARN_BOOL_CONVERSION = YES; 291 | CLANG_WARN_COMMA = YES; 292 | CLANG_WARN_CONSTANT_CONVERSION = YES; 293 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 294 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 295 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 296 | CLANG_WARN_EMPTY_BODY = YES; 297 | CLANG_WARN_ENUM_CONVERSION = YES; 298 | CLANG_WARN_INFINITE_RECURSION = YES; 299 | CLANG_WARN_INT_CONVERSION = YES; 300 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 301 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 302 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 303 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 304 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 305 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 306 | CLANG_WARN_STRICT_PROTOTYPES = YES; 307 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 308 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 309 | CLANG_WARN_UNREACHABLE_CODE = YES; 310 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 311 | COPY_PHASE_STRIP = NO; 312 | CURRENT_PROJECT_VERSION = 1; 313 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 314 | ENABLE_NS_ASSERTIONS = NO; 315 | ENABLE_STRICT_OBJC_MSGSEND = YES; 316 | ENABLE_USER_SCRIPT_SANDBOXING = YES; 317 | GCC_C_LANGUAGE_STANDARD = gnu17; 318 | GCC_NO_COMMON_BLOCKS = YES; 319 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 320 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 321 | GCC_WARN_UNDECLARED_SELECTOR = YES; 322 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 323 | GCC_WARN_UNUSED_FUNCTION = YES; 324 | GCC_WARN_UNUSED_VARIABLE = YES; 325 | IPHONEOS_DEPLOYMENT_TARGET = 17.0; 326 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES; 327 | MTL_ENABLE_DEBUG_INFO = NO; 328 | MTL_FAST_MATH = YES; 329 | SDKROOT = iphoneos; 330 | VALIDATE_PRODUCT = YES; 331 | VERSIONING_SYSTEM = "apple-generic"; 332 | VERSION_INFO_PREFIX = ""; 333 | }; 334 | name = Release; 335 | }; 336 | 87168C1F2B4C710A00DC6AB9 /* Debug */ = { 337 | isa = XCBuildConfiguration; 338 | buildSettings = { 339 | CODE_SIGN_STYLE = Automatic; 340 | CURRENT_PROJECT_VERSION = 1; 341 | DEFINES_MODULE = YES; 342 | DYLIB_COMPATIBILITY_VERSION = 1; 343 | DYLIB_CURRENT_VERSION = 1; 344 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 345 | ENABLE_MODULE_VERIFIER = YES; 346 | ENABLE_TESTABILITY = YES; 347 | GENERATE_INFOPLIST_FILE = YES; 348 | HEADER_SEARCH_PATHS = "${SRCROOT}/include"; 349 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 350 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 351 | IPHONEOS_DEPLOYMENT_TARGET = 15.0; 352 | LD_RUNPATH_SEARCH_PATHS = ( 353 | "$(inherited)", 354 | "@executable_path/Frameworks", 355 | "@loader_path/Frameworks", 356 | ); 357 | LIBRARY_SEARCH_PATHS = "${SRCROOT}/lib"; 358 | MARKETING_VERSION = 1.0; 359 | MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; 360 | MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; 361 | PRODUCT_BUNDLE_IDENTIFIER = net.tihmstar.JBKit; 362 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 363 | SKIP_INSTALL = YES; 364 | SWIFT_EMIT_LOC_STRINGS = YES; 365 | TARGETED_DEVICE_FAMILY = "1,2"; 366 | }; 367 | name = Debug; 368 | }; 369 | 87168C202B4C710A00DC6AB9 /* Release */ = { 370 | isa = XCBuildConfiguration; 371 | buildSettings = { 372 | CODE_SIGN_STYLE = Automatic; 373 | CURRENT_PROJECT_VERSION = 1; 374 | DEFINES_MODULE = YES; 375 | DYLIB_COMPATIBILITY_VERSION = 1; 376 | DYLIB_CURRENT_VERSION = 1; 377 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 378 | ENABLE_MODULE_VERIFIER = YES; 379 | GENERATE_INFOPLIST_FILE = YES; 380 | HEADER_SEARCH_PATHS = "${SRCROOT}/include"; 381 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 382 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 383 | IPHONEOS_DEPLOYMENT_TARGET = 15.0; 384 | LD_RUNPATH_SEARCH_PATHS = ( 385 | "$(inherited)", 386 | "@executable_path/Frameworks", 387 | "@loader_path/Frameworks", 388 | ); 389 | LIBRARY_SEARCH_PATHS = "${SRCROOT}/lib"; 390 | MARKETING_VERSION = 1.0; 391 | MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; 392 | MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; 393 | PRODUCT_BUNDLE_IDENTIFIER = net.tihmstar.JBKit; 394 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 395 | SKIP_INSTALL = YES; 396 | SWIFT_EMIT_LOC_STRINGS = YES; 397 | TARGETED_DEVICE_FAMILY = "1,2"; 398 | }; 399 | name = Release; 400 | }; 401 | /* End XCBuildConfiguration section */ 402 | 403 | /* Begin XCConfigurationList section */ 404 | 87168C112B4C710A00DC6AB9 /* Build configuration list for PBXProject "JBKit" */ = { 405 | isa = XCConfigurationList; 406 | buildConfigurations = ( 407 | 87168C1C2B4C710A00DC6AB9 /* Debug */, 408 | 87168C1D2B4C710A00DC6AB9 /* Release */, 409 | ); 410 | defaultConfigurationIsVisible = 0; 411 | defaultConfigurationName = Release; 412 | }; 413 | 87168C1E2B4C710A00DC6AB9 /* Build configuration list for PBXNativeTarget "JBKit" */ = { 414 | isa = XCConfigurationList; 415 | buildConfigurations = ( 416 | 87168C1F2B4C710A00DC6AB9 /* Debug */, 417 | 87168C202B4C710A00DC6AB9 /* Release */, 418 | ); 419 | defaultConfigurationIsVisible = 0; 420 | defaultConfigurationName = Release; 421 | }; 422 | /* End XCConfigurationList section */ 423 | }; 424 | rootObject = 87168C0E2B4C710A00DC6AB9 /* Project object */; 425 | } 426 | -------------------------------------------------------------------------------- /JBKit/JBException.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // JBException.cpp 3 | // JBKit 4 | // 5 | // Created by tihmstar on 08.01.24. 6 | // 7 | 8 | #include "JBMacros.h" 9 | #include "JBException.hpp" 10 | #include 11 | #include 12 | #include 13 | 14 | using namespace JBKit; 15 | 16 | exception::exception(const char *commit_count_str, const char *commit_sha_str, int line, const char *filename, const char *err ...) : 17 | _commit_count_str(commit_count_str), 18 | _commit_sha_str(commit_sha_str), 19 | _line(line), 20 | _filename(filename), 21 | _err(NULL) 22 | { 23 | va_list ap = {}; 24 | va_start(ap, err); 25 | vasprintf(&_err, err, ap); 26 | va_end(ap); 27 | }; 28 | 29 | exception::exception(const char *commit_count_str, const char *commit_sha_str, int line, const char *filename, va_list ap, const char *err) : 30 | _commit_count_str(commit_count_str), 31 | _commit_sha_str(commit_sha_str), 32 | _line(line), 33 | _filename(filename), 34 | _err(NULL) 35 | { 36 | vasprintf(&_err, err, ap); 37 | }; 38 | 39 | exception::exception(const exception &e) : //copy constructor 40 | _commit_count_str(e._commit_count_str), 41 | _commit_sha_str(e._commit_sha_str), 42 | _line(e._line), 43 | _filename(e._filename), 44 | _err(NULL) 45 | { 46 | if (e._err) { 47 | size_t len = strlen(e._err); 48 | _err = (char*)malloc(len+1); 49 | strncpy(_err, e._err, len); 50 | _err[len] = '\0'; 51 | } 52 | } 53 | exception::~exception(){ 54 | safeFree(_err); 55 | } 56 | 57 | 58 | const char *exception::what() const noexcept { 59 | return _err; 60 | } 61 | 62 | int exception::code() const{ 63 | return (_line << 16) | (int)(_filename.size()); 64 | } 65 | 66 | void exception::dump() const{ 67 | printf("%s",dumpStr().c_str()); 68 | } 69 | 70 | std::string exception::dumpStr() const{ 71 | char *dumpstr = NULL; 72 | asprintf(&dumpstr, "[exception]:\n" 73 | "what=%s\n" 74 | "code=%d\n" 75 | "line=%d\n" 76 | "file=%s\n" 77 | "commit count=%s\n" 78 | "commit sha =%s\n" 79 | ,_err 80 | ,code() 81 | ,_line 82 | ,_filename.c_str() 83 | ,build_commit_count().c_str() 84 | ,build_commit_sha().c_str() 85 | ); 86 | { 87 | std::string ret = dumpstr; 88 | safeFree(dumpstr); 89 | return ret; 90 | } 91 | } 92 | 93 | 94 | std::string exception::build_commit_count() const { 95 | return _commit_count_str; 96 | }; 97 | 98 | std::string exception::build_commit_sha() const { 99 | return _commit_sha_str; 100 | }; 101 | 102 | 103 | EASY_BASE_EXCEPTION_DEF(JBException); 104 | -------------------------------------------------------------------------------- /JBKit/JBException.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // JBException.hpp 3 | // JBKit 4 | // 5 | // Created by tihmstar on 08.01.24. 6 | // 7 | 8 | #ifndef JBException_hpp 9 | #define JBException_hpp 10 | #ifdef __cplusplus 11 | 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | #if defined(WIN32) && !__clang__ 18 | # define JBKIT_VISIBLE_EXCEPTION_TYPEINFO __declspec( dllexport ) 19 | #else 20 | # ifdef HAVE_FVISIBILITY 21 | # define JBKIT_VISIBLE_EXCEPTION_TYPEINFO __attribute__((visibility("default"))) 22 | # else 23 | # define JBKIT_VISIBLE_EXCEPTION_TYPEINFO 24 | # endif 25 | #endif 26 | 27 | #define EASY_BASE_EXCEPTION(name) \ 28 | class JBKIT_VISIBLE_EXCEPTION_TYPEINFO name : public JBKit::exception{ \ 29 | public: \ 30 | using exception::exception; \ 31 | /*this makes sure typeinfo works correcty in other libs!*/ \ 32 | virtual const char *what() const noexcept override; \ 33 | } 34 | 35 | #define EASY_EXCEPTION(name, base) \ 36 | class JBKIT_VISIBLE_EXCEPTION_TYPEINFO name : public JBKit::base{ \ 37 | using base::base; \ 38 | } 39 | 40 | #define EASY_BASE_EXCEPTION_DEF(name) \ 41 | JBKIT_VISIBLE_EXCEPTION_TYPEINFO const char *JBKit::name::what() const noexcept{ \ 42 | /*this makes sure typeinfo works correcty in other libs!*/\ 43 | return JBKit::exception::what();\ 44 | } 45 | 46 | namespace JBKit { 47 | class JBKIT_VISIBLE_EXCEPTION_TYPEINFO exception : public std::exception{ 48 | const char *_commit_count_str; 49 | const char *_commit_sha_str; 50 | int _line; 51 | std::string _filename; 52 | char *_err; 53 | 54 | public: 55 | exception(const char *commit_count_str, const char *commit_sha_str, int line, const char *filename, const char *err ...); 56 | exception(const char *commit_count_str, const char *commit_sha_str, int line, const char *filename, va_list ap, const char *err); 57 | 58 | exception(const exception &e); //copy constructor 59 | 60 | //custom error can be used 61 | virtual const char *what() const noexcept override; 62 | 63 | /* 64 | -first lowest two bytes of code is sourcecode line 65 | -next two bytes is strlen of filename in which error happened 66 | */ 67 | int code() const; 68 | 69 | virtual void dump() const; 70 | virtual std::string dumpStr() const; 71 | 72 | //Information about build 73 | virtual std::string build_commit_count() const; 74 | virtual std::string build_commit_sha() const; 75 | 76 | ~exception(); 77 | }; 78 | 79 | #pragma mark easy exception 80 | 81 | EASY_BASE_EXCEPTION(JBException); 82 | 83 | EASY_EXCEPTION(JBException_primitive_unavailable, JBException); 84 | EASY_EXCEPTION(JBException_incomplete_read_or_write, JBException); 85 | EASY_EXCEPTION(JBException_exploit_failed_needs_reboot, JBException); 86 | 87 | }; 88 | 89 | #endif //__cplusplus 90 | #endif /* JBException_hpp */ 91 | -------------------------------------------------------------------------------- /JBKit/JBExploit.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // JBExploit.cpp 3 | // JBKit 4 | // 5 | // Created by tihmstar on 08.01.24. 6 | // 7 | 8 | #include "JBExploit.hpp" 9 | #include "JBMacros.h" 10 | 11 | #include 12 | #include 13 | 14 | using namespace JBKit; 15 | 16 | #pragma mark constructor 17 | JBExploit::JBExploit(){ 18 | // 19 | } 20 | 21 | JBExploit::~JBExploit(){ 22 | // 23 | } 24 | 25 | #pragma mark public availability infos 26 | bool JBExploit::hasRead64() const noexcept{ 27 | return false; 28 | } 29 | 30 | bool JBExploit::hasRead32() const noexcept{ 31 | return false; 32 | } 33 | 34 | bool JBExploit::hasWrite64() const noexcept{ 35 | return false; 36 | } 37 | 38 | bool JBExploit::hasWrite32() const noexcept{ 39 | return false; 40 | } 41 | 42 | bool JBExploit::hasExecute() const noexcept{ 43 | return false; 44 | } 45 | 46 | #pragma mark public provide primitives 47 | size_t JBExploit::unstable_read_generic(kptr_t kaddr, void *dstbuf, size_t size, BOOLEAN honorSizeLimit){ 48 | bool hasr64 = hasRead64(); 49 | bool hasr32 = hasRead32(); 50 | size_t didRead = 0; 51 | uint8_t *dst = (uint8_t*)dstbuf; 52 | 53 | retcustomassure(JBException_primitive_unavailable, hasr64 || hasr32, "read is not implemented by the primitive"); 54 | 55 | if (hasr64) { 56 | while (size - didRead > sizeof(uint64_t)) { 57 | uint64_t r = unstable_read64(kaddr + didRead); 58 | memcpy(&dst[didRead], &r, sizeof(r)); 59 | didRead += sizeof(r); 60 | } 61 | } 62 | 63 | if (hasr32) { 64 | while (size - didRead > sizeof(uint32_t)) { 65 | uint32_t r = unstable_read32(kaddr + didRead); 66 | memcpy(&dst[didRead], &r, sizeof(r)); 67 | didRead += sizeof(r); 68 | } 69 | } 70 | 71 | if (honorSizeLimit) return didRead; 72 | 73 | //we will perform an overread and return only as much bytes as requested 74 | size_t reminder = size - didRead; 75 | 76 | if (hasr64 && (reminder > sizeof(uint32_t) || !hasr32)) { 77 | uint64_t r = unstable_read64(kaddr + didRead); 78 | memcpy(&dst[didRead], &r, reminder); 79 | didRead += reminder; 80 | }else if (hasr32){ 81 | 82 | if (reminder > sizeof(uint32_t)) reminder = sizeof(reminder); 83 | 84 | { 85 | uint32_t r = unstable_read32(kaddr + didRead); 86 | memcpy(&dst[didRead], &r, reminder); 87 | didRead += reminder; 88 | } 89 | 90 | reminder = size - didRead; 91 | if (reminder > sizeof(uint32_t)) reminder = sizeof(reminder); 92 | 93 | if (reminder){ 94 | uint32_t r = unstable_read32(kaddr + didRead); 95 | memcpy(&dst[didRead], &r, reminder); 96 | didRead += reminder; 97 | } 98 | } 99 | 100 | return didRead; 101 | } 102 | 103 | size_t JBExploit::unstable_write_generic(kptr_t kaddr, const void *srcbuf, size_t size, BOOLEAN honorSizeLimit){ 104 | bool hasw64 = hasWrite64(); 105 | bool hasw32 = hasWrite32(); 106 | size_t didWrite = 0; 107 | const uint8_t *src = (const uint8_t*)srcbuf; 108 | 109 | retcustomassure(JBException_primitive_unavailable, hasw64 || hasw32, "write is not implemented by the primitive"); 110 | 111 | if (hasw64) { 112 | while (size - didWrite > sizeof(uint64_t)) { 113 | uint64_t w = 0; 114 | memcpy(&w, &src[didWrite], sizeof(w)); 115 | unstable_write64(kaddr + didWrite, w); 116 | didWrite += sizeof(w); 117 | } 118 | } 119 | 120 | if (hasw32) { 121 | while (size - didWrite > sizeof(uint64_t)) { 122 | uint32_t w = 0; 123 | memcpy(&w, &src[didWrite], sizeof(w)); 124 | unstable_write32(kaddr + didWrite, w); 125 | didWrite += sizeof(w); 126 | } 127 | } 128 | 129 | if (honorSizeLimit) return didWrite; 130 | 131 | //we will perform an overwrite with previously read back bytes 132 | size_t reminder = size - didWrite; 133 | 134 | if (hasw64 && (reminder > sizeof(uint32_t) || !hasw32)) { 135 | uint64_t w = unstable_read64(kaddr + didWrite); 136 | memcpy(&w, &src[didWrite], reminder); 137 | unstable_write64(kaddr + didWrite, w); 138 | didWrite += reminder; 139 | }else if (hasw32){ 140 | 141 | if (reminder > sizeof(uint32_t)) reminder = sizeof(reminder); 142 | { 143 | uint32_t w = unstable_read32(kaddr + didWrite); 144 | memcpy(&w, &src[didWrite], reminder); 145 | unstable_write32(kaddr + didWrite, w); 146 | didWrite += reminder; 147 | } 148 | 149 | reminder = size - didWrite; 150 | if (reminder > sizeof(uint32_t)) reminder = sizeof(reminder); 151 | 152 | if (reminder) { 153 | uint32_t w = unstable_read32(kaddr + didWrite); 154 | memcpy(&w, &src[didWrite], reminder); 155 | unstable_write32(kaddr + didWrite, w); 156 | didWrite += reminder; 157 | } 158 | } 159 | 160 | return didWrite; 161 | } 162 | 163 | #pragma mark public 164 | #pragma mark primitives 165 | 166 | uint64_t JBExploit::unstable_read64(kptr_t kaddr){ 167 | retcustomerror(JBException_primitive_unavailable, "unstable_read64 is not implemented by the exploit"); 168 | } 169 | 170 | uint32_t JBExploit::unstable_read32(kptr_t kaddr){ 171 | retcustomerror(JBException_primitive_unavailable, "unstable_read32 is not implemented by the exploit"); 172 | } 173 | 174 | void JBExploit::unstable_write64(kptr_t kaddr, uint64_t val){ 175 | retcustomerror(JBException_primitive_unavailable, "unstable_write64 is not implemented by the exploit"); 176 | } 177 | 178 | void JBExploit::unstable_write32(kptr_t kaddr, uint32_t val){ 179 | retcustomerror(JBException_primitive_unavailable, "unstable_write32 is not implemented by the exploit"); 180 | } 181 | 182 | kptr_t JBExploit::unstable_execute(kptr_t kaddr, callargs_t args){ 183 | retcustomerror(JBException_primitive_unavailable, "unstable_execute is not implemented by the exploit"); 184 | } 185 | 186 | kptr_t JBExploit::getKernelBase(){ 187 | retcustomerror(JBException_primitive_unavailable, "getKernelBase is not implemented by the exploit"); 188 | } 189 | 190 | #pragma mark static 191 | static std::map gExploits; 192 | static std::mutex gExploitsLck; 193 | void JBExploit::registerExploit(JBExploit *exp) noexcept { 194 | std::unique_lock ul(gExploitsLck); 195 | auto old = gExploits.find(exp->exploitName()); 196 | if (old != gExploits.end()){ 197 | JBExploit *olde = old->second; 198 | gExploits.erase(old); 199 | safeDelete(olde); 200 | } 201 | gExploits[exp->exploitName()] = exp; 202 | } 203 | 204 | JBExploit *JBExploit::getExploitWithName(const char *name) noexcept{ 205 | std::unique_lock ul(gExploitsLck); 206 | try { 207 | return gExploits.at(name); 208 | } catch (...) { 209 | return NULL; 210 | } 211 | } 212 | 213 | std::vector JBExploit::listRegisteredExploits() noexcept{ 214 | std::unique_lock ul(gExploitsLck); 215 | std::vector ret; 216 | for (auto e : gExploits) { 217 | ret.push_back(e.first); 218 | } 219 | return ret; 220 | } 221 | -------------------------------------------------------------------------------- /JBKit/JBExploit.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // JBExploit.hpp 3 | // JBKit 4 | // 5 | // Created by tihmstar on 08.01.24. 6 | // 7 | 8 | #ifndef JBExploit_hpp 9 | #define JBExploit_hpp 10 | #ifdef __cplusplus 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | namespace JBKit { 19 | 20 | class JBExploit{ 21 | 22 | public: 23 | JBExploit(); 24 | virtual ~JBExploit(); 25 | 26 | #pragma mark exploit 27 | virtual bool initExploit(JBOffsets offsets, readfunc_t func_read = NULL, writefunc_t func_write = NULL, execfunc_t func_exec = NULL) = 0; 28 | virtual void cleanupExploit() = 0; 29 | virtual void runExploit() = 0; 30 | 31 | #pragma mark infos 32 | virtual const char *exploitName() = 0; 33 | 34 | #pragma mark availability infos 35 | virtual bool hasRead64() const noexcept; 36 | virtual bool hasRead32() const noexcept; 37 | virtual bool hasWrite64() const noexcept; 38 | virtual bool hasWrite32() const noexcept; 39 | virtual bool hasExecute() const noexcept; 40 | 41 | #pragma mark provide primitives 42 | /* 43 | Args: 44 | honorSizeLimit: 45 | if false, a larger read may be performed this can be problematic when (potentially) reading past a page boundry which may cause a panic 46 | Returns: number of bytes read 47 | */ 48 | virtual size_t unstable_read_generic(kptr_t kaddr, void *dstbuf, size_t size, BOOLEAN honorSizeLimit = false); 49 | 50 | 51 | /* 52 | Args: 53 | honorSizeLimit: 54 | if false, a larger write may be performed this can be problematic when (potentially) writing past a page boundry which may cause a panic 55 | Returns: number of bytes written 56 | */ 57 | virtual size_t unstable_write_generic(kptr_t kaddr, const void *srcbuf, size_t size, BOOLEAN honorSizeLimit = false); 58 | 59 | #pragma mark primitives 60 | virtual uint64_t unstable_read64(kptr_t kaddr); 61 | virtual uint32_t unstable_read32(kptr_t kaddr); 62 | 63 | virtual void unstable_write64(kptr_t kaddr, uint64_t val); 64 | virtual void unstable_write32(kptr_t kaddr, uint32_t val); 65 | 66 | virtual kptr_t unstable_execute(kptr_t kaddr, callargs_t args = {}); 67 | 68 | virtual kptr_t getKernelBase(); 69 | 70 | #pragma mark static 71 | static void registerExploit(JBExploit *exp) noexcept; 72 | static JBExploit *getExploitWithName(const char *name) noexcept; 73 | static std::vector listRegisteredExploits() noexcept; 74 | }; 75 | 76 | } 77 | 78 | #endif // __cplusplus 79 | #endif /* JBExploit_hpp */ 80 | -------------------------------------------------------------------------------- /JBKit/JBExploit_c.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // JBExploit_c.cpp 3 | // JBKit 4 | // 5 | // Created by tihmstar on 08.01.24. 6 | // 7 | 8 | #include "JBExploit_c.h" 9 | #include "JBExploit.hpp" 10 | 11 | #include 12 | 13 | using namespace JBKit; 14 | 15 | #pragma mark get exploit 16 | extern "C" 17 | char **JBExploit_getRegisteredExploitsList(){ 18 | char **retval = NULL; 19 | std::vector list; 20 | try { 21 | list = JBExploit::listRegisteredExploits(); 22 | } catch (...) { 23 | return NULL; 24 | } 25 | retval = (char**)calloc(list.size()+1, sizeof(char*)); 26 | { 27 | char **ri = retval; 28 | for (auto e : list) { 29 | *ri++ = strdup(e.c_str()); 30 | } 31 | } 32 | return retval; 33 | } 34 | 35 | extern "C" 36 | void JBExploit_freeRegisteredExploitsList(char **list){ 37 | for (char **ri = list; *ri; ri++) { 38 | free(*ri); 39 | } 40 | free(list); 41 | } 42 | 43 | extern "C" 44 | JBExploit_ctx_t JBExploit_getExploitWithName(const char *name){ 45 | try { 46 | return (JBExploit_ctx_t)JBExploit::getExploitWithName(name); 47 | } catch (...) { 48 | return NULL; 49 | } 50 | } 51 | 52 | 53 | #pragma mark use exploit 54 | 55 | extern "C" 56 | int JBExploit_exploit_initExploit(JBExploit_ctx_t ctx, JBOffset_ctx_t offsets, readfunc_t func_read, writefunc_t func_write, execfunc_t func_exec){ 57 | JBExploit *obj = (JBExploit *)ctx; 58 | JBOffsets *obj_offsets = (JBOffsets *)offsets; 59 | 60 | try { 61 | return obj->initExploit(*obj_offsets, func_read, func_write, func_exec) ? 0 : -2; 62 | } catch (...) { 63 | return -1; 64 | } 65 | } 66 | 67 | extern "C" 68 | int JBExploit_exploit_cleanupExploit(JBExploit_ctx_t ctx){ 69 | JBExploit *obj = (JBExploit *)ctx; 70 | try { 71 | obj->cleanupExploit(); 72 | return 0; 73 | } catch (...) { 74 | return -1; 75 | } 76 | } 77 | 78 | extern "C" 79 | int JBExploit_exploit_runExploit(JBExploit_ctx_t ctx){ 80 | JBExploit *obj = (JBExploit *)ctx; 81 | try { 82 | obj->runExploit(); 83 | return 0; 84 | } catch (...) { 85 | return -1; 86 | } 87 | } 88 | 89 | extern "C" 90 | const char * JBExploit_exploit_exploitName(JBExploit_ctx_t ctx){ 91 | JBExploit *obj = (JBExploit *)ctx; 92 | try { 93 | return obj->exploitName(); 94 | } catch (...) { 95 | return NULL; 96 | } 97 | } 98 | 99 | extern "C" 100 | BOOLEAN JBExploit_exploit_hasRead64(JBExploit_ctx_t ctx){ 101 | JBExploit *obj = (JBExploit *)ctx; 102 | try { 103 | return obj->hasRead64(); 104 | } catch (...) { 105 | return FALSE; 106 | } 107 | } 108 | 109 | extern "C" 110 | BOOLEAN JBExploit_exploit_hasRead32(JBExploit_ctx_t ctx){ 111 | JBExploit *obj = (JBExploit *)ctx; 112 | try { 113 | return obj->hasRead32(); 114 | } catch (...) { 115 | return FALSE; 116 | } 117 | } 118 | 119 | extern "C" 120 | BOOLEAN JBExploit_exploit_hasWrite64(JBExploit_ctx_t ctx){ 121 | JBExploit *obj = (JBExploit *)ctx; 122 | try { 123 | return obj->hasWrite64(); 124 | } catch (...) { 125 | return FALSE; 126 | } 127 | } 128 | 129 | extern "C" 130 | BOOLEAN JBExploit_exploit_hasWrite32(JBExploit_ctx_t ctx){ 131 | JBExploit *obj = (JBExploit *)ctx; 132 | try { 133 | return obj->hasWrite32(); 134 | } catch (...) { 135 | return FALSE; 136 | } 137 | } 138 | 139 | extern "C" 140 | BOOLEAN JBExploit_exploit_hasExecute(JBExploit_ctx_t ctx){ 141 | JBExploit *obj = (JBExploit *)ctx; 142 | try { 143 | return obj->hasExecute(); 144 | } catch (...) { 145 | return FALSE; 146 | } 147 | } 148 | 149 | extern "C" 150 | size_t JBExploit_exploit_unstable_read_generic(JBExploit_ctx_t ctx, kptr_t kaddr, void *dstbuf, size_t size, BOOLEAN honorSizeLimit){ 151 | JBExploit *obj = (JBExploit *)ctx; 152 | try { 153 | return obj->unstable_read_generic(kaddr, dstbuf, size, honorSizeLimit); 154 | } catch (...) { 155 | return 0; 156 | } 157 | } 158 | 159 | extern "C" 160 | size_t JBExploit_exploit_unstable_write_generic(JBExploit_ctx_t ctx, kptr_t kaddr, const void *srcbuf, size_t size, BOOLEAN honorSizeLimit){ 161 | JBExploit *obj = (JBExploit *)ctx; 162 | try { 163 | return obj->unstable_write_generic(kaddr, srcbuf, size, honorSizeLimit); 164 | } catch (...) { 165 | return 0; 166 | } 167 | } 168 | 169 | extern "C" 170 | uint64_t JBExploit_exploit_unstable_read64(JBExploit_ctx_t ctx, kptr_t kaddr){ 171 | JBExploit *obj = (JBExploit *)ctx; 172 | try { 173 | return obj->unstable_read64(kaddr); 174 | } catch (...) { 175 | return 0; 176 | } 177 | } 178 | 179 | extern "C" 180 | uint32_t JBExploit_exploit_unstable_read32(JBExploit_ctx_t ctx, kptr_t kaddr){ 181 | JBExploit *obj = (JBExploit *)ctx; 182 | try { 183 | return obj->unstable_read32(kaddr); 184 | } catch (...) { 185 | return 0; 186 | } 187 | } 188 | 189 | extern "C" 190 | int JBExploit_exploit_unstable_write64(JBExploit_ctx_t ctx, kptr_t kaddr, uint64_t val){ 191 | JBExploit *obj = (JBExploit *)ctx; 192 | try { 193 | obj->unstable_write64(kaddr, val); 194 | return 0; 195 | } catch (...) { 196 | return -1; 197 | } 198 | } 199 | 200 | extern "C" 201 | int JBExploit_exploit_unstable_write32(JBExploit_ctx_t ctx, kptr_t kaddr, uint32_t val){ 202 | JBExploit *obj = (JBExploit *)ctx; 203 | try { 204 | obj->unstable_write32(kaddr, val); 205 | return 0; 206 | } catch (...) { 207 | return -1; 208 | } 209 | } 210 | 211 | extern "C" 212 | kptr_t JBExploit_exploit_unstable_execute(JBExploit_ctx_t ctx, kptr_t kaddr, callargs_t args){ 213 | JBExploit *obj = (JBExploit *)ctx; 214 | try { 215 | return obj->unstable_execute(kaddr, args); 216 | } catch (...) { 217 | return 0; 218 | } 219 | } 220 | 221 | extern "C" 222 | kptr_t JBExploit_exploit_getKernelBase(JBExploit_ctx_t ctx){ 223 | JBExploit *obj = (JBExploit *)ctx; 224 | try { 225 | return obj->getKernelBase(); 226 | } catch (...) { 227 | return 0; 228 | } 229 | } 230 | -------------------------------------------------------------------------------- /JBKit/JBExploit_c.h: -------------------------------------------------------------------------------- 1 | // 2 | // JBExploit_c.hpp 3 | // JBKit 4 | // 5 | // Created by tihmstar on 08.01.24. 6 | // 7 | 8 | #ifndef JBExploit_c_h 9 | #define JBExploit_c_h 10 | 11 | #include 12 | 13 | #ifdef __cplusplus 14 | extern "C" { 15 | #endif //__cplusplus 16 | 17 | typedef void* JBExploit_ctx_t; 18 | 19 | #pragma mark get exploit 20 | 21 | /* 22 | Return: 23 | returns a null terminated list of char * 24 | caller needs to pass it to JBExploit_freeRegisteredExploitsList to free resources 25 | */ 26 | char **JBExploit_getRegisteredExploitsList(); 27 | void JBExploit_freeRegisteredExploitsList(char **list); 28 | 29 | JBExploit_ctx_t JBExploit_getExploitWithName(const char *name); 30 | 31 | #pragma mark use exploit 32 | 33 | int JBExploit_exploit_initExploit(JBExploit_ctx_t ctx, JBOffset_ctx_t offsets, readfunc_t func_read, writefunc_t func_write, execfunc_t func_exec); 34 | int JBExploit_exploit_cleanupExploit(JBExploit_ctx_t ctx); 35 | int JBExploit_exploit_runExploit(JBExploit_ctx_t ctx); 36 | 37 | const char * JBExploit_exploit_exploitName(JBExploit_ctx_t ctx); 38 | 39 | BOOLEAN JBExploit_exploit_hasRead64(JBExploit_ctx_t ctx); 40 | BOOLEAN JBExploit_exploit_hasRead32(JBExploit_ctx_t ctx); 41 | BOOLEAN JBExploit_exploit_hasWrite64(JBExploit_ctx_t ctx); 42 | BOOLEAN JBExploit_exploit_hasWrite32(JBExploit_ctx_t ctx); 43 | BOOLEAN JBExploit_exploit_hasExecute(JBExploit_ctx_t ctx); 44 | 45 | size_t JBExploit_exploit_unstable_read_generic(JBExploit_ctx_t ctx, kptr_t kaddr, void *dstbuf, size_t size, BOOLEAN honorSizeLimit); 46 | size_t JBExploit_exploit_unstable_write_generic(JBExploit_ctx_t ctx, kptr_t kaddr, const void *srcbuf, size_t size, BOOLEAN honorSizeLimit); 47 | 48 | uint64_t JBExploit_exploit_unstable_read64(JBExploit_ctx_t ctx, kptr_t kaddr); 49 | uint32_t JBExploit_exploit_unstable_read32(JBExploit_ctx_t ctx, kptr_t kaddr); 50 | 51 | int JBExploit_exploit_unstable_write64(JBExploit_ctx_t ctx, kptr_t kaddr, uint64_t val); 52 | int JBExploit_exploit_unstable_write32(JBExploit_ctx_t ctx, kptr_t kaddr, uint32_t val); 53 | 54 | kptr_t JBExploit_exploit_unstable_execute(JBExploit_ctx_t ctx, kptr_t kaddr, callargs_t args); 55 | 56 | kptr_t JBExploit_exploit_getKernelBase(JBExploit_ctx_t ctx); 57 | 58 | #ifdef __cplusplus 59 | }; 60 | #endif //__cplusplus 61 | #endif /* JBExploit_c_h */ 62 | -------------------------------------------------------------------------------- /JBKit/JBKit.h: -------------------------------------------------------------------------------- 1 | // 2 | // JBKit.h 3 | // JBKit 4 | // 5 | // Created by tihmstar on 08.01.24. 6 | // 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | -------------------------------------------------------------------------------- /JBKit/JBMacros.h: -------------------------------------------------------------------------------- 1 | // 2 | // JBMacros.h 3 | // JBKit 4 | // 5 | // Created by tihmstar on 08.01.24. 6 | // 7 | 8 | #ifndef JBMacros_h 9 | #define JBMacros_h 10 | 11 | #include 12 | 13 | #ifndef VERSION_COMMIT_COUNT 14 | # define VERSION_COMMIT_COUNT "VERSION_COMMIT_COUNT_not_set" 15 | #endif 16 | #ifndef VERSION_COMMIT_SHA 17 | # define VERSION_COMMIT_SHA "VERSION_COMMIT_SHA_not_set Build: " __DATE__ " " __TIME__ 18 | #endif 19 | 20 | #ifdef STRIP_ASSURES 21 | # define JBKIT__FILE__ "" 22 | # define JBKIT_ERRSTR(errstr ...) "" 23 | #else //STRIP_ASSURES 24 | # define JBKIT__FILE__ __FILE__ 25 | # define JBKIT_ERRSTR(errstr ...) errstr 26 | #endif //STRIP_ASSURES 27 | 28 | #ifndef EXPECTIONNAME 29 | # define EXPECTIONNAME exception 30 | #endif 31 | 32 | #define assure(cond) do{ if ((cond) == 0) throw JBKit::EXPECTIONNAME(VERSION_COMMIT_COUNT, VERSION_COMMIT_SHA, __LINE__, JBKIT__FILE__, JBKIT_ERRSTR("assure failed")); } while(0) 33 | #define retassure(cond, errstr ...) do{ if ((cond) == 0) throw JBKit::EXPECTIONNAME(VERSION_COMMIT_COUNT, VERSION_COMMIT_SHA, __LINE__,JBKIT__FILE__,JBKIT_ERRSTR(errstr)); } while(0) 34 | #define customassure(custom_except, cond) do{ if ((cond) == 0) throw JBKit::custom_except(VERSION_COMMIT_COUNT, VERSION_COMMIT_SHA, __LINE__, JBKIT__FILE__, JBKIT_ERRSTR("assure failed")); } while(0) 35 | #define retcustomassure(custom_except, cond, errstr ...) do{ if ((cond) == 0) throw JBKit::custom_except(VERSION_COMMIT_COUNT, VERSION_COMMIT_SHA, __LINE__, JBKIT__FILE__, JBKIT_ERRSTR(errstr)); } while(0) 36 | #define reterror(errstr ...) do{ throw JBKit::EXPECTIONNAME(VERSION_COMMIT_COUNT, VERSION_COMMIT_SHA, __LINE__, JBKIT__FILE__, JBKIT_ERRSTR(errstr)); } while(0) 37 | #define retcustomerror(custom_except,errstr ...) do{ throw JBKit::custom_except(VERSION_COMMIT_COUNT, VERSION_COMMIT_SHA, __LINE__, JBKIT__FILE__, JBKIT_ERRSTR(errstr)); } while(0) 38 | #define doassure(cond,code) do {if (!(cond)){(code);assure(cond);}} while(0) 39 | 40 | #define safeFree(ptr) ({if (ptr) {free(ptr); ptr=NULL;}}) 41 | #define safeFreeCustom(ptr,func) ({if (ptr) {func(ptr); ptr=NULL;}}) 42 | #define safeFreeConst(ptr) ({if(ptr){void *fbuf = (void*)ptr;ptr = NULL; free(fbuf);}}) 43 | #define safeClose(fd) ({if (fd != -1) {close(fd); fd=-1;}}) 44 | #define safeCloseCustom(fd,func) ({if (fd != -1) {func(fd); fd=-1;}}) 45 | 46 | #ifdef __cplusplus 47 | # define safeDelete(ptr) ({if (ptr) {delete ptr; ptr=NULL;}}) 48 | class guard{ 49 | std::function _f; 50 | public: 51 | guard(std::function cleanup) : _f(cleanup) {} 52 | guard(const guard&) = delete; //delete copy constructor 53 | guard(guard &&o) = delete; //move constructor 54 | 55 | ~guard(){_f();} 56 | }; 57 | # define cleanup(f) guard _cleanup(f); 58 | #endif //__cplusplus 59 | 60 | #endif /* JBMacros_h */ 61 | -------------------------------------------------------------------------------- /JBKit/JBOffsets.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // JBOffsets.cpp 3 | // JBKit 4 | // 5 | // Created by tihmstar on 08.01.24. 6 | // 7 | 8 | #include "JBOffsets.hpp" 9 | #include "JBMacros.h" 10 | #include 11 | #include 12 | #include 13 | 14 | extern "C" xpc_object_t xpc_create_from_plist(void *data, size_t size); 15 | 16 | using namespace JBKit; 17 | 18 | #pragma mark constructor 19 | JBOffsets::JBOffsets(){ 20 | assure(_xdict = xpc_dictionary_create_empty()); 21 | } 22 | 23 | JBOffsets::~JBOffsets(){ 24 | safeFreeCustom(_xdict, xpc_release); 25 | } 26 | 27 | #pragma mark public 28 | 29 | void JBOffsets::setOffset(const char *name, kptr_t offset){ 30 | xpc_dictionary_set_uint64(_xdict, name, offset); 31 | } 32 | 33 | kptr_t JBOffsets::getOffset(const char *name){ 34 | return xpc_dictionary_get_uint64(_xdict, name); 35 | } 36 | 37 | void JBOffsets::saveOffsets(const char *path){ 38 | FILE *f = NULL; 39 | cleanup([&]{ 40 | safeFreeCustom(f, fclose); 41 | }); 42 | assure(f = fopen(path, "w")); 43 | 44 | fprintf(f, "\n\n\n\n"); 45 | xpc_dictionary_apply(_xdict, ^bool(const char * _Nonnull key, xpc_object_t _Nonnull value) { 46 | uint64_t valueInt = xpc_uint64_get_value(value); 47 | fprintf(f, "\t%s\n\t%llu\n", key, valueInt); 48 | return true; 49 | }); 50 | fprintf(f, "\n\n"); 51 | } 52 | 53 | void JBOffsets::loadOffsets(const char *path){ 54 | int fd = -1; 55 | size_t plistDataLen = 0; 56 | void *plistData = NULL; 57 | cleanup([&]{ 58 | if (plistData) { 59 | munmap(plistData, plistDataLen);plistData = NULL; 60 | } 61 | safeClose(fd); 62 | }); 63 | struct stat s = { 0 }; 64 | 65 | assure((fd = open(path, O_RDONLY)) != -1); 66 | assure(!fstat(fd, &s)); 67 | 68 | plistDataLen = s.st_size; 69 | assure((plistData = mmap(NULL, plistDataLen, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0)) != MAP_FAILED); 70 | safeFreeCustom(_xdict, xpc_release); 71 | assure(_xdict = xpc_create_from_plist(plistData, plistDataLen)); 72 | } 73 | 74 | void JBOffsets::sendOffsets(mach_port_t dst){ 75 | //TODO 76 | } 77 | 78 | void JBOffsets::recvOffsets(mach_port_t src){ 79 | //TODO 80 | } 81 | -------------------------------------------------------------------------------- /JBKit/JBOffsets.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // JBOffsets.hpp 3 | // JBKit 4 | // 5 | // Created by tihmstar on 08.01.24. 6 | // 7 | 8 | #ifndef JBOffsets_hpp 9 | #define JBOffsets_hpp 10 | #ifdef __cplusplus 11 | 12 | #include 13 | #include 14 | 15 | typedef void * xpc_object_t; 16 | 17 | namespace JBKit { 18 | 19 | class JBOffsets { 20 | private: 21 | xpc_object_t _xdict; 22 | 23 | public: 24 | JBOffsets(); 25 | ~JBOffsets(); 26 | 27 | void setOffset(const char *name, kptr_t offset); 28 | kptr_t getOffset(const char *name); 29 | 30 | void saveOffsets(const char *path); 31 | void loadOffsets(const char *path); 32 | 33 | void sendOffsets(mach_port_t dst); //port with send right 34 | void recvOffsets(mach_port_t src); //port with recv right 35 | }; 36 | 37 | 38 | } 39 | #endif //__cplusplus 40 | 41 | #endif /* JBOffsets_hpp */ 42 | -------------------------------------------------------------------------------- /JBKit/JBOffsets_c.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // JBOffsets_c.cpp 3 | // JBKit 4 | // 5 | // Created by tihmstar on 08.01.24. 6 | // 7 | 8 | #include "JBOffsets_c.h" 9 | #include "JBOffsets.hpp" 10 | #include "JBMacros.h" 11 | 12 | using namespace JBKit; 13 | 14 | 15 | extern "C" 16 | JBOffset_ctx_t JBOffsets_offsets_new(){ 17 | try { 18 | return (JBOffset_ctx_t)new JBOffsets; 19 | } catch (...) { 20 | return NULL; 21 | } 22 | } 23 | 24 | extern "C" 25 | void JBOffsets_offsets_free(JBOffset_ctx_t ctx){ 26 | JBOffsets *obj = (JBOffsets*)ctx; 27 | safeDelete(obj); 28 | } 29 | 30 | extern "C" 31 | int JBOffsets_offsets_setOffset(JBOffset_ctx_t ctx, const char *name, kptr_t offset){ 32 | JBOffsets *obj = (JBOffsets*)ctx; 33 | try { 34 | obj->setOffset(name, offset); 35 | return 0; 36 | } catch (...) { 37 | return -1; 38 | } 39 | } 40 | 41 | extern "C" 42 | kptr_t JBOffsets_offsets_getOffset(JBOffset_ctx_t ctx, const char *name){ 43 | JBOffsets *obj = (JBOffsets*)ctx; 44 | try { 45 | return obj->getOffset(name); 46 | } catch (...) { 47 | return 0; 48 | } 49 | } 50 | 51 | extern "C" 52 | int JBOffsets_offsets_saveOffsets(JBOffset_ctx_t ctx, const char *path){ 53 | JBOffsets *obj = (JBOffsets*)ctx; 54 | try { 55 | obj->saveOffsets(path); 56 | return 0; 57 | } catch (...) { 58 | return -1; 59 | } 60 | } 61 | 62 | extern "C" 63 | int JBOffsets_offsets_loadOffsets(JBOffset_ctx_t ctx, const char *path){ 64 | JBOffsets *obj = (JBOffsets*)ctx; 65 | try { 66 | obj->loadOffsets(path); 67 | return 0; 68 | } catch (...) { 69 | return -1; 70 | } 71 | } 72 | 73 | extern "C" 74 | int JBOffsets_offsets_sendOffsets(JBOffset_ctx_t ctx, mach_port_t dst){ 75 | JBOffsets *obj = (JBOffsets*)ctx; 76 | try { 77 | obj->sendOffsets(dst); 78 | return 0; 79 | } catch (...) { 80 | return -1; 81 | } 82 | } 83 | 84 | extern "C" 85 | int JBOffsets_offsets_recvOffsets(JBOffset_ctx_t ctx, mach_port_t src){ 86 | JBOffsets *obj = (JBOffsets*)ctx; 87 | try { 88 | obj->recvOffsets(src); 89 | return 0; 90 | } catch (...) { 91 | return -1; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /JBKit/JBOffsets_c.h: -------------------------------------------------------------------------------- 1 | // 2 | // JBOffsets_c.hpp 3 | // JBKit 4 | // 5 | // Created by tihmstar on 08.01.24. 6 | // 7 | 8 | #ifndef JBOffsets_c_h 9 | #define JBOffsets_c_h 10 | 11 | #include 12 | #include 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif //__cplusplus 17 | 18 | typedef void* JBOffset_ctx_t; 19 | 20 | JBOffset_ctx_t JBOffsets_offsets_new(); 21 | void JBOffsets_offsets_free(JBOffset_ctx_t ctx); 22 | 23 | int JBOffsets_offsets_setOffset(JBOffset_ctx_t ctx, const char *name, kptr_t offset); 24 | kptr_t JBOffsets_offsets_getOffset(JBOffset_ctx_t ctx, const char *name); 25 | 26 | int JBOffsets_offsets_saveOffsets(JBOffset_ctx_t ctx, const char *path); 27 | int JBOffsets_offsets_loadOffsets(JBOffset_ctx_t ctx, const char *path); 28 | 29 | int JBOffsets_offsets_sendOffsets(JBOffset_ctx_t ctx, mach_port_t dst); //port with send right 30 | int JBOffsets_offsets_recvOffsets(JBOffset_ctx_t ctx, mach_port_t src); //port with recv right 31 | 32 | #ifdef __cplusplus 33 | }; 34 | #endif //__cplusplus 35 | #endif /* JBOffsets_c_h */ 36 | -------------------------------------------------------------------------------- /JBKit/JBPrimitive.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // JBPrimitive.cpp 3 | // JBKit 4 | // 5 | // Created by tihmstar on 08.01.24. 6 | // 7 | 8 | #include "JBPrimitive.hpp" 9 | #include "JBMacros.h" 10 | 11 | #include 12 | #include 13 | 14 | using namespace JBKit; 15 | 16 | #pragma mark constructor 17 | JBPrimitive::JBPrimitive(){ 18 | // 19 | } 20 | 21 | JBPrimitive::~JBPrimitive(){ 22 | // 23 | } 24 | 25 | #pragma mark private 26 | bool JBPrimitive::hasRead64() const noexcept{ 27 | return false; 28 | } 29 | 30 | bool JBPrimitive::hasRead32() const noexcept{ 31 | return false; 32 | } 33 | 34 | bool JBPrimitive::hasReadGeneric() const noexcept{ 35 | return false; 36 | } 37 | 38 | bool JBPrimitive::hasWrite64() const noexcept{ 39 | return false; 40 | } 41 | 42 | bool JBPrimitive::hasWrite32() const noexcept{ 43 | return false; 44 | } 45 | 46 | bool JBPrimitive::hasWriteGeneric() const noexcept{ 47 | return false; 48 | } 49 | 50 | #pragma mark public 51 | #pragma mark availability infos 52 | 53 | bool JBPrimitive::hasRead() const noexcept{ 54 | return hasReadGeneric() || hasRead64() || hasRead32(); 55 | } 56 | 57 | bool JBPrimitive::hasWrite() const noexcept{ 58 | return hasWriteGeneric() || hasWrite64() || hasWrite32(); 59 | } 60 | 61 | bool JBPrimitive::hasExecute() const noexcept{ 62 | return false; 63 | } 64 | 65 | #pragma mark primitives 66 | uint64_t JBPrimitive::read64(kptr_t kaddr){ 67 | uint64_t retval = 0; 68 | if (hasReadGeneric()) { 69 | size_t didread = read_generic(kaddr, &retval, sizeof(retval));; 70 | retcustomassure(JBException_incomplete_read_or_write, didread == sizeof(retval), "read64-generic read returned %zu (!= 8) bytes",didread); 71 | }else if (hasRead32()){ 72 | uint32_t *r = (uint32_t*)&retval; 73 | r[0] = read32(kaddr); 74 | r[1] = read32(kaddr + sizeof(uint32_t)); 75 | }else{ 76 | retcustomerror(JBException_primitive_unavailable, "read is not implemented by the primitive"); 77 | } 78 | return retval; 79 | } 80 | 81 | uint32_t JBPrimitive::read32(kptr_t kaddr){ 82 | uint32_t retval = 0; 83 | if (hasReadGeneric()) { 84 | size_t didread = read_generic(kaddr, &retval, sizeof(retval));; 85 | retcustomassure(JBException_incomplete_read_or_write, didread == sizeof(retval), "read32-generic read returned %zu (!= 4) bytes",didread); 86 | }else if (hasRead64()){ 87 | uint64_t r = read64(kaddr); 88 | retval = (uint32_t)r; 89 | }else{ 90 | retcustomerror(JBException_primitive_unavailable, "read is not implemented by the primitive"); 91 | } 92 | return retval; 93 | } 94 | 95 | size_t JBPrimitive::read_generic(kptr_t kaddr, void *dstbuf, size_t size, BOOLEAN honorSizeLimit){ 96 | bool hasr64 = hasRead64(); 97 | bool hasr32 = hasRead32(); 98 | size_t didRead = 0; 99 | uint8_t *dst = (uint8_t*)dstbuf; 100 | 101 | retcustomassure(JBException_primitive_unavailable, hasr64 || hasr32, "read is not implemented by the primitive"); 102 | 103 | if (hasr64) { 104 | while (size - didRead > sizeof(uint64_t)) { 105 | uint64_t r = read64(kaddr + didRead); 106 | memcpy(&dst[didRead], &r, sizeof(r)); 107 | didRead += sizeof(r); 108 | } 109 | } 110 | 111 | if (hasr32) { 112 | while (size - didRead > sizeof(uint32_t)) { 113 | uint32_t r = read32(kaddr + didRead); 114 | memcpy(&dst[didRead], &r, sizeof(r)); 115 | didRead += sizeof(r); 116 | } 117 | } 118 | 119 | if (honorSizeLimit) return didRead; 120 | 121 | //we will perform an overread and return only as much bytes as requested 122 | size_t reminder = size - didRead; 123 | 124 | if (hasr64 && (reminder > sizeof(uint32_t) || !hasr32)) { 125 | uint64_t r = read64(kaddr + didRead); 126 | memcpy(&dst[didRead], &r, reminder); 127 | didRead += reminder; 128 | }else if (hasr32){ 129 | 130 | if (reminder > sizeof(uint32_t)) reminder = sizeof(reminder); 131 | 132 | { 133 | uint32_t r = read32(kaddr + didRead); 134 | memcpy(&dst[didRead], &r, reminder); 135 | didRead += reminder; 136 | } 137 | 138 | reminder = size - didRead; 139 | if (reminder > sizeof(uint32_t)) reminder = sizeof(reminder); 140 | 141 | if (reminder){ 142 | uint32_t r = read32(kaddr + didRead); 143 | memcpy(&dst[didRead], &r, reminder); 144 | didRead += reminder; 145 | } 146 | } 147 | 148 | return didRead; 149 | } 150 | 151 | void JBPrimitive::write64(kptr_t kaddr, uint64_t val){ 152 | if (hasWriteGeneric()) { 153 | size_t didwrite = write_generic(kaddr, &val, sizeof(val)); 154 | retcustomassure(JBException_incomplete_read_or_write, didwrite == sizeof(val), "write64-generic read returned %zu (!= 8) bytes",didwrite); 155 | }else if (hasWrite32()){ 156 | uint32_t *r = (uint32_t*)&val; 157 | write32(kaddr, r[0]); 158 | write32(kaddr + sizeof(uint32_t), r[1]); 159 | }else{ 160 | retcustomerror(JBException_primitive_unavailable, "write is not implemented by the primitive"); 161 | } 162 | } 163 | 164 | void JBPrimitive::write32(kptr_t kaddr, uint32_t val){ 165 | if (hasWriteGeneric()) { 166 | size_t didwrite = write_generic(kaddr, &val, sizeof(val)); 167 | retcustomassure(JBException_incomplete_read_or_write, didwrite == sizeof(val), "write32-generic read returned %zu (!= 4) bytes",didwrite); 168 | }else if (hasWrite64()){ 169 | uint64_t r = read64(kaddr); 170 | *(uint32_t*)r = val; 171 | write64(kaddr, r); 172 | }else{ 173 | retcustomerror(JBException_primitive_unavailable, "write is not implemented by the primitive"); 174 | } 175 | } 176 | 177 | size_t JBPrimitive::write_generic(kptr_t kaddr, const void *srcbuf, size_t size, BOOLEAN honorSizeLimit){ 178 | bool hasw64 = hasWrite64(); 179 | bool hasw32 = hasWrite32(); 180 | size_t didWrite = 0; 181 | const uint8_t *src = (const uint8_t*)srcbuf; 182 | 183 | retcustomassure(JBException_primitive_unavailable, hasw64 || hasw32, "write is not implemented by the primitive"); 184 | 185 | if (hasw64) { 186 | while (size - didWrite > sizeof(uint64_t)) { 187 | uint64_t w = 0; 188 | memcpy(&w, &src[didWrite], sizeof(w)); 189 | write64(kaddr + didWrite, w); 190 | didWrite += sizeof(w); 191 | } 192 | } 193 | 194 | if (hasw32) { 195 | while (size - didWrite > sizeof(uint64_t)) { 196 | uint32_t w = 0; 197 | memcpy(&w, &src[didWrite], sizeof(w)); 198 | write32(kaddr + didWrite, w); 199 | didWrite += sizeof(w); 200 | } 201 | } 202 | 203 | if (honorSizeLimit) return didWrite; 204 | 205 | //we will perform an overwrite with previously read back bytes 206 | size_t reminder = size - didWrite; 207 | 208 | if (hasw64 && (reminder > sizeof(uint32_t) || !hasw32)) { 209 | uint64_t w = read64(kaddr + didWrite); 210 | memcpy(&w, &src[didWrite], reminder); 211 | write64(kaddr + didWrite, w); 212 | didWrite += reminder; 213 | }else if (hasw32){ 214 | 215 | if (reminder > sizeof(uint32_t)) reminder = sizeof(reminder); 216 | { 217 | uint32_t w = read32(kaddr + didWrite); 218 | memcpy(&w, &src[didWrite], reminder); 219 | write32(kaddr + didWrite, w); 220 | didWrite += reminder; 221 | } 222 | 223 | reminder = size - didWrite; 224 | if (reminder > sizeof(uint32_t)) reminder = sizeof(reminder); 225 | 226 | if (reminder) { 227 | uint32_t w = read32(kaddr + didWrite); 228 | memcpy(&w, &src[didWrite], reminder); 229 | write32(kaddr + didWrite, w); 230 | didWrite += reminder; 231 | } 232 | } 233 | 234 | return didWrite; 235 | } 236 | 237 | kptr_t JBPrimitive::execute(kptr_t kaddr, callargs_t args){ 238 | retcustomerror(JBException_primitive_unavailable, "execute is not implemented by the primitive"); 239 | } 240 | 241 | kptr_t JBPrimitive::getKernelBase(){ 242 | retcustomerror(JBException_primitive_unavailable, "getKernelBase is not implemented by the primitive"); 243 | } 244 | 245 | #pragma mark transfer 246 | void JBPrimitive::sendPrimitive(mach_port_t dst){ 247 | retcustomerror(JBException_primitive_unavailable, "sendPrimitive is not implemented by the primitive"); 248 | } 249 | 250 | void JBPrimitive::recvPrimitive(mach_port_t src){ 251 | retcustomerror(JBException_primitive_unavailable, "recvPrimitive is not implemented by the primitive"); 252 | } 253 | 254 | #pragma mark static 255 | static std::map gPrimitives; 256 | static std::mutex gPrimitivesLck; 257 | void JBPrimitive::registerPrimitive(JBPrimitive *prim) noexcept { 258 | std::unique_lock ul(gPrimitivesLck); 259 | auto old = gPrimitives.find(prim->primitiveName()); 260 | if (old != gPrimitives.end()){ 261 | JBPrimitive *olde = old->second; 262 | gPrimitives.erase(old); 263 | safeDelete(olde); 264 | } 265 | gPrimitives[prim->primitiveName()] = prim; 266 | } 267 | 268 | JBPrimitive *JBPrimitive::getPrimitiveWithName(const char *name) noexcept{ 269 | std::unique_lock ul(gPrimitivesLck); 270 | try { 271 | return gPrimitives.at(name); 272 | } catch (...) { 273 | return NULL; 274 | } 275 | } 276 | 277 | std::vector JBPrimitive::listRegisteredPrimitives() noexcept{ 278 | std::unique_lock ul(gPrimitivesLck); 279 | std::vector ret; 280 | for (auto p : gPrimitives) { 281 | ret.push_back(p.first); 282 | } 283 | return ret; 284 | } 285 | -------------------------------------------------------------------------------- /JBKit/JBPrimitive.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // JBPrimitive.hpp 3 | // JBKit 4 | // 5 | // Created by tihmstar on 08.01.24. 6 | // 7 | 8 | #ifndef JBPrimitive_hpp 9 | #define JBPrimitive_hpp 10 | #ifdef __cplusplus 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | namespace JBKit { 19 | 20 | class JBPrimitive{ 21 | 22 | public: 23 | JBPrimitive(); 24 | virtual ~JBPrimitive(); 25 | 26 | #pragma mark public exploit init/cleanup 27 | virtual bool initPrimitive(JBOffsets offsets, readfunc_t func_read, writefunc_t func_write, execfunc_t func_exec = NULL) = 0; 28 | virtual void cleanupPrimitive() = 0; 29 | 30 | #pragma mark infos 31 | virtual const char *primitiveName() = 0; 32 | 33 | #pragma mark availability infos 34 | bool hasRead() const noexcept; 35 | bool hasWrite() const noexcept; 36 | virtual bool hasRead64() const noexcept; 37 | virtual bool hasRead32() const noexcept; 38 | virtual bool hasReadGeneric() const noexcept; 39 | virtual bool hasWrite64() const noexcept; 40 | virtual bool hasWrite32() const noexcept; 41 | virtual bool hasWriteGeneric() const noexcept; 42 | virtual bool hasExecute() const noexcept; 43 | 44 | #pragma mark primitives 45 | virtual uint64_t read64(kptr_t kaddr); 46 | virtual uint32_t read32(kptr_t kaddr); 47 | virtual size_t read_generic(kptr_t kaddr, void *dstbuf, size_t size, BOOLEAN honorSizeLimit = FALSE); 48 | 49 | virtual void write64(kptr_t kaddr, uint64_t val); 50 | virtual void write32(kptr_t kaddr, uint32_t val); 51 | virtual size_t write_generic(kptr_t kaddr, const void *srcbuf, size_t size, BOOLEAN honorSizeLimit = FALSE); 52 | 53 | virtual kptr_t execute(kptr_t kaddr, callargs_t args = {}); 54 | 55 | virtual kptr_t getKernelBase(); 56 | 57 | #pragma mark transfer 58 | virtual void sendPrimitive(mach_port_t dst); //port with send right 59 | virtual void recvPrimitive(mach_port_t src); //port with recv right 60 | 61 | #pragma mark static 62 | static void registerPrimitive(JBPrimitive *prim) noexcept; 63 | static JBPrimitive *getPrimitiveWithName(const char *name) noexcept; 64 | static std::vector listRegisteredPrimitives() noexcept; 65 | }; 66 | 67 | } 68 | 69 | #endif //__cplusplus 70 | #endif /* JBPrimitive_hpp */ 71 | -------------------------------------------------------------------------------- /JBKit/JBPrimitive_c.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // JBPrimitive_c.cpp 3 | // JBKit 4 | // 5 | // Created by tihmstar on 08.01.24. 6 | // 7 | 8 | #include "JBPrimitive_c.h" 9 | #include "JBPrimitive.hpp" 10 | 11 | using namespace JBKit; 12 | 13 | #pragma mark get primitive 14 | 15 | extern "C" 16 | char **JBPrimitive_getRegisteredPrimitivesList(){ 17 | char **retval = NULL; 18 | std::vector list; 19 | try { 20 | list = JBPrimitive::listRegisteredPrimitives(); 21 | } catch (...) { 22 | return NULL; 23 | } 24 | retval = (char**)calloc(list.size()+1, sizeof(char*)); 25 | { 26 | char **ri = retval; 27 | for (auto e : list) { 28 | *ri++ = strdup(e.c_str()); 29 | } 30 | } 31 | return retval; 32 | } 33 | 34 | extern "C" 35 | void JBPrimitive_freeRegisteredPrimitivesList(char **list){ 36 | for (char **ri = list; *ri; ri++) { 37 | free(*ri); 38 | } 39 | free(list); 40 | } 41 | 42 | extern "C" 43 | JBPrimitive_ctx_t JBPrimitive_getPrimitiveWithName(const char *name){ 44 | try { 45 | return (JBPrimitive_ctx_t)JBPrimitive::getPrimitiveWithName(name); 46 | } catch (...) { 47 | return NULL; 48 | } 49 | } 50 | 51 | #pragma mark use #pragma mark use exploit 52 | 53 | extern "C" 54 | int JBPrimitive_primitive_initPrimitive(JBPrimitive_ctx_t ctx, JBOffset_ctx_t offsets, readfunc_t func_read, writefunc_t func_write, execfunc_t func_exec){ 55 | JBPrimitive *obj = (JBPrimitive *)ctx; 56 | JBOffsets *obj_offsets = (JBOffsets *)offsets; 57 | 58 | try { 59 | return obj->initPrimitive(*obj_offsets, func_read, func_write, func_exec) ? 0 : -2; 60 | } catch (...) { 61 | return -1; 62 | } 63 | } 64 | 65 | extern "C" 66 | int JBPrimitive_primitive_cleanupPrimitive(JBPrimitive_ctx_t ctx){ 67 | JBPrimitive *obj = (JBPrimitive *)ctx; 68 | try { 69 | obj->cleanupPrimitive(); 70 | return 0; 71 | } catch (...) { 72 | return -1; 73 | } 74 | } 75 | 76 | extern "C" 77 | const char * JBPrimitive_primitive_primitiveName(JBPrimitive_ctx_t ctx){ 78 | JBPrimitive *obj = (JBPrimitive *)ctx; 79 | try { 80 | return obj->primitiveName(); 81 | } catch (...) { 82 | return NULL; 83 | } 84 | } 85 | 86 | extern "C" 87 | BOOLEAN JBPrimitive_primitive_hasRead(JBPrimitive_ctx_t ctx){ 88 | JBPrimitive *obj = (JBPrimitive *)ctx; 89 | try { 90 | return obj->hasRead(); 91 | } catch (...) { 92 | return false; 93 | } 94 | } 95 | 96 | extern "C" 97 | BOOLEAN JBPrimitive_primitive_hasWrite(JBPrimitive_ctx_t ctx){ 98 | JBPrimitive *obj = (JBPrimitive *)ctx; 99 | try { 100 | return obj->hasWrite(); 101 | } catch (...) { 102 | return false; 103 | } 104 | } 105 | 106 | extern "C" 107 | BOOLEAN JBPrimitive_primitive_hasRead64(JBPrimitive_ctx_t ctx){ 108 | JBPrimitive *obj = (JBPrimitive *)ctx; 109 | try { 110 | return obj->hasRead64(); 111 | } catch (...) { 112 | return false; 113 | } 114 | } 115 | 116 | extern "C" 117 | BOOLEAN JBPrimitive_primitive_hasRead32(JBPrimitive_ctx_t ctx){ 118 | JBPrimitive *obj = (JBPrimitive *)ctx; 119 | try { 120 | return obj->hasRead32(); 121 | } catch (...) { 122 | return false; 123 | } 124 | } 125 | 126 | extern "C" 127 | BOOLEAN JBPrimitive_primitive_hasReadGeneric(JBPrimitive_ctx_t ctx){ 128 | JBPrimitive *obj = (JBPrimitive *)ctx; 129 | try { 130 | return obj->hasReadGeneric(); 131 | } catch (...) { 132 | return false; 133 | } 134 | } 135 | 136 | extern "C" 137 | BOOLEAN JBPrimitive_primitive_hasWrite64(JBPrimitive_ctx_t ctx){ 138 | JBPrimitive *obj = (JBPrimitive *)ctx; 139 | try { 140 | return obj->hasWrite64(); 141 | } catch (...) { 142 | return false; 143 | } 144 | } 145 | 146 | extern "C" 147 | BOOLEAN JBPrimitive_primitive_hasWrite32(JBPrimitive_ctx_t ctx){ 148 | JBPrimitive *obj = (JBPrimitive *)ctx; 149 | try { 150 | return obj->hasWrite32(); 151 | } catch (...) { 152 | return false; 153 | } 154 | } 155 | 156 | extern "C" 157 | BOOLEAN JBPrimitive_primitive_hasWriteGeneric(JBPrimitive_ctx_t ctx){ 158 | JBPrimitive *obj = (JBPrimitive *)ctx; 159 | try { 160 | return obj->hasWriteGeneric(); 161 | } catch (...) { 162 | return false; 163 | } 164 | } 165 | 166 | extern "C" 167 | BOOLEAN JBPrimitive_primitive_hasExecute(JBPrimitive_ctx_t ctx){ 168 | JBPrimitive *obj = (JBPrimitive *)ctx; 169 | try { 170 | return obj->hasExecute(); 171 | } catch (...) { 172 | return false; 173 | } 174 | } 175 | 176 | extern "C" 177 | int JBPrimitive_primitive_sendPrimitive(JBPrimitive_ctx_t ctx, mach_port_t dst){ 178 | JBPrimitive *obj = (JBPrimitive *)ctx; 179 | try { 180 | obj->sendPrimitive(dst); 181 | return 0; 182 | } catch (...) { 183 | return -1; 184 | } 185 | } 186 | 187 | extern "C" 188 | int JBPrimitive_primitive_recvPrimitive(JBPrimitive_ctx_t ctx, mach_port_t src){ 189 | JBPrimitive *obj = (JBPrimitive *)ctx; 190 | try { 191 | obj->recvPrimitive(src); 192 | return 0; 193 | } catch (...) { 194 | return -1; 195 | } 196 | } 197 | 198 | extern "C" 199 | uint64_t JBPrimitive_primitive_read64(JBPrimitive_ctx_t ctx, kptr_t kaddr){ 200 | JBPrimitive *obj = (JBPrimitive *)ctx; 201 | try { 202 | return obj->read64(kaddr); 203 | } catch (...) { 204 | return 0; 205 | } 206 | } 207 | 208 | extern "C" 209 | uint32_t JBPrimitive_primitive_read32(JBPrimitive_ctx_t ctx, kptr_t kaddr){ 210 | JBPrimitive *obj = (JBPrimitive *)ctx; 211 | try { 212 | return obj->read32(kaddr); 213 | } catch (...) { 214 | return 0; 215 | } 216 | } 217 | 218 | extern "C" 219 | size_t JBPrimitive_primitive_read_generic(JBPrimitive_ctx_t ctx, kptr_t kaddr, void *dstbuf, size_t size, BOOLEAN honorSizeLimit){ 220 | JBPrimitive *obj = (JBPrimitive *)ctx; 221 | try { 222 | return obj->read_generic(kaddr, dstbuf, size, honorSizeLimit); 223 | } catch (...) { 224 | return 0; 225 | } 226 | } 227 | 228 | extern "C" 229 | int JBPrimitive_primitive_write64(JBPrimitive_ctx_t ctx, kptr_t kaddr, uint64_t val){ 230 | JBPrimitive *obj = (JBPrimitive *)ctx; 231 | try { 232 | obj->write64(kaddr,val); 233 | return 0; 234 | } catch (...) { 235 | return -1; 236 | } 237 | } 238 | 239 | extern "C" 240 | int JBPrimitive_primitive_write32(JBPrimitive_ctx_t ctx, kptr_t kaddr, uint32_t val){ 241 | JBPrimitive *obj = (JBPrimitive *)ctx; 242 | try { 243 | obj->write32(kaddr,val); 244 | return 0; 245 | } catch (...) { 246 | return -1; 247 | } 248 | } 249 | 250 | extern "C" 251 | size_t JBPrimitive_primitive_write_generic(JBPrimitive_ctx_t ctx, kptr_t kaddr, const void *srcbuf, size_t size, BOOLEAN honorSizeLimit){ 252 | JBPrimitive *obj = (JBPrimitive *)ctx; 253 | try { 254 | return obj->write_generic(kaddr, srcbuf, size, honorSizeLimit); 255 | } catch (...) { 256 | return 0; 257 | } 258 | } 259 | 260 | extern "C" 261 | kptr_t JBPrimitive_primitive_execute(JBPrimitive_ctx_t ctx, kptr_t kaddr, callargs_t args){ 262 | JBPrimitive *obj = (JBPrimitive *)ctx; 263 | try { 264 | return obj->execute(kaddr,args); 265 | } catch (...) { 266 | return 0; 267 | } 268 | } 269 | 270 | extern "C" 271 | kptr_t JBPrimitive_primitive_getKernelBase(JBPrimitive_ctx_t ctx){ 272 | JBPrimitive *obj = (JBPrimitive *)ctx; 273 | try { 274 | return obj->getKernelBase(); 275 | } catch (...) { 276 | return 0; 277 | } 278 | } 279 | -------------------------------------------------------------------------------- /JBKit/JBPrimitive_c.h: -------------------------------------------------------------------------------- 1 | // 2 | // JBPrimitive_c.hpp 3 | // JBKit 4 | // 5 | // Created by tihmstar on 08.01.24. 6 | // 7 | 8 | #ifndef JBPrimitive_c_h 9 | #define JBPrimitive_c_h 10 | 11 | #include 12 | 13 | #ifdef __cplusplus 14 | extern "C" { 15 | #endif //__cplusplus 16 | 17 | typedef void* JBPrimitive_ctx_t; 18 | 19 | #pragma mark get primitive 20 | 21 | /* 22 | Return: 23 | returns a null terminated list of char * 24 | caller needs to pass it to JBPrimitive_freeRegisteredPrimitivesList to free resources 25 | */ 26 | char **JBPrimitive_getRegisteredPrimitivesList(); 27 | void JBPrimitive_freeRegisteredPrimitivesList(char **list); 28 | 29 | JBPrimitive_ctx_t JBPrimitive_getPrimitiveWithName(const char *name); 30 | 31 | #pragma mark use #pragma mark use exploit 32 | int JBPrimitive_primitive_initPrimitive(JBPrimitive_ctx_t ctx, JBOffset_ctx_t offsets, readfunc_t func_read, writefunc_t func_write, execfunc_t func_exec); 33 | int JBPrimitive_primitive_cleanupPrimitive(JBPrimitive_ctx_t ctx); 34 | 35 | const char * JBPrimitive_primitive_primitiveName(JBPrimitive_ctx_t ctx); 36 | 37 | BOOLEAN JBPrimitive_primitive_hasRead(JBPrimitive_ctx_t ctx); 38 | BOOLEAN JBPrimitive_primitive_hasWrite(JBPrimitive_ctx_t ctx); 39 | BOOLEAN JBPrimitive_primitive_hasRead64(JBPrimitive_ctx_t ctx); 40 | BOOLEAN JBPrimitive_primitive_hasRead32(JBPrimitive_ctx_t ctx); 41 | BOOLEAN JBPrimitive_primitive_hasReadGeneric(JBPrimitive_ctx_t ctx); 42 | BOOLEAN JBPrimitive_primitive_hasWrite64(JBPrimitive_ctx_t ctx); 43 | BOOLEAN JBPrimitive_primitive_hasWrite32(JBPrimitive_ctx_t ctx); 44 | BOOLEAN JBPrimitive_primitive_hasWriteGeneric(JBPrimitive_ctx_t ctx); 45 | BOOLEAN JBPrimitive_primitive_hasExecute(JBPrimitive_ctx_t ctx); 46 | 47 | int JBPrimitive_primitive_sendPrimitive(JBPrimitive_ctx_t ctx, mach_port_t dst); //port with send right 48 | int JBPrimitive_primitive_recvPrimitive(JBPrimitive_ctx_t ctx, mach_port_t src); //port with recv right 49 | 50 | uint64_t JBPrimitive_primitive_read64(JBPrimitive_ctx_t ctx, kptr_t kaddr); 51 | uint32_t JBPrimitive_primitive_read32(JBPrimitive_ctx_t ctx, kptr_t kaddr); 52 | size_t JBPrimitive_primitive_read_generic(JBPrimitive_ctx_t ctx, kptr_t kaddr, void *dstbuf, size_t size, BOOLEAN honorSizeLimit); 53 | 54 | int JBPrimitive_primitive_write64(JBPrimitive_ctx_t ctx, kptr_t kaddr, uint64_t val); 55 | int JBPrimitive_primitive_write32(JBPrimitive_ctx_t ctx, kptr_t kaddr, uint32_t val); 56 | size_t JBPrimitive_primitive_write_generic(JBPrimitive_ctx_t ctx, kptr_t kaddr, const void *srcbuf, size_t size, BOOLEAN honorSizeLimit); 57 | 58 | kptr_t JBPrimitive_primitive_execute(JBPrimitive_ctx_t ctx, kptr_t kaddr, callargs_t args); 59 | 60 | kptr_t JBPrimitive_primitive_getKernelBase(JBPrimitive_ctx_t ctx); 61 | 62 | #ifdef __cplusplus 63 | }; 64 | #endif //__cplusplus 65 | #endif /* JBPrimitive_c_h */ 66 | -------------------------------------------------------------------------------- /JBKit/JBTypes.h: -------------------------------------------------------------------------------- 1 | // 2 | // JBTypes.h 3 | // JBKit 4 | // 5 | // Created by tihmstar on 08.01.24. 6 | // 7 | 8 | #ifndef JBTypes_h 9 | #define JBTypes_h 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif //__cplusplus 14 | 15 | #include 16 | #include 17 | 18 | typedef uint64_t kptr_t; 19 | typedef int BOOLEAN; 20 | #define TRUE 1 21 | #define FALSE 0 22 | 23 | typedef struct{ 24 | kptr_t args[32]; 25 | } callargs_t; 26 | 27 | typedef size_t readfunc_t(kptr_t kaddr, void *dstbuf, size_t size, BOOLEAN honorSizeLimit); 28 | typedef size_t writefunc_t(kptr_t kaddr, const void *srcbuf, size_t size, BOOLEAN honorSizeLimit); 29 | typedef kptr_t execfunc_t(kptr_t kaddr, callargs_t args); 30 | 31 | #ifdef __cplusplus 32 | }; 33 | #endif //__cplusplus 34 | #endif /* JBTypes_h */ 35 | -------------------------------------------------------------------------------- /include/launch.h: -------------------------------------------------------------------------------- 1 | #ifndef __XPC_LAUNCH_H__ 2 | #define __XPC_LAUNCH_H__ 3 | 4 | /*! 5 | * @header 6 | * These interfaces were only ever documented for the purpose of allowing a 7 | * launchd job to obtain file descriptors associated with the sockets it 8 | * advertised in its launchd.plist(5). That functionality is now available in a 9 | * much more straightforward fashion through the {@link launch_activate_socket} 10 | * API. 11 | * 12 | * There are currently no replacements for other uses of the {@link launch_msg} 13 | * API, including submitting, removing, starting, stopping and listing jobs. 14 | */ 15 | 16 | #include 17 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #if __has_feature(assume_nonnull) 25 | _Pragma("clang assume_nonnull begin") 26 | #endif 27 | __BEGIN_DECLS 28 | 29 | #define LAUNCH_KEY_SUBMITJOB "SubmitJob" 30 | #define LAUNCH_KEY_REMOVEJOB "RemoveJob" 31 | #define LAUNCH_KEY_STARTJOB "StartJob" 32 | #define LAUNCH_KEY_STOPJOB "StopJob" 33 | #define LAUNCH_KEY_GETJOB "GetJob" 34 | #define LAUNCH_KEY_GETJOBS "GetJobs" 35 | #define LAUNCH_KEY_CHECKIN "CheckIn" 36 | 37 | #define LAUNCH_JOBKEY_LABEL "Label" 38 | #define LAUNCH_JOBKEY_DISABLED "Disabled" 39 | #define LAUNCH_JOBKEY_USERNAME "UserName" 40 | #define LAUNCH_JOBKEY_GROUPNAME "GroupName" 41 | #define LAUNCH_JOBKEY_TIMEOUT "TimeOut" 42 | #define LAUNCH_JOBKEY_EXITTIMEOUT "ExitTimeOut" 43 | #define LAUNCH_JOBKEY_INITGROUPS "InitGroups" 44 | #define LAUNCH_JOBKEY_SOCKETS "Sockets" 45 | #define LAUNCH_JOBKEY_MACHSERVICES "MachServices" 46 | #define LAUNCH_JOBKEY_MACHSERVICELOOKUPPOLICIES "MachServiceLookupPolicies" 47 | #define LAUNCH_JOBKEY_INETDCOMPATIBILITY "inetdCompatibility" 48 | #define LAUNCH_JOBKEY_ENABLEGLOBBING "EnableGlobbing" 49 | #define LAUNCH_JOBKEY_PROGRAMARGUMENTS "ProgramArguments" 50 | #define LAUNCH_JOBKEY_PROGRAM "Program" 51 | #define LAUNCH_JOBKEY_ONDEMAND "OnDemand" 52 | #define LAUNCH_JOBKEY_KEEPALIVE "KeepAlive" 53 | #define LAUNCH_JOBKEY_LIMITLOADTOHOSTS "LimitLoadToHosts" 54 | #define LAUNCH_JOBKEY_LIMITLOADFROMHOSTS "LimitLoadFromHosts" 55 | #define LAUNCH_JOBKEY_LIMITLOADTOSESSIONTYPE "LimitLoadToSessionType" 56 | #define LAUNCH_JOBKEY_LIMITLOADTOHARDWARE "LimitLoadToHardware" 57 | #define LAUNCH_JOBKEY_LIMITLOADFROMHARDWARE "LimitLoadFromHardware" 58 | #define LAUNCH_JOBKEY_RUNATLOAD "RunAtLoad" 59 | #define LAUNCH_JOBKEY_ROOTDIRECTORY "RootDirectory" 60 | #define LAUNCH_JOBKEY_WORKINGDIRECTORY "WorkingDirectory" 61 | #define LAUNCH_JOBKEY_ENVIRONMENTVARIABLES "EnvironmentVariables" 62 | #define LAUNCH_JOBKEY_USERENVIRONMENTVARIABLES "UserEnvironmentVariables" 63 | #define LAUNCH_JOBKEY_UMASK "Umask" 64 | #define LAUNCH_JOBKEY_NICE "Nice" 65 | #define LAUNCH_JOBKEY_HOPEFULLYEXITSFIRST "HopefullyExitsFirst" 66 | #define LAUNCH_JOBKEY_HOPEFULLYEXITSLAST "HopefullyExitsLast" 67 | #define LAUNCH_JOBKEY_LOWPRIORITYIO "LowPriorityIO" 68 | #define LAUNCH_JOBKEY_LOWPRIORITYBACKGROUNDIO "LowPriorityBackgroundIO" 69 | #define LAUNCH_JOBKEY_MATERIALIZEDATALESSFILES "MaterializeDatalessFiles" 70 | #define LAUNCH_JOBKEY_SESSIONCREATE "SessionCreate" 71 | #define LAUNCH_JOBKEY_STARTONMOUNT "StartOnMount" 72 | #define LAUNCH_JOBKEY_SOFTRESOURCELIMITS "SoftResourceLimits" 73 | #define LAUNCH_JOBKEY_HARDRESOURCELIMITS "HardResourceLimits" 74 | #define LAUNCH_JOBKEY_STANDARDINPATH "StandardInPath" 75 | #define LAUNCH_JOBKEY_STANDARDOUTPATH "StandardOutPath" 76 | #define LAUNCH_JOBKEY_STANDARDERRORPATH "StandardErrorPath" 77 | #define LAUNCH_JOBKEY_DEBUG "Debug" 78 | #define LAUNCH_JOBKEY_WAITFORDEBUGGER "WaitForDebugger" 79 | #define LAUNCH_JOBKEY_QUEUEDIRECTORIES "QueueDirectories" 80 | #define LAUNCH_JOBKEY_HOMERELATIVEQUEUEDIRECTORIES "HomeRelativeQueueDirectories" 81 | #define LAUNCH_JOBKEY_WATCHPATHS "WatchPaths" 82 | #define LAUNCH_JOBKEY_STARTINTERVAL "StartInterval" 83 | #define LAUNCH_JOBKEY_STARTCALENDARINTERVAL "StartCalendarInterval" 84 | #define LAUNCH_JOBKEY_BONJOURFDS "BonjourFDs" 85 | #define LAUNCH_JOBKEY_LASTEXITSTATUS "LastExitStatus" 86 | #define LAUNCH_JOBKEY_PID "PID" 87 | #define LAUNCH_JOBKEY_THROTTLEINTERVAL "ThrottleInterval" 88 | #define LAUNCH_JOBKEY_LAUNCHONLYONCE "LaunchOnlyOnce" 89 | #define LAUNCH_JOBKEY_ABANDONPROCESSGROUP "AbandonProcessGroup" 90 | #define LAUNCH_JOBKEY_IGNOREPROCESSGROUPATSHUTDOWN \ 91 | "IgnoreProcessGroupAtShutdown" 92 | #define LAUNCH_JOBKEY_LEGACYTIMERS "LegacyTimers" 93 | #define LAUNCH_JOBKEY_ENABLEPRESSUREDEXIT "EnablePressuredExit" 94 | #define LAUNCH_JOBKEY_ENABLETRANSACTIONS "EnableTransactions" 95 | #define LAUNCH_JOBKEY_DRAINMESSAGESONFAILEDINIT "DrainMessagesOnFailedInit" 96 | #define LAUNCH_JOBKEY_POLICIES "Policies" 97 | #define LAUNCH_JOBKEY_BUNDLEPROGRAM "BundleProgram" 98 | #define LAUNCH_JOBKEY_ASSOCIATEDBUNDLEIDENTIFIERS "AssociatedBundleIdentifiers" 99 | 100 | #define LAUNCH_JOBKEY_PUBLISHESEVENTS "PublishesEvents" 101 | #define LAUNCH_KEY_PUBLISHESEVENTS_DOMAININTERNAL "DomainInternal" 102 | 103 | #define LAUNCH_JOBPOLICY_DENYCREATINGOTHERJOBS "DenyCreatingOtherJobs" 104 | 105 | #define LAUNCH_JOBINETDCOMPATIBILITY_WAIT "Wait" 106 | #define LAUNCH_JOBINETDCOMPATIBILITY_INSTANCES "Instances" 107 | 108 | #define LAUNCH_JOBKEY_MACH_RESETATCLOSE "ResetAtClose" 109 | #define LAUNCH_JOBKEY_MACH_HIDEUNTILCHECKIN "HideUntilCheckIn" 110 | 111 | #define LAUNCH_JOBKEY_KEEPALIVE_SUCCESSFULEXIT "SuccessfulExit" 112 | #define LAUNCH_JOBKEY_KEEPALIVE_NETWORKSTATE "NetworkState" 113 | #define LAUNCH_JOBKEY_KEEPALIVE_PATHSTATE "PathState" 114 | #define LAUNCH_JOBKEY_KEEPALIVE_HOMERELATIVEPATHSTATE "HomeRelativePathState" 115 | #define LAUNCH_JOBKEY_KEEPALIVE_OTHERJOBACTIVE "OtherJobActive" 116 | #define LAUNCH_JOBKEY_KEEPALIVE_OTHERJOBENABLED "OtherJobEnabled" 117 | #define LAUNCH_JOBKEY_KEEPALIVE_AFTERINITIALDEMAND "AfterInitialDemand" 118 | #define LAUNCH_JOBKEY_KEEPALIVE_CRASHED "Crashed" 119 | 120 | #define LAUNCH_JOBKEY_LAUNCHEVENTS "LaunchEvents" 121 | 122 | #define LAUNCH_JOBKEY_CAL_MINUTE "Minute" 123 | #define LAUNCH_JOBKEY_CAL_HOUR "Hour" 124 | #define LAUNCH_JOBKEY_CAL_DAY "Day" 125 | #define LAUNCH_JOBKEY_CAL_WEEKDAY "Weekday" 126 | #define LAUNCH_JOBKEY_CAL_MONTH "Month" 127 | 128 | #define LAUNCH_JOBKEY_RESOURCELIMIT_CORE "Core" 129 | #define LAUNCH_JOBKEY_RESOURCELIMIT_CPU "CPU" 130 | #define LAUNCH_JOBKEY_RESOURCELIMIT_DATA "Data" 131 | #define LAUNCH_JOBKEY_RESOURCELIMIT_FSIZE "FileSize" 132 | #define LAUNCH_JOBKEY_RESOURCELIMIT_MEMLOCK "MemoryLock" 133 | #define LAUNCH_JOBKEY_RESOURCELIMIT_NOFILE "NumberOfFiles" 134 | #define LAUNCH_JOBKEY_RESOURCELIMIT_NPROC "NumberOfProcesses" 135 | #define LAUNCH_JOBKEY_RESOURCELIMIT_RSS "ResidentSetSize" 136 | #define LAUNCH_JOBKEY_RESOURCELIMIT_STACK "Stack" 137 | 138 | #define LAUNCH_JOBKEY_DISABLED_MACHINETYPE "MachineType" 139 | #define LAUNCH_JOBKEY_DISABLED_MODELNAME "ModelName" 140 | 141 | #define LAUNCH_JOBKEY_DATASTORES "Datastores" 142 | #define LAUNCH_JOBKEY_DATASTORES_SIZELIMIT "SizeLimit" 143 | 144 | #define LAUNCH_JOBSOCKETKEY_TYPE "SockType" 145 | #define LAUNCH_JOBSOCKETKEY_PASSIVE "SockPassive" 146 | #define LAUNCH_JOBSOCKETKEY_BONJOUR "Bonjour" 147 | #define LAUNCH_JOBSOCKETKEY_SECUREWITHKEY "SecureSocketWithKey" 148 | #define LAUNCH_JOBSOCKETKEY_PATHNAME "SockPathName" 149 | #define LAUNCH_JOBSOCKETKEY_PATHMODE "SockPathMode" 150 | #define LAUNCH_JOBSOCKETKEY_PATHOWNER "SockPathOwner" 151 | #define LAUNCH_JOBSOCKETKEY_PATHGROUP "SockPathGroup" 152 | #define LAUNCH_JOBSOCKETKEY_NODENAME "SockNodeName" 153 | #define LAUNCH_JOBSOCKETKEY_SERVICENAME "SockServiceName" 154 | #define LAUNCH_JOBSOCKETKEY_FAMILY "SockFamily" 155 | #define LAUNCH_JOBSOCKETKEY_PROTOCOL "SockProtocol" 156 | #define LAUNCH_JOBSOCKETKEY_MULTICASTGROUP "MulticastGroup" 157 | 158 | #define LAUNCH_JOBKEY_PROCESSTYPE "ProcessType" 159 | #define LAUNCH_KEY_PROCESSTYPE_APP "App" 160 | #define LAUNCH_KEY_PROCESSTYPE_STANDARD "Standard" 161 | #define LAUNCH_KEY_PROCESSTYPE_BACKGROUND "Background" 162 | #define LAUNCH_KEY_PROCESSTYPE_INTERACTIVE "Interactive" 163 | #define LAUNCH_KEY_PROCESSTYPE_ADAPTIVE "Adaptive" 164 | 165 | /*! 166 | * @function launch_activate_socket 167 | * 168 | * @abstract 169 | * Retrieves the file descriptors for sockets specified in the process' 170 | * launchd.plist(5). 171 | * 172 | * @param name 173 | * The name of the socket entry in the service's Sockets dictionary. 174 | * 175 | * @param fds 176 | * On return, this parameter will be populated with an array of file 177 | * descriptors. One socket can have many descriptors associated with it 178 | * depending on the characteristics of the network interfaces on the system. 179 | * The descriptors in this array are the results of calling getaddrinfo(3) with 180 | * the parameters described in launchd.plist(5). 181 | * 182 | * The caller is responsible for calling free(3) on the returned pointer. 183 | * 184 | * @param cnt 185 | * The number of file descriptor entries in the returned array. 186 | * 187 | * @result 188 | * On success, zero is returned. Otherwise, an appropriate POSIX-domain is 189 | * returned. Possible error codes are: 190 | * 191 | * ENOENT -> There was no socket of the specified name owned by the caller. 192 | * ESRCH -> The caller is not a process managed by launchd. 193 | * EALREADY -> The socket has already been activated by the caller. 194 | */ 195 | __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0) 196 | OS_EXPORT OS_WARN_RESULT OS_NONNULL1 OS_NONNULL2 OS_NONNULL3 197 | int 198 | launch_activate_socket(const char *name, 199 | int * _Nonnull * _Nullable fds, size_t *cnt); 200 | 201 | typedef struct _launch_data *launch_data_t; 202 | typedef void (*launch_data_dict_iterator_t)(const launch_data_t lval, 203 | const char *key, void * _Nullable ctx); 204 | 205 | typedef enum { 206 | LAUNCH_DATA_DICTIONARY = 1, 207 | LAUNCH_DATA_ARRAY, 208 | LAUNCH_DATA_FD, 209 | LAUNCH_DATA_INTEGER, 210 | LAUNCH_DATA_REAL, 211 | LAUNCH_DATA_BOOL, 212 | LAUNCH_DATA_STRING, 213 | LAUNCH_DATA_OPAQUE, 214 | LAUNCH_DATA_ERRNO, 215 | LAUNCH_DATA_MACHPORT, 216 | } launch_data_type_t; 217 | 218 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 219 | OS_EXPORT OS_MALLOC OS_WARN_RESULT 220 | launch_data_t 221 | launch_data_alloc(launch_data_type_t type); 222 | 223 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 224 | OS_EXPORT OS_MALLOC OS_WARN_RESULT OS_NONNULL1 225 | launch_data_t 226 | launch_data_copy(launch_data_t ld); 227 | 228 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 229 | OS_EXPORT OS_WARN_RESULT OS_NONNULL1 230 | launch_data_type_t 231 | launch_data_get_type(const launch_data_t ld); 232 | 233 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 234 | OS_EXPORT OS_NONNULL1 235 | void 236 | launch_data_free(launch_data_t ld); 237 | 238 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 239 | OS_EXPORT OS_NONNULL1 OS_NONNULL2 OS_NONNULL3 240 | bool 241 | launch_data_dict_insert(launch_data_t ldict, const launch_data_t lval, 242 | const char *key); 243 | 244 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 245 | OS_EXPORT OS_WARN_RESULT OS_NONNULL1 OS_NONNULL2 246 | launch_data_t _Nullable 247 | launch_data_dict_lookup(const launch_data_t ldict, const char *key); 248 | 249 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 250 | OS_EXPORT OS_NONNULL1 OS_NONNULL2 251 | bool 252 | launch_data_dict_remove(launch_data_t ldict, const char *key); 253 | 254 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 255 | OS_EXPORT OS_NONNULL1 OS_NONNULL2 256 | void 257 | launch_data_dict_iterate(const launch_data_t ldict, 258 | launch_data_dict_iterator_t iterator, void * _Nullable ctx); 259 | 260 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 261 | OS_EXPORT OS_WARN_RESULT OS_NONNULL1 262 | size_t 263 | launch_data_dict_get_count(const launch_data_t ldict); 264 | 265 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 266 | OS_EXPORT OS_NONNULL1 OS_NONNULL2 267 | bool 268 | launch_data_array_set_index(launch_data_t larray, const launch_data_t lval, 269 | size_t idx); 270 | 271 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 272 | OS_EXPORT OS_WARN_RESULT OS_NONNULL1 273 | launch_data_t 274 | launch_data_array_get_index(const launch_data_t larray, size_t idx); 275 | 276 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 277 | OS_EXPORT OS_WARN_RESULT OS_NONNULL1 278 | size_t 279 | launch_data_array_get_count(const launch_data_t larray); 280 | 281 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 282 | OS_EXPORT OS_MALLOC OS_WARN_RESULT 283 | launch_data_t 284 | launch_data_new_fd(int fd); 285 | 286 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 287 | OS_EXPORT OS_MALLOC OS_WARN_RESULT 288 | launch_data_t 289 | launch_data_new_machport(mach_port_t val); 290 | 291 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 292 | OS_EXPORT OS_MALLOC OS_WARN_RESULT 293 | launch_data_t 294 | launch_data_new_integer(long long val); 295 | 296 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 297 | OS_EXPORT OS_MALLOC OS_WARN_RESULT 298 | launch_data_t 299 | launch_data_new_bool(bool val); 300 | 301 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 302 | OS_EXPORT OS_MALLOC OS_WARN_RESULT 303 | launch_data_t 304 | launch_data_new_real(double val); 305 | 306 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 307 | OS_EXPORT OS_MALLOC OS_WARN_RESULT 308 | launch_data_t 309 | launch_data_new_string(const char *val); 310 | 311 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 312 | OS_EXPORT OS_MALLOC OS_WARN_RESULT 313 | launch_data_t 314 | launch_data_new_opaque(const void *bytes, size_t sz); 315 | 316 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 317 | OS_EXPORT OS_NONNULL1 318 | bool 319 | launch_data_set_fd(launch_data_t ld, int fd); 320 | 321 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 322 | OS_EXPORT OS_NONNULL1 323 | bool 324 | launch_data_set_machport(launch_data_t ld, mach_port_t mp); 325 | 326 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 327 | OS_EXPORT OS_NONNULL1 328 | bool 329 | launch_data_set_integer(launch_data_t ld, long long val); 330 | 331 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 332 | OS_EXPORT OS_NONNULL1 333 | bool 334 | launch_data_set_bool(launch_data_t ld, bool val); 335 | 336 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 337 | OS_EXPORT OS_NONNULL1 338 | bool 339 | launch_data_set_real(launch_data_t ld, double val); 340 | 341 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 342 | OS_EXPORT OS_NONNULL1 343 | bool 344 | launch_data_set_string(launch_data_t ld, const char *val); 345 | 346 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 347 | OS_EXPORT OS_NONNULL1 348 | bool 349 | launch_data_set_opaque(launch_data_t ld, const void *bytes, size_t sz); 350 | 351 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 352 | OS_EXPORT OS_WARN_RESULT OS_NONNULL1 353 | int 354 | launch_data_get_fd(const launch_data_t ld); 355 | 356 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 357 | OS_EXPORT OS_WARN_RESULT OS_NONNULL1 358 | mach_port_t 359 | launch_data_get_machport(const launch_data_t ld); 360 | 361 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 362 | OS_EXPORT OS_WARN_RESULT OS_NONNULL1 363 | long long 364 | launch_data_get_integer(const launch_data_t ld); 365 | 366 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 367 | OS_EXPORT OS_WARN_RESULT OS_NONNULL1 368 | bool 369 | launch_data_get_bool(const launch_data_t ld); 370 | 371 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 372 | OS_EXPORT OS_WARN_RESULT OS_NONNULL1 373 | double 374 | launch_data_get_real(const launch_data_t ld); 375 | 376 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 377 | OS_EXPORT OS_WARN_RESULT OS_NONNULL1 378 | const char * 379 | launch_data_get_string(const launch_data_t ld); 380 | 381 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 382 | OS_EXPORT OS_WARN_RESULT OS_NONNULL1 383 | void * _Nullable 384 | launch_data_get_opaque(const launch_data_t ld); 385 | 386 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 387 | OS_EXPORT OS_WARN_RESULT OS_NONNULL1 388 | size_t 389 | launch_data_get_opaque_size(const launch_data_t ld); 390 | 391 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 392 | OS_EXPORT OS_WARN_RESULT OS_NONNULL1 393 | int 394 | launch_data_get_errno(const launch_data_t ld); 395 | 396 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 397 | OS_EXPORT OS_WARN_RESULT 398 | int 399 | launch_get_fd(void); 400 | 401 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 402 | OS_EXPORT OS_MALLOC OS_WARN_RESULT OS_NONNULL1 403 | launch_data_t 404 | launch_msg(const launch_data_t request); 405 | 406 | __END_DECLS 407 | #if __has_feature(assume_nonnull) 408 | _Pragma("clang assume_nonnull end") 409 | #endif 410 | 411 | #endif // __XPC_LAUNCH_H__ 412 | -------------------------------------------------------------------------------- /include/xpc/XPC.apinotes: -------------------------------------------------------------------------------- 1 | Name: XPC 2 | Functions: 3 | # xpc_object 4 | - Name: xpc_retain 5 | Availability: nonswift 6 | - Name: xpc_release 7 | Availability: nonswift 8 | -------------------------------------------------------------------------------- /include/xpc/activity.h: -------------------------------------------------------------------------------- 1 | #ifndef __XPC_ACTIVITY_H__ 2 | #define __XPC_ACTIVITY_H__ 3 | 4 | #ifndef __XPC_INDIRECT__ 5 | #error "Please #include instead of this file directly." 6 | // For HeaderDoc. 7 | #include 8 | #endif // __XPC_INDIRECT__ 9 | 10 | #ifdef __BLOCKS__ 11 | 12 | XPC_ASSUME_NONNULL_BEGIN 13 | __BEGIN_DECLS 14 | 15 | /* 16 | * The following are a collection of keys and values used to set an activity's 17 | * execution criteria. 18 | */ 19 | 20 | /*! 21 | * @constant XPC_ACTIVITY_INTERVAL 22 | * An integer property indicating the desired time interval (in seconds) of the 23 | * activity. The activity will not be run more than once per time interval. 24 | * Due to the nature of XPC Activity finding an opportune time to run 25 | * the activity, any two occurrences may be more or less than 'interval' 26 | * seconds apart, but on average will be 'interval' seconds apart. 27 | * The presence of this key implies the following, unless overridden: 28 | * - XPC_ACTIVITY_REPEATING with a value of true 29 | * - XPC_ACTIVITY_DELAY with a value of half the 'interval' 30 | * The delay enforces a minimum distance between any two occurrences. 31 | * - XPC_ACTIVITY_GRACE_PERIOD with a value of half the 'interval'. 32 | * The grace period is the amount of time allowed to pass after the end of 33 | * the interval before more aggressive scheduling occurs. The grace period 34 | * does not increase the size of the interval. 35 | */ 36 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 37 | XPC_EXPORT 38 | const char * const XPC_ACTIVITY_INTERVAL; 39 | 40 | /*! 41 | * @constant XPC_ACTIVITY_REPEATING 42 | * A boolean property indicating whether this is a repeating activity. 43 | */ 44 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 45 | XPC_EXPORT 46 | const char * const XPC_ACTIVITY_REPEATING; 47 | 48 | /*! 49 | * @constant XPC_ACTIVITY_DELAY 50 | * An integer property indicating the number of seconds to delay before 51 | * beginning the activity. 52 | */ 53 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 54 | XPC_EXPORT 55 | const char * const XPC_ACTIVITY_DELAY; 56 | 57 | /*! 58 | * @constant XPC_ACTIVITY_GRACE_PERIOD 59 | * An integer property indicating the number of seconds to allow as a grace 60 | * period before the scheduling of the activity becomes more aggressive. 61 | */ 62 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 63 | XPC_EXPORT 64 | const char * const XPC_ACTIVITY_GRACE_PERIOD; 65 | 66 | 67 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 68 | XPC_EXPORT 69 | const int64_t XPC_ACTIVITY_INTERVAL_1_MIN; 70 | 71 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 72 | XPC_EXPORT 73 | const int64_t XPC_ACTIVITY_INTERVAL_5_MIN; 74 | 75 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 76 | XPC_EXPORT 77 | const int64_t XPC_ACTIVITY_INTERVAL_15_MIN; 78 | 79 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 80 | XPC_EXPORT 81 | const int64_t XPC_ACTIVITY_INTERVAL_30_MIN; 82 | 83 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 84 | XPC_EXPORT 85 | const int64_t XPC_ACTIVITY_INTERVAL_1_HOUR; 86 | 87 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 88 | XPC_EXPORT 89 | const int64_t XPC_ACTIVITY_INTERVAL_4_HOURS; 90 | 91 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 92 | XPC_EXPORT 93 | const int64_t XPC_ACTIVITY_INTERVAL_8_HOURS; 94 | 95 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 96 | XPC_EXPORT 97 | const int64_t XPC_ACTIVITY_INTERVAL_1_DAY; 98 | 99 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 100 | XPC_EXPORT 101 | const int64_t XPC_ACTIVITY_INTERVAL_7_DAYS; 102 | 103 | /*! 104 | * @constant XPC_ACTIVITY_PRIORITY 105 | * A string property indicating the priority of the activity. 106 | */ 107 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 108 | XPC_EXPORT 109 | const char * const XPC_ACTIVITY_PRIORITY; 110 | 111 | /*! 112 | * @constant XPC_ACTIVITY_PRIORITY_MAINTENANCE 113 | * A string indicating activity is maintenance priority. 114 | * 115 | * Maintenance priority is intended for user-invisible maintenance tasks 116 | * such as garbage collection or optimization. 117 | * 118 | * Maintenance activities are not permitted to run if the device thermal 119 | * condition exceeds a nominal level or if the battery level is lower than 20%. 120 | * In Low Power Mode (on supported devices), maintenance activities are not 121 | * permitted to run while the device is on battery, or plugged in and the 122 | * battery level is lower than 30%. 123 | */ 124 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 125 | XPC_EXPORT 126 | const char * const XPC_ACTIVITY_PRIORITY_MAINTENANCE; 127 | 128 | /*! 129 | * @constant XPC_ACTIVITY_PRIORITY_UTILITY 130 | * A string indicating activity is utility priority. 131 | * 132 | * Utility priority is intended for user-visible tasks such as fetching data 133 | * from the network, copying files, or importing data. 134 | * 135 | * Utility activities are not permitted to run if the device thermal condition 136 | * exceeds a moderate level or if the battery level is less than 10%. In Low 137 | * Power Mode (on supported devices) when on battery power, utility activities 138 | * are only permitted when they are close to their deadline (90% of their time 139 | * window has elapsed). 140 | */ 141 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 142 | XPC_EXPORT 143 | const char * const XPC_ACTIVITY_PRIORITY_UTILITY; 144 | 145 | /*! 146 | * @constant XPC_ACTIVITY_ALLOW_BATTERY 147 | * A Boolean value indicating whether the activity should be allowed to run 148 | * while the computer is on battery power. The default value is false for 149 | * maintenance priority activity and true for utility priority activity. 150 | */ 151 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 152 | XPC_EXPORT 153 | const char * const XPC_ACTIVITY_ALLOW_BATTERY; 154 | 155 | /*! 156 | * @constant XPC_ACTIVITY_REQUIRE_SCREEN_SLEEP 157 | * A Boolean value indicating whether the activity should only be performed 158 | * while device appears to be asleep. Note that the definition of screen sleep 159 | * may vary by platform and may include states where the device is known to be 160 | * idle despite the fact that the display itself is still powered. Defaults to 161 | * false. 162 | */ 163 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 164 | XPC_EXPORT 165 | const char * const XPC_ACTIVITY_REQUIRE_SCREEN_SLEEP; // bool 166 | 167 | /*! 168 | * @constant XPC_ACTIVITY_PREVENT_DEVICE_SLEEP 169 | * A Boolean value indicating whether the activity should prevent system sleep while 170 | * running on battery. 171 | * If this property is set, the activity scheduler will take the appropriate power 172 | * assertion to keep the device (but not the screen) awake while the activity is running. 173 | * Only activities which perform critical system functions that do not want to be 174 | * interrupted by system sleep should set this. 175 | * Setting this property can impact battery life. 176 | */ 177 | __API_AVAILABLE(macos(12.0), ios(15.0), watchos(8.0)) 178 | XPC_EXPORT 179 | const char * const XPC_ACTIVITY_PREVENT_DEVICE_SLEEP; // bool 180 | 181 | /*! 182 | * @constant XPC_ACTIVITY_REQUIRE_BATTERY_LEVEL 183 | * An integer percentage of minimum battery charge required to allow the 184 | * activity to run. A default minimum battery level is determined by the 185 | * system. 186 | */ 187 | __OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_10_9, __MAC_10_9, __IPHONE_7_0, __IPHONE_7_0, 188 | "REQUIRE_BATTERY_LEVEL is not implemented") 189 | XPC_EXPORT 190 | const char * const XPC_ACTIVITY_REQUIRE_BATTERY_LEVEL; // int (%) 191 | 192 | /*! 193 | * @constant XPC_ACTIVITY_REQUIRE_HDD_SPINNING 194 | * A Boolean value indicating whether the activity should only be performed 195 | * while the hard disk drive (HDD) is spinning. Computers with flash storage 196 | * are considered to be equivalent to HDD spinning. Defaults to false. 197 | */ 198 | __OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_10_9, __MAC_10_9, __IPHONE_7_0, __IPHONE_7_0, 199 | "REQUIRE_HDD_SPINNING is not implemented") 200 | XPC_EXPORT 201 | const char * const XPC_ACTIVITY_REQUIRE_HDD_SPINNING; // bool 202 | 203 | /*! 204 | * @define XPC_TYPE_ACTIVITY 205 | * A type representing the XPC activity object. 206 | */ 207 | #define XPC_TYPE_ACTIVITY (&_xpc_type_activity) 208 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 209 | XPC_EXPORT 210 | XPC_TYPE(_xpc_type_activity); 211 | 212 | /*! 213 | * @typedef xpc_activity_t 214 | * 215 | * @abstract 216 | * An XPC activity object. 217 | * 218 | * @discussion 219 | * This object represents a set of execution criteria and a current execution 220 | * state for background activity on the system. Once an activity is registered, 221 | * the system will evaluate its criteria to determine whether the activity is 222 | * eligible to run under current system conditions. When an activity becomes 223 | * eligible to run, its execution state will be updated and an invocation of 224 | * its handler block will be made. 225 | */ 226 | XPC_DECL(xpc_activity); 227 | 228 | /*! 229 | * @typedef xpc_activity_handler_t 230 | * 231 | * @abstract 232 | * A block that is called when an XPC activity becomes eligible to run. 233 | */ 234 | XPC_NONNULL1 235 | typedef void (^xpc_activity_handler_t)(xpc_activity_t activity); 236 | 237 | /*! 238 | * @constant XPC_ACTIVITY_CHECK_IN 239 | * This constant may be passed to xpc_activity_register() as the criteria 240 | * dictionary in order to check in with the system for previously registered 241 | * activity using the same identifier (for example, an activity taken from a 242 | * launchd property list). 243 | */ 244 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 245 | XPC_EXPORT 246 | const xpc_object_t XPC_ACTIVITY_CHECK_IN; 247 | 248 | /*! 249 | * @function xpc_activity_register 250 | * 251 | * @abstract 252 | * Registers an activity with the system. 253 | * 254 | * @discussion 255 | * Registers a new activity with the system. The criteria of the activity are 256 | * described by the dictionary passed to this function. If an activity with the 257 | * same identifier already exists, the criteria provided override the existing 258 | * criteria unless the special dictionary XPC_ACTIVITY_CHECK_IN is used. The 259 | * XPC_ACTIVITY_CHECK_IN dictionary instructs the system to first look up an 260 | * existing activity without modifying its criteria. Once the existing activity 261 | * is found (or a new one is created with an empty set of criteria) the handler 262 | * will be called with an activity object in the XPC_ACTIVITY_STATE_CHECK_IN 263 | * state. 264 | * 265 | * @param identifier 266 | * A unique identifier for the activity. Each application has its own namespace. 267 | * The identifier should remain constant across registrations, relaunches of 268 | * the application, and reboots. It should identify the kind of work being done, 269 | * not a particular invocation of the work. 270 | * 271 | * @param criteria 272 | * A dictionary of criteria for the activity. 273 | * 274 | * @param handler 275 | * The handler block to be called when the activity changes state to one of the 276 | * following states: 277 | * - XPC_ACTIVITY_STATE_CHECK_IN (optional) 278 | * - XPC_ACTIVITY_STATE_RUN 279 | * 280 | * The handler block is never invoked reentrantly. It will be invoked on a 281 | * dispatch queue with an appropriate priority to perform the activity. 282 | */ 283 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 284 | XPC_EXPORT XPC_NONNULL1 XPC_NONNULL2 XPC_NONNULL3 285 | void 286 | xpc_activity_register(const char *identifier, xpc_object_t criteria, 287 | xpc_activity_handler_t handler); 288 | 289 | /*! 290 | * @function xpc_activity_copy_criteria 291 | * 292 | * @abstract 293 | * Returns an XPC dictionary describing the execution criteria of an activity. 294 | * This will return NULL in cases where the activity has already completed, e.g. 295 | * when checking in to an event that finished and was not rescheduled. 296 | */ 297 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 298 | XPC_EXPORT XPC_WARN_RESULT XPC_RETURNS_RETAINED XPC_NONNULL1 299 | xpc_object_t _Nullable 300 | xpc_activity_copy_criteria(xpc_activity_t activity); 301 | 302 | /*! 303 | * @function xpc_activity_set_criteria 304 | * 305 | * @abstract 306 | * Modifies the execution criteria of an activity. 307 | */ 308 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 309 | XPC_EXPORT XPC_NONNULL1 XPC_NONNULL2 310 | void 311 | xpc_activity_set_criteria(xpc_activity_t activity, xpc_object_t criteria); 312 | 313 | /*! 314 | * @enum xpc_activity_state_t 315 | * An activity is defined to be in one of the following states. Applications 316 | * may check the current state of the activity using xpc_activity_get_state() 317 | * in the handler block provided to xpc_activity_register(). 318 | * 319 | * The application can modify the state of the activity by calling 320 | * xpc_activity_set_state() with one of the following: 321 | * - XPC_ACTIVITY_STATE_DEFER 322 | * - XPC_ACTIVITY_STATE_CONTINUE 323 | * - XPC_ACTIVITY_STATE_DONE 324 | * 325 | * @constant XPC_ACTIVITY_STATE_CHECK_IN 326 | * An activity in this state has just completed a checkin with the system after 327 | * XPC_ACTIVITY_CHECK_IN was provided as the criteria dictionary to 328 | * xpc_activity_register. The state gives the application an opportunity to 329 | * inspect and modify the activity's criteria. 330 | * 331 | * @constant XPC_ACTIVITY_STATE_WAIT 332 | * An activity in this state is waiting for an opportunity to run. This value 333 | * is never returned within the activity's handler block, as the block is 334 | * invoked in response to XPC_ACTIVITY_STATE_CHECK_IN or XPC_ACTIVITY_STATE_RUN. 335 | * 336 | * Note: 337 | * A launchd job may idle exit while an activity is in the wait state and be 338 | * relaunched in response to the activity becoming runnable. The launchd job 339 | * simply needs to re-register for the activity on its next launch by passing 340 | * XPC_ACTIVITY_STATE_CHECK_IN to xpc_activity_register(). 341 | * 342 | * @constant XPC_ACTIVITY_STATE_RUN 343 | * An activity in this state is eligible to run based on its criteria. 344 | * 345 | * @constant XPC_ACTIVITY_STATE_DEFER 346 | * An application may pass this value to xpc_activity_set_state() to indicate 347 | * that the activity should be deferred (placed back into the WAIT state) until 348 | * a time when its criteria are met again. Deferring an activity does not reset 349 | * any of its time-based criteria (in other words, it will remain past due). 350 | * 351 | * IMPORTANT: 352 | * This should be done in response to observing xpc_activity_should_defer(). 353 | * It should not be done unilaterally. If you determine that conditions are bad 354 | * to do your activity's work for reasons you can't express in a criteria 355 | * dictionary, you should set the activity's state to XPC_ACTIVITY_STATE_DONE. 356 | * 357 | * 358 | * @constant XPC_ACTIVITY_STATE_CONTINUE 359 | * An application may pass this value to xpc_activity_set_state() to indicate 360 | * that the activity will continue its operation beyond the return of its 361 | * handler block. This can be used to extend an activity to include asynchronous 362 | * operations. The activity's handler block will not be invoked again until the 363 | * state has been updated to either XPC_ACTIVITY_STATE_DEFER or, in the case 364 | * of repeating activity, XPC_ACTIVITY_STATE_DONE. 365 | * 366 | * @constant XPC_ACTIVITY_STATE_DONE 367 | * An application may pass this value to xpc_activity_set_state() to indicate 368 | * that the activity has completed. For non-repeating activity, the resources 369 | * associated with the activity will be automatically released upon return from 370 | * the handler block. For repeating activity, timers present in the activity's 371 | * criteria will be reset. 372 | */ 373 | enum { 374 | XPC_ACTIVITY_STATE_CHECK_IN, 375 | XPC_ACTIVITY_STATE_WAIT, 376 | XPC_ACTIVITY_STATE_RUN, 377 | XPC_ACTIVITY_STATE_DEFER, 378 | XPC_ACTIVITY_STATE_CONTINUE, 379 | XPC_ACTIVITY_STATE_DONE, 380 | }; 381 | typedef long xpc_activity_state_t; 382 | 383 | /*! 384 | * @function xpc_activity_get_state 385 | * 386 | * @abstract 387 | * Returns the current state of an activity. 388 | */ 389 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 390 | XPC_EXPORT XPC_WARN_RESULT XPC_NONNULL1 391 | xpc_activity_state_t 392 | xpc_activity_get_state(xpc_activity_t activity); 393 | 394 | /*! 395 | * @function xpc_activity_set_state 396 | * 397 | * @abstract 398 | * Updates the current state of an activity. 399 | * 400 | * @return 401 | * Returns true if the state was successfully updated; otherwise, returns 402 | * false if the requested state transition is not valid. 403 | */ 404 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 405 | XPC_EXPORT XPC_WARN_RESULT XPC_NONNULL1 406 | bool 407 | xpc_activity_set_state(xpc_activity_t activity, xpc_activity_state_t state); 408 | 409 | /*! 410 | * @function xpc_activity_should_defer 411 | * 412 | * @abstract 413 | * Test whether an activity should be deferred. 414 | * 415 | * @discussion 416 | * This function may be used to test whether the criteria of a long-running 417 | * activity are still satisfied. If not, the system indicates that the 418 | * application should defer the activity. The application may acknowledge the 419 | * deferral by calling xpc_activity_set_state() with XPC_ACTIVITY_STATE_DEFER. 420 | * Once deferred, the system will place the activity back into the WAIT state 421 | * and re-invoke the handler block at the earliest opportunity when the criteria 422 | * are once again satisfied. 423 | * 424 | * @return 425 | * Returns true if the activity should be deferred. 426 | */ 427 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 428 | XPC_EXPORT XPC_WARN_RESULT XPC_NONNULL1 429 | bool 430 | xpc_activity_should_defer(xpc_activity_t activity); 431 | 432 | /*! 433 | * @function xpc_activity_unregister 434 | * 435 | * @abstract 436 | * Unregisters an activity found by its identifier. 437 | * 438 | * @discussion 439 | * A dynamically registered activity will be deleted in response to this call. 440 | * Statically registered activity (from a launchd property list) will be 441 | * deleted until the job is next loaded (e.g. at next boot). 442 | * 443 | * Unregistering an activity has no effect on any outstanding xpc_activity_t 444 | * objects or any currently executing xpc_activity_handler_t blocks; however, 445 | * no new handler block invocations will be made after it is unregistered. 446 | * 447 | * @param identifier 448 | * The identifier of the activity to unregister. 449 | */ 450 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 451 | XPC_EXPORT XPC_NONNULL1 452 | void 453 | xpc_activity_unregister(const char *identifier); 454 | 455 | __END_DECLS 456 | XPC_ASSUME_NONNULL_END 457 | 458 | #endif // __BLOCKS__ 459 | 460 | #endif // __XPC_ACTIVITY_H__ 461 | 462 | -------------------------------------------------------------------------------- /include/xpc/availability.h: -------------------------------------------------------------------------------- 1 | #ifndef __XPC_AVAILABILITY_H__ 2 | #define __XPC_AVAILABILITY_H__ 3 | 4 | #include 5 | 6 | // Certain parts of the project use all the project's headers but have to build 7 | // against newer OSX SDKs than ebuild uses -- liblaunch_host being the example. 8 | // So we need to define these. 9 | #ifndef __MAC_10_16 10 | #define __MAC_10_16 101600 11 | #endif // __MAC_10_16 12 | 13 | #ifndef __MAC_10_15 14 | #define __MAC_10_15 101500 15 | #define __AVAILABILITY_INTERNAL__MAC_10_15 \ 16 | __attribute__((availability(macosx, introduced=10.15))) 17 | #endif // __MAC_10_15 18 | 19 | #ifndef __MAC_10_14 20 | #define __MAC_10_14 101400 21 | #define __AVAILABILITY_INTERNAL__MAC_10_14 \ 22 | __attribute__((availability(macosx, introduced=10.14))) 23 | #endif // __MAC_10_14 24 | 25 | #ifndef __MAC_10_13 26 | #define __MAC_10_13 101300 27 | #define __AVAILABILITY_INTERNAL__MAC_10_13 \ 28 | __attribute__((availability(macosx, introduced=10.13))) 29 | #endif // __MAC_10_13 30 | 31 | #ifndef __MAC_10_12 32 | #define __MAC_10_12 101200 33 | #define __AVAILABILITY_INTERNAL__MAC_10_12 \ 34 | __attribute__((availability(macosx, introduced=10.12))) 35 | #endif // __MAC_10_12 36 | 37 | #ifndef __MAC_10_11 38 | #define __MAC_10_11 101100 39 | #define __AVAILABILITY_INTERNAL__MAC_10_11 \ 40 | __attribute__((availability(macosx, introduced=10.11))) 41 | #endif // __MAC_10_11 42 | 43 | #ifndef __MAC_12_0 44 | #define __MAC_12_0 120000 45 | #define __AVAILABILITY_INTERNAL__MAC_12_0 \ 46 | __attribute__((availability(macosx, introduced=12.0))) 47 | #endif // __MAC_12_0 48 | 49 | #ifndef __MAC_13_3 50 | #define __MAC_13_3 130300 51 | #endif // __MAC_13_3 52 | 53 | #ifndef __AVAILABILITY_INTERNAL__MAC_10_2_DEP__MAC_10_11 54 | #define __AVAILABILITY_INTERNAL__MAC_10_2_DEP__MAC_10_11 55 | #endif // __AVAILABILITY_INTERNAL__MAC_10_2_DEP__MAC_10_11 56 | 57 | #ifndef __AVAILABILITY_INTERNAL__MAC_10_3_DEP__MAC_10_11 58 | #define __AVAILABILITY_INTERNAL__MAC_10_3_DEP__MAC_10_11 59 | #endif // __AVAILABILITY_INTERNAL__MAC_10_3_DEP__MAC_10_11 60 | 61 | #ifndef __AVAILABILITY_INTERNAL__MAC_10_4_DEP__MAC_10_11 62 | #define __AVAILABILITY_INTERNAL__MAC_10_4_DEP__MAC_10_11 63 | #endif // __AVAILABILITY_INTERNAL__MAC_10_4_DEP__MAC_10_11 64 | 65 | #ifndef __AVAILABILITY_INTERNAL__MAC_10_5_DEP__MAC_10_11 66 | #define __AVAILABILITY_INTERNAL__MAC_10_5_DEP__MAC_10_11 67 | #endif // __AVAILABILITY_INTERNAL__MAC_10_5_DEP__MAC_10_11 68 | 69 | #ifndef __AVAILABILITY_INTERNAL__MAC_10_6_DEP__MAC_10_11 70 | #define __AVAILABILITY_INTERNAL__MAC_10_6_DEP__MAC_10_11 71 | #endif // __AVAILABILITY_INTERNAL__MAC_10_6_DEP__MAC_10_11 72 | 73 | #ifndef __AVAILABILITY_INTERNAL__MAC_10_7_DEP__MAC_10_11 74 | #define __AVAILABILITY_INTERNAL__MAC_10_7_DEP__MAC_10_11 75 | #endif // __AVAILABILITY_INTERNAL__MAC_10_7_DEP__MAC_10_11 76 | 77 | #ifndef __AVAILABILITY_INTERNAL__MAC_10_8_DEP__MAC_10_11 78 | #define __AVAILABILITY_INTERNAL__MAC_10_8_DEP__MAC_10_11 79 | #endif // __AVAILABILITY_INTERNAL__MAC_10_8_DEP__MAC_10_11 80 | 81 | #ifndef __AVAILABILITY_INTERNAL__MAC_10_9_DEP__MAC_10_11 82 | #define __AVAILABILITY_INTERNAL__MAC_10_9_DEP__MAC_10_11 83 | #endif // __AVAILABILITY_INTERNAL__MAC_10_9_DEP__MAC_10_11 84 | 85 | #ifndef __AVAILABILITY_INTERNAL__MAC_10_10_DEP__MAC_10_11 86 | #define __AVAILABILITY_INTERNAL__MAC_10_10_DEP__MAC_10_11 87 | #endif // __AVAILABILITY_INTERNAL__MAC_10_10_DEP__MAC_10_11 88 | 89 | #ifndef __AVAILABILITY_INTERNAL__MAC_10_11_DEP__MAC_10_11 90 | #define __AVAILABILITY_INTERNAL__MAC_10_11_DEP__MAC_10_11 91 | #endif // __AVAILABILITY_INTERNAL__MAC_10_11_DEP__MAC_10_11 92 | 93 | #ifndef __AVAILABILITY_INTERNAL__MAC_10_6_DEP__MAC_10_13 94 | #define __AVAILABILITY_INTERNAL__MAC_10_6_DEP__MAC_10_13 95 | #endif // __AVAILABILITY_INTERNAL__MAC_10_6_DEP__MAC_10_13 96 | 97 | #if __has_include() 98 | #include 99 | #else // __has_include() 100 | #ifndef IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED 101 | #define IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED 999999 102 | #endif // IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED 103 | #endif // __has_include() 104 | 105 | #ifndef __WATCHOS_UNAVAILABLE 106 | #define __WATCHOS_UNAVAILABLE 107 | #endif 108 | 109 | #ifndef __TVOS_UNAVAILABLE 110 | #define __TVOS_UNAVAILABLE 111 | #endif 112 | 113 | // simulator host-side bits build against SDKs not having __*_AVAILABLE() yet 114 | #ifndef __OSX_AVAILABLE 115 | #define __OSX_AVAILABLE(...) 116 | #endif 117 | 118 | #ifndef __IOS_AVAILABLE 119 | #define __IOS_AVAILABLE(...) 120 | #endif 121 | 122 | #ifndef __TVOS_AVAILABLE 123 | #define __TVOS_AVAILABLE(...) 124 | #endif 125 | 126 | #ifndef __WATCHOS_AVAILABLE 127 | #define __WATCHOS_AVAILABLE(...) 128 | #endif 129 | 130 | #ifndef __API_AVAILABLE 131 | #define __API_AVAILABLE(...) 132 | #endif 133 | 134 | #endif // __XPC_AVAILABILITY_H__ 135 | -------------------------------------------------------------------------------- /include/xpc/base.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2011 Apple Inc. All rights reserved. 2 | 3 | #ifndef __XPC_BASE_H__ 4 | #define __XPC_BASE_H__ 5 | 6 | #include 7 | 8 | __BEGIN_DECLS 9 | 10 | #if !defined(__has_include) 11 | #define __has_include(x) 0 12 | #endif // !defined(__has_include) 13 | 14 | #if !defined(__has_attribute) 15 | #define __has_attribute(x) 0 16 | #endif // !defined(__has_attribute) 17 | 18 | #if !defined(__has_feature) 19 | #define __has_feature(x) 0 20 | #endif // !defined(__has_feature) 21 | 22 | #if !defined(__has_extension) 23 | #define __has_extension(x) 0 24 | #endif // !defined(__has_extension) 25 | 26 | #if __has_include() 27 | #include 28 | #else // __has_include() 29 | #include 30 | #endif // __has_include() 31 | 32 | #include 33 | 34 | #ifndef __XPC_INDIRECT__ 35 | #error "Please #include instead of this file directly." 36 | #endif // __XPC_INDIRECT__ 37 | 38 | #pragma mark Attribute Shims 39 | #ifdef __GNUC__ 40 | #define XPC_CONSTRUCTOR __attribute__((constructor)) 41 | #define XPC_NORETURN __attribute__((__noreturn__)) 42 | #define XPC_NOTHROW __attribute__((__nothrow__)) 43 | #define XPC_NONNULL1 __attribute__((__nonnull__(1))) 44 | #define XPC_NONNULL2 __attribute__((__nonnull__(2))) 45 | #define XPC_NONNULL3 __attribute__((__nonnull__(3))) 46 | #define XPC_NONNULL4 __attribute__((__nonnull__(4))) 47 | #define XPC_NONNULL5 __attribute__((__nonnull__(5))) 48 | #define XPC_NONNULL6 __attribute__((__nonnull__(6))) 49 | #define XPC_NONNULL7 __attribute__((__nonnull__(7))) 50 | #define XPC_NONNULL8 __attribute__((__nonnull__(8))) 51 | #define XPC_NONNULL9 __attribute__((__nonnull__(9))) 52 | #define XPC_NONNULL10 __attribute__((__nonnull__(10))) 53 | #define XPC_NONNULL11 __attribute__((__nonnull__(11))) 54 | #define XPC_NONNULL_ALL __attribute__((__nonnull__)) 55 | #define XPC_SENTINEL __attribute__((__sentinel__)) 56 | #define XPC_PURE __attribute__((__pure__)) 57 | #define XPC_WARN_RESULT __attribute__((__warn_unused_result__)) 58 | #define XPC_MALLOC __attribute__((__malloc__)) 59 | #define XPC_UNUSED __attribute__((__unused__)) 60 | #define XPC_USED __attribute__((__used__)) 61 | #define XPC_PACKED __attribute__((__packed__)) 62 | #define XPC_PRINTF(m, n) __attribute__((format(printf, m, n))) 63 | #define XPC_INLINE static __inline__ __attribute__((__always_inline__)) 64 | #define XPC_NOINLINE __attribute__((noinline)) 65 | #define XPC_NOIMPL __attribute__((unavailable)) 66 | 67 | #if __has_attribute(noescape) 68 | #define XPC_NOESCAPE __attribute__((__noescape__)) 69 | #else 70 | #define XPC_NOESCAPE 71 | #endif 72 | 73 | #if __has_extension(attribute_unavailable_with_message) 74 | #define XPC_UNAVAILABLE(m) __attribute__((unavailable(m))) 75 | #else // __has_extension(attribute_unavailable_with_message) 76 | #define XPC_UNAVAILABLE(m) XPC_NOIMPL 77 | #endif // __has_extension(attribute_unavailable_with_message) 78 | 79 | #define XPC_EXPORT extern __attribute__((visibility("default"))) 80 | #define XPC_NOEXPORT __attribute__((visibility("hidden"))) 81 | #define XPC_WEAKIMPORT extern __attribute__((weak_import)) 82 | #define XPC_DEBUGGER_EXCL XPC_NOEXPORT XPC_USED 83 | #define XPC_TRANSPARENT_UNION __attribute__((transparent_union)) 84 | #if __clang__ 85 | #define XPC_DEPRECATED(m) __attribute__((deprecated(m))) 86 | #else // __clang__ 87 | #define XPC_DEPRECATED(m) __attribute__((deprecated)) 88 | #endif // __clang 89 | #ifndef XPC_TESTEXPORT 90 | #define XPC_TESTEXPORT XPC_NOEXPORT 91 | #endif // XPC_TESTEXPORT 92 | 93 | #if defined(__XPC_TEST__) && __XPC_TEST__ 94 | #define XPC_TESTSTATIC 95 | #define XPC_TESTEXTERN extern 96 | #else // defined(__XPC_TEST__) && __XPC_TEST__ 97 | #define XPC_TESTSTATIC static 98 | #endif // defined(__XPC_TEST__) && __XPC_TEST__ 99 | 100 | #if __has_feature(objc_arc) 101 | #define XPC_GIVES_REFERENCE __strong 102 | #define XPC_UNRETAINED __unsafe_unretained 103 | #define XPC_BRIDGE(xo) ((__bridge void *)(xo)) 104 | #define XPC_BRIDGEREF_BEGIN(xo) ((__bridge_retained void *)(xo)) 105 | #define XPC_BRIDGEREF_BEGIN_WITH_REF(xo) ((__bridge void *)(xo)) 106 | #define XPC_BRIDGEREF_MIDDLE(xo) ((__bridge id)(xo)) 107 | #define XPC_BRIDGEREF_END(xo) ((__bridge_transfer id)(xo)) 108 | #else // __has_feature(objc_arc) 109 | #define XPC_GIVES_REFERENCE 110 | #define XPC_UNRETAINED 111 | #define XPC_BRIDGE(xo) (xo) 112 | #define XPC_BRIDGEREF_BEGIN(xo) (xo) 113 | #define XPC_BRIDGEREF_BEGIN_WITH_REF(xo) (xo) 114 | #define XPC_BRIDGEREF_MIDDLE(xo) (xo) 115 | #define XPC_BRIDGEREF_END(xo) (xo) 116 | #endif // __has_feature(objc_arc) 117 | 118 | #define _xpc_unreachable() __builtin_unreachable() 119 | #else // __GNUC__ 120 | /*! @parseOnly */ 121 | #define XPC_CONSTRUCTOR 122 | /*! @parseOnly */ 123 | #define XPC_NORETURN 124 | /*! @parseOnly */ 125 | #define XPC_NOTHROW 126 | /*! @parseOnly */ 127 | #define XPC_NONNULL1 128 | /*! @parseOnly */ 129 | #define XPC_NONNULL2 130 | /*! @parseOnly */ 131 | #define XPC_NONNULL3 132 | /*! @parseOnly */ 133 | #define XPC_NONNULL4 134 | /*! @parseOnly */ 135 | #define XPC_NONNULL5 136 | /*! @parseOnly */ 137 | #define XPC_NONNULL6 138 | /*! @parseOnly */ 139 | #define XPC_NONNULL7 140 | /*! @parseOnly */ 141 | #define XPC_NONNULL8 142 | /*! @parseOnly */ 143 | #define XPC_NONNULL9 144 | /*! @parseOnly */ 145 | #define XPC_NONNULL10 146 | /*! @parseOnly */ 147 | #define XPC_NONNULL11 148 | /*! @parseOnly */ 149 | #define XPC_NONNULL(n) 150 | /*! @parseOnly */ 151 | #define XPC_NONNULL_ALL 152 | /*! @parseOnly */ 153 | #define XPC_SENTINEL 154 | /*! @parseOnly */ 155 | #define XPC_PURE 156 | /*! @parseOnly */ 157 | #define XPC_WARN_RESULT 158 | /*! @parseOnly */ 159 | #define XPC_MALLOC 160 | /*! @parseOnly */ 161 | #define XPC_UNUSED 162 | /*! @parseOnly */ 163 | #define XPC_PACKED 164 | /*! @parseOnly */ 165 | #define XPC_PRINTF(m, n) 166 | /*! @parseOnly */ 167 | #define XPC_INLINE static inline 168 | /*! @parseOnly */ 169 | #define XPC_NOINLINE 170 | /*! @parseOnly */ 171 | #define XPC_NOIMPL 172 | /*! @parseOnly */ 173 | #define XPC_EXPORT extern 174 | /*! @parseOnly */ 175 | #define XPC_WEAKIMPORT 176 | /*! @parseOnly */ 177 | #define XPC_DEPRECATED 178 | /*! @parseOnly */ 179 | #define XPC_UNAVAILABLE(m) 180 | /*! @parseOnly */ 181 | #define XPC_NOESCAPE 182 | #endif // __GNUC__ 183 | 184 | #if __has_feature(assume_nonnull) 185 | #define XPC_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") 186 | #define XPC_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end") 187 | #else 188 | #define XPC_ASSUME_NONNULL_BEGIN 189 | #define XPC_ASSUME_NONNULL_END 190 | #endif 191 | 192 | #if __has_feature(nullability_on_arrays) 193 | #define XPC_NONNULL_ARRAY _Nonnull 194 | #else 195 | #define XPC_NONNULL_ARRAY 196 | #endif 197 | 198 | #if defined(__has_ptrcheck) && __has_ptrcheck 199 | #define XPC_PTR_ASSUMES_SINGLE __ptrcheck_abi_assume_single() 200 | #define XPC_SINGLE __single 201 | #define XPC_UNSAFE_INDEXABLE __unsafe_indexable 202 | #define XPC_CSTRING XPC_UNSAFE_INDEXABLE 203 | #define XPC_SIZEDBY(N) __sized_by(N) 204 | #define XPC_COUNTEDBY(N) __counted_by(N) 205 | #define XPC_UNSAFE_FORGE_SIZED_BY(_type, _ptr, _size) \ 206 | __unsafe_forge_bidi_indexable(_type, _ptr, _size) 207 | #define XPC_UNSAFE_FORGE_SINGLE(_type, _ptr) \ 208 | __unsafe_forge_single(_type, _ptr) 209 | #else // defined(__has_ptrcheck) ** __has_ptrcheck 210 | #define XPC_PTR_ASSUMES_SINGLE 211 | #define XPC_SINGLE 212 | #define XPC_UNSAFE_INDEXABLE 213 | #define XPC_CSTRING 214 | #define XPC_SIZEDBY(N) 215 | #define XPC_COUNTEDBY(N) 216 | #define XPC_UNSAFE_FORGE_SIZED_BY(_type, _ptr, _size) ((_type)(_ptr)) 217 | #define XPC_UNSAFE_FORGE_SINGLE(_type, _ptr) ((_type)(_ptr)) 218 | #endif // defined(__has_ptrcheck) ** __has_ptrcheck 219 | 220 | #ifdef OS_CLOSED_OPTIONS 221 | #define XPC_FLAGS_ENUM(_name, _type, ...) \ 222 | OS_CLOSED_OPTIONS(_name, _type, __VA_ARGS__) 223 | #else // OS_CLOSED_ENUM 224 | #define XPC_FLAGS_ENUM(_name, _type, ...) \ 225 | OS_ENUM(_name, _type, __VA_ARGS__) 226 | #endif // OS_CLOSED_ENUM 227 | 228 | #ifdef OS_CLOSED_ENUM 229 | #define XPC_ENUM(_name, _type, ...) \ 230 | OS_CLOSED_ENUM(_name, _type, __VA_ARGS__) 231 | #else // OS_CLOSED_ENUM 232 | #define XPC_ENUM(_name, _type, ...) \ 233 | OS_ENUM(_name, _type, __VA_ARGS__) 234 | #endif // OS_CLOSED_ENUM 235 | 236 | #if __has_attribute(swift_name) 237 | # define XPC_SWIFT_NAME(_name) __attribute__((swift_name(_name))) 238 | #else 239 | # define XPC_SWIFT_NAME(_name) // __has_attribute(swift_name) 240 | #endif 241 | 242 | __END_DECLS 243 | 244 | #endif // __XPC_BASE_H__ 245 | -------------------------------------------------------------------------------- /include/xpc/connection.h: -------------------------------------------------------------------------------- 1 | #ifndef __XPC_CONNECTION_H__ 2 | #define __XPC_CONNECTION_H__ 3 | 4 | #ifndef __XPC_INDIRECT__ 5 | #error "Please #include instead of this file directly." 6 | // For HeaderDoc. 7 | #include 8 | #endif // __XPC_INDIRECT__ 9 | 10 | #ifndef __BLOCKS__ 11 | #error "XPC connections require Blocks support." 12 | #endif // __BLOCKS__ 13 | 14 | XPC_ASSUME_NONNULL_BEGIN 15 | __BEGIN_DECLS 16 | 17 | /*! 18 | * @constant XPC_ERROR_CONNECTION_INTERRUPTED 19 | * Will be delivered to the connection's event handler if the remote service 20 | * exited. The connection is still live even in this case, and resending a 21 | * message will cause the service to be launched on-demand. This error serves 22 | * as a client's indication that it should resynchronize any state that it had 23 | * given the service. 24 | * 25 | * Any messages in the queue to be sent will be unwound and canceled when this 26 | * error occurs. In the case where a message waiting to be sent has a reply 27 | * handler, that handler will be invoked with this error. In the context of the 28 | * reply handler, this error indicates that a reply to the message will never 29 | * arrive. 30 | * 31 | * Messages that do not have reply handlers associated with them will be 32 | * silently disposed of. This error will only be given to peer connections. 33 | */ 34 | #define XPC_ERROR_CONNECTION_INTERRUPTED \ 35 | XPC_GLOBAL_OBJECT(_xpc_error_connection_interrupted) 36 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 37 | XPC_EXPORT 38 | const struct _xpc_dictionary_s _xpc_error_connection_interrupted; 39 | 40 | /*! 41 | * @constant XPC_ERROR_CONNECTION_INVALID 42 | * Will be delivered to the connection's event handler if the named service 43 | * provided to xpc_connection_create() could not be found in the XPC service 44 | * namespace. The connection is useless and should be disposed of. 45 | * 46 | * Any messages in the queue to be sent will be unwound and canceled when this 47 | * error occurs, similarly to the behavior when XPC_ERROR_CONNECTION_INTERRUPTED 48 | * occurs. The only difference is that the XPC_ERROR_CONNECTION_INVALID will be 49 | * given to outstanding reply handlers and the connection's event handler. 50 | * 51 | * This error may be given to any type of connection. 52 | */ 53 | #define XPC_ERROR_CONNECTION_INVALID \ 54 | XPC_GLOBAL_OBJECT(_xpc_error_connection_invalid) 55 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 56 | XPC_EXPORT 57 | const struct _xpc_dictionary_s _xpc_error_connection_invalid; 58 | 59 | /*! 60 | * @constant XPC_ERROR_TERMINATION_IMMINENT 61 | * On macOS, this error will be delivered to a peer connection's event handler 62 | * when the XPC runtime has determined that the program should exit and that 63 | * all outstanding transactions must be wound down, and no new transactions can 64 | * be opened. 65 | * 66 | * After this error has been delivered to the event handler, no more messages 67 | * will be received by the connection. The runtime will still attempt to deliver 68 | * outgoing messages, but this error should be treated as an indication that 69 | * the program will exit very soon, and any outstanding business over the 70 | * connection should be wrapped up as quickly as possible and the connection 71 | * canceled shortly thereafter. 72 | * 73 | * This error will only be delivered to peer connections received through a 74 | * listener or the xpc_main() event handler. 75 | */ 76 | #define XPC_ERROR_TERMINATION_IMMINENT \ 77 | XPC_GLOBAL_OBJECT(_xpc_error_termination_imminent) 78 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 79 | XPC_EXPORT 80 | const struct _xpc_dictionary_s _xpc_error_termination_imminent; 81 | 82 | /*! 83 | * @constant XPC_ERROR_PEER_CODE_SIGNING_REQUIREMENT 84 | * On macOS, this error will be delivered to a peer connection's event handler 85 | * when the XPC runtime has detected that a peer connection does not 86 | * satisfy the code signing requirement specified for the connection. 87 | * 88 | * See {@link xpc_connection_set_peer_code_signing_requirement} 89 | */ 90 | #define XPC_ERROR_PEER_CODE_SIGNING_REQUIREMENT \ 91 | XPC_GLOBAL_OBJECT(_xpc_error_peer_code_signing_requirement) 92 | __API_AVAILABLE(macos(12.0)) 93 | XPC_EXPORT 94 | const struct _xpc_dictionary_s _xpc_error_peer_code_signing_requirement; 95 | 96 | /*! 97 | * @constant XPC_CONNECTION_MACH_SERVICE_LISTENER 98 | * Passed to xpc_connection_create_mach_service(). This flag indicates that the 99 | * caller is the listener for the named service. This flag may only be passed 100 | * for services which are advertised in the process' launchd.plist(5). You may 101 | * not use this flag to dynamically add services to the Mach bootstrap 102 | * namespace. 103 | */ 104 | #define XPC_CONNECTION_MACH_SERVICE_LISTENER (1 << 0) 105 | 106 | /*! 107 | * @constant XPC_CONNECTION_MACH_SERVICE_PRIVILEGED 108 | * Passed to xpc_connection_create_mach_service(). This flag indicates that the 109 | * job advertising the service name in its launchd.plist(5) should be in the 110 | * privileged Mach bootstrap. This is typically accomplished by placing your 111 | * launchd.plist(5) in /Library/LaunchDaemons. If specified alongside the 112 | * XPC_CONNECTION_MACH_SERVICE_LISTENER flag, this flag is a no-op. 113 | */ 114 | #define XPC_CONNECTION_MACH_SERVICE_PRIVILEGED (1 << 1) 115 | 116 | /*! 117 | * @typedef xpc_finalizer_f 118 | * A function that is invoked when a connection is being torn down and its 119 | * context needs to be freed. The sole argument is the value that was given to 120 | * {@link xpc_connection_set_context} or NULL if no context has been set. It is 121 | * not safe to reference the connection from within this function. 122 | * 123 | * @param value 124 | * The context object that is to be disposed of. 125 | */ 126 | typedef void (*xpc_finalizer_t)(void * _Nullable value); 127 | 128 | /*! 129 | * @function xpc_connection_create 130 | * Creates a new connection object. 131 | * 132 | * @param name 133 | * If non-NULL, the name of the service with which to connect. The returned 134 | * connection will be a peer. 135 | * 136 | * If NULL, an anonymous listener connection will be created. You can embed the 137 | * ability to create new peer connections in an endpoint, which can be inserted 138 | * into a message and sent to another process . 139 | * 140 | * @param targetq 141 | * The GCD queue to which the event handler block will be submitted. This 142 | * parameter may be NULL, in which case the connection's target queue will be 143 | * libdispatch's default target queue, defined as DISPATCH_TARGET_QUEUE_DEFAULT. 144 | * The target queue may be changed later with a call to 145 | * xpc_connection_set_target_queue(). 146 | * 147 | * @result 148 | * A new connection object. The caller is responsible for disposing of the 149 | * returned object with {@link xpc_release} when it is no longer needed. 150 | * 151 | * @discussion 152 | * This method will succeed even if the named service does not exist. This is 153 | * because the XPC namespace is not queried for the service name until the 154 | * connection has been activated. See {@link xpc_connection_activate()}. 155 | * 156 | * XPC connections, like dispatch sources, are returned in an inactive state, so 157 | * you must call {@link xpc_connection_activate()} in order to begin receiving 158 | * events from the connection. Also like dispatch sources, connections must be 159 | * activated and not suspended in order to be safely released. It is 160 | * a programming error to release an inactive or suspended connection. 161 | */ 162 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 163 | XPC_EXPORT XPC_MALLOC XPC_RETURNS_RETAINED XPC_WARN_RESULT 164 | xpc_connection_t 165 | xpc_connection_create(const char * _Nullable name, 166 | dispatch_queue_t _Nullable targetq); 167 | 168 | /*! 169 | * @function xpc_connection_create_mach_service 170 | * Creates a new connection object representing a Mach service. 171 | * 172 | * @param name 173 | * The name of the remote service with which to connect. The service name must 174 | * exist in a Mach bootstrap that is accessible to the process and be advertised 175 | * in a launchd.plist. 176 | * 177 | * @param targetq 178 | * The GCD queue to which the event handler block will be submitted. This 179 | * parameter may be NULL, in which case the connection's target queue will be 180 | * libdispatch's default target queue, defined as DISPATCH_TARGET_QUEUE_DEFAULT. 181 | * The target queue may be changed later with a call to 182 | * xpc_connection_set_target_queue(). 183 | * 184 | * @param flags 185 | * Additional attributes with which to create the connection. 186 | * 187 | * @result 188 | * A new connection object. 189 | * 190 | * @discussion 191 | * If the XPC_CONNECTION_MACH_SERVICE_LISTENER flag is given to this method, 192 | * then the connection returned will be a listener connection. Otherwise, a peer 193 | * connection will be returned. See the documentation for 194 | * {@link xpc_connection_set_event_handler()} for the semantics of listener 195 | * connections versus peer connections. 196 | * 197 | * This method will succeed even if the named service does not exist. This is 198 | * because the Mach namespace is not queried for the service name until the 199 | * connection has been activated. See {@link xpc_connection_activate()}. 200 | */ 201 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 202 | XPC_EXPORT XPC_MALLOC XPC_RETURNS_RETAINED XPC_WARN_RESULT XPC_NONNULL1 203 | xpc_connection_t 204 | xpc_connection_create_mach_service(const char *name, 205 | dispatch_queue_t _Nullable targetq, uint64_t flags); 206 | 207 | /*! 208 | * @function xpc_connection_create_from_endpoint 209 | * Creates a new connection from the given endpoint. 210 | * 211 | * @param endpoint 212 | * The endpoint from which to create the new connection. 213 | * 214 | * @result 215 | * A new peer connection to the listener represented by the given endpoint. 216 | * 217 | * The same responsibilities of setting an event handler and activating the 218 | * connection after calling xpc_connection_create() apply to the connection 219 | * returned by this API. Since the connection yielded by this API is not 220 | * associated with a name (and therefore is not rediscoverable), this connection 221 | * will receive XPC_ERROR_CONNECTION_INVALID if the listening side crashes, 222 | * exits or cancels the listener connection. 223 | */ 224 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 225 | XPC_EXPORT XPC_MALLOC XPC_RETURNS_RETAINED XPC_WARN_RESULT XPC_NONNULL_ALL 226 | xpc_connection_t 227 | xpc_connection_create_from_endpoint(xpc_endpoint_t endpoint); 228 | 229 | /*! 230 | * @function xpc_connection_set_target_queue 231 | * Sets the target queue of the given connection. 232 | * 233 | * @param connection 234 | * The connection object which is to be manipulated. 235 | * 236 | * @param targetq 237 | * The GCD queue to which the event handler block will be submitted. This 238 | * parameter may be NULL, in which case the connection's target queue will be 239 | * libdispatch's default target queue, defined as DISPATCH_TARGET_QUEUE_DEFAULT. 240 | * 241 | * @discussion 242 | * Setting the target queue is asynchronous and non-preemptive and therefore 243 | * this method will not interrupt the execution of an already-running event 244 | * handler block. Setting the target queue may be likened to issuing a barrier 245 | * to the connection which does the actual work of changing the target queue. 246 | * 247 | * The XPC runtime guarantees this non-preemptiveness even for concurrent target 248 | * queues. If the target queue is a concurrent queue, then XPC still guarantees 249 | * that there will never be more than one invocation of the connection's event 250 | * handler block executing concurrently. If you wish to process events 251 | * concurrently, you can dispatch_async(3) to a concurrent queue from within 252 | * the event handler. 253 | * 254 | * IMPORTANT: When called from within the event handler block, 255 | * dispatch_get_current_queue(3) is NOT guaranteed to return a pointer to the 256 | * queue set with this method. 257 | * 258 | * Despite this seeming inconsistency, the XPC runtime guarantees that, when the 259 | * target queue is a serial queue, the event handler block will execute 260 | * synchronously with respect to other blocks submitted to that same queue. When 261 | * the target queue is a concurrent queue, the event handler block may run 262 | * concurrently with other blocks submitted to that queue, but it will never run 263 | * concurrently with other invocations of itself for the same connection, as 264 | * discussed previously. 265 | */ 266 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 267 | XPC_EXPORT XPC_NONNULL1 268 | void 269 | xpc_connection_set_target_queue(xpc_connection_t connection, 270 | dispatch_queue_t _Nullable targetq); 271 | 272 | /*! 273 | * @function xpc_connection_set_event_handler 274 | * Sets the event handler block for the connection. 275 | * 276 | * @param connection 277 | * The connection object which is to be manipulated. 278 | * 279 | * @param handler 280 | * The event handler block. 281 | * 282 | * @discussion 283 | * Setting the event handler is asynchronous and non-preemptive, and therefore 284 | * this method will not interrupt the execution of an already-running event 285 | * handler block. If the event handler is executing at the time of this call, it 286 | * will finish, and then the connection's event handler will be changed before 287 | * the next invocation of the event handler. The XPC runtime guarantees this 288 | * non-preemptiveness even for concurrent target queues. 289 | * 290 | * Connection event handlers are non-reentrant, so it is safe to call 291 | * xpc_connection_set_event_handler() from within the event handler block. 292 | * 293 | * The event handler's execution should be treated as a barrier to all 294 | * connection activity. When it is executing, the connection will not attempt to 295 | * send or receive messages, including reply messages. Thus, it is not safe to 296 | * call xpc_connection_send_message_with_reply_sync() on the connection from 297 | * within the event handler. 298 | * 299 | * You do not hold a reference on the object received as the event handler's 300 | * only argument. Regardless of the type of object received, it is safe to call 301 | * xpc_retain() on the object to obtain a reference to it. 302 | * 303 | * A connection may receive different events depending upon whether it is a 304 | * listener or not. Any connection may receive an error in its event handler. 305 | * But while normal connections may receive messages in addition to errors, 306 | * listener connections will receive connections and and not messages. 307 | * 308 | * Connections received by listeners are equivalent to those returned by 309 | * xpc_connection_create() with a non-NULL name argument and a NULL targetq 310 | * argument with the exception that you do not hold a reference on them. 311 | * You must set an event handler and activate the connection. If you do not wish 312 | * to accept the connection, you may simply call xpc_connection_cancel() on it 313 | * and return. The runtime will dispose of it for you. 314 | * 315 | * If there is an error in the connection, this handler will be invoked with the 316 | * error dictionary as its argument. This dictionary will be one of the well- 317 | * known XPC_ERROR_* dictionaries. 318 | * 319 | * Regardless of the type of event, ownership of the event object is NOT 320 | * implicitly transferred. Thus, the object will be released and deallocated at 321 | * some point in the future after the event handler returns. If you wish the 322 | * event's lifetime to persist, you must retain it with xpc_retain(). 323 | * 324 | * Connections received through the event handler will be released and 325 | * deallocated after the connection has gone invalid and delivered that event to 326 | * its event handler. 327 | */ 328 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 329 | XPC_EXPORT XPC_NONNULL_ALL 330 | void 331 | xpc_connection_set_event_handler(xpc_connection_t connection, 332 | xpc_handler_t handler); 333 | 334 | /*! 335 | * @function xpc_connection_activate 336 | * Activates the connection. Connections start in an inactive state, so you must 337 | * call xpc_connection_activate() on a connection before it will send or receive 338 | * any messages. 339 | * 340 | * @param connection 341 | * The connection object which is to be manipulated. 342 | * 343 | * @discussion 344 | * Calling xpc_connection_activate() on an active connection has no effect. 345 | * Releasing the last reference on an inactive connection that was created with 346 | * an xpc_connection_create*() call is undefined. 347 | * 348 | * For backward compatibility reasons, xpc_connection_resume() on an inactive 349 | * and not otherwise suspended xpc connection has the same effect as calling 350 | * xpc_connection_activate(). For new code, using xpc_connection_activate() 351 | * is preferred. 352 | */ 353 | __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) 354 | __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) 355 | XPC_EXPORT XPC_NONNULL_ALL 356 | void 357 | xpc_connection_activate(xpc_connection_t connection); 358 | 359 | /*! 360 | * @function xpc_connection_suspend 361 | * Suspends the connection so that the event handler block will not fire and 362 | * that the connection will not attempt to send any messages it has in its 363 | * queue. All calls to xpc_connection_suspend() must be balanced with calls to 364 | * xpc_connection_resume() before releasing the last reference to the 365 | * connection. 366 | * 367 | * @param connection 368 | * The connection object which is to be manipulated. 369 | * 370 | * @discussion 371 | * Suspension is asynchronous and non-preemptive, and therefore this method will 372 | * not interrupt the execution of an already-running event handler block. If 373 | * the event handler is executing at the time of this call, it will finish, and 374 | * then the connection will be suspended before the next scheduled invocation 375 | * of the event handler. The XPC runtime guarantees this non-preemptiveness even 376 | * for concurrent target queues. 377 | * 378 | * Connection event handlers are non-reentrant, so it is safe to call 379 | * xpc_connection_suspend() from within the event handler block. 380 | */ 381 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 382 | XPC_EXPORT XPC_NONNULL_ALL 383 | void 384 | xpc_connection_suspend(xpc_connection_t connection); 385 | 386 | /*! 387 | * @function xpc_connection_resume 388 | * Resumes the connection. 389 | * 390 | * @param connection 391 | * The connection object which is to be manipulated. 392 | * 393 | * @discussion 394 | * In order for a connection to become live, every call to 395 | * xpc_connection_suspend() must be balanced with a call to 396 | * xpc_connection_resume(). 397 | * 398 | * For backward compatibility reasons, xpc_connection_resume() on an inactive 399 | * and not otherwise suspended xpc connection has the same effect as calling 400 | * xpc_connection_activate(). For new code, using xpc_connection_activate() 401 | * is preferred. 402 | * 403 | * Calling xpc_connection_resume() more times than xpc_connection_suspend() 404 | * has been called is otherwise considered an error. 405 | */ 406 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 407 | XPC_EXPORT XPC_NONNULL_ALL 408 | void 409 | xpc_connection_resume(xpc_connection_t connection); 410 | 411 | /*! 412 | * @function xpc_connection_send_message 413 | * Sends a message over the connection to the destination service. 414 | * 415 | * @param connection 416 | * The connection over which the message shall be sent. 417 | * 418 | * @param message 419 | * The message to send. This must be a dictionary object. This dictionary is 420 | * logically copied by the connection, so it is safe to modify the dictionary 421 | * after this call. 422 | * 423 | * @discussion 424 | * Messages are delivered in FIFO order. This API is safe to call from multiple 425 | * GCD queues. There is no indication that a message was delivered successfully. 426 | * This is because even once the message has been successfully enqueued on the 427 | * remote end, there are no guarantees about when the runtime will dequeue the 428 | * message and invoke the other connection's event handler block. 429 | * 430 | * If this API is used to send a message that is in reply to another message, 431 | * there is no guarantee of ordering between the invocations of the connection's 432 | * event handler and the reply handler for that message, even if they are 433 | * targeted to the same queue. 434 | * 435 | * After extensive study, we have found that clients who are interested in 436 | * the state of the message on the server end are typically holding open 437 | * transactions related to that message. And the only reliable way to track the 438 | * lifetime of that transaction is at the protocol layer. So the server should 439 | * send a reply message, which upon receiving, will cause the client to close 440 | * its transaction. 441 | */ 442 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 443 | XPC_EXPORT XPC_NONNULL_ALL 444 | void 445 | xpc_connection_send_message(xpc_connection_t connection, xpc_object_t message); 446 | 447 | /*! 448 | * @function xpc_connection_send_barrier 449 | * Issues a barrier against the connection's message-send activity. 450 | * 451 | * @param connection 452 | * The connection against which the barrier is to be issued. 453 | * 454 | * @param barrier 455 | * The barrier block to issue. This barrier prevents concurrent message-send 456 | * activity on the connection. No messages will be sent while the barrier block 457 | * is executing. 458 | * 459 | * @discussion 460 | * XPC guarantees that, even if the connection's target queue is a concurrent 461 | * queue, there are no other messages being sent concurrently while the barrier 462 | * block is executing. XPC does not guarantee that the receipt of messages 463 | * (either through the connection's event handler or through reply handlers) 464 | * will be suspended while the barrier is executing. 465 | * 466 | * A barrier is issued relative to the message-send queue. Thus, if you call 467 | * xpc_connection_send_message() five times and then call 468 | * xpc_connection_send_barrier(), the barrier will be invoked after the fifth 469 | * message has been sent and its memory disposed of. You may safely cancel a 470 | * connection from within a barrier block. 471 | * 472 | * If a barrier is issued after sending a message which expects a reply, the 473 | * behavior is the same as described above. The receipt of a reply message will 474 | * not influence when the barrier runs. 475 | * 476 | * A barrier block can be useful for throttling resource consumption on the 477 | * connected side of a connection. For example, if your connection sends many 478 | * large messages, you can use a barrier to limit the number of messages that 479 | * are inflight at any given time. This can be particularly useful for messages 480 | * that contain kernel resources (like file descriptors) which have a system- 481 | * wide limit. 482 | * 483 | * If a barrier is issued on a canceled connection, it will be invoked 484 | * immediately. If a connection has been canceled and still has outstanding 485 | * barriers, those barriers will be invoked as part of the connection's 486 | * unwinding process. 487 | * 488 | * It is important to note that a barrier block's execution order is not 489 | * guaranteed with respect to other blocks that have been scheduled on the 490 | * target queue of the connection. Or said differently, 491 | * xpc_connection_send_barrier(3) is not equivalent to dispatch_async(3). 492 | */ 493 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 494 | XPC_EXPORT XPC_NONNULL_ALL 495 | void 496 | xpc_connection_send_barrier(xpc_connection_t connection, 497 | dispatch_block_t barrier); 498 | 499 | /*! 500 | * @function xpc_connection_send_message_with_reply 501 | * Sends a message over the connection to the destination service and associates 502 | * a handler to be invoked when the remote service sends a reply message. 503 | * 504 | * @param connection 505 | * The connection over which the message shall be sent. 506 | * 507 | * @param message 508 | * The message to send. This must be a dictionary object. 509 | * 510 | * @param replyq 511 | * The GCD queue to which the reply handler will be submitted. This may be a 512 | * concurrent queue. 513 | * 514 | * @param handler 515 | * The handler block to invoke when a reply to the message is received from 516 | * the connection. If the remote service exits prematurely before the reply was 517 | * received, the XPC_ERROR_CONNECTION_INTERRUPTED error will be returned. 518 | * If the connection went invalid before the message could be sent, the 519 | * XPC_ERROR_CONNECTION_INVALID error will be returned. 520 | * 521 | * @discussion 522 | * If the given GCD queue is a concurrent queue, XPC cannot guarantee that there 523 | * will not be multiple reply handlers being invoked concurrently. XPC does not 524 | * guarantee any ordering for the invocation of reply handlers. So if multiple 525 | * messages are waiting for replies and the connection goes invalid, there is no 526 | * guarantee that the reply handlers will be invoked in FIFO order. Similarly, 527 | * XPC does not guarantee that reply handlers will not run concurrently with 528 | * the connection's event handler in the case that the reply queue and the 529 | * connection's target queue are the same concurrent queue. 530 | */ 531 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 532 | XPC_EXPORT XPC_NONNULL1 XPC_NONNULL2 XPC_NONNULL4 533 | void 534 | xpc_connection_send_message_with_reply(xpc_connection_t connection, 535 | xpc_object_t message, dispatch_queue_t _Nullable replyq, 536 | xpc_handler_t handler); 537 | 538 | /*! 539 | * @function xpc_connection_send_message_with_reply_sync 540 | * Sends a message over the connection and blocks the caller until a reply is 541 | * received. 542 | * 543 | * @param connection 544 | * The connection over which the message shall be sent. 545 | * 546 | * @param message 547 | * The message to send. This must be a dictionary object. 548 | * 549 | * @result 550 | * The message that the remote service sent in reply to the original message. 551 | * If the remote service exits prematurely before the reply was received, the 552 | * XPC_ERROR_CONNECTION_INTERRUPTED error will be returned. If the connection 553 | * went invalid before the message could be sent, the 554 | * XPC_ERROR_CONNECTION_INVALID error will be returned. 555 | * 556 | * You are responsible for releasing the returned object. 557 | * 558 | * @discussion 559 | * This API supports priority inversion avoidance, and should be used instead of 560 | * combining xpc_connection_send_message_with_reply() with a semaphore. 561 | * 562 | * Invoking this API from a queue that is a part of the target queue hierarchy 563 | * results in deadlocks under certain conditions. 564 | * 565 | * Be judicious about your use of this API. It can block indefinitely, so if you 566 | * are using it to implement an API that can be called from the main thread, you 567 | * may wish to consider allowing the API to take a queue and callback block so 568 | * that results may be delivered asynchronously if possible. 569 | */ 570 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 571 | XPC_EXPORT XPC_NONNULL_ALL XPC_WARN_RESULT XPC_RETURNS_RETAINED 572 | xpc_object_t 573 | xpc_connection_send_message_with_reply_sync(xpc_connection_t connection, 574 | xpc_object_t message); 575 | 576 | /*! 577 | * @function xpc_connection_cancel 578 | * Cancels the connection and ensures that its event handler will not fire 579 | * again. After this call, any messages that have not yet been sent will be 580 | * discarded, and the connection will be unwound. If there are messages that are 581 | * awaiting replies, they will have their reply handlers invoked with the 582 | * XPC_ERROR_CONNECTION_INVALID error. 583 | * 584 | * @param connection 585 | * The connection object which is to be manipulated. 586 | * 587 | * @discussion 588 | * Cancellation is asynchronous and non-preemptive and therefore this method 589 | * will not interrupt the execution of an already-running event handler block. 590 | * If the event handler is executing at the time of this call, it will finish, 591 | * and then the connection will be canceled, causing a final invocation of the 592 | * event handler to be scheduled with the XPC_ERROR_CONNECTION_INVALID error. 593 | * After that invocation, there will be no further invocations of the event 594 | * handler. 595 | * 596 | * The XPC runtime guarantees this non-preemptiveness even for concurrent target 597 | * queues. 598 | */ 599 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 600 | XPC_EXPORT XPC_NONNULL_ALL 601 | void 602 | xpc_connection_cancel(xpc_connection_t connection); 603 | 604 | /*! 605 | * @function xpc_connection_get_name 606 | * Returns the name of the service with which the connections was created. 607 | * 608 | * @param connection 609 | * The connection object which is to be examined. 610 | * 611 | * @result 612 | * The name of the remote service. If you obtained the connection through an 613 | * invocation of another connection's event handler, NULL is returned. 614 | */ 615 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 616 | XPC_EXPORT XPC_NONNULL_ALL XPC_WARN_RESULT 617 | const char * _Nullable 618 | xpc_connection_get_name(xpc_connection_t connection); 619 | 620 | /*! 621 | * @function xpc_connection_get_euid 622 | * Returns the EUID of the remote peer. 623 | * 624 | * @param connection 625 | * The connection object which is to be examined. 626 | * 627 | * @result 628 | * The EUID of the remote peer at the time the connection was made. 629 | */ 630 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 631 | XPC_EXPORT XPC_NONNULL_ALL XPC_WARN_RESULT 632 | uid_t 633 | xpc_connection_get_euid(xpc_connection_t connection); 634 | 635 | /*! 636 | * @function xpc_connection_get_egid 637 | * Returns the EGID of the remote peer. 638 | * 639 | * @param connection 640 | * The connection object which is to be examined. 641 | * 642 | * @result 643 | * The EGID of the remote peer at the time the connection was made. 644 | */ 645 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 646 | XPC_EXPORT XPC_NONNULL_ALL XPC_WARN_RESULT 647 | gid_t 648 | xpc_connection_get_egid(xpc_connection_t connection); 649 | 650 | /*! 651 | * @function xpc_connection_get_pid 652 | * Returns the PID of the remote peer. 653 | * 654 | * @param connection 655 | * The connection object which is to be examined. 656 | * 657 | * @result 658 | * The PID of the remote peer. 659 | * 660 | * @discussion 661 | * A given PID is not guaranteed to be unique across an entire boot cycle. 662 | * Great care should be taken when dealing with this information, as it can go 663 | * stale after the connection is established. OS X recycles PIDs, and therefore 664 | * another process could spawn and claim the PID before a message is actually 665 | * received from the connection. 666 | * 667 | * XPC will deliver an error to your event handler if the remote process goes 668 | * away, but there are no guarantees as to the timing of this notification's 669 | * delivery either at the kernel layer or at the XPC layer. 670 | */ 671 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 672 | XPC_EXPORT XPC_NONNULL_ALL XPC_WARN_RESULT 673 | pid_t 674 | xpc_connection_get_pid(xpc_connection_t connection); 675 | 676 | /*! 677 | * @function xpc_connection_get_asid 678 | * Returns the audit session identifier of the remote peer. 679 | * 680 | * @param connection 681 | * The connection object which is to be examined. 682 | * 683 | * @result 684 | * The audit session ID of the remote peer at the time the connection was made. 685 | */ 686 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 687 | XPC_EXPORT XPC_NONNULL_ALL XPC_WARN_RESULT 688 | au_asid_t 689 | xpc_connection_get_asid(xpc_connection_t connection); 690 | 691 | /*! 692 | * @function xpc_connection_set_context 693 | * Sets context on an connection. 694 | * 695 | * @param connection 696 | * The connection which is to be manipulated. 697 | * 698 | * @param context 699 | * The context to associate with the connection. 700 | * 701 | * @discussion 702 | * If you must manage the memory of the context object, you must set a finalizer 703 | * to dispose of it. If this method is called on a connection which already has 704 | * context associated with it, the finalizer will NOT be invoked. The finalizer 705 | * is only invoked when the connection is being deallocated. 706 | * 707 | * It is recommended that, instead of changing the actual context pointer 708 | * associated with the object, you instead change the state of the context 709 | * object itself. 710 | */ 711 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 712 | XPC_EXPORT XPC_NONNULL1 713 | void 714 | xpc_connection_set_context(xpc_connection_t connection, 715 | void * _Nullable context); 716 | 717 | /*! 718 | * @function xpc_connection_get_context 719 | * Returns the context associated with the connection. 720 | * 721 | * @param connection 722 | * The connection which is to be examined. 723 | * 724 | * @result 725 | * The context associated with the connection. NULL if there has been no context 726 | * associated with the object. 727 | */ 728 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 729 | XPC_EXPORT XPC_NONNULL_ALL XPC_WARN_RESULT 730 | void * _Nullable 731 | xpc_connection_get_context(xpc_connection_t connection); 732 | 733 | /*! 734 | * @function xpc_connection_set_finalizer_f 735 | * Sets the finalizer for the given connection. 736 | * 737 | * @param connection 738 | * The connection on which to set the finalizer. 739 | * 740 | * @param finalizer 741 | * The function that will be invoked when the connection's retain count has 742 | * dropped to zero and is being torn down. 743 | * 744 | * @discussion 745 | * This method disposes of the context value associated with a connection, as 746 | * set by {@link xpc_connection_set_context}. 747 | * 748 | * For many uses of context objects, this API allows for a convenient shorthand 749 | * for freeing them. For example, for a context object allocated with malloc(3): 750 | * 751 | * xpc_connection_set_finalizer_f(object, free); 752 | */ 753 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 754 | XPC_EXPORT XPC_NONNULL1 755 | void 756 | xpc_connection_set_finalizer_f(xpc_connection_t connection, 757 | xpc_finalizer_t _Nullable finalizer); 758 | 759 | /*! 760 | * @function xpc_connection_set_peer_code_signing_requirement 761 | * Requires that the connection peer satisfies a code signing requirement. 762 | * 763 | * @param connection 764 | * The connection object which is to be modified. 765 | * 766 | * @param requirement 767 | * The code signing requirement to be satisfied by the peer 768 | * It is safe to deallocate the requirement string after calling `xpc_connection_set_peer_code_signing_requirement` 769 | * 770 | * @result 771 | * 0 on success, non-zero on error 772 | * 773 | * @discussion 774 | * This function will return an error promptly if the code signing requirement string is invalid. 775 | * 776 | * It is a programming error to call `xpc_connection_set_peer_code_signing_requirement` more than once per connection. 777 | * 778 | * All messages received on this connection will be checked to ensure they come from a peer who satisfies 779 | * the code signing requirement. For a listener connection, requests that do not satisfy the requirement 780 | * are dropped. When a reply is expected on the connection and the peer does not satisfy the requirement 781 | * XPC_ERROR_PEER_CODE_SIGNING_REQUIREMENT will be delivered instead of the reply. 782 | * 783 | * This API is not supported on embedded platforms and will return ENOTSUP. 784 | * 785 | * @see https://developer.apple.com/library/archive/documentation/Security/Conceptual/CodeSigningGuide/RequirementLang/RequirementLang.html 786 | */ 787 | __API_AVAILABLE(macos(12.0)) 788 | XPC_EXPORT XPC_NONNULL_ALL XPC_WARN_RESULT 789 | int 790 | xpc_connection_set_peer_code_signing_requirement(xpc_connection_t connection, const char *requirement); 791 | 792 | 793 | __END_DECLS 794 | XPC_ASSUME_NONNULL_END 795 | 796 | #endif // __XPC_CONNECTION_H__ 797 | -------------------------------------------------------------------------------- /include/xpc/debug.h: -------------------------------------------------------------------------------- 1 | #ifndef __XPC_DEBUG_H__ 2 | #define __XPC_DEBUG_H__ 3 | 4 | /*! 5 | * @function xpc_debugger_api_misuse_info 6 | * Returns a pointer to a string describing the reason XPC aborted the calling 7 | * process. On OS X, this will be the same string present in the "Application 8 | * Specific Information" section of the crash report. 9 | * 10 | * @result 11 | * A pointer to the human-readable string describing the reason the caller was 12 | * aborted. If XPC was not responsible for the program's termination, NULL will 13 | * be returned. 14 | * 15 | * @discussion 16 | * This function is only callable from within a debugger. It is not meant to be 17 | * called by the program directly. 18 | */ 19 | XPC_DEBUGGER_EXCL 20 | const char * 21 | xpc_debugger_api_misuse_info(void); 22 | 23 | #endif // __XPC_DEBUG_H__ 24 | -------------------------------------------------------------------------------- /include/xpc/endpoint.h: -------------------------------------------------------------------------------- 1 | #ifndef __XPC_ENDPOINT_H__ 2 | #define __XPC_ENDPOINT_H__ 3 | 4 | /*! 5 | * @function xpc_endpoint_create 6 | * Creates a new endpoint from a connection that is suitable for embedding into 7 | * messages. 8 | * 9 | * @param connection 10 | * Only connections obtained through calls to xpc_connection_create*() may be 11 | * given to this API. Passing any other type of connection is not supported and 12 | * will result in undefined behavior. 13 | * 14 | * @result 15 | * A new endpoint object. 16 | */ 17 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 18 | XPC_EXPORT XPC_MALLOC XPC_RETURNS_RETAINED XPC_WARN_RESULT XPC_NONNULL1 19 | xpc_endpoint_t _Nonnull 20 | xpc_endpoint_create(xpc_connection_t _Nonnull connection); 21 | 22 | #endif // __XPC_ENDPOINT_H__ 23 | -------------------------------------------------------------------------------- /include/xpc/module.modulemap: -------------------------------------------------------------------------------- 1 | module XPC [system] [extern_c] { 2 | header "xpc.h" 3 | header "availability.h" 4 | header "base.h" 5 | header "activity.h" 6 | header "connection.h" 7 | header "debug.h" 8 | header "endpoint.h" 9 | export * 10 | } 11 | -------------------------------------------------------------------------------- /include/xpc/private.h: -------------------------------------------------------------------------------- 1 | void xpc_dictionary_get_audit_token(xpc_object_t xdict, audit_token_t *token); 2 | char *xpc_strerror (int); 3 | 4 | extern XPC_RETURNS_RETAINED xpc_object_t xpc_pipe_create_from_port(mach_port_t port, uint32_t flags); 5 | extern int xpc_pipe_simpleroutine(xpc_object_t pipe, xpc_object_t message); 6 | extern int xpc_pipe_routine(xpc_object_t pipe, xpc_object_t message, XPC_GIVES_REFERENCE xpc_object_t *reply); 7 | extern int xpc_pipe_routine_with_flags(xpc_object_t xpc_pipe, xpc_object_t inDict, XPC_GIVES_REFERENCE xpc_object_t *reply, uint32_t flags); 8 | extern int xpc_pipe_routine_reply(xpc_object_t reply); 9 | extern int xpc_pipe_receive(mach_port_t port, XPC_GIVES_REFERENCE xpc_object_t *message); 10 | 11 | extern XPC_RETURNS_RETAINED xpc_object_t xpc_copy_entitlement_for_token(const char *, audit_token_t *); -------------------------------------------------------------------------------- /include/xpc/rich_error.h: -------------------------------------------------------------------------------- 1 | #ifndef __XPC_RICH_ERROR_H__ 2 | #define __XPC_RICH_ERROR_H__ 3 | 4 | #ifndef __XPC_INDIRECT__ 5 | #error "Please #include instead of this file directly." 6 | // For HeaderDoc. 7 | #include 8 | #endif // __XPC_INDIRECT__ 9 | 10 | #ifndef __BLOCKS__ 11 | #error "XPC Rich Errors require Blocks support." 12 | #endif // __BLOCKS__ 13 | 14 | XPC_ASSUME_NONNULL_BEGIN 15 | __BEGIN_DECLS 16 | 17 | #pragma mark Properties 18 | /*! 19 | * @function xpc_rich_error_copy_description 20 | * Copy the string description of an error. 21 | * 22 | * @param error 23 | * The error to be examined. 24 | * 25 | * @result 26 | * The underlying C string for the provided error. This string should be 27 | * disposed of with free(3) when done. 28 | * 29 | * This will return NULL if a string description could not be generated. 30 | */ 31 | XPC_EXPORT XPC_WARN_RESULT 32 | char * _Nullable 33 | xpc_rich_error_copy_description(xpc_rich_error_t error); 34 | 35 | /*! 36 | * @function xpc_rich_error_can_retry 37 | * Whether the operation the error originated from can be retried. 38 | * 39 | * @param error 40 | * The error to be inspected. 41 | * 42 | * @result 43 | * Whether the operation the error originated from can be retried. 44 | */ 45 | XPC_EXPORT XPC_WARN_RESULT 46 | bool 47 | xpc_rich_error_can_retry(xpc_rich_error_t error); 48 | 49 | __END_DECLS 50 | XPC_ASSUME_NONNULL_END 51 | 52 | #endif // __XPC_RICH_ERROR_H__ 53 | -------------------------------------------------------------------------------- /include/xpc/session.h: -------------------------------------------------------------------------------- 1 | #ifndef __XPC_SESSION_H__ 2 | #define __XPC_SESSION_H__ 3 | 4 | #ifndef __XPC_INDIRECT__ 5 | #error "Please #include instead of this file directly." 6 | // For HeaderDoc. 7 | #include 8 | #endif // __XPC_INDIRECT__ 9 | 10 | #ifndef __BLOCKS__ 11 | #error "XPC Session require Blocks support." 12 | #endif // __BLOCKS__ 13 | 14 | XPC_ASSUME_NONNULL_BEGIN 15 | __BEGIN_DECLS 16 | 17 | #pragma mark Constants 18 | /*! 19 | * @typedef xpc_session_create_flags_t 20 | * Constants representing different options available when creating an XPC 21 | * Session. 22 | * 23 | * @const XPC_SESSION_CREATE_INACTIVE 24 | * Indicates that the session should not be activated during its creation. The 25 | * returned session must be manually activated using 26 | * {@link xpc_session_activate} before it can be used. 27 | * 28 | * @const XPC_SESSION_CREATE_MACH_PRIVILEGED 29 | * Passed to {@link xpc_session_create_mach_service} to indicate that the job 30 | * advertising the service name in its launchd.plist(5) should be in the 31 | * privileged Mach bootstrap. This is typically accomplished by placing your 32 | * launchd.plist(5) in /Library/LaunchDaemons. 33 | */ 34 | XPC_FLAGS_ENUM(xpc_session_create_flags, uint64_t, 35 | XPC_SESSION_CREATE_NONE XPC_SWIFT_NAME("none") = 0, 36 | XPC_SESSION_CREATE_INACTIVE XPC_SWIFT_NAME("inactive") = (1 << 0), 37 | XPC_SESSION_CREATE_MACH_PRIVILEGED XPC_SWIFT_NAME("privileged") = (1 << 1) 38 | ); 39 | 40 | #pragma mark Handlers 41 | typedef void (^xpc_session_cancel_handler_t)(xpc_rich_error_t error); 42 | typedef void (^xpc_session_incoming_message_handler_t)(xpc_object_t message); 43 | typedef void (^xpc_session_reply_handler_t)(xpc_object_t _Nullable reply, 44 | xpc_rich_error_t _Nullable error); 45 | 46 | #pragma mark Helpers 47 | /*! 48 | * @function xpc_session_copy_description 49 | * Copy the string description of the session. 50 | * 51 | * @param session 52 | * The session to be examined. 53 | * 54 | * @result 55 | * The underlying C string description for the provided session. This string 56 | * should be disposed of with free(3) when done. This will return NULL if a 57 | * string description could not be generated. 58 | */ 59 | API_AVAILABLE(macos(13.0), ios(16.0), tvos(16.0), watchos(9.0)) 60 | XPC_EXPORT XPC_WARN_RESULT 61 | char * _Nullable 62 | xpc_session_copy_description(xpc_session_t session); 63 | 64 | #pragma mark Client Session Creation 65 | /*! 66 | * @function xpc_session_create_xpc_service 67 | * Creates a new session object representing a connection to the named service. 68 | * 69 | * @param name 70 | * The name of the service to create a session with. 71 | * 72 | * @param target_queue 73 | * The GCD queue onto which session events will be submitted. This may be a 74 | * concurrent queue. This parameter may be NULL, in which case the target queue 75 | * will be libdispatch's default target queue, defined as 76 | * DISPATCH_TARGET_QUEUE_DEFAULT. 77 | * 78 | * @param flags 79 | * Additional attributes which which to create the session. 80 | * 81 | * @param error_out 82 | * An out-parameter that, if set and in the event of an error, will point to an 83 | * {@link xpc_rich_error_t} describing the details of any errors that occurred. 84 | * 85 | * @result 86 | * On success this returns a new session object. The returned session is 87 | * activated by default and can be used to send messages. The caller is 88 | * responsible for disposing of the returned object with {@link xpc_release} 89 | * when it is no longer needed. On failure this will return NULL and if set, 90 | * error_out will be set to an error describing the failure. 91 | * 92 | * @discussion 93 | * This will fail if the specified XPC service is either not found or is 94 | * unavailable. 95 | */ 96 | API_AVAILABLE(macos(13.0), ios(16.0), tvos(16.0), watchos(9.0)) 97 | XPC_EXPORT XPC_RETURNS_RETAINED XPC_WARN_RESULT 98 | xpc_session_t _Nullable 99 | xpc_session_create_xpc_service(const char *name, 100 | dispatch_queue_t _Nullable target_queue, 101 | xpc_session_create_flags_t flags, 102 | xpc_rich_error_t _Nullable * _Nullable error_out); 103 | 104 | /*! 105 | * @function xpc_session_create_mach_service 106 | * Creates a session with the service defined by the provided Mach service name. 107 | * 108 | * @param mach_service 109 | * The Mach service to create a session with. The service name must exist in the 110 | * Mach bootstrap that is accessible to the process and be advertised in a 111 | * launchd.plist. 112 | * 113 | * @param target_queue 114 | * The GCD queue onto which session events will be submitted. This may be a 115 | * concurrent queue. This parameter may be NULL, in which case the target queue 116 | * will be libdispatch's default target queue, defined as 117 | * DISPATCH_TARGET_QUEUE_DEFAULT. 118 | * 119 | * @param flags 120 | * Additional attributes which which to create the session. 121 | * 122 | * @param error_out 123 | * An out-parameter that, if set and in the event of an error, will point to an 124 | * {@link xpc_rich_error_t} describing the details of any errors that occurred. 125 | * 126 | * @param cancel_handler 127 | * The cancel handler block that will be executed when this session is canceled. 128 | * 129 | * @result 130 | * On success this returns a new session object. The returned session is 131 | * activated by default and can be used to send messages. The caller is 132 | * responsible for disposing of the returned object with {@link xpc_release} 133 | * when it is no longer needed. On failure this will return NULL and if set, 134 | * error_out will be set to an error describing the failure. 135 | * 136 | * @discussion 137 | * This will fail if the specified Mach service is either not found in the 138 | * bootstrap or is otherwise unavailable. 139 | * 140 | */ 141 | API_AVAILABLE(macos(13.0), ios(16.0), tvos(16.0), watchos(9.0)) 142 | XPC_EXPORT XPC_RETURNS_RETAINED XPC_WARN_RESULT 143 | xpc_session_t _Nullable 144 | xpc_session_create_mach_service(const char *mach_service, 145 | dispatch_queue_t _Nullable target_queue, 146 | xpc_session_create_flags_t flags, 147 | xpc_rich_error_t _Nullable * _Nullable error_out); 148 | 149 | #pragma mark Session Configuration 150 | /*! 151 | * @function xpc_session_set_incoming_message_handler 152 | * Set an incoming message handler for a session. 153 | * 154 | * @param session 155 | * The session to set the handler for. 156 | * 157 | * @param handler 158 | * The handler block to be called when a message originated by the peer is 159 | * received through the provided session. 160 | * 161 | * @discussion 162 | * This can only be called on an inactive session. Calling this on a session 163 | * with an existing event handler will replace it. 164 | */ 165 | API_AVAILABLE(macos(13.0), ios(16.0), tvos(16.0), watchos(9.0)) 166 | XPC_EXPORT 167 | void 168 | xpc_session_set_incoming_message_handler(xpc_session_t session, 169 | xpc_session_incoming_message_handler_t handler); 170 | 171 | /*! 172 | * @function xpc_session_set_cancel_handler 173 | * Set the cancel handler for a session. 174 | * 175 | * @param session 176 | * The session to set the cancel handler for. 177 | * 178 | * @param cancel_handler 179 | * The cancel handler block that will be executed when this session is canceled. 180 | * 181 | * @discussion 182 | * This can only be called on an inactive session. Calling this on a session 183 | * with an existing cancel handler will replace the existing cancel handler with 184 | * the one provided. 185 | */ 186 | API_AVAILABLE(macos(13.0), ios(16.0), tvos(16.0), watchos(9.0)) 187 | XPC_EXPORT 188 | void 189 | xpc_session_set_cancel_handler(xpc_session_t session, 190 | xpc_session_cancel_handler_t cancel_handler); 191 | 192 | #pragma mark Lifecycle 193 | /*! 194 | * @function xpc_session_activate 195 | * Activates a session. 196 | * 197 | * @param session 198 | * The session object to activate. 199 | * 200 | * @param error_out 201 | * An out-parameter that, if set and in the event of an error, will point to an 202 | * {@link xpc_rich_error_t} describing the details of any errors that occurred. 203 | * 204 | * @result 205 | * Returns whether session activation succeeded. 206 | * 207 | * @discussion 208 | * xpc_session_activate must not be called on a session that has been already 209 | * activated. Releasing the last reference on an inactive session that was 210 | * created with an xpc_session_create*() is undefined. 211 | */ 212 | API_AVAILABLE(macos(13.0), ios(16.0), tvos(16.0), watchos(9.0)) 213 | XPC_EXPORT 214 | bool 215 | xpc_session_activate(xpc_session_t session, 216 | xpc_rich_error_t _Nullable * _Nullable error_out); 217 | 218 | /*! 219 | * @function xpc_session_cancel 220 | * Cancels the session. After this call, any messages that have not yet been 221 | * sent will be discarded, and the connection will be unwound. If there are 222 | * messages that are awaiting replies, they will have their reply handlers 223 | * invoked with an appropriate {@link xpc_rich_error_t}. 224 | * 225 | * @param session 226 | * The session object to cancel. 227 | * 228 | * @discussion 229 | * Session must have been activated to be canceled. Cancellation is asynchronous 230 | * and non-preemptive. 231 | */ 232 | API_AVAILABLE(macos(13.0), ios(16.0), tvos(16.0), watchos(9.0)) 233 | XPC_EXPORT 234 | void 235 | xpc_session_cancel(xpc_session_t session); 236 | 237 | #pragma mark Message Send 238 | /*! 239 | * @function xpc_session_send_message 240 | * Sends a message over the session to the destination service. 241 | * 242 | * @param session 243 | * The session to send the message over. 244 | * 245 | * @param message 246 | * The message to send. This must be a dictionary object. 247 | * 248 | * @result 249 | * In the event of an error this will return an {@link xpc_rich_error_t} 250 | * detailing the reasons for the failure. On success this return value will be 251 | * NULL. 252 | * 253 | * @discussion 254 | * Messages are delivered in FIFO order. This API is safe to call from multiple 255 | * GCD queues. There is no indication that a message was delivered successfully. 256 | * This is because even once the message has been successfully enqueued on the 257 | * remote end, there are no guarantees about when the runtime will dequeue the 258 | * message and invoke the other session's event handler block. 259 | * 260 | * If this is invoked on an inactive session, one created using the 261 | * XPC_SESSION_CREATE_INACTIVE flag and hasn't yet been activated, the process 262 | * will crash. 263 | */ 264 | API_AVAILABLE(macos(13.0), ios(16.0), tvos(16.0), watchos(9.0)) 265 | XPC_EXPORT XPC_RETURNS_RETAINED XPC_WARN_RESULT 266 | xpc_rich_error_t _Nullable 267 | xpc_session_send_message(xpc_session_t session, xpc_object_t message); 268 | 269 | /*! 270 | * @function xpc_session_send_message_with_reply_sync 271 | * Sends a message over the session to the destination service and blocks the 272 | * caller until a reply is received. 273 | * 274 | * @param session 275 | * The session over which the message will be sent. 276 | * 277 | * @param message 278 | * The message to send. This must be a dictionary object. 279 | * 280 | * @param error_out 281 | * If this parameter is provided, in the event of a failure it will point to an 282 | * {@link xpc_rich_error_t} describing the details of the error. 283 | * 284 | * @result 285 | * On success, this will return the reply message as an {@link xpc_object_t}. 286 | * Otherwise NULL is returned. 287 | * 288 | * @discussion 289 | * This API supports priority inversion avoidance and should be used instead of 290 | * combining xpc_session_send_message_with_reply_async with a semaphore. 291 | * 292 | * If this is invoked on an inactive session, for example one created using the 293 | * XPC_SESSION_CREATE_INACTIVE flag that hasn't yet been activated, the process 294 | * will crash. 295 | * 296 | * Invoking this API while the target queue is blocked would lead to deadlocks 297 | * in certain scenarios. For that reason, invoking it from the target queue 298 | * results in a crash. 299 | * 300 | * Be judicious about your use of this API. It can block indefinitely, so if you 301 | * are using it to implement an API that can be called from the main queue, you 302 | * may wish to consider allowing the API to take a queue and callback block so 303 | * that results may be delivered asynchronously if possible. 304 | */ 305 | API_AVAILABLE(macos(13.0), ios(16.0), tvos(16.0), watchos(9.0)) 306 | XPC_EXPORT XPC_RETURNS_RETAINED XPC_WARN_RESULT 307 | xpc_object_t _Nullable 308 | xpc_session_send_message_with_reply_sync(xpc_session_t session, 309 | xpc_object_t message, xpc_rich_error_t _Nullable * _Nullable error_out); 310 | 311 | /*! 312 | * @function xpc_session_send_message_with_reply_async 313 | * Sends a message over the session to the destination service and executes the 314 | * provided callback when a reply is received. 315 | * 316 | * @param session 317 | * The session over which the message will be sent. 318 | * 319 | * @param message 320 | * The message to send. This must be a dictionary object. 321 | * 322 | * @param reply_handler 323 | * The handler block to invoke when a reply to the message is received from the 324 | * session. If the session is torn down before the reply was received, for 325 | * example if the remote service exits prematurely, this handler will be 326 | * executed and passed an appropriate {@link xpc_rich_error_t} object describing 327 | * the failure. 328 | * 329 | * @discussion 330 | * If this is invoked on an inactive session, for example one created using the 331 | * XPC_SESSION_CREATE_INACTIVE flag that hasn't yet been activated, the process 332 | * will crash. 333 | * 334 | * If this is invoked on a cancelled session, this will generate a simulated 335 | * crash. 336 | */ 337 | API_AVAILABLE(macos(13.0), ios(16.0), tvos(16.0), watchos(9.0)) 338 | XPC_EXPORT 339 | void 340 | xpc_session_send_message_with_reply_async(xpc_session_t session, 341 | xpc_object_t message, xpc_session_reply_handler_t reply_handler); 342 | 343 | __END_DECLS 344 | XPC_ASSUME_NONNULL_END 345 | 346 | #endif // __XPC_SESSION_H__ 347 | -------------------------------------------------------------------------------- /lib/libxpc.tbd: -------------------------------------------------------------------------------- 1 | --- !tapi-tbd 2 | tbd-version: 4 3 | targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, 4 | arm64e-macos, arm64e-maccatalyst, arm64-ios, arm64e-ios ] 5 | install-name: '/usr/lib/system/libxpc.dylib' 6 | current-version: 2679.0.25 7 | parent-umbrella: 8 | - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, 9 | arm64e-macos, arm64e-maccatalyst, arm64-ios, arm64e-ios ] 10 | umbrella: System 11 | exports: 12 | - targets: [ x86_64-macos, x86_64-maccatalyst, arm64-macos, arm64-maccatalyst, 13 | arm64e-macos, arm64e-maccatalyst, arm64-ios, arm64e-ios ] 14 | symbols: [ _XPC_ACTIVITY_ALLOW_BATTERY, _XPC_ACTIVITY_APP_REFRESH, _XPC_ACTIVITY_CHECK_IN, 15 | _XPC_ACTIVITY_COMMUNICATES_WITH_PAIRED_DEVICE, _XPC_ACTIVITY_CPU_INTENSIVE, 16 | _XPC_ACTIVITY_DELAY, _XPC_ACTIVITY_DESIRED_MOTION_STATE, _XPC_ACTIVITY_DISK_INTENSIVE, 17 | _XPC_ACTIVITY_DO_IT_LATER, _XPC_ACTIVITY_DUET_ACTIVITY_SCHEDULER_DATA, 18 | _XPC_ACTIVITY_DUET_ATTRIBUTE_COST, _XPC_ACTIVITY_DUET_ATTRIBUTE_NAME, 19 | _XPC_ACTIVITY_DUET_ATTRIBUTE_VALUE, _XPC_ACTIVITY_DUET_RELATED_APPLICATIONS, 20 | _XPC_ACTIVITY_EXCLUSIVE, _XPC_ACTIVITY_EXPECTED_DURATION, 21 | _XPC_ACTIVITY_GRACE_PERIOD, _XPC_ACTIVITY_GROUP_CONCURRENCY_LIMIT, 22 | _XPC_ACTIVITY_GROUP_NAME, _XPC_ACTIVITY_INTERVAL, _XPC_ACTIVITY_INTERVAL_15_MIN, 23 | _XPC_ACTIVITY_INTERVAL_1_DAY, _XPC_ACTIVITY_INTERVAL_1_HOUR, 24 | _XPC_ACTIVITY_INTERVAL_1_MIN, _XPC_ACTIVITY_INTERVAL_30_MIN, 25 | _XPC_ACTIVITY_INTERVAL_4_HOURS, _XPC_ACTIVITY_INTERVAL_5_MIN, 26 | _XPC_ACTIVITY_INTERVAL_7_DAYS, _XPC_ACTIVITY_INTERVAL_8_HOURS, 27 | _XPC_ACTIVITY_INVOLVED_PROCESSES, _XPC_ACTIVITY_MAY_REBOOT_DEVICE, 28 | _XPC_ACTIVITY_MEMORY_INTENSIVE, _XPC_ACTIVITY_MOTION_STATE_AUTOMOTIVE, 29 | _XPC_ACTIVITY_MOTION_STATE_AUTOMOTIVE_MOVING, _XPC_ACTIVITY_MOTION_STATE_AUTOMOTIVE_STATIONARY, 30 | _XPC_ACTIVITY_MOTION_STATE_CYCLING, _XPC_ACTIVITY_MOTION_STATE_RUNNING, 31 | _XPC_ACTIVITY_MOTION_STATE_STATIONARY, _XPC_ACTIVITY_MOTION_STATE_WALKING, 32 | _XPC_ACTIVITY_NETWORK_DOWNLOAD_SIZE, _XPC_ACTIVITY_NETWORK_TRANSFER_BIDIRECTIONAL, 33 | _XPC_ACTIVITY_NETWORK_TRANSFER_DIRECTION, _XPC_ACTIVITY_NETWORK_TRANSFER_DIRECTION_DOWNLOAD, 34 | _XPC_ACTIVITY_NETWORK_TRANSFER_DIRECTION_UPLOAD, _XPC_ACTIVITY_NETWORK_TRANSFER_ENDPOINT, 35 | _XPC_ACTIVITY_NETWORK_TRANSFER_PARAMETERS, _XPC_ACTIVITY_NETWORK_TRANSFER_SIZE, 36 | _XPC_ACTIVITY_NETWORK_UPLOAD_SIZE, _XPC_ACTIVITY_POST_INSTALL, 37 | _XPC_ACTIVITY_POWER_NAP, _XPC_ACTIVITY_PREVENT_DEVICE_SLEEP, 38 | _XPC_ACTIVITY_PRIORITY, _XPC_ACTIVITY_PRIORITY_MAINTENANCE, 39 | _XPC_ACTIVITY_PRIORITY_UTILITY, _XPC_ACTIVITY_RANDOM_INITIAL_DELAY, 40 | _XPC_ACTIVITY_REPEATING, _XPC_ACTIVITY_REPLY_ENDPOINT, _XPC_ACTIVITY_REQUIRES_BUDDY_COMPLETE, 41 | _XPC_ACTIVITY_REQUIRES_CLASS_A, _XPC_ACTIVITY_REQUIRES_CLASS_B, 42 | _XPC_ACTIVITY_REQUIRES_CLASS_C, _XPC_ACTIVITY_REQUIRE_BATTERY_LEVEL, 43 | _XPC_ACTIVITY_REQUIRE_HDD_SPINNING, _XPC_ACTIVITY_REQUIRE_INEXPENSIVE_NETWORK_CONNECTIVITY, 44 | _XPC_ACTIVITY_REQUIRE_NETWORK_CONNECTIVITY, _XPC_ACTIVITY_REQUIRE_SCREEN_SLEEP, 45 | _XPC_ACTIVITY_REQUIRE_SIGNIFICANT_USER_INACTIVITY, _XPC_ACTIVITY_RUN_WHEN_APP_FOREGROUNDED, 46 | _XPC_ACTIVITY_SEQUENCE_NUMBER, _XPC_ACTIVITY_SHOULD_WAKE_DEVICE, 47 | _XPC_ACTIVITY_USER_REQUESTED_BACKUP_TASK, _XPC_ACTIVITY_USES_DATA_BUDGETING, 48 | _XPC_ACTIVITY_USES_DUET_POWER_BUDGETING, _XPC_COALITION_INFO_KEY_BUNDLE_IDENTIFIER, 49 | _XPC_COALITION_INFO_KEY_CID, _XPC_COALITION_INFO_KEY_NAME, 50 | _XPC_COALITION_INFO_KEY_RESOURCE_USAGE_BLOB, ___xpc_connection_set_logging, 51 | __availability_version_check, __launch_job_routine, __launch_job_routine_async, 52 | __launch_msg2, __launch_server_test_routine, __launch_service_stats_copy_4ppse_impl, 53 | __launch_service_stats_copy_impl, __libxpc_initializer, __spawn_via_launchd, 54 | __system_ios_support_version_copy_string_sysctl, __system_version_copy_string_plist, 55 | __system_version_copy_string_sysctl, __system_version_fallback, 56 | __system_version_parse_string, __vproc_get_last_exit_status, 57 | __vproc_grab_subset, __vproc_kickstart_by_label, __vproc_log, 58 | __vproc_log_error, __vproc_logv, __vproc_pid_is_managed, __vproc_post_fork_ping, 59 | __vproc_send_signal_by_label, __vproc_set_global_on_demand, 60 | __vproc_standby_begin, __vproc_standby_count, __vproc_standby_end, 61 | __vproc_standby_timeout, __vproc_transaction_begin, __vproc_transaction_count, 62 | __vproc_transaction_count_for_pid, __vproc_transaction_end, 63 | __vproc_transaction_set_clean_callback, __vproc_transaction_try_exit, 64 | __vproc_transactions_enable, __vprocmgr_detach_from_console, 65 | __vprocmgr_getsocket, __vprocmgr_init, __vprocmgr_log_drain, 66 | __vprocmgr_log_forward, __vprocmgr_move_subset_to_user, __vprocmgr_switch_to_session, 67 | __xpc_bool_create_distinct, __xpc_bool_false, __xpc_bool_set_value, 68 | __xpc_bool_true, __xpc_connection_create_internal_listener, 69 | __xpc_connection_get_parent_4test, __xpc_connection_get_recvp_4test, 70 | __xpc_connection_set_event_handler_f, __xpc_data_set_value, 71 | __xpc_dictionary_create_reply_with_port, __xpc_dictionary_extract_mach_send, 72 | __xpc_dictionary_extract_reply_msg_id, __xpc_dictionary_extract_reply_port, 73 | __xpc_dictionary_get_reply_msg_id, __xpc_dictionary_set_remote_connection, 74 | __xpc_dictionary_set_reply_msg_id, __xpc_domain_routine, __xpc_double_set_value, 75 | __xpc_error_connection_interrupted, __xpc_error_connection_invalid, 76 | __xpc_error_key_description, __xpc_error_peer_code_signing_requirement, 77 | __xpc_error_termination_imminent, __xpc_event_key_name, __xpc_event_key_stream_name, 78 | __xpc_fd_get_port, __xpc_int64_set_value, __xpc_payload_create_from_mach_msg, 79 | __xpc_pipe_handle_mig, __xpc_pipe_interface_routine, __xpc_pipe_interface_routine_async, 80 | __xpc_pipe_interface_simpleroutine, __xpc_runtime_get_entitlements_data, 81 | __xpc_runtime_get_self_entitlements, __xpc_runtime_is_app_sandboxed, 82 | __xpc_service_last_xref_cancel, __xpc_service_routine, __xpc_shmem_get_mach_port, 83 | __xpc_spawnattr_binprefs_pack, __xpc_spawnattr_binprefs_size, 84 | __xpc_spawnattr_binprefs_unpack, __xpc_spawnattr_pack_bytes, 85 | __xpc_spawnattr_pack_string, __xpc_spawnattr_pack_string_fragment, 86 | __xpc_spawnattr_unpack_bytes, __xpc_spawnattr_unpack_string, 87 | __xpc_spawnattr_unpack_strings, __xpc_string_set_value, __xpc_type_activity, 88 | __xpc_type_array, __xpc_type_base, __xpc_type_bool, __xpc_type_bundle, 89 | __xpc_type_connection, __xpc_type_data, __xpc_type_date, __xpc_type_dictionary, 90 | __xpc_type_double, __xpc_type_endpoint, __xpc_type_error, 91 | __xpc_type_fd, __xpc_type_file_transfer, __xpc_type_int64, 92 | __xpc_type_mach_recv, __xpc_type_mach_send, __xpc_type_mach_send_once, 93 | __xpc_type_null, __xpc_type_pipe, __xpc_type_pointer, __xpc_type_rich_error, 94 | __xpc_type_serializer, __xpc_type_service, __xpc_type_service_instance, 95 | __xpc_type_session, __xpc_type_shmem, __xpc_type_string, __xpc_type_uint64, 96 | __xpc_type_uuid, __xpc_vtables, _bootstrap_check_in, _bootstrap_check_in2, 97 | _bootstrap_check_in3, _bootstrap_create_server, _bootstrap_create_service, 98 | _bootstrap_get_root, _bootstrap_info, _bootstrap_init, _bootstrap_look_up, 99 | _bootstrap_look_up2, _bootstrap_look_up3, _bootstrap_look_up_per_user, 100 | _bootstrap_lookup_children, _bootstrap_parent, _bootstrap_register, 101 | _bootstrap_register2, _bootstrap_status, _bootstrap_strerror, 102 | _bootstrap_subset, _bootstrap_unprivileged, _create_and_switch_to_per_session_launchd, 103 | _launch_activate_socket, _launch_active_user_login, _launch_active_user_logout, 104 | _launch_active_user_switch, _launch_add_external_service, 105 | _launch_bootout_user_service_4coresim, _launch_copy_busy_extension_instances, 106 | _launch_copy_endpoints_properties_for_pid, _launch_copy_extension_properties, 107 | _launch_copy_extension_properties_for_pid, _launch_copy_properties_for_pid_4assertiond, 108 | _launch_create_persona, _launch_cryptex_terminate, _launch_data_alloc, 109 | _launch_data_array_get_count, _launch_data_array_get_index, 110 | _launch_data_array_set_index, _launch_data_copy, _launch_data_dict_get_count, 111 | _launch_data_dict_insert, _launch_data_dict_iterate, _launch_data_dict_lookup, 112 | _launch_data_dict_remove, _launch_data_free, _launch_data_get_bool, 113 | _launch_data_get_errno, _launch_data_get_fd, _launch_data_get_integer, 114 | _launch_data_get_machport, _launch_data_get_opaque, _launch_data_get_opaque_size, 115 | _launch_data_get_real, _launch_data_get_string, _launch_data_get_type, 116 | _launch_data_new_bool, _launch_data_new_errno, _launch_data_new_fd, 117 | _launch_data_new_integer, _launch_data_new_machport, _launch_data_new_opaque, 118 | _launch_data_new_real, _launch_data_new_string, _launch_data_pack, 119 | _launch_data_set_bool, _launch_data_set_errno, _launch_data_set_fd, 120 | _launch_data_set_integer, _launch_data_set_machport, _launch_data_set_opaque, 121 | _launch_data_set_real, _launch_data_set_string, _launch_data_unpack, 122 | _launch_destroy_persona, _launch_disable_directory, _launch_enable_directory, 123 | _launch_extension_check_in_live_4UIKit, _launch_extension_property_bundle_id, 124 | _launch_extension_property_host_bundle_id, _launch_extension_property_host_pid, 125 | _launch_extension_property_path, _launch_extension_property_pid, 126 | _launch_extension_property_version, _launch_extension_property_xpc_bundle, 127 | _launch_get_fd, _launch_get_service_enabled, _launch_get_system_service_enabled, 128 | _launch_load_mounted_jetsam_properties, _launch_msg, _launch_path_for_user_service_4coresim, 129 | _launch_perfcheck_property_endpoint_active, _launch_perfcheck_property_endpoint_event, 130 | _launch_perfcheck_property_endpoint_name, _launch_perfcheck_property_endpoint_needs_activation, 131 | _launch_perfcheck_property_endpoints, _launch_remove_external_service, 132 | _launch_service_instance_copy_uuids, _launch_service_instance_create, 133 | _launch_service_instance_remove, _launch_service_stats_disable, 134 | _launch_service_stats_disable_4ppse, _launch_service_stats_enable, 135 | _launch_service_stats_enable_4ppse, _launch_service_stats_is_enabled, 136 | _launch_service_stats_is_enabled_4ppse, _launch_set_service_enabled, 137 | _launch_set_system_service_enabled, _launch_socket_service_check_in, 138 | _launch_version_for_user_service_4coresim, _launch_wait, _launchd_close, 139 | _launchd_fdopen, _launchd_getfd, _launchd_msg_recv, _launchd_msg_send, 140 | _load_launchd_jobs_at_loginwindow_prompt, _mpm_uncork_fork, 141 | _mpm_wait, _os_system_version_get_current_version, _os_system_version_get_ios_support_version, 142 | _os_system_version_sim_get_current_host_version, _os_transaction_copy_description, 143 | _os_transaction_create, _os_transaction_get_description, _os_transaction_get_timestamp, 144 | _os_transaction_needs_more_time, _place_hold_on_real_loginwindow, 145 | _reboot2, _reboot3, _vproc_release, _vproc_retain, _vproc_standby_begin, 146 | _vproc_standby_end, _vproc_swap_complex, _vproc_swap_integer, 147 | _vproc_swap_string, _vproc_transaction_begin, _vproc_transaction_end, 148 | _vprocmgr_lookup_vproc, _xpc_activity_add_eligibility_changed_handler, 149 | _xpc_activity_copy_criteria, _xpc_activity_copy_dispatch_queue, 150 | _xpc_activity_copy_identifier, _xpc_activity_debug, _xpc_activity_defer_until_network_change, 151 | _xpc_activity_defer_until_percentage, _xpc_activity_get_percentage, 152 | _xpc_activity_get_state, _xpc_activity_list, _xpc_activity_register, 153 | _xpc_activity_remove_eligibility_changed_handler, _xpc_activity_run, 154 | _xpc_activity_set_completion_status, _xpc_activity_set_criteria, 155 | _xpc_activity_set_network_threshold, _xpc_activity_set_state, 156 | _xpc_activity_should_be_data_budgeted, _xpc_activity_should_defer, 157 | _xpc_activity_unregister, _xpc_add_bundle, _xpc_add_bundles_for_domain, 158 | _xpc_array_append_value, _xpc_array_apply, _xpc_array_apply_f, 159 | _xpc_array_copy_mach_send, _xpc_array_create, _xpc_array_create_connection, 160 | _xpc_array_create_empty, _xpc_array_dup_fd, _xpc_array_get_array, 161 | _xpc_array_get_bool, _xpc_array_get_count, _xpc_array_get_data, 162 | _xpc_array_get_date, _xpc_array_get_dictionary, _xpc_array_get_double, 163 | _xpc_array_get_int64, _xpc_array_get_pointer, _xpc_array_get_string, 164 | _xpc_array_get_uint64, _xpc_array_get_uuid, _xpc_array_get_value, 165 | _xpc_array_set_bool, _xpc_array_set_connection, _xpc_array_set_data, 166 | _xpc_array_set_date, _xpc_array_set_double, _xpc_array_set_fd, 167 | _xpc_array_set_int64, _xpc_array_set_mach_send, _xpc_array_set_pointer, 168 | _xpc_array_set_string, _xpc_array_set_uint64, _xpc_array_set_uuid, 169 | _xpc_array_set_value, _xpc_atfork_child, _xpc_atfork_parent, 170 | _xpc_atfork_prepare, _xpc_binprefs_add, _xpc_binprefs_alloc, 171 | _xpc_binprefs_copy, _xpc_binprefs_copy_description, _xpc_binprefs_count, 172 | _xpc_binprefs_cpu_subtype, _xpc_binprefs_cpu_type, _xpc_binprefs_equal, 173 | _xpc_binprefs_init, _xpc_binprefs_is_noop, _xpc_binprefs_set_psattr, 174 | _xpc_bool_create, _xpc_bool_get_value, _xpc_bs_main, _xpc_bundle_copy_info_dictionary, 175 | _xpc_bundle_copy_normalized_cryptex_path, _xpc_bundle_copy_resource_path, 176 | _xpc_bundle_copy_services, _xpc_bundle_create, _xpc_bundle_create_from_origin, 177 | _xpc_bundle_create_main, _xpc_bundle_get_error, _xpc_bundle_get_executable_path, 178 | _xpc_bundle_get_info_dictionary, _xpc_bundle_get_path, _xpc_bundle_get_property, 179 | _xpc_bundle_get_xpcservice_dictionary, _xpc_bundle_populate, 180 | _xpc_bundle_resolve, _xpc_bundle_resolve_on_queue, _xpc_bundle_resolve_sync, 181 | _xpc_coalition_copy_info, _xpc_coalition_history_pipe_async, 182 | _xpc_connection_activate, _xpc_connection_cancel, _xpc_connection_copy_bundle_id, 183 | _xpc_connection_copy_entitlement_value, _xpc_connection_copy_invalidation_reason, 184 | _xpc_connection_create, _xpc_connection_create_bs_service_listener, 185 | _xpc_connection_create_from_endpoint, _xpc_connection_create_listener, 186 | _xpc_connection_create_mach_service, _xpc_connection_enable_sim2host_4sim, 187 | _xpc_connection_enable_termination_imminent_event, _xpc_connection_get_asid, 188 | _xpc_connection_get_audit_token, _xpc_connection_get_bs_type, 189 | _xpc_connection_get_context, _xpc_connection_get_egid, _xpc_connection_get_euid, 190 | _xpc_connection_get_filter_policy_id_4test, _xpc_connection_get_instance, 191 | _xpc_connection_get_name, _xpc_connection_get_peer_instance, 192 | _xpc_connection_get_pid, _xpc_connection_is_extension, _xpc_connection_kill, 193 | _xpc_connection_resume, _xpc_connection_send_barrier, _xpc_connection_send_message, 194 | _xpc_connection_send_message_with_reply, _xpc_connection_send_message_with_reply_sync, 195 | _xpc_connection_send_notification, _xpc_connection_set_bootstrap, 196 | _xpc_connection_set_bs_type, _xpc_connection_set_context, 197 | _xpc_connection_set_distorter, _xpc_connection_set_event_channel, 198 | _xpc_connection_set_event_handler, _xpc_connection_set_finalizer_f, 199 | _xpc_connection_set_instance, _xpc_connection_set_instance_binpref, 200 | _xpc_connection_set_legacy, _xpc_connection_set_non_launching, 201 | _xpc_connection_set_oneshot_instance, _xpc_connection_set_peer_code_signing_requirement, 202 | _xpc_connection_set_privileged, _xpc_connection_set_qos_class_fallback, 203 | _xpc_connection_set_qos_class_floor, _xpc_connection_set_target_queue, 204 | _xpc_connection_set_target_uid, _xpc_connection_set_target_user_session_uid, 205 | _xpc_connection_suspend, _xpc_copy, _xpc_copy_bootstrap, _xpc_copy_clean_description, 206 | _xpc_copy_code_signing_identity_for_token, _xpc_copy_debug_description, 207 | _xpc_copy_description, _xpc_copy_domain, _xpc_copy_entitlement_for_self, 208 | _xpc_copy_entitlement_for_token, _xpc_copy_entitlements_data_for_token, 209 | _xpc_copy_entitlements_for_pid, _xpc_copy_entitlements_for_self, 210 | _xpc_copy_event, _xpc_copy_event_entitlements, _xpc_copy_short_description, 211 | _xpc_create_from_ce_der, _xpc_create_from_ce_der_with_key, 212 | _xpc_create_from_plist, _xpc_create_from_plist_descriptor, 213 | _xpc_create_from_serialization, _xpc_create_from_serialization_with_ool, 214 | _xpc_create_reply_with_format, _xpc_create_reply_with_format_and_arguments, 215 | _xpc_create_with_format, _xpc_create_with_format_and_arguments, 216 | _xpc_data_create, _xpc_data_create_with_dispatch_data, _xpc_data_get_bytes, 217 | _xpc_data_get_bytes_ptr, _xpc_data_get_bytes_ptr_and_length, 218 | _xpc_data_get_inline_max, _xpc_data_get_length, _xpc_date_create, 219 | _xpc_date_create_absolute, _xpc_date_create_from_current, 220 | _xpc_date_get_value, _xpc_date_get_value_absolute, _xpc_date_is_int64_range, 221 | _xpc_dictionary_apply, _xpc_dictionary_apply_f, _xpc_dictionary_copy_basic_description, 222 | _xpc_dictionary_copy_mach_send, _xpc_dictionary_create, _xpc_dictionary_create_connection, 223 | _xpc_dictionary_create_empty, _xpc_dictionary_create_reply, 224 | _xpc_dictionary_dup_fd, _xpc_dictionary_expects_reply, _xpc_dictionary_extract_mach_recv, 225 | _xpc_dictionary_get_array, _xpc_dictionary_get_audit_token, 226 | _xpc_dictionary_get_bool, _xpc_dictionary_get_connection, 227 | _xpc_dictionary_get_count, _xpc_dictionary_get_data, _xpc_dictionary_get_date, 228 | _xpc_dictionary_get_dictionary, _xpc_dictionary_get_double, 229 | _xpc_dictionary_get_int64, _xpc_dictionary_get_pointer, _xpc_dictionary_get_remote_connection, 230 | _xpc_dictionary_get_string, _xpc_dictionary_get_uint64, _xpc_dictionary_get_uuid, 231 | _xpc_dictionary_get_value, _xpc_dictionary_handoff_reply, 232 | _xpc_dictionary_handoff_reply_f, _xpc_dictionary_send_reply, 233 | _xpc_dictionary_send_reply_4SWIFT, _xpc_dictionary_set_bool, 234 | _xpc_dictionary_set_connection, _xpc_dictionary_set_data, 235 | _xpc_dictionary_set_date, _xpc_dictionary_set_double, _xpc_dictionary_set_fd, 236 | _xpc_dictionary_set_int64, _xpc_dictionary_set_mach_recv, 237 | _xpc_dictionary_set_mach_send, _xpc_dictionary_set_pointer, 238 | _xpc_dictionary_set_string, _xpc_dictionary_set_uint64, _xpc_dictionary_set_uuid, 239 | _xpc_dictionary_set_value, _xpc_double_create, _xpc_double_get_value, 240 | _xpc_endpoint_compare, _xpc_endpoint_copy_listener_port_4sim, 241 | _xpc_endpoint_create, _xpc_endpoint_create_bs_named, _xpc_endpoint_create_bs_service, 242 | _xpc_endpoint_create_mach_port_4sim, _xpc_endpoint_get_bs_job_handle, 243 | _xpc_equal, _xpc_event_publisher_activate, _xpc_event_publisher_copy_event, 244 | _xpc_event_publisher_create, _xpc_event_publisher_fire, _xpc_event_publisher_fire_noboost, 245 | _xpc_event_publisher_fire_with_reply, _xpc_event_publisher_fire_with_reply_sync, 246 | _xpc_event_publisher_get_subscriber_asid, _xpc_event_publisher_set_error_handler, 247 | _xpc_event_publisher_set_event, _xpc_event_publisher_set_handler, 248 | _xpc_event_publisher_set_initial_load_completed_handler_4remoted, 249 | _xpc_event_publisher_set_subscriber_keepalive, _xpc_event_stream_check_in, 250 | _xpc_event_stream_check_in2, _xpc_exit_reason_get_label, _xpc_extension_type_init, 251 | _xpc_fd_create, _xpc_fd_dup, _xpc_file_transfer_cancel, _xpc_file_transfer_copy_io, 252 | _xpc_file_transfer_create_with_fd, _xpc_file_transfer_create_with_path, 253 | _xpc_file_transfer_get_size, _xpc_file_transfer_get_transfer_id, 254 | _xpc_file_transfer_send_finished, _xpc_file_transfer_set_transport_writing_callbacks, 255 | _xpc_file_transfer_write_finished, _xpc_file_transfer_write_to_fd, 256 | _xpc_file_transfer_write_to_path, _xpc_generate_audit_token, 257 | _xpc_get_attachment_endpoint, _xpc_get_class4NSXPC, _xpc_get_event_name, 258 | _xpc_get_instance, _xpc_get_type, _xpc_handle_service, _xpc_handle_subservice, 259 | _xpc_hash, _xpc_impersonate_user, _xpc_init_services, _xpc_inspect_copy_description, 260 | _xpc_inspect_copy_description_local, _xpc_inspect_copy_short_description, 261 | _xpc_inspect_copy_short_description_local, _xpc_install_remote_hooks, 262 | _xpc_int64_create, _xpc_int64_get_value, _xpc_is_kind_of_xpc_object4NSXPC, 263 | _xpc_is_system_session, _xpc_listener_activate, _xpc_listener_cancel, 264 | _xpc_listener_copy_description, _xpc_listener_create, _xpc_listener_create_anonymous, 265 | _xpc_listener_create_endpoint, _xpc_listener_reject_peer, 266 | _xpc_mach_recv_create, _xpc_mach_recv_extract_right, _xpc_mach_send_copy_right, 267 | _xpc_mach_send_create, _xpc_mach_send_create_with_disposition, 268 | _xpc_mach_send_get_right, _xpc_mach_send_once_create, _xpc_mach_send_once_extract_right, 269 | _xpc_main, _xpc_make_serialization, _xpc_make_serialization_with_ool, 270 | _xpc_null_create, _xpc_pipe_create, _xpc_pipe_create_from_port, 271 | _xpc_pipe_create_reply_from_port, _xpc_pipe_create_with_user_session_uid, 272 | _xpc_pipe_invalidate, _xpc_pipe_receive, _xpc_pipe_routine, 273 | _xpc_pipe_routine_async, _xpc_pipe_routine_forward, _xpc_pipe_routine_reply, 274 | _xpc_pipe_routine_with_flags, _xpc_pipe_simpleroutine, _xpc_pipe_try_receive, 275 | _xpc_pointer_create, _xpc_pointer_get_value, _xpc_receive_mach_msg, 276 | _xpc_receive_remote_msg, _xpc_release, _xpc_retain, _xpc_rich_error_can_retry, 277 | _xpc_rich_error_copy_description, _xpc_service_attach, _xpc_service_attach_with_flags, 278 | _xpc_service_create, _xpc_service_create_from_specifier, _xpc_service_get_rendezvous_token, 279 | _xpc_service_instance_dup2, _xpc_service_instance_get_context, 280 | _xpc_service_instance_get_host_pid, _xpc_service_instance_get_pid, 281 | _xpc_service_instance_get_type, _xpc_service_instance_is_configurable, 282 | _xpc_service_instance_run, _xpc_service_instance_set_binpref, 283 | _xpc_service_instance_set_context, _xpc_service_instance_set_cwd, 284 | _xpc_service_instance_set_endpoint, _xpc_service_instance_set_environment, 285 | _xpc_service_instance_set_finalizer_f, _xpc_service_instance_set_jetsam_properties, 286 | _xpc_service_instance_set_path, _xpc_service_instance_set_start_suspended, 287 | _xpc_service_kickstart, _xpc_service_kickstart_with_flags, 288 | _xpc_service_set_attach_handler, _xpc_session_activate, _xpc_session_cancel, 289 | _xpc_session_copy_description, _xpc_session_create_mach_service, 290 | _xpc_session_create_xpc_endpoint, _xpc_session_create_xpc_service, 291 | _xpc_session_send_message, _xpc_session_send_message_with_reply_async, 292 | _xpc_session_send_message_with_reply_sync, _xpc_session_set_cancel_handler, 293 | _xpc_session_set_incoming_message_handler, _xpc_session_set_target_queue, 294 | _xpc_session_set_target_user_session_uid, _xpc_set_event, 295 | _xpc_set_event_state, _xpc_set_event_stream_handler, _xpc_set_event_with_flags, 296 | _xpc_set_idle_handler, _xpc_shmem_create, _xpc_shmem_create_readonly, 297 | _xpc_shmem_get_length, _xpc_shmem_map, _xpc_strerror, _xpc_string_create, 298 | _xpc_string_create_no_copy, _xpc_string_create_with_format, 299 | _xpc_string_create_with_format_and_arguments, _xpc_string_get_length, 300 | _xpc_string_get_string_ptr, _xpc_test_symbols_exported, _xpc_track_activity, 301 | _xpc_transaction_begin, _xpc_transaction_end, _xpc_transaction_exit_clean, 302 | _xpc_transaction_interrupt_clean_exit, _xpc_transaction_try_exit_clean, 303 | _xpc_transactions_enable, _xpc_traverse_serialized_data, _xpc_type_get_name, 304 | _xpc_uint64_create, _xpc_uint64_get_value, _xpc_user_sessions_enabled, 305 | _xpc_user_sessions_get_foreground_uid, _xpc_user_sessions_get_session_uid, 306 | _xpc_uuid_create, _xpc_uuid_get_bytes ] 307 | objc-classes: [ OS_xpc_object ] 308 | ... 309 | --------------------------------------------------------------------------------