Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't comment them out #25

Open
Torrekie opened this issue Mar 26, 2022 · 1 comment
Open

Don't comment them out #25

Torrekie opened this issue Mar 26, 2022 · 1 comment

Comments

@Torrekie
Copy link

Torrekie commented Mar 26, 2022

I figured out how <os/feature_private.h> was, and those dyld magic values.

https://github.com/Torrekie/apple_internal_sdk

I started working on this while compiling latest objc4 for porting it to older iOS. Commenting out featureflag and OS detection codes was really a bad idea since it ACTUALLY affecting how libobjc works. The reason I am doing this is, I can't find any useful information except bunch copies of articles telling me to comment these undefined values out, no, don't do that.

These undefined values and undeclared functions can be easily figured out by simple searching or reversing. For that non-open feature_private.h, I have done that here.

And for those dyld version check constants, they should originally be in <mach-o/dyld_priv.h> but stripped out by Apple. They are simple structs containing two uint32_t values referring to platforms and versions.

typedef uint32_t dyld_platform_t;

typedef struct {
    dyld_platform_t platform;
    uint32_t        version;
} dyld_build_version_t;

These are actual values of those dyld_fall_20*_os_versions stuff

// Sat Mar 26 18:48:53 CST 2022
// reversed from /usr/lib/libobjc.A.dylib and /usr/lib/system/libcommonCrypto.dylib
// Also tested
#define dyld_fall_2017_os_versions		(dyld_build_version_t) { 0xFFFFFFFF, 0x07E10901 }
#define dyld_fall_2018_os_versions		(dyld_build_version_t) { 0xFFFFFFFF, 0x07E20901 }
#define dyld_fall_2019_os_versions		(dyld_build_version_t) { 0xFFFFFFFF, 0x07E30901 }
#define dyld_fall_2020_os_versions		(dyld_build_version_t) { 0xFFFFFFFF, 0x07E40901 }
#define dyld_fall_2021_os_versions		(dyld_build_version_t) { 0xFFFFFFFF, 0x07E50901 }

#define dyld_platform_version_macOS_10_11       (dyld_build_version_t) { PLATFORM_MACOS, 0x000A0B00 }
#define dyld_platform_version_macOS_10_12       (dyld_build_version_t) { PLATFORM_MACOS, 0x000A0C00 }
#define dyld_platform_version_macOS_10_13	(dyld_build_version_t) { PLATFORM_MACOS, 0x000A0D00 }
#define dyld_platform_version_macOS_10_14	(dyld_build_version_t) { PLATFORM_MACOS, 0x000A0E00 }
#define dyld_platform_version_macOS_10_15	(dyld_build_version_t) { PLATFORM_MACOS, 0x000A0F00 }
#define dyld_platform_version_macOS_10_16	(dyld_build_version_t) { PLATFORM_MACOS, 0x000A1000 }
#define dyld_platform_version_macOS_12_00	(dyld_build_version_t) { PLATFORM_MACOS, 0x000C0000 }

#define dyld_platform_version_tvOS_10_0         (dyld_build_version_t) { PLATFORM_TVOS, 0x000A0000 }
#define dyld_platform_version_tvOS_11_0         (dyld_build_version_t) { PLATFORM_TVOS, 0x000B0000 }
#define dyld_platform_version_tvOS_12_0		(dyld_build_version_t) { PLATFORM_TVOS, 0x000C0000 }
#define dyld_platform_version_tvOS_13_0		(dyld_build_version_t) { PLATFORM_TVOS, 0x000D0000 }
#define dyld_platform_version_tvOS_14_0		(dyld_build_version_t) { PLATFORM_TVOS, 0x000E0000 }
#define dyld_platform_version_tvOS_15_0		(dyld_build_version_t) { PLATFORM_TVOS, 0x000F0000 }

#define dyld_platform_version_iOS_10_0          (dyld_build_version_t) { PLATFORM_IOS, 0x000A0000 }
#define dyld_platform_version_iOS_11_0          (dyld_build_version_t) { PLATFORM_IOS, 0x000B0000 }
#define dyld_platform_version_iOS_12_0		(dyld_build_version_t) { PLATFORM_IOS, 0x000C0000 }
#define dyld_platform_version_iOS_13_0		(dyld_build_version_t) { PLATFORM_IOS, 0x000D0000 }
#define dyld_platform_version_iOS_14_0		(dyld_build_version_t) { PLATFORM_IOS, 0x000E0000 }
#define dyld_platform_version_iOS_15_0		(dyld_build_version_t) { PLATFORM_IOS, 0x000F0000 }

#define dyld_platform_version_watchOS_3_0       (dyld_build_version_t) { PLATFORM_WATCHOS, 0x00030000 }
#define dyld_platform_version_watchOS_4_0       (dyld_build_version_t) { PLATFORM_WATCHOS, 0x00040000 }
#define dyld_platform_version_watchOS_5_0	(dyld_build_version_t) { PLATFORM_WATCHOS, 0x00050000 }
#define dyld_platform_version_watchOS_6_0	(dyld_build_version_t) { PLATFORM_WATCHOS, 0x00060000 }
#define dyld_platform_version_watchOS_7_0	(dyld_build_version_t) { PLATFORM_WATCHOS, 0x00070000 }
#define dyld_platform_version_watchOS_8_0	(dyld_build_version_t) { PLATFORM_WATCHOS, 0x00080000 }

#define dyld_platform_version_bridgeOS_2_0      (dyld_build_version_t) { PLATFORM_BRIDGEOS, 0x00020000 }
#define dyld_platform_version_bridgeOS_3_0      (dyld_build_version_t) { PLATFORM_BRIDGEOS, 0x00030000 }
#define dyld_platform_version_bridgeOS_4_0      (dyld_build_version_t) { PLATFORM_BRIDGEOS, 0x00040000 }
#define dyld_platform_version_bridgeOS_5_0      (dyld_build_version_t) { PLATFORM_BRIDGEOS, 0x00050000 }
#define dyld_platform_version_bridgeOS_6_0      (dyld_build_version_t) { PLATFORM_BRIDGEOS, 0x00060000 }

Using that CrashReporterClient.h stub which appears in older Libc was not quite a good idea, since linking libCrashReporterClient would insert a load command section to Mach-O files (that also indicates libCrashReporterClient was a static library)


Section
  sectname __crash_info
   segname __DATA
      addr 0x00000001d97f8ad8
      size 0x0000000000000040
    offset 246296
     align 2^3 (8)
    reloff 0
    nreloc 0
     flags 0x00000000
 reserved1 0
 reserved2 0

We can find CrashReporterClient implementation under WTF/wtf/spi/cocoa/CrashReporterClientSPI.h and WTF/wtf/cocoa/CrashReporter.cpp, these codes also appears in many other Apple OSSes.

Now we have <CrashReporterClient.h> and libCrashReporterClient.a

For those Cambria APIs, we can see objc-cache.mm was calling two of them

#if TARGET_OS_OSX
        if (oah_is_current_process_translated()) {
            kern_return_t ret = objc_thread_get_rip(threads[count], (uint64_t*)&pc);
            if (ret != KERN_SUCCESS) {
                pc = PC_SENTINEL;
            }
        } else {
            pc = _get_pc_for_thread (threads[count]);
        }
#else
        pc = _get_pc_for_thread (threads[count]);
#endif

It was really easy to figure out that oah_is_current_process_translated() was returning bool, with no arguments, then we have its prototype

bool oah_is_current_process_translated(void);

objc_thread_get_rip() was kinda tricky but still easy to find out how to correctly call it, the definition of thread was
thread_act_port_array_t threads;, and the actual type of thread_act_port_array_t was

// <arm/_types.h> or <i386/_types.h>
typedef unsigned int            __darwin_natural_t;
// <sys/_types.h>
typedef __darwin_natural_t __darwin_mach_port_name_t; /* Used by mach */
typedef __darwin_mach_port_name_t __darwin_mach_port_t; /* Used by mach */
// <sys/_types/_mach_port_t.h>
typedef __darwin_mach_port_t mach_port_t;
// <mach/mach-types.h>
typedef mach_port_t             thread_act_t;
typedef thread_act_t            *thread_act_array_t;
typedef thread_act_array_t      thread_act_port_array_t;

We can see the 1st arg of objc_thread_get_rip() was a member of thread_act_port_array_t, then the type is thread_act_t but not thread_act_port_array_t, then we get prototype

kern_return_t objc_thread_get_rip(thread_act_t thread, uint64_t** buf);

These codes cannot successfully compile without linking liboah, which was not presenting in MacOSX.sdk, we can extract dyld shared cache, get /usr/lib/liboah.dylib, generate liboah.tbd from it. I have done Cambria headers also

@adalric
Copy link

adalric commented May 23, 2022

WOHO!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants