From 4a806431bef66e0053d0d2e2baf35b709343e57c Mon Sep 17 00:00:00 2001 From: Steven Michaud Date: Wed, 26 May 2021 15:58:02 -0500 Subject: [PATCH] Deal with breakage caused by macOS 11.4 (fixes issue #28) --- 0-whats-new.md | 15 ++++++- 1-more-about.md | 2 +- HookCase/HookCase.xcodeproj/project.pbxproj | 4 +- HookCase/HookCase/HookCase.cpp | 46 ++++++++++++++++++++- HookCase/HookCase/Info.plist | 4 +- examples-kernel-logging.md | 2 +- 6 files changed, 64 insertions(+), 9 deletions(-) diff --git a/0-whats-new.md b/0-whats-new.md index 063d1e0..27536b4 100644 --- a/0-whats-new.md +++ b/0-whats-new.md @@ -1,3 +1,14 @@ +# What's New in Version 5.0.5 + +macOS 11.4 broke HookCase, just like macOS 11.3 did. macOS 11.4 made +further changes to `struct thread`, of a kind that normally only takes +place in a new major release. These changes caused a kernel panic +every time you tried to load a hook library into an application. The +problem is fixed by HookCase 5.0.5. `struct thread` is one of several +kernel structures that HookCase needs to access directly. For more +information see +[Issue #28](https://github.com/steven-michaud/HookCase/issues/28). + # What's New in Version 5.0.4 This version of HookCase fixes a bug that caused intermittent @@ -215,12 +226,12 @@ can now hook methods that aren't in their module's symbol table. For more information see [Hooked_sub_123abc() in the hook library template](HookLibraryTemplate/hook.mm#L1105). -* Version 2.0 [fixes a bug](HookCase/HookCase/HookCase.cpp#L9870) that +* Version 2.0 [fixes a bug](HookCase/HookCase/HookCase.cpp#L9914) that prevented interpose hooks from working outside the shared cache of system modules. * Version 2.0 -[fixes a previously undiscovered edge case](HookCase/HookCase/HookCase.cpp#L11361) +[fixes a previously undiscovered edge case](HookCase/HookCase/HookCase.cpp#L11405) of an Apple kernel panic bug that was partially fixed in version 1. * Version 2.0 diff --git a/1-more-about.md b/1-more-about.md index 0d7bfe9..a229d30 100644 --- a/1-more-about.md +++ b/1-more-about.md @@ -88,5 +88,5 @@ allow the original `dyld::InitializeMainExecutable()` method to run (which, among other things, runs the process's C++ initializers). For more information, the best place to start is the -[long series of comments](HookCase/HookCase/HookCase.cpp#L6987) +[long series of comments](HookCase/HookCase/HookCase.cpp#L7031) in `HookCase.cpp` before the definition of `C_64_REDZONE_LEN`. diff --git a/HookCase/HookCase.xcodeproj/project.pbxproj b/HookCase/HookCase.xcodeproj/project.pbxproj index 5642053..6068ae7 100644 --- a/HookCase/HookCase.xcodeproj/project.pbxproj +++ b/HookCase/HookCase.xcodeproj/project.pbxproj @@ -231,7 +231,7 @@ MODULE_NAME = org.smichaud.HookCase; MODULE_START = HookCase_start; MODULE_STOP = HookCase_stop; - MODULE_VERSION = 5.0.4; + MODULE_VERSION = 5.0.5; PRODUCT_BUNDLE_IDENTIFIER = org.smichaud.HookCase; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = kext; @@ -247,7 +247,7 @@ MODULE_NAME = org.smichaud.HookCase; MODULE_START = HookCase_start; MODULE_STOP = HookCase_stop; - MODULE_VERSION = 5.0.4; + MODULE_VERSION = 5.0.5; PRODUCT_BUNDLE_IDENTIFIER = org.smichaud.HookCase; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = kext; diff --git a/HookCase/HookCase/HookCase.cpp b/HookCase/HookCase/HookCase.cpp index 1fc0a76..f59981d 100644 --- a/HookCase/HookCase/HookCase.cpp +++ b/HookCase/HookCase/HookCase.cpp @@ -332,6 +332,16 @@ bool macOS_BigSur_less_than_3() return ((OSX_Version() & 0xFF) < 0x40); } +bool macOS_BigSur_4_or_greater() +{ + if (!((OSX_Version() & 0xFF00) == MAC_OS_X_VERSION_10_16_HEX)) { + return false; + } + // The output of "uname -r" for macOS 11.4 is actually "20.5.0", and + // for 11.3 is "20.4.0". + return ((OSX_Version() & 0xFF) >= 0x50); +} + bool OSX_Version_Unsupported() { return (((OSX_Version() & 0xFF00) < MAC_OS_X_VERSION_10_9_HEX) || @@ -3902,6 +3912,19 @@ typedef struct thread_fake_bigsur_3 vm_map_t map; // Offset 0x6a8 } thread_fake_bigsur_3_t; +typedef struct thread_fake_bigsur_4 +{ + uint32_t pad1[24]; + integer_t options; // Offset 0x60 + uint32_t pad2[15]; + // Actually a member of thread_t's 'machine' member. + void *ifps; // Offset 0xa0 + uint32_t pad3[230]; + int iotier_override; // Offset 0x440 + uint32_t pad4[155]; + vm_map_t map; // Offset 0x6b0 +} thread_fake_bigsur_4_t; + typedef struct thread_fake_bigsur_development { uint32_t pad1[26]; @@ -3928,6 +3951,19 @@ typedef struct thread_fake_bigsur_development_3 vm_map_t map; // Offset 0x718 } thread_fake_bigsur_development_3_t; +typedef struct thread_fake_bigsur_development_4 +{ + uint32_t pad1[26]; + integer_t options; // Offset 0x68 + uint32_t pad2[15]; + // Actually a member of thread_t's 'machine' member. + void *ifps; // Offset 0xa8 + uint32_t pad3[248]; + int iotier_override; // Offset 0x490 + uint32_t pad4[163]; + vm_map_t map; // Offset 0x720 +} thread_fake_bigsur_development_4_t; + typedef struct thread_fake_catalina { uint32_t pad1[24]; @@ -4276,7 +4312,15 @@ bool initialize_thread_offsets() } } - if (macOS_BigSur_less_than_3()) { + if (macOS_BigSur_4_or_greater()) { + if (kernel_type_is_release()) { + g_iotier_override_offset = + offsetof(struct thread_fake_bigsur_4, iotier_override); + } else if (kernel_type_is_development()) { + g_iotier_override_offset = + offsetof(struct thread_fake_bigsur_development_4, iotier_override); + } + } else if (macOS_BigSur_less_than_3()) { if (kernel_type_is_release()) { g_iotier_override_offset = offsetof(struct thread_fake_bigsur, iotier_override); diff --git a/HookCase/HookCase/Info.plist b/HookCase/HookCase/Info.plist index 13ef5a0..9f178f0 100644 --- a/HookCase/HookCase/Info.plist +++ b/HookCase/HookCase/Info.plist @@ -15,11 +15,11 @@ CFBundlePackageType KEXT CFBundleShortVersionString - 5.0.4 + 5.0.5 CFBundleSignature ???? CFBundleVersion - 5.0.4 + 5.0.5 NSHumanReadableCopyright Copyright © 2021 Steven Michaud. All rights reserved. OSBundleLibraries diff --git a/examples-kernel-logging.md b/examples-kernel-logging.md index 3e73106..817cb3c 100644 --- a/examples-kernel-logging.md +++ b/examples-kernel-logging.md @@ -23,7 +23,7 @@ kernel extensions whose `start()` method fails. Note that there's a workaround, which involves installing a serial port and using `kprintf()` to write to it. For more information see -[HookCase_start()](HookCase/HookCase/HookCase.cpp#L12659). +[HookCase_start()](HookCase/HookCase/HookCase.cpp#L12703). The root of the problem is that the messages received by Apple's new logging subsystem no longer contain full strings. Instead each