diff --git a/gui/gui_main.py b/gui/gui_main.py index c9f9c7bbd..32680a597 100644 --- a/gui/gui_main.py +++ b/gui/gui_main.py @@ -1184,7 +1184,7 @@ class wx_python_gui: self.developer_note.SetLabel("Starting shortly") sys.stdout=menu_redirect.RedirectLabel(self.developer_note) - kdk_result, error_msg = kdk_handler.kernel_debug_kit_handler(self.constants).download_kdk(self.constants.detected_os_version, self.constants.detected_os_build) + kdk_result, error_msg, detected_build = kdk_handler.kernel_debug_kit_handler(self.constants).download_kdk(self.constants.detected_os_version, self.constants.detected_os_build) sys.stdout=sys.__stdout__ if kdk_result is False: diff --git a/resources/kdk_handler.py b/resources/kdk_handler.py index 3b6b5989c..378b3e3e3 100644 --- a/resources/kdk_handler.py +++ b/resources/kdk_handler.py @@ -93,7 +93,7 @@ class kernel_debug_kit_handler: # Note: cannot do lazy matching as we don't store old version/build numbers nor can we enumerate KDKs from the portal URL_TEMPLATE = f"https://download.developer.apple.com/macOS/Kernel_Debug_Kit_{version}_build_{build}/Kernel_Debug_Kit_{version}_build_{build}.dmg" - return URL_TEMPLATE + return URL_TEMPLATE, build def verify_apple_developer_portal(self, link): @@ -129,45 +129,46 @@ class kernel_debug_kit_handler: def download_kdk(self, version: str, build: str): error_msg = "" + detected_build = build if self.is_kdk_installed(build) is True: print(" - KDK is already installed") - return True, error_msg + return True, error_msg, detected_build # Note: cannot do lazy matching as we don't store old version/build numbers nor can we enumerate KDKs from the portal - URL_TEMPLATE = self.generate_kdk_link(version, build) + URL_TEMPLATE, detected_build = self.generate_kdk_link(version, build) print(f"- Downloading Apple KDK for macOS {version} build {build}") result = self.verify_apple_developer_portal(URL_TEMPLATE) if result == 2: error_msg = "Could not contact Apple download servers" - return False, error_msg + return False, error_msg, "" elif result == 0: print(" - Downloading KDK") elif result == 1: print(" - Could not find KDK, finding closest match") - URL_TEMPLATE, closest_build = self.get_closest_match(version, build) + URL_TEMPLATE, detected_build = self.get_closest_match(version, build) - if self.is_kdk_installed(closest_build) is True: - return True, error_msg + if self.is_kdk_installed(detected_build) is True: + return True, error_msg, detected_build if URL_TEMPLATE is None: error_msg = "Could not find KDK for host, nor closest match" - return False, error_msg + return False, error_msg, "" result = self.verify_apple_developer_portal(URL_TEMPLATE) if result == 2: error_msg = "Could not contact Apple download servers" - return False, error_msg + return False, error_msg, "" elif result == 0: print(" - Downloading KDK") elif result == 1: print(" - Could not find KDK") error_msg = "Could not find KDK for host on Apple's servers, nor closest match" - return False, error_msg + return False, error_msg, "" if utilities.download_apple_developer_portal(URL_TEMPLATE, self.constants.kdk_download_path): - return True, error_msg + return True, error_msg, detected_build error_msg = "Failed to download KDK" - return False, error_msg + return False, error_msg, "" def is_kdk_installed(self, build): if Path("/Library/Developer/KDKs").exists(): diff --git a/resources/sys_patch.py b/resources/sys_patch.py index 422910ada..f3b79a422 100644 --- a/resources/sys_patch.py +++ b/resources/sys_patch.py @@ -117,15 +117,16 @@ class PatchSysVolume: # Assume KDK is already merged return + downloaded_kdk = None kdk_path = sys_patch_helpers.sys_patch_helpers(self.constants).determine_kdk_present(match_closest=False) if kdk_path is None: if not self.constants.kdk_download_path.exists(): - kdk_result, error_msg = kdk_handler.kernel_debug_kit_handler(self.constants).download_kdk(self.constants.detected_os_version, self.constants.detected_os_build) + kdk_result, error_msg, downloaded_kdk = kdk_handler.kernel_debug_kit_handler(self.constants).download_kdk(self.constants.detected_os_version, self.constants.detected_os_build) if kdk_result is False: raise Exception(f"Unable to download KDK: {error_msg}") sys_patch_helpers.sys_patch_helpers(self.constants).install_kdk() - kdk_path = sys_patch_helpers.sys_patch_helpers(self.constants).determine_kdk_present(match_closest=True) + kdk_path = sys_patch_helpers.sys_patch_helpers(self.constants).determine_kdk_present(match_closest=False, override_build=downloaded_kdk) if kdk_path is None: print("- Unable to find Kernel Debug Kit") raise Exception("Unable to find Kernel Debug Kit") diff --git a/resources/sys_patch_helpers.py b/resources/sys_patch_helpers.py index ac89fc12f..858c2c849 100644 --- a/resources/sys_patch_helpers.py +++ b/resources/sys_patch_helpers.py @@ -71,6 +71,9 @@ class sys_patch_helpers: return False def install_kdk(self): + if not self.constants.kdk_download_path.exists(): + return + print(f"- Installing downloaded KDK (this may take a while)") with tempfile.TemporaryDirectory() as mount_point: utilities.process_status(subprocess.run(["hdiutil", "attach", self.constants.kdk_download_path, "-mountpoint", mount_point, "-nobrowse"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)) @@ -80,31 +83,35 @@ class sys_patch_helpers: print("- Successfully installed KDK") - def determine_kdk_present(self, match_closest=False): + def determine_kdk_present(self, match_closest=False, override_build=None): # Check if KDK is present # If 'match_closest' is True, will provide the closest match to the reported KDK kdk_array = [] + search_build = self.constants.detected_os + if override_build: + search_build = override_build + if not Path("/Library/Developer/KDKs").exists(): return None for kdk_folder in Path("/Library/Developer/KDKs").iterdir(): # Ensure direct match - if kdk_folder.name.endswith(f"{self.constants.detected_os_build}.kdk"): + if kdk_folder.name.endswith(f"{search_build}.kdk"): # Verify that the KDK is valid if (kdk_folder / Path("System/Library/Extensions/System.kext/PlugIns/Libkern.kext/Libkern")).exists(): return kdk_folder if match_closest is True: # ex: KDK_13.0_22A5266r.kdk -> 22A5266r.kdk -> 22A5266r build = kdk_folder.name.split("_")[2].split(".")[0] - if build.startswith(str(self.constants.detected_os)): + if build.startswith(str(search_build)): kdk_array.append(build) if match_closest is True: result = os_data.os_conversion.find_largest_build(kdk_array) - print(f"- Closest KDK match: {result}") + print(f"- Closest KDK match to {search_build}: {result}") for kdk_folder in Path("/Library/Developer/KDKs").iterdir(): if kdk_folder.name.endswith(f"{result}.kdk"): # Verify that the KDK is valid