@@ -442,54 +442,179 @@ int enable_grid_app_switcher(RemoteCall *proc) {
442442 return 0 ;
443443}
444444
445- int enable_debug_overlay (RemoteCall *proc) {
445+ static uint64_t get_main_window_scene (RemoteCall *proc) {
446+ if (!proc) return 0 ;
447+ uint64_t selMainWindowScene = remote_sel (proc, " mainWindowScene" );
448+ uint64_t selSharedInstance = remote_sel (proc, " sharedInstance" );
449+
446450 uint64_t clsSBMainWorkspace = remote_getClass (proc, " SBMainWorkspace" );
451+ if (clsSBMainWorkspace) {
452+ uint64_t workspace = remote_msg (proc, clsSBMainWorkspace, selSharedInstance, 0 ,0 ,0 ,0 );
453+ if (workspace) {
454+ uint64_t scene = remote_msg (proc, workspace, selMainWindowScene, 0 ,0 ,0 ,0 );
455+ if (scene) return scene;
456+ }
457+ }
458+
459+ uint64_t clsUIApplication = remote_getClass (proc, " UIApplication" );
460+ if (clsUIApplication) {
461+ uint64_t selSharedApp = remote_sel (proc, " sharedApplication" );
462+ uint64_t app = remote_msg (proc, clsUIApplication, selSharedApp, 0 ,0 ,0 ,0 );
463+ if (app) {
464+ uint64_t selKeyWindow = remote_sel (proc, " keyWindow" );
465+ uint64_t selWindows = remote_sel (proc, " windows" );
466+ uint64_t selFirstObj = remote_sel (proc, " firstObject" );
467+ uint64_t selWindowScene = remote_sel (proc, " windowScene" );
468+
469+ uint64_t window = remote_msg (proc, app, selKeyWindow, 0 ,0 ,0 ,0 );
470+ if (!window) {
471+ uint64_t windows = remote_msg (proc, app, selWindows, 0 ,0 ,0 ,0 );
472+ if (windows) {
473+ window = remote_msg (proc, windows, selFirstObj, 0 ,0 ,0 ,0 );
474+ }
475+ }
476+
477+ if (window) {
478+ uint64_t scene = remote_msg (proc, window, selWindowScene, 0 ,0 ,0 ,0 );
479+ if (scene) return scene;
480+ }
481+
482+ uint64_t selConnectedScenes = remote_sel (proc, " connectedScenes" );
483+ uint64_t selAnyObject = remote_sel (proc, " anyObject" );
484+ uint64_t scenes = remote_msg (proc, app, selConnectedScenes, 0 ,0 ,0 ,0 );
485+ if (scenes) {
486+ uint64_t scene = remote_msg (proc, scenes, selAnyObject, 0 ,0 ,0 ,0 );
487+ if (scene) return scene;
488+ }
489+ }
490+ }
491+ return 0 ;
492+ }
493+
494+ int enable_debug_overlay (RemoteCall *proc) {
495+ if (!proc) return -1 ;
496+
447497 uint64_t clsDebugOverlayWindow = remote_getClass (proc, " UIDebuggingInformationOverlay" );
448498 uint64_t clsDebugOverlayHandler = remote_getClass (proc, " UIDebuggingInformationOverlayInvokeGestureHandler" );
449499 uint64_t clsUIApplication = remote_getClass (proc, " UIApplication" );
450500 uint64_t clsUITapGestureRecognizer = remote_getClass (proc, " UITapGestureRecognizer" );
451501 uint64_t clsUIWindow = remote_getClass (proc, " UIWindow" );
452502
503+ if (!clsDebugOverlayWindow) {
504+ printf (" (rc) UIDebuggingInformationOverlay class not found\n " );
505+ return -1 ;
506+ }
507+
453508 uint64_t selAddGestureRecognizer = remote_sel (proc, " addGestureRecognizer:" );
454509 uint64_t selHandleActivation = remote_sel (proc, " _handleActivationGesture:" );
455510 uint64_t selInit = remote_sel (proc, " init" );
456511 uint64_t selInitWithTargetAction = remote_sel (proc, " initWithTarget:action:" );
457512 uint64_t selMainHandler = remote_sel (proc, " mainHandler" );
458- uint64_t selMainWindowScene = remote_sel (proc, " mainWindowScene" );
459513 uint64_t selOverlay = remote_sel (proc, " overlay" );
460514 uint64_t selPerform = remote_sel (proc, " performSelectorOnMainThread:withObject:waitUntilDone:" );
461515 uint64_t selSetNumberOfTapsRequired = remote_sel (proc, " setNumberOfTapsRequired:" );
462516 uint64_t selSetWindowScene = remote_sel (proc, " setWindowScene:" );
463517 uint64_t selSharedApplication = remote_sel (proc, " sharedApplication" );
464- uint64_t selSharedInstance = remote_sel (proc, " sharedInstance" );
465518 uint64_t selStatusBar = remote_sel (proc, " statusBarForEmbeddedDisplay" );
466519
467520 // Swizzle -[UIDebuggingInformationOverlay init] to -[UIWindow init] to bypass internal check
468521 uint64_t methodWindowInit = RemoteArbCall (proc, class_getInstanceMethod , clsUIWindow, selInit);
469522 uint64_t methodOverlayInit = RemoteArbCall (proc, class_getInstanceMethod , clsDebugOverlayWindow, selInit);
470523 uint64_t impWindowInit = RemoteArbCall (proc, method_getImplementation , methodWindowInit);
471- RemoteArbCall (proc, method_setImplementation , methodOverlayInit, impWindowInit);
524+ if (methodOverlayInit && impWindowInit) {
525+ RemoteArbCall (proc, method_setImplementation , methodOverlayInit, impWindowInit);
526+ }
472527
473528 // Set windowScene
474- uint64_t workspace = remote_msg (proc, clsSBMainWorkspace, selSharedInstance, 0 ,0 ,0 ,0 );
475- uint64_t mainWindowScene = remote_msg (proc, workspace, selMainWindowScene, 0 ,0 ,0 ,0 );
476- remote_msg (proc, clsDebugOverlayWindow, selPerform, selOverlay, 0 , 1 ,0 ); // init window
477- uint64_t debugOverlay = remote_msg (proc, clsDebugOverlayWindow, selOverlay, 0 ,0 ,0 ,0 );
478- remote_msg (proc, debugOverlay, selPerform, selSetWindowScene, mainWindowScene, 1 ,0 );
479-
480- // register gesture recognizer to the status bar
481- uint64_t target = remote_msg (proc, clsDebugOverlayHandler, selMainHandler, 0 ,0 ,0 ,0 );
482- uint64_t doubleTapGesture = RemoteArbCall (proc, objc_alloc, clsUITapGestureRecognizer);
483- doubleTapGesture = remote_msg (proc, doubleTapGesture, selInitWithTargetAction, target, selHandleActivation, 0 ,0 );
484- remote_msg (proc, doubleTapGesture, selSetNumberOfTapsRequired, 2 , 0 ,0 ,0 );
485- uint64_t app = remote_msg (proc, clsUIApplication, selSharedApplication, 0 ,0 ,0 ,0 );
486- uint64_t statusBar = remote_msg (proc, app, selStatusBar, 0 ,0 ,0 ,0 );
487- remote_msg (proc, statusBar, selPerform, selAddGestureRecognizer, doubleTapGesture, 1 ,0 );
488- RemoteArbCall (proc, objc_release, doubleTapGesture);
529+ uint64_t mainWindowScene = get_main_window_scene (proc);
530+ remote_msg (proc, clsDebugOverlayWindow, selPerform, selOverlay, 0 , 1 , 0 ); // init window
531+ uint64_t debugOverlay = remote_msg (proc, clsDebugOverlayWindow, selOverlay, 0 , 0 , 0 , 0 );
532+ if (debugOverlay && mainWindowScene) {
533+ remote_msg (proc, debugOverlay, selPerform, selSetWindowScene, mainWindowScene, 1 , 0 );
534+ }
535+
536+ if (debugOverlay) {
537+ uint64_t selToggle = remote_sel (proc, " toggleVisibility" );
538+ remote_msg (proc, debugOverlay, selPerform, selToggle, 0 , 1 , 0 );
539+ }
540+
541+ // register gesture recognizer to status bar or key window
542+ if (clsDebugOverlayHandler && clsUITapGestureRecognizer) {
543+ uint64_t target = remote_msg (proc, clsDebugOverlayHandler, selMainHandler, 0 , 0 , 0 , 0 );
544+ if (target) {
545+ uint64_t doubleTapGesture = RemoteArbCall (proc, objc_alloc, clsUITapGestureRecognizer);
546+ doubleTapGesture = remote_msg (proc, doubleTapGesture, selInitWithTargetAction, target, selHandleActivation, 0 , 0 );
547+ remote_msg (proc, doubleTapGesture, selSetNumberOfTapsRequired, 2 , 0 , 0 , 0 );
548+
549+ uint64_t app = remote_msg (proc, clsUIApplication, selSharedApplication, 0 , 0 , 0 , 0 );
550+ uint64_t targetView = 0 ;
551+ if (app) {
552+ targetView = remote_msg (proc, app, selStatusBar, 0 , 0 , 0 , 0 );
553+ if (!targetView) {
554+ uint64_t selKeyWindow = remote_sel (proc, " keyWindow" );
555+ targetView = remote_msg (proc, app, selKeyWindow, 0 , 0 , 0 , 0 );
556+ }
557+ if (!targetView) {
558+ uint64_t selWindows = remote_sel (proc, " windows" );
559+ uint64_t windows = remote_msg (proc, app, selWindows, 0 , 0 , 0 , 0 );
560+ if (windows) {
561+ targetView = remote_msg (proc, windows, remote_sel (proc, " firstObject" ), 0 , 0 , 0 , 0 );
562+ }
563+ }
564+ }
565+ if (targetView) {
566+ remote_msg (proc, targetView, selPerform, selAddGestureRecognizer, doubleTapGesture, 1 , 0 );
567+ }
568+ RemoteArbCall (proc, objc_release, doubleTapGesture);
569+ }
570+ }
489571
490572 return 0 ;
491573}
492574
575+ int enable_maps_debug_menu (RemoteCall *proc) {
576+ if (!proc) {
577+ printf (" (rc) RemoteCall not initialized for Maps\n " );
578+ return -1 ;
579+ }
580+
581+ printf (" (rc) Enabling UI debugging menu for Apple Maps...\n " );
582+
583+ // Enable standard UIKit Debugging Overlay in Maps
584+ int result = enable_debug_overlay (proc);
585+
586+ // Also set Maps-specific debug flags in NSUserDefaults inside the Maps process
587+ uint64_t clsNSUserDefaults = remote_getClass (proc, " NSUserDefaults" );
588+ if (clsNSUserDefaults) {
589+ uint64_t selStandard = remote_sel (proc, " standardUserDefaults" );
590+ uint64_t defaults = remote_msg (proc, clsNSUserDefaults, selStandard, 0 , 0 , 0 , 0 );
591+ if (defaults) {
592+ uint64_t selSetBool = remote_sel (proc, " setBool:forKey:" );
593+
594+ uint64_t k1 = remote_NSString (proc, " MapsDebug" );
595+ uint64_t k2 = remote_NSString (proc, " EnableDebugMenu" );
596+ uint64_t k3 = remote_NSString (proc, " GEOTraceLoggingEnabled" );
597+ uint64_t k4 = remote_NSString (proc, " MNEnvironment" );
598+
599+ remote_msg (proc, defaults, selSetBool, 1 , k1, 0 , 0 );
600+ remote_msg (proc, defaults, selSetBool, 1 , k2, 0 , 0 );
601+ remote_msg (proc, defaults, selSetBool, 1 , k3, 0 , 0 );
602+ remote_msg (proc, defaults, selSetBool, 1 , k4, 0 , 0 );
603+
604+ RemoteArbCall (proc, CFRelease, k1);
605+ RemoteArbCall (proc, CFRelease, k2);
606+ RemoteArbCall (proc, CFRelease, k3);
607+ RemoteArbCall (proc, CFRelease, k4);
608+
609+ uint64_t selSynchronize = remote_sel (proc, " synchronize" );
610+ remote_msg (proc, defaults, selSynchronize, 0 , 0 , 0 , 0 );
611+ }
612+ }
613+
614+ printf (" (rc) Apple Maps debug menu enabled!\n " );
615+ return result;
616+ }
617+
493618static const NSInteger kFreakyDogTag = 0xD06 ;
494619
495620static uint64_t freakywindow (RemoteCall *proc) {
0 commit comments