├── .gitignore ├── AltSpringBoardServices.mm ├── Makefile ├── README.md ├── include └── libSandy.h ├── layout ├── DEBIAN │ ├── control │ ├── postinst │ └── prerm └── Library │ ├── MobileSubstrate │ └── DynamicLibraries │ │ ├── AltSpringBoardServices.dylib │ │ └── AltSpringBoardServices.plist │ └── libSandy │ └── com.darwindev.AltSpringBoardServices.plist ├── springboard.h └── springboard.m /.gitignore: -------------------------------------------------------------------------------- 1 | .theos/ 2 | packages/ 3 | -------------------------------------------------------------------------------- /AltSpringBoardServices.mm: -------------------------------------------------------------------------------- 1 | #if ! __has_feature(objc_arc) 2 | #error This file must be compiled with ARC. Use -fobjc-arc flag. 3 | #endif 4 | 5 | #import "springboard.h" 6 | 7 | #import 8 | #import 9 | #import 10 | #import 11 | #import 12 | #import 13 | #import 14 | 15 | 16 | #define SB_SERVICE_NAME "com.darwindev.AltSpringBoard" 17 | #define SBS_SERVICE_NAME "com.darwindev.AltSpringBoardServices" 18 | 19 | #define SERVICE_SEND_TIMEOUT 3.0 20 | #define SERVICE_RECV_TIMEOUT 3.0 21 | 22 | 23 | #pragma mark - 24 | 25 | #define SBSCopyFrontmostApplicationDisplayIdentifierMsgID 0x1000 26 | #define SBSCopyApplicationDisplayIdentifiersMsgID 0x1001 27 | #define SBSCopyDisplayIdentifierForProcessIDMsgID 0x1002 28 | #define SBSCopyLocalizedApplicationNameForDisplayIdentifierMsgID 0x1003 29 | #define SBSCopyIconImagePNGDataForDisplayIdentifierMsgID 0x1004 30 | #define SBSCopyInfoForApplicationWithProcessIDMsgID 0x1005 31 | #define SBSProcessIDForDisplayIdentifierMsgID 0x1006 32 | #define SBSLaunchApplicationWithIdentifierMsgID 0x1100 33 | #define SBSLaunchApplicationWithIdentifierAndLaunchOptionsMsgID 0x1101 34 | #define SBSLaunchApplicationWithIdentifierAndURLAndLaunchOptionsMsgID 0x1102 35 | #define SBSApplicationLaunchingErrorStringMsgID 0x1103 36 | 37 | 38 | #pragma mark - 39 | 40 | @interface SBApplication : NSObject 41 | - (NSString *)bundleIdentifier; 42 | @end 43 | 44 | @interface SpringBoard : UIApplication 45 | + (SpringBoard *)sharedApplication; 46 | - (SBApplication *)_accessibilityFrontMostApplication; 47 | @end 48 | 49 | 50 | #pragma mark - 51 | 52 | __used 53 | static AltSpringboardApi *AltGetSpringBoardServicesApi(void) 54 | { 55 | static AltSpringboardApi *_api = NULL; 56 | static dispatch_once_t onceToken; 57 | dispatch_once(&onceToken, ^(void) { 58 | _api = _alt_get_springboard_api(); 59 | }); 60 | return _api; 61 | } 62 | 63 | __used 64 | static CFMessagePortRef AltCreateSpringBoardRemotePort(void) 65 | { 66 | return rocketbootstrap_cfmessageportcreateremote(kCFAllocatorDefault, CFSTR(SB_SERVICE_NAME)); 67 | } 68 | 69 | __used 70 | static CFMessagePortRef AltCreateSpringBoardServicesRemotePort(void) 71 | { 72 | return rocketbootstrap_cfmessageportcreateremote(kCFAllocatorDefault, CFSTR(SBS_SERVICE_NAME)); 73 | } 74 | 75 | __used 76 | static CFDataRef AltSpringBoardCallback(CFMessagePortRef port, SInt32 messageID, CFDataRef data, void *info) 77 | { 78 | #if DEBUG 79 | NSArray *arguments = nil; 80 | if (data) 81 | { 82 | CFPropertyListRef argumentsList = 83 | CFPropertyListCreateWithData(kCFAllocatorDefault, data, kCFPropertyListImmutable, NULL, NULL); 84 | if (argumentsList && CFGetTypeID(argumentsList) == CFArrayGetTypeID()) 85 | arguments = (NSArray *)CFBridgingRelease(argumentsList); 86 | } 87 | #endif 88 | 89 | CFPropertyListRef returnObj = NULL; 90 | if (messageID == SBSCopyFrontmostApplicationDisplayIdentifierMsgID) 91 | { 92 | NSString *bundleIdentifier = 93 | [[(SpringBoard *)[objc_getClass("SpringBoard") sharedApplication] _accessibilityFrontMostApplication] bundleIdentifier]; 94 | returnObj = (CFPropertyListRef)CFBridgingRetain(bundleIdentifier); 95 | } 96 | 97 | #if DEBUG 98 | os_log_debug(OS_LOG_DEFAULT, SB_SERVICE_NAME " %{public}d %{public}@ -> %{public}@", messageID, arguments, returnObj); 99 | #endif 100 | 101 | if (!returnObj) 102 | return NULL; 103 | 104 | CFDataRef returnData = 105 | CFPropertyListCreateData(kCFAllocatorDefault, returnObj, kCFPropertyListBinaryFormat_v1_0, 0, NULL); 106 | CFRelease(returnObj); 107 | 108 | return returnData; 109 | } 110 | 111 | __used 112 | static CFDataRef AltSpringBoardServicesCallback(CFMessagePortRef port, SInt32 messageID, CFDataRef data, void *info) 113 | { 114 | #if DEBUG 115 | os_log_debug(OS_LOG_DEFAULT, SBS_SERVICE_NAME " %{public}@ %{public}d %{public}@", port, messageID, data); 116 | #endif 117 | 118 | NSArray *arguments = nil; 119 | if (data) 120 | { 121 | CFPropertyListRef argumentsList = 122 | CFPropertyListCreateWithData(kCFAllocatorDefault, data, kCFPropertyListImmutable, NULL, NULL); 123 | if (argumentsList && CFGetTypeID(argumentsList) == CFArrayGetTypeID()) 124 | arguments = (NSArray *)CFBridgingRelease(argumentsList); 125 | } 126 | 127 | CFPropertyListRef returnObj = NULL; 128 | if (messageID == SBSCopyApplicationDisplayIdentifiersMsgID) 129 | { 130 | if (arguments.count != 2) return NULL; 131 | returnObj = (CFPropertyListRef)AltGetSpringBoardServicesApi()->SBSCopyApplicationDisplayIdentifiers([arguments[0] boolValue], [arguments[1] boolValue]); 132 | } 133 | else if (messageID == SBSCopyDisplayIdentifierForProcessIDMsgID) 134 | { 135 | if (arguments.count != 1) return NULL; 136 | returnObj = (CFPropertyListRef)AltGetSpringBoardServicesApi()->SBSCopyDisplayIdentifierForProcessID([arguments[0] unsignedIntValue]); 137 | } 138 | else if (messageID == SBSCopyLocalizedApplicationNameForDisplayIdentifierMsgID) 139 | { 140 | if (arguments.count != 1) return NULL; 141 | returnObj = (CFPropertyListRef)AltGetSpringBoardServicesApi()->SBSCopyLocalizedApplicationNameForDisplayIdentifier((__bridge CFStringRef)arguments[0]); 142 | } 143 | else if (messageID == SBSCopyIconImagePNGDataForDisplayIdentifierMsgID) 144 | { 145 | if (arguments.count != 1) return NULL; 146 | returnObj = (CFPropertyListRef)AltGetSpringBoardServicesApi()->SBSCopyIconImagePNGDataForDisplayIdentifier((__bridge CFStringRef)arguments[0]); 147 | } 148 | else if (messageID == SBSCopyInfoForApplicationWithProcessIDMsgID) 149 | { 150 | if (arguments.count != 1) return NULL; 151 | returnObj = (CFPropertyListRef)AltGetSpringBoardServicesApi()->SBSCopyInfoForApplicationWithProcessID([arguments[0] unsignedIntValue]); 152 | } 153 | else if (messageID == SBSProcessIDForDisplayIdentifierMsgID) 154 | { 155 | if (arguments.count != 1) return NULL; 156 | returnObj = (CFPropertyListRef)CFBridgingRetain(@(AltGetSpringBoardServicesApi()->SBSProcessIDForDisplayIdentifier((__bridge CFStringRef)arguments[0]))); 157 | } 158 | else if (messageID == SBSLaunchApplicationWithIdentifierMsgID) 159 | { 160 | if (arguments.count != 1) return NULL; 161 | returnObj = (CFPropertyListRef)CFBridgingRetain(@(AltGetSpringBoardServicesApi()->SBSLaunchApplicationWithIdentifier((__bridge CFStringRef)arguments[0]))); 162 | } 163 | else if (messageID == SBSLaunchApplicationWithIdentifierAndLaunchOptionsMsgID) 164 | { 165 | if (arguments.count != 3) return NULL; 166 | returnObj = (CFPropertyListRef)CFBridgingRetain(@(AltGetSpringBoardServicesApi()->SBSLaunchApplicationWithIdentifierAndLaunchOptions((__bridge CFStringRef)arguments[0], (__bridge CFDictionaryRef)arguments[1], [arguments[2] boolValue]))); 167 | } 168 | else if (messageID == SBSLaunchApplicationWithIdentifierAndURLAndLaunchOptionsMsgID) 169 | { 170 | if (arguments.count != 5) return NULL; 171 | returnObj = (CFPropertyListRef)CFBridgingRetain(@(AltGetSpringBoardServicesApi()->SBSLaunchApplicationWithIdentifierAndURLAndLaunchOptions((__bridge CFStringRef)arguments[0], (__bridge CFURLRef)arguments[1], (__bridge CFDictionaryRef)arguments[2], (__bridge CFDictionaryRef)arguments[3], [arguments[4] boolValue]))); 172 | } 173 | else if (messageID == SBSApplicationLaunchingErrorStringMsgID) 174 | { 175 | if (arguments.count != 1) return NULL; 176 | returnObj = (CFPropertyListRef)AltGetSpringBoardServicesApi()->SBSApplicationLaunchingErrorString([arguments[0] unsignedIntValue]); 177 | } 178 | 179 | #if DEBUG 180 | os_log_debug(OS_LOG_DEFAULT, SBS_SERVICE_NAME " %{public}d %{public}@ -> %{public}@", messageID, arguments, returnObj); 181 | #endif 182 | 183 | if (!returnObj) 184 | return NULL; 185 | 186 | CFDataRef returnData = 187 | CFPropertyListCreateData(kCFAllocatorDefault, returnObj, kCFPropertyListBinaryFormat_v1_0, 0, NULL); 188 | CFRelease(returnObj); 189 | 190 | return returnData; 191 | } 192 | 193 | 194 | #pragma mark - 195 | 196 | CF_EXTERN_C_BEGIN 197 | CFStringRef SBSCopyFrontmostApplicationDisplayIdentifier(void); 198 | CFArrayRef SBSCopyApplicationDisplayIdentifiers(BOOL active, BOOL debuggable); 199 | CFStringRef SBSCopyDisplayIdentifierForProcessID(UInt32 pid); 200 | CFStringRef SBSCopyLocalizedApplicationNameForDisplayIdentifier(CFStringRef identifier); 201 | CFDataRef SBSCopyIconImagePNGDataForDisplayIdentifier(CFStringRef identifier); 202 | CFDictionaryRef SBSCopyInfoForApplicationWithProcessID(UInt32 pid); 203 | UInt32 SBSProcessIDForDisplayIdentifier(CFStringRef identifier); 204 | UInt32 SBSLaunchApplicationWithIdentifier(CFStringRef identifier); 205 | UInt32 SBSLaunchApplicationWithIdentifierAndLaunchOptions(CFStringRef identifier, CFDictionaryRef options, BOOL suspended); 206 | UInt32 SBSLaunchApplicationWithIdentifierAndURLAndLaunchOptions(CFStringRef identifier, CFURLRef url, CFDictionaryRef params, CFDictionaryRef options, BOOL suspended); 207 | CFStringRef SBSApplicationLaunchingErrorString(UInt32 error); 208 | CFStringRef SBSApplicationLaunchOptionUnlockDeviceKey = CFSTR("unlockDevice"); 209 | CF_EXTERN_C_END 210 | 211 | 212 | #pragma mark - 213 | 214 | CFStringRef SBSCopyFrontmostApplicationDisplayIdentifier(void) 215 | { 216 | if (@available(iOS 15.0, *)) 217 | { 218 | CFMessagePortRef remotePort = AltCreateSpringBoardRemotePort(); 219 | if (!remotePort) return NULL; 220 | 221 | CFDataRef returnData = NULL; 222 | SInt32 status = 223 | CFMessagePortSendRequest(remotePort, 224 | SBSCopyFrontmostApplicationDisplayIdentifierMsgID, 225 | NULL, 226 | SERVICE_SEND_TIMEOUT, 227 | SERVICE_RECV_TIMEOUT, 228 | kCFRunLoopDefaultMode, 229 | &returnData); 230 | CFRelease(remotePort); 231 | 232 | if (status != kCFMessagePortSuccess) 233 | return NULL; 234 | 235 | CFPropertyListRef propertyList = 236 | CFPropertyListCreateWithData(kCFAllocatorDefault, returnData, kCFPropertyListImmutable, NULL, NULL); 237 | CFRelease(returnData); 238 | 239 | if (!propertyList) return NULL; 240 | 241 | if (CFGetTypeID(propertyList) != CFStringGetTypeID()) { 242 | CFRelease(propertyList); 243 | return NULL; 244 | } 245 | 246 | return (CFStringRef) propertyList; 247 | } 248 | else 249 | { 250 | return AltGetSpringBoardServicesApi()->SBSCopyFrontmostApplicationDisplayIdentifier(); 251 | } 252 | } 253 | 254 | CFArrayRef SBSCopyApplicationDisplayIdentifiers(BOOL active, BOOL debuggable) 255 | { 256 | if (@available(iOS 15.0, *)) 257 | { 258 | CFMessagePortRef remotePort = AltCreateSpringBoardServicesRemotePort(); 259 | if (!remotePort) return NULL; 260 | 261 | CFArrayRef arguments = (__bridge CFArrayRef)@[@(active), @(debuggable)]; 262 | CFDataRef argumentsData = 263 | CFPropertyListCreateData(kCFAllocatorDefault, arguments, kCFPropertyListBinaryFormat_v1_0, 0, NULL); 264 | 265 | CFDataRef returnData = NULL; 266 | SInt32 status = 267 | CFMessagePortSendRequest(remotePort, 268 | SBSCopyApplicationDisplayIdentifiersMsgID, 269 | argumentsData, 270 | SERVICE_SEND_TIMEOUT, 271 | SERVICE_RECV_TIMEOUT, 272 | kCFRunLoopDefaultMode, 273 | &returnData); 274 | CFRelease(remotePort); 275 | CFRelease(argumentsData); 276 | 277 | if (status != kCFMessagePortSuccess) 278 | return NULL; 279 | 280 | CFPropertyListRef propertyList = 281 | CFPropertyListCreateWithData(kCFAllocatorDefault, returnData, kCFPropertyListImmutable, NULL, NULL); 282 | CFRelease(returnData); 283 | 284 | if (!propertyList) return NULL; 285 | 286 | if (CFGetTypeID(propertyList) != CFArrayGetTypeID()) { 287 | CFRelease(propertyList); 288 | return NULL; 289 | } 290 | 291 | return (CFArrayRef) propertyList; 292 | } 293 | else 294 | { 295 | return AltGetSpringBoardServicesApi()->SBSCopyApplicationDisplayIdentifiers(active, debuggable); 296 | } 297 | } 298 | 299 | CFStringRef SBSCopyDisplayIdentifierForProcessID(UInt32 pid) 300 | { 301 | if (pid <= 1) return NULL; 302 | if (@available(iOS 15.0, *)) 303 | { 304 | CFMessagePortRef remotePort = AltCreateSpringBoardServicesRemotePort(); 305 | if (!remotePort) return NULL; 306 | 307 | CFArrayRef arguments = (__bridge CFArrayRef)@[@(pid)]; 308 | CFDataRef argumentsData = 309 | CFPropertyListCreateData(kCFAllocatorDefault, arguments, kCFPropertyListBinaryFormat_v1_0, 0, NULL); 310 | 311 | CFDataRef returnData = NULL; 312 | SInt32 status = 313 | CFMessagePortSendRequest(remotePort, 314 | SBSCopyDisplayIdentifierForProcessIDMsgID, 315 | argumentsData, 316 | SERVICE_SEND_TIMEOUT, 317 | SERVICE_RECV_TIMEOUT, 318 | kCFRunLoopDefaultMode, 319 | &returnData); 320 | CFRelease(remotePort); 321 | CFRelease(argumentsData); 322 | 323 | if (status != kCFMessagePortSuccess) 324 | return NULL; 325 | 326 | CFPropertyListRef propertyList = 327 | CFPropertyListCreateWithData(kCFAllocatorDefault, returnData, kCFPropertyListImmutable, NULL, NULL); 328 | CFRelease(returnData); 329 | 330 | if (!propertyList) return NULL; 331 | 332 | if (CFGetTypeID(propertyList) != CFStringGetTypeID()) { 333 | CFRelease(propertyList); 334 | return NULL; 335 | } 336 | 337 | return (CFStringRef) propertyList; 338 | } 339 | else 340 | { 341 | return AltGetSpringBoardServicesApi()->SBSCopyDisplayIdentifierForProcessID(pid); 342 | } 343 | } 344 | 345 | CFStringRef SBSCopyLocalizedApplicationNameForDisplayIdentifier(CFStringRef identifier) 346 | { 347 | if (!identifier) return NULL; 348 | if (@available(iOS 15.0, *)) 349 | { 350 | CFMessagePortRef remotePort = AltCreateSpringBoardServicesRemotePort(); 351 | if (!remotePort) return NULL; 352 | 353 | CFArrayRef arguments = (__bridge CFArrayRef)@[(__bridge NSString *)identifier]; 354 | CFDataRef argumentsData = 355 | CFPropertyListCreateData(kCFAllocatorDefault, arguments, kCFPropertyListBinaryFormat_v1_0, 0, NULL); 356 | 357 | CFDataRef returnData = NULL; 358 | SInt32 status = 359 | CFMessagePortSendRequest(remotePort, 360 | SBSCopyLocalizedApplicationNameForDisplayIdentifierMsgID, 361 | argumentsData, 362 | SERVICE_SEND_TIMEOUT, 363 | SERVICE_RECV_TIMEOUT, 364 | kCFRunLoopDefaultMode, 365 | &returnData); 366 | CFRelease(remotePort); 367 | CFRelease(argumentsData); 368 | 369 | if (status != kCFMessagePortSuccess) 370 | return NULL; 371 | 372 | CFPropertyListRef propertyList = 373 | CFPropertyListCreateWithData(kCFAllocatorDefault, returnData, kCFPropertyListImmutable, NULL, NULL); 374 | CFRelease(returnData); 375 | 376 | if (!propertyList) return NULL; 377 | 378 | if (CFGetTypeID(propertyList) != CFStringGetTypeID()) { 379 | CFRelease(propertyList); 380 | return NULL; 381 | } 382 | 383 | return (CFStringRef) propertyList; 384 | } 385 | else 386 | { 387 | return AltGetSpringBoardServicesApi()->SBSCopyLocalizedApplicationNameForDisplayIdentifier(identifier); 388 | } 389 | } 390 | 391 | CFDataRef SBSCopyIconImagePNGDataForDisplayIdentifier(CFStringRef identifier) 392 | { 393 | if (!identifier) return NULL; 394 | if (@available(iOS 15.0, *)) 395 | { 396 | CFMessagePortRef remotePort = AltCreateSpringBoardServicesRemotePort(); 397 | if (!remotePort) return NULL; 398 | 399 | CFArrayRef arguments = (__bridge CFArrayRef)@[(__bridge NSString *)identifier]; 400 | CFDataRef argumentsData = 401 | CFPropertyListCreateData(kCFAllocatorDefault, arguments, kCFPropertyListBinaryFormat_v1_0, 0, NULL); 402 | 403 | CFDataRef returnData = NULL; 404 | SInt32 status = 405 | CFMessagePortSendRequest(remotePort, 406 | SBSCopyIconImagePNGDataForDisplayIdentifierMsgID, 407 | argumentsData, 408 | SERVICE_SEND_TIMEOUT, 409 | SERVICE_RECV_TIMEOUT, 410 | kCFRunLoopDefaultMode, 411 | &returnData); 412 | CFRelease(remotePort); 413 | CFRelease(argumentsData); 414 | 415 | if (status != kCFMessagePortSuccess) 416 | return NULL; 417 | 418 | CFPropertyListRef propertyList = 419 | CFPropertyListCreateWithData(kCFAllocatorDefault, returnData, kCFPropertyListImmutable, NULL, NULL); 420 | CFRelease(returnData); 421 | 422 | if (!propertyList) return NULL; 423 | 424 | if (CFGetTypeID(propertyList) != CFDataGetTypeID()) { 425 | CFRelease(propertyList); 426 | return NULL; 427 | } 428 | 429 | return (CFDataRef) propertyList; 430 | } 431 | else 432 | { 433 | return AltGetSpringBoardServicesApi()->SBSCopyIconImagePNGDataForDisplayIdentifier(identifier); 434 | } 435 | } 436 | 437 | CFDictionaryRef SBSCopyInfoForApplicationWithProcessID(UInt32 pid) 438 | { 439 | if (pid <= 1) return NULL; 440 | if (@available(iOS 15.0, *)) 441 | { 442 | CFMessagePortRef remotePort = AltCreateSpringBoardServicesRemotePort(); 443 | if (!remotePort) return NULL; 444 | 445 | CFArrayRef arguments = (__bridge CFArrayRef)@[@(pid)]; 446 | CFDataRef argumentsData = 447 | CFPropertyListCreateData(kCFAllocatorDefault, arguments, kCFPropertyListBinaryFormat_v1_0, 0, NULL); 448 | 449 | CFDataRef returnData = NULL; 450 | SInt32 status = 451 | CFMessagePortSendRequest(remotePort, 452 | SBSCopyInfoForApplicationWithProcessIDMsgID, 453 | argumentsData, 454 | SERVICE_SEND_TIMEOUT, 455 | SERVICE_RECV_TIMEOUT, 456 | kCFRunLoopDefaultMode, 457 | &returnData); 458 | CFRelease(remotePort); 459 | CFRelease(argumentsData); 460 | 461 | if (status != kCFMessagePortSuccess) 462 | return NULL; 463 | 464 | CFPropertyListRef propertyList = 465 | CFPropertyListCreateWithData(kCFAllocatorDefault, returnData, kCFPropertyListImmutable, NULL, NULL); 466 | CFRelease(returnData); 467 | 468 | if (!propertyList) return NULL; 469 | 470 | if (CFGetTypeID(propertyList) != CFDictionaryGetTypeID()) { 471 | CFRelease(propertyList); 472 | return NULL; 473 | } 474 | 475 | return (CFDictionaryRef) propertyList; 476 | } 477 | else 478 | { 479 | return AltGetSpringBoardServicesApi()->SBSCopyInfoForApplicationWithProcessID(pid); 480 | } 481 | } 482 | 483 | UInt32 SBSLaunchApplicationWithIdentifier(CFStringRef identifier) 484 | { 485 | if (!identifier) return 0; 486 | if (@available(iOS 15.0, *)) 487 | { 488 | CFMessagePortRef remotePort = AltCreateSpringBoardServicesRemotePort(); 489 | if (!remotePort) return 0; 490 | 491 | CFArrayRef arguments = (__bridge CFArrayRef)@[(__bridge NSString *)identifier]; 492 | CFDataRef argumentsData = 493 | CFPropertyListCreateData(kCFAllocatorDefault, arguments, kCFPropertyListBinaryFormat_v1_0, 0, NULL); 494 | 495 | CFDataRef returnData = NULL; 496 | SInt32 status = 497 | CFMessagePortSendRequest(remotePort, 498 | SBSLaunchApplicationWithIdentifierMsgID, 499 | argumentsData, 500 | SERVICE_SEND_TIMEOUT, 501 | SERVICE_RECV_TIMEOUT, 502 | kCFRunLoopDefaultMode, 503 | &returnData); 504 | CFRelease(remotePort); 505 | CFRelease(argumentsData); 506 | 507 | if (status != kCFMessagePortSuccess) 508 | return 0; 509 | 510 | CFPropertyListRef propertyList = 511 | CFPropertyListCreateWithData(kCFAllocatorDefault, returnData, kCFPropertyListImmutable, NULL, NULL); 512 | CFRelease(returnData); 513 | 514 | if (!propertyList) return 0; 515 | 516 | if (CFGetTypeID(propertyList) != CFNumberGetTypeID()) { 517 | CFRelease(propertyList); 518 | return 0; 519 | } 520 | 521 | UInt32 pid = 0; 522 | CFNumberGetValue((CFNumberRef) propertyList, kCFNumberSInt32Type, &pid); 523 | CFRelease(propertyList); 524 | 525 | return pid; 526 | } 527 | else 528 | { 529 | return AltGetSpringBoardServicesApi()->SBSLaunchApplicationWithIdentifier(identifier); 530 | } 531 | } 532 | 533 | UInt32 SBSLaunchApplicationWithIdentifierAndLaunchOptions(CFStringRef identifier, CFDictionaryRef options, BOOL suspended) 534 | { 535 | if (!identifier) return 0; 536 | if (@available(iOS 15.0, *)) 537 | { 538 | CFMessagePortRef remotePort = AltCreateSpringBoardServicesRemotePort(); 539 | if (!remotePort) return 0; 540 | 541 | CFArrayRef arguments = (__bridge CFArrayRef)@[(__bridge NSString *)identifier, (__bridge NSDictionary *)options, @(suspended)]; 542 | CFDataRef argumentsData = 543 | CFPropertyListCreateData(kCFAllocatorDefault, arguments, kCFPropertyListBinaryFormat_v1_0, 0, NULL); 544 | 545 | CFDataRef returnData = NULL; 546 | SInt32 status = 547 | CFMessagePortSendRequest(remotePort, 548 | SBSLaunchApplicationWithIdentifierAndLaunchOptionsMsgID, 549 | argumentsData, 550 | SERVICE_SEND_TIMEOUT, 551 | SERVICE_RECV_TIMEOUT, 552 | kCFRunLoopDefaultMode, 553 | &returnData); 554 | CFRelease(remotePort); 555 | CFRelease(argumentsData); 556 | 557 | if (status != kCFMessagePortSuccess) 558 | return 0; 559 | 560 | CFPropertyListRef propertyList = 561 | CFPropertyListCreateWithData(kCFAllocatorDefault, returnData, kCFPropertyListImmutable, NULL, NULL); 562 | CFRelease(returnData); 563 | 564 | if (!propertyList) return 0; 565 | 566 | if (CFGetTypeID(propertyList) != CFNumberGetTypeID()) { 567 | CFRelease(propertyList); 568 | return 0; 569 | } 570 | 571 | UInt32 pid = 0; 572 | CFNumberGetValue((CFNumberRef) propertyList, kCFNumberSInt32Type, &pid); 573 | CFRelease(propertyList); 574 | 575 | return pid; 576 | } 577 | else 578 | { 579 | return AltGetSpringBoardServicesApi()->SBSLaunchApplicationWithIdentifierAndLaunchOptions(identifier, options, suspended); 580 | } 581 | } 582 | 583 | UInt32 SBSLaunchApplicationWithIdentifierAndURLAndLaunchOptions(CFStringRef identifier, CFURLRef url, CFDictionaryRef params, CFDictionaryRef options, BOOL suspended) 584 | { 585 | if (!identifier) return 0; 586 | if (@available(iOS 15.0, *)) 587 | { 588 | CFMessagePortRef remotePort = AltCreateSpringBoardServicesRemotePort(); 589 | if (!remotePort) return 0; 590 | 591 | CFArrayRef arguments = (__bridge CFArrayRef)@[(__bridge NSString *)identifier, (__bridge NSURL *)url, (__bridge NSDictionary *)params, (__bridge NSDictionary *)options, @(suspended)]; 592 | CFDataRef argumentsData = 593 | CFPropertyListCreateData(kCFAllocatorDefault, arguments, kCFPropertyListBinaryFormat_v1_0, 0, NULL); 594 | 595 | CFDataRef returnData = NULL; 596 | SInt32 status = 597 | CFMessagePortSendRequest(remotePort, 598 | SBSLaunchApplicationWithIdentifierAndURLAndLaunchOptionsMsgID, 599 | argumentsData, 600 | SERVICE_SEND_TIMEOUT, 601 | SERVICE_RECV_TIMEOUT, 602 | kCFRunLoopDefaultMode, 603 | &returnData); 604 | CFRelease(remotePort); 605 | CFRelease(argumentsData); 606 | 607 | if (status != kCFMessagePortSuccess) 608 | return 0; 609 | 610 | CFPropertyListRef propertyList = 611 | CFPropertyListCreateWithData(kCFAllocatorDefault, returnData, kCFPropertyListImmutable, NULL, NULL); 612 | CFRelease(returnData); 613 | 614 | if (!propertyList) return 0; 615 | 616 | if (CFGetTypeID(propertyList) != CFNumberGetTypeID()) { 617 | CFRelease(propertyList); 618 | return 0; 619 | } 620 | 621 | UInt32 pid = 0; 622 | CFNumberGetValue((CFNumberRef) propertyList, kCFNumberSInt32Type, &pid); 623 | CFRelease(propertyList); 624 | 625 | return pid; 626 | } 627 | else 628 | { 629 | return AltGetSpringBoardServicesApi()->SBSLaunchApplicationWithIdentifierAndURLAndLaunchOptions(identifier, url, params, options, suspended); 630 | } 631 | } 632 | 633 | CFStringRef SBSApplicationLaunchingErrorString(UInt32 error) 634 | { 635 | if (@available(iOS 15.0, *)) 636 | { 637 | CFMessagePortRef remotePort = AltCreateSpringBoardServicesRemotePort(); 638 | if (!remotePort) return NULL; 639 | 640 | CFArrayRef arguments = (__bridge CFArrayRef)@[@(error)]; 641 | CFDataRef argumentsData = 642 | CFPropertyListCreateData(kCFAllocatorDefault, arguments, kCFPropertyListBinaryFormat_v1_0, 0, NULL); 643 | 644 | CFDataRef returnData = NULL; 645 | SInt32 status = 646 | CFMessagePortSendRequest(remotePort, 647 | SBSApplicationLaunchingErrorStringMsgID, 648 | argumentsData, 649 | SERVICE_SEND_TIMEOUT, 650 | SERVICE_RECV_TIMEOUT, 651 | kCFRunLoopDefaultMode, 652 | &returnData); 653 | CFRelease(remotePort); 654 | CFRelease(argumentsData); 655 | 656 | if (status != kCFMessagePortSuccess) 657 | return NULL; 658 | 659 | CFPropertyListRef propertyList = 660 | CFPropertyListCreateWithData(kCFAllocatorDefault, returnData, kCFPropertyListImmutable, NULL, NULL); 661 | CFRelease(returnData); 662 | 663 | if (!propertyList) return NULL; 664 | 665 | if (CFGetTypeID(propertyList) != CFStringGetTypeID()) { 666 | CFRelease(propertyList); 667 | return NULL; 668 | } 669 | 670 | return (CFStringRef) propertyList; 671 | } 672 | else 673 | { 674 | return AltGetSpringBoardServicesApi()->SBSApplicationLaunchingErrorString(error); 675 | } 676 | } 677 | 678 | 679 | #pragma mark - Constructor 680 | 681 | #import 682 | 683 | static const char *MyExecutablePath(void) 684 | { 685 | static char *executablePath = NULL; 686 | if (!executablePath) 687 | { 688 | uint32_t executablePathSize = 0; 689 | _NSGetExecutablePath(NULL, &executablePathSize); 690 | executablePath = (char *)calloc(1, executablePathSize); 691 | if (0 == _NSGetExecutablePath(executablePath, &executablePathSize)) 692 | { 693 | /* Resolve Symbolic Links */ 694 | char realExecutablePath[PATH_MAX] = {0}; 695 | if (realpath(executablePath, realExecutablePath) != NULL) 696 | { 697 | free(executablePath); 698 | executablePath = strdup(realExecutablePath); 699 | } 700 | 701 | /* Supports Procursus */ 702 | if (strncmp("/private/preboot" "/", executablePath, sizeof("/private/preboot")) == 0) 703 | { 704 | const char *littlePtr = strstr(executablePath, "/procursus" "/"); 705 | if (littlePtr != NULL) 706 | { 707 | char *suffixPtr = strdup(littlePtr + sizeof("/procursus") - 1); 708 | free(executablePath); 709 | char *markPtr = (char *)calloc(1, strlen(suffixPtr) + sizeof(JB_PREFIX)); 710 | markPtr = strcat(strcat(markPtr, JB_PREFIX), suffixPtr); 711 | free(suffixPtr); 712 | executablePath = markPtr; 713 | } 714 | } 715 | } 716 | } 717 | 718 | return executablePath; 719 | } 720 | 721 | static __attribute__((constructor)) void CHConstructor_AltSpringBoardServices(void) 722 | { 723 | const char *processName = MyExecutablePath(); 724 | if (strncmp("/usr/sbin/", processName, sizeof("/usr/sbin/") - 1) != 0 && 725 | strncmp("/usr/libexec/", processName, sizeof("/usr/libexec/") - 1) != 0 && 726 | strncmp("/System/Library/Frameworks/", processName, sizeof("/System/Library/Frameworks/") - 1) != 0 && 727 | strncmp("/System/Library/PrivateFrameworks/", processName, sizeof("/System/Library/PrivateFrameworks/") - 1) != 0 && 728 | strncmp("/System/Library/CoreServices/", processName, sizeof("/System/Library/CoreServices/") - 1) != 0 && 729 | strncmp("/Applications/", processName, sizeof("/Applications/") - 1) != 0) 730 | return; 731 | 732 | @autoreleasepool 733 | { 734 | NSString *executableName = [[NSProcessInfo processInfo] processName]; 735 | NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier]; 736 | 737 | if ([executableName isEqualToString:@"MobileGestaltHelper"]) 738 | { /* Server Process - MobileGestaltHelper (alternative to SpringBoardServices) */ 739 | 740 | void *sandyHandle = dlopen(JB_PREFIX "/usr/lib/libsandy.dylib", RTLD_LAZY); 741 | if (sandyHandle) 742 | { 743 | int (*__dyn_libSandy_applyProfile)(const char *profileName) = (int (*)(const char *))dlsym(sandyHandle, "libSandy_applyProfile"); 744 | if (__dyn_libSandy_applyProfile) 745 | { 746 | int sandyStatus = __dyn_libSandy_applyProfile(SBS_SERVICE_NAME); 747 | if (sandyStatus == kLibSandyErrorXPCFailure) 748 | os_log_error(OS_LOG_DEFAULT, "[" SBS_SERVICE_NAME "] Failed to apply sandbox profile: %{public}d", sandyStatus); 749 | else 750 | os_log_info(OS_LOG_DEFAULT, "[" SBS_SERVICE_NAME "] Successfully applied sandbox profile"); 751 | } 752 | } 753 | 754 | AltGetSpringBoardServicesApi(); 755 | 756 | static CFMessagePortRef _localPort = NULL; 757 | _localPort = CFMessagePortCreateLocal(nil, CFSTR(SBS_SERVICE_NAME), AltSpringBoardServicesCallback, NULL, NULL); 758 | if (_localPort) 759 | { 760 | CFRunLoopSourceRef runLoopSource = CFMessagePortCreateRunLoopSource(kCFAllocatorDefault, _localPort, 0); 761 | if (runLoopSource) 762 | { 763 | CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes); 764 | CFRelease(runLoopSource); 765 | rocketbootstrap_cfmessageportexposelocal(_localPort); 766 | } 767 | 768 | os_log_info(OS_LOG_DEFAULT, "server %{public}@ initialized %{public}@ %{public}s, pid = %{public}d", 769 | _localPort, bundleIdentifier ?: executableName, processName, getpid()); 770 | } 771 | } 772 | else if ([bundleIdentifier isEqualToString:@"com.apple.springboard"]) 773 | { /* Server Process - SpringBoard 774 | * 775 | * We made SpringBoard as another server process because some APIs of 776 | * SpringBoardServices are deprecated. So we will get these results directly 777 | * from the final data source - SpringBoard. 778 | */ 779 | 780 | static CFMessagePortRef _localPort = NULL; 781 | _localPort = CFMessagePortCreateLocal(kCFAllocatorDefault, CFSTR(SB_SERVICE_NAME), AltSpringBoardCallback, NULL, NULL); 782 | if (_localPort) 783 | { 784 | CFRunLoopSourceRef runLoopSource = CFMessagePortCreateRunLoopSource(kCFAllocatorDefault, _localPort, 0); 785 | if (runLoopSource) 786 | { 787 | CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes); 788 | CFRelease(runLoopSource); 789 | rocketbootstrap_cfmessageportexposelocal(_localPort); 790 | } 791 | 792 | os_log_info(OS_LOG_DEFAULT, "server %{public}@ initialized %{public}@ %{public}s, pid = %{public}d", 793 | _localPort, bundleIdentifier ?: executableName, processName, getpid()); 794 | } 795 | } 796 | else 797 | { /* Client Process - any other process 798 | * 799 | * On iOS 15 and above, we are unable to access SpringBoardServices directly 800 | * due to the lacking of credentials. Also, the SpringBoard process is unable 801 | * to access SpringBoardServices because itself works as the data source of that. 802 | * Here is a workaround to access SpringBoardServices via a middleman process. 803 | */ 804 | 805 | if (@available(iOS 15.0, *)) {} 806 | else AltGetSpringBoardServicesApi(); 807 | } 808 | } 809 | } 810 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | TARGET := iphone:clang:14.5:13.0 2 | ARCHS := arm64 arm64e 3 | INSTALL_TARGET_PROCESSES := MobileGestaltHelper 4 | 5 | include $(THEOS)/makefiles/common.mk 6 | 7 | LIBRARY_NAME := libAltSpringBoardServices 8 | 9 | libAltSpringBoardServices_FILES += AltSpringBoardServices.mm 10 | libAltSpringBoardServices_FILES += springboard.m 11 | springboard.m_CFLAGS += -fno-objc-arc 12 | libAltSpringBoardServices_CFLAGS += -fobjc-arc 13 | libAltSpringBoardServices_CFLAGS += -Iinclude 14 | libAltSpringBoardServices_CFLAGS += -DJB_PREFIX=\"/var/jb\" 15 | libAltSpringBoardServices_CCFLAGS += -std=c++14 16 | libAltSpringBoardServices_LDFLAGS += -Wl,-no_warn_inits 17 | libAltSpringBoardServices_LIBRARIES += rocketbootstrap 18 | libAltSpringBoardServices_INSTALL_PATH = /usr/lib 19 | 20 | include $(THEOS_MAKE_PATH)/library.mk -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AltSpringBoardServices 2 | An alternative SpringBoardServices implementation for iOS 13 and above, especially for iOS 15 and above. 3 | 4 | ## Why we need this? 5 | If you come here, you may know the reason. 6 | -------------------------------------------------------------------------------- /include/libSandy.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #if defined(__cplusplus) 4 | extern "C" { 5 | #endif 6 | 7 | #define kLibSandySuccess 0 8 | #define kLibSandyErrorXPCFailure 1 9 | #define kLibSandyErrorRestricted 2 10 | 11 | extern int libSandy_applyProfile(const char* profileName); 12 | extern bool libSandy_works(void); 13 | 14 | #if defined(__cplusplus) 15 | } 16 | #endif -------------------------------------------------------------------------------- /layout/DEBIAN/control: -------------------------------------------------------------------------------- 1 | Package: com.darwindev.alternative-springboardservices 2 | Name: Alternative SpringBoardServices 3 | Version: 0.1-2 4 | Section: Tweaks 5 | Depends: firmware (>= 13.0), com.rpetrich.rocketbootstrap, com.opa334.libsandy 6 | Architecture: iphoneos-arm 7 | Author: Darwin Developer <82flex@gmail.com> 8 | Maintainer: Darwin Developer <82flex@gmail.com> 9 | Description: An alternative SpringBoardServices implementation for iOS 13 and above, especially for iOS 15 and above. 10 | 11 | -------------------------------------------------------------------------------- /layout/DEBIAN/postinst: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | launchctl kill 9 system/com.apple.mobilegestalt.xpc > /dev/null 2>&1 3 | exit 0 -------------------------------------------------------------------------------- /layout/DEBIAN/prerm: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | launchctl kill 9 system/com.apple.mobilegestalt.xpc > /dev/null 2>&1 3 | exit 0 -------------------------------------------------------------------------------- /layout/Library/MobileSubstrate/DynamicLibraries/AltSpringBoardServices.dylib: -------------------------------------------------------------------------------- 1 | /usr/lib/libAltSpringBoardServices.dylib -------------------------------------------------------------------------------- /layout/Library/MobileSubstrate/DynamicLibraries/AltSpringBoardServices.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Filter 6 | 7 | Bundles 8 | 9 | com.apple.springboard 10 | 11 | Executables 12 | 13 | MobileGestaltHelper 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /layout/Library/libSandy/com.darwindev.AltSpringBoardServices.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AllowedProcesses 6 | 7 | MobileGestaltHelper 8 | 9 | Extensions 10 | 11 | 12 | type 13 | mach 14 | extension_class 15 | com.apple.security.exception.mach-lookup.global-name 16 | mach_name 17 | com.darwindev.AltSpringBoardServices 18 | 19 | 20 | type 21 | mach 22 | extension_class 23 | com.apple.security.exception.mach-register.global-name 24 | mach_name 25 | com.darwindev.AltSpringBoardServices 26 | 27 | 28 | type 29 | mach 30 | extension_class 31 | com.apple.security.exception.mach-lookup.global-name 32 | mach_name 33 | lh:rbs:com.darwindev.AltSpringBoardServices 34 | 35 | 36 | type 37 | mach 38 | extension_class 39 | com.apple.security.exception.mach-register.global-name 40 | mach_name 41 | lh:rbs:com.darwindev.AltSpringBoardServices 42 | 43 | 44 | type 45 | mach 46 | extension_class 47 | com.apple.security.exception.mach-lookup.global-name 48 | mach_name 49 | cy:rbs:com.darwindev.AltSpringBoardServices 50 | 51 | 52 | type 53 | mach 54 | extension_class 55 | com.apple.security.exception.mach-register.global-name 56 | mach_name 57 | cy:rbs:com.darwindev.AltSpringBoardServices 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /springboard.h: -------------------------------------------------------------------------------- 1 | #ifndef __ALT_DARWIN_SPRINGBOARD_H__ 2 | #define __ALT_DARWIN_SPRINGBOARD_H__ 3 | 4 | #import 5 | 6 | typedef struct _AltSpringboardApi AltSpringboardApi; 7 | typedef void (^ FBSOpenResultCallback) (NSError * error); 8 | 9 | typedef enum _FBProcessKillReason 10 | { 11 | FBProcessKillReasonUnknown, 12 | FBProcessKillReasonUser, 13 | FBProcessKillReasonPurge, 14 | FBProcessKillReasonGracefulPurge, 15 | FBProcessKillReasonThermal, 16 | FBProcessKillReasonNone, 17 | FBProcessKillReasonShutdown, 18 | FBProcessKillReasonLaunchTest, 19 | FBProcessKillReasonInsecureDrawing 20 | } FBProcessKillReason; 21 | 22 | @interface FBSSystemService : NSObject 23 | 24 | + (FBSSystemService *)sharedService; 25 | 26 | - (pid_t)pidForApplication:(NSString *)identifier; 27 | - (void)openApplication:(NSString *)identifier 28 | options:(NSDictionary *)options 29 | clientPort:(mach_port_t)port 30 | withResult:(FBSOpenResultCallback)result; 31 | - (void)openURL:(NSURL *)url 32 | application:(NSString *)identifier 33 | options:(NSDictionary *)options 34 | clientPort:(mach_port_t)port 35 | withResult:(FBSOpenResultCallback)result; 36 | - (void)terminateApplication:(NSString *)identifier 37 | forReason:(FBProcessKillReason)reason 38 | andReport:(BOOL)report 39 | withDescription:(NSString *)description; 40 | 41 | - (mach_port_t)createClientPort; 42 | - (void)cleanupClientPort:(mach_port_t)port; 43 | 44 | @end 45 | 46 | @interface LSApplicationProxy : NSObject 47 | 48 | + (LSApplicationProxy *)applicationProxyForIdentifier:(NSString *)identifier; 49 | 50 | - (NSString *)shortVersionString; 51 | - (NSString *)bundleVersion; 52 | - (NSURL *)bundleURL; 53 | - (NSURL *)dataContainerURL; 54 | - (NSDictionary *)groupContainerURLs; 55 | - (id)entitlementValueForKey:(NSString *)key ofClass:(Class)klass; 56 | 57 | @end 58 | 59 | struct _AltSpringboardApi 60 | { 61 | void * sbs; 62 | void * fbs; 63 | void * mcs; 64 | 65 | CFStringRef (* SBSCopyFrontmostApplicationDisplayIdentifier) (void); 66 | CFArrayRef (* SBSCopyApplicationDisplayIdentifiers) (BOOL active, BOOL debuggable); 67 | CFStringRef (* SBSCopyDisplayIdentifierForProcessID) (UInt32 pid); 68 | CFStringRef (* SBSCopyLocalizedApplicationNameForDisplayIdentifier) (CFStringRef identifier); 69 | CFDataRef (* SBSCopyIconImagePNGDataForDisplayIdentifier) (CFStringRef identifier); 70 | CFDictionaryRef (* SBSCopyInfoForApplicationWithProcessID) (UInt32 pid); 71 | UInt32 (* SBSProcessIDForDisplayIdentifier) (CFStringRef identifier); 72 | UInt32 (* SBSLaunchApplicationWithIdentifier) (CFStringRef identifier); 73 | UInt32 (* SBSLaunchApplicationWithIdentifierAndLaunchOptions) (CFStringRef identifier, CFDictionaryRef options, BOOL suspended); 74 | UInt32 (* SBSLaunchApplicationWithIdentifierAndURLAndLaunchOptions) (CFStringRef identifier, CFURLRef url, CFDictionaryRef params, CFDictionaryRef options, BOOL suspended); 75 | CFStringRef (* SBSApplicationLaunchingErrorString) (UInt32 error); 76 | 77 | CFStringRef SBSApplicationLaunchOptionUnlockDeviceKey; 78 | 79 | CFStringRef FBSOpenApplicationOptionKeyUnlockDevice; 80 | CFStringRef FBSOpenApplicationOptionKeyDebuggingOptions; 81 | 82 | CFStringRef FBSDebugOptionKeyArguments; 83 | CFStringRef FBSDebugOptionKeyEnvironment; 84 | CFStringRef FBSDebugOptionKeyStandardOutPath; 85 | CFStringRef FBSDebugOptionKeyStandardErrorPath; 86 | CFStringRef FBSDebugOptionKeyDisableASLR; 87 | 88 | id FBSSystemService; 89 | id LSApplicationProxy; 90 | }; 91 | 92 | OBJC_EXTERN AltSpringboardApi * _alt_get_springboard_api (void); 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /springboard.m: -------------------------------------------------------------------------------- 1 | #if __has_feature(objc_arc) 2 | #error This file must not be compiled with ARC. Use -fno-objc-arc flag. 3 | #endif 4 | 5 | #import "springboard.h" 6 | #import 7 | 8 | 9 | #define CHStringify_(x) #x 10 | #define CHStringify(x) CHStringify_(x) 11 | 12 | #define ALT_ASSIGN_SBS_FUNC(N) \ 13 | api->N = dlsym (api->sbs, CHStringify (N)); \ 14 | assert (api->N != NULL) 15 | #define ALT_ASSIGN_SBS_CONSTANT(N) \ 16 | str = dlsym (api->sbs, CHStringify (N)); \ 17 | assert (str != NULL); \ 18 | api->N = *str 19 | #define ALT_ASSIGN_FBS_CONSTANT(N) \ 20 | str = dlsym (api->fbs, CHStringify (N)); \ 21 | assert (str != NULL); \ 22 | api->N = *str 23 | 24 | static AltSpringboardApi * alt_springboard_api = NULL; 25 | 26 | AltSpringboardApi * 27 | _alt_get_springboard_api (void) 28 | { 29 | if (alt_springboard_api == NULL) 30 | { 31 | AltSpringboardApi * api = NULL; 32 | CFStringRef *str = nil; 33 | id (* objc_get_class_impl) (const char * name); 34 | 35 | api = (AltSpringboardApi *)calloc(1, sizeof(AltSpringboardApi)); 36 | 37 | api->sbs = dlopen ("/System/Library/PrivateFrameworks/SpringBoardServices.framework/SpringBoardServices", RTLD_GLOBAL | RTLD_LAZY); 38 | assert (api->sbs != NULL); 39 | 40 | api->fbs = dlopen ("/System/Library/PrivateFrameworks/FrontBoardServices.framework/FrontBoardServices", RTLD_GLOBAL | RTLD_LAZY); 41 | 42 | ALT_ASSIGN_SBS_FUNC (SBSCopyFrontmostApplicationDisplayIdentifier); 43 | ALT_ASSIGN_SBS_FUNC (SBSCopyApplicationDisplayIdentifiers); 44 | ALT_ASSIGN_SBS_FUNC (SBSCopyDisplayIdentifierForProcessID); 45 | ALT_ASSIGN_SBS_FUNC (SBSCopyLocalizedApplicationNameForDisplayIdentifier); 46 | ALT_ASSIGN_SBS_FUNC (SBSCopyIconImagePNGDataForDisplayIdentifier); 47 | ALT_ASSIGN_SBS_FUNC (SBSCopyInfoForApplicationWithProcessID); 48 | ALT_ASSIGN_SBS_FUNC (SBSProcessIDForDisplayIdentifier); 49 | ALT_ASSIGN_SBS_FUNC (SBSLaunchApplicationWithIdentifier); 50 | ALT_ASSIGN_SBS_FUNC (SBSLaunchApplicationWithIdentifierAndLaunchOptions); 51 | ALT_ASSIGN_SBS_FUNC (SBSLaunchApplicationWithIdentifierAndURLAndLaunchOptions); 52 | ALT_ASSIGN_SBS_FUNC (SBSApplicationLaunchingErrorString); 53 | 54 | ALT_ASSIGN_SBS_CONSTANT (SBSApplicationLaunchOptionUnlockDeviceKey); 55 | 56 | objc_get_class_impl = dlsym (RTLD_DEFAULT, "objc_getClass"); 57 | assert (objc_get_class_impl != NULL); 58 | 59 | if (api->fbs != NULL) 60 | { 61 | api->FBSSystemService = objc_get_class_impl ("FBSSystemService"); 62 | assert (api->FBSSystemService != nil); 63 | 64 | ALT_ASSIGN_FBS_CONSTANT (FBSOpenApplicationOptionKeyUnlockDevice); 65 | ALT_ASSIGN_FBS_CONSTANT (FBSOpenApplicationOptionKeyDebuggingOptions); 66 | 67 | ALT_ASSIGN_FBS_CONSTANT (FBSDebugOptionKeyArguments); 68 | ALT_ASSIGN_FBS_CONSTANT (FBSDebugOptionKeyEnvironment); 69 | ALT_ASSIGN_FBS_CONSTANT (FBSDebugOptionKeyStandardOutPath); 70 | ALT_ASSIGN_FBS_CONSTANT (FBSDebugOptionKeyStandardErrorPath); 71 | ALT_ASSIGN_FBS_CONSTANT (FBSDebugOptionKeyDisableASLR); 72 | } 73 | 74 | api->mcs = dlopen ("/System/Library/Frameworks/MobileCoreServices.framework/MobileCoreServices", RTLD_GLOBAL | RTLD_LAZY); 75 | assert (api->mcs != NULL); 76 | 77 | api->LSApplicationProxy = objc_get_class_impl ("LSApplicationProxy"); 78 | assert (api->LSApplicationProxy != nil); 79 | 80 | alt_springboard_api = api; 81 | } 82 | 83 | return alt_springboard_api; 84 | } 85 | --------------------------------------------------------------------------------