Skip to content

Commit e560621

Browse files
committed
maybe fix
1 parent 28f1691 commit e560621

1 file changed

Lines changed: 46 additions & 11 deletions

File tree

  • lara/kexploit/pe

lara/kexploit/pe/rc.m

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,7 @@ int enable_debug_overlay(RemoteCall *proc) {
541541
uint64_t clsUIApplication = remote_getClass(proc, "UIApplication");
542542
uint64_t clsUITapGestureRecognizer = remote_getClass(proc, "UITapGestureRecognizer");
543543
uint64_t clsUIWindow = remote_getClass(proc, "UIWindow");
544+
uint64_t clsUIViewController = remote_getClass(proc, "UIViewController");
544545

545546
if (!clsDebugOverlayWindow) {
546547
printf("(rc) UIDebuggingInformationOverlay class not found\n");
@@ -550,20 +551,34 @@ int enable_debug_overlay(RemoteCall *proc) {
550551
uint64_t selInit = remote_sel(proc, "init");
551552
uint64_t selOverlay = remote_sel(proc, "overlay");
552553
uint64_t selPrepare = remote_sel(proc, "prepareDebuggingOverlay");
554+
uint64_t selOverlayStatus = remote_sel(proc, "overlayStatus");
553555
uint64_t selPerform = remote_sel(proc, "performSelectorOnMainThread:withObject:waitUntilDone:");
554556

555-
// 1. Swizzle -[UIDebuggingInformationOverlay init] to -[UIWindow init] to bypass internal check
557+
// 1. Get return 1 gadget from UIViewController _canShowWhileLocked
558+
if (clsUIViewController) {
559+
uint64_t selReturn1 = remote_sel(proc, "_canShowWhileLocked");
560+
uint64_t methodReturn1 = RemoteArbCall(proc, class_getInstanceMethod, clsUIViewController, selReturn1);
561+
uint64_t return1Imp = RemoteArbCall(proc, method_getImplementation, methodReturn1);
562+
563+
// 2. Swizzle +[UIDebuggingInformationOverlay overlayStatus] to return 1 (YES)
564+
uint64_t methodOverlayStatus = RemoteArbCall(proc, class_getClassMethod, clsDebugOverlayWindow, selOverlayStatus);
565+
if (methodOverlayStatus && return1Imp) {
566+
RemoteArbCall(proc, method_setImplementation, methodOverlayStatus, (uint64_t)return1Imp);
567+
}
568+
}
569+
570+
// 3. Swizzle -[UIDebuggingInformationOverlay init] to -[UIWindow init] to bypass internal check
556571
uint64_t methodWindowInit = RemoteArbCall(proc, class_getInstanceMethod, clsUIWindow, selInit);
557572
uint64_t methodOverlayInit = RemoteArbCall(proc, class_getInstanceMethod, clsDebugOverlayWindow, selInit);
558573
uint64_t impWindowInit = RemoteArbCall(proc, method_getImplementation, methodWindowInit);
559574
if (methodOverlayInit && impWindowInit) {
560575
RemoteArbCall(proc, method_setImplementation, methodOverlayInit, impWindowInit);
561576
}
562577

563-
// 2. Call +[UIDebuggingInformationOverlay prepareDebuggingOverlay] to prevent UIDebuggingInformationOverlayNotPrepared exception
578+
// 4. Call +[UIDebuggingInformationOverlay prepareDebuggingOverlay]
564579
remote_msg(proc, clsDebugOverlayWindow, selPerform, selPrepare, 0, 1, 0);
565580

566-
// 3. Get or allocate overlay window
581+
// 5. Get or allocate overlay window
567582
remote_msg(proc, clsDebugOverlayWindow, selPerform, selOverlay, 0, 1, 0);
568583
uint64_t debugOverlay = remote_msg(proc, clsDebugOverlayWindow, selOverlay, 0, 0, 0, 0);
569584
if (!debugOverlay) {
@@ -572,26 +587,46 @@ int enable_debug_overlay(RemoteCall *proc) {
572587
debugOverlay = remote_msg(proc, debugOverlay, selInit, 0, 0, 0, 0);
573588
}
574589
}
575-
576-
// 4. Set windowScene
590+
591+
if (!debugOverlay) {
592+
printf("(rc) Failed to obtain UIDebuggingInformationOverlay instance\n");
593+
return -1;
594+
}
595+
596+
// 6. Ensure rootViewController is NEVER nil (prevents app crash when UIWindow is unhidden!)
597+
uint64_t selRootVC = remote_sel(proc, "rootViewController");
598+
uint64_t selSetRootVC = remote_sel(proc, "setRootViewController:");
599+
uint64_t rootVC = remote_msg(proc, debugOverlay, selRootVC, 0, 0, 0, 0);
600+
if (!rootVC) {
601+
uint64_t clsRootTVC = remote_getClass(proc, "UIDebuggingInformationRootTableViewController");
602+
if (!clsRootTVC) clsRootTVC = remote_getClass(proc, "UIDebuggingInformationOverlayViewController");
603+
if (!clsRootTVC) clsRootTVC = clsUIViewController;
604+
605+
if (clsRootTVC) {
606+
uint64_t newRootVC = RemoteArbCall(proc, objc_alloc, clsRootTVC);
607+
newRootVC = remote_msg(proc, newRootVC, selInit, 0, 0, 0, 0);
608+
if (newRootVC) {
609+
remote_msg(proc, debugOverlay, selPerform, selSetRootVC, newRootVC, 1, 0);
610+
}
611+
}
612+
}
613+
614+
// 7. Set windowScene
577615
uint64_t mainWindowScene = get_main_window_scene(proc);
578616
if (debugOverlay && mainWindowScene) {
579617
uint64_t selSetWindowScene = remote_sel(proc, "setWindowScene:");
580618
remote_msg(proc, debugOverlay, selPerform, selSetWindowScene, mainWindowScene, 1, 0);
581619
}
582620

583-
// 5. Show overlay window immediately
621+
// 8. Show overlay window
584622
if (debugOverlay) {
585623
uint64_t selSetHidden = remote_sel(proc, "setHidden:");
586-
uint64_t selMakeKeyAndVisible = remote_sel(proc, "makeKeyAndVisible");
587624
uint64_t selToggle = remote_sel(proc, "toggleVisibility");
588-
589-
remote_msg(proc, debugOverlay, selPerform, selSetHidden, 0, 1, 0);
590-
remote_msg(proc, debugOverlay, selPerform, selMakeKeyAndVisible, 0, 1, 0);
625+
remote_msg(proc, debugOverlay, selPerform, selSetHidden, 0, 1, 0); // setHidden:NO
591626
remote_msg(proc, debugOverlay, selPerform, selToggle, 0, 1, 0);
592627
}
593628

594-
// 6. Register gesture recognizer to status bar and main window
629+
// 9. Register activation gesture recognizers to status bar and main window
595630
if (clsDebugOverlayHandler && clsUITapGestureRecognizer) {
596631
uint64_t selMainHandler = remote_sel(proc, "mainHandler");
597632
uint64_t selSharedInstance = remote_sel(proc, "sharedInstance");

0 commit comments

Comments
 (0)