11 typedef const char * _Nullable (*objc_hook_lazyClassNamer)(_Nonnull Class);
13 void objc_setHook_lazyClassNamer(_Nonnull objc_hook_lazyClassNamer newValue,
14 _Nonnull objc_hook_lazyClassNamer * _Nonnull oldOutValue);
16 #define RW_COPIED_RO (1<<27)
19 struct ObjCClass * __ptrauth_objc_isa_pointer isa;
20 struct ObjCClass * __ptrauth_objc_super_pointer superclass;
28 uint32_t instanceStart;
29 uint32_t instanceSize;
35 const uint8_t * ivarLayout;
36 struct ObjCClass * nonMetaClass;
40 struct ObjCMethodList * __ptrauth_objc_method_list_pointer baseMethodList;
41 struct protocol_list_t * baseProtocols;
42 const struct ivar_list_t * ivars;
44 const uint8_t * weakIvarLayout;
45 struct property_list_t *baseProperties;
48 extern struct ObjCClass OBJC_METACLASS_$_NSObject;
49 extern struct ObjCClass OBJC_CLASS_$_NSObject;
51 extern struct ObjCClass LazyClassName;
52 extern struct ObjCClass LazyClassName2;
54 struct ObjCClass_ro LazyClassNameMetaclass_ro = {
58 .nonMetaClass = &LazyClassName,
61 struct ObjCClass LazyClassNameMetaclass = {
62 .isa = &OBJC_METACLASS_$_NSObject,
63 .superclass = &OBJC_METACLASS_$_NSObject,
64 .cachePtr = &_objc_empty_cache,
65 .data = (uintptr_t)&LazyClassNameMetaclass_ro,
68 struct ObjCClass_ro LazyClassName_ro = {
73 struct ObjCClass LazyClassName = {
74 .isa = &LazyClassNameMetaclass,
75 .superclass = &OBJC_CLASS_$_NSObject,
76 .cachePtr = &_objc_empty_cache,
77 .data = (uintptr_t)&LazyClassName_ro + 2,
80 struct ObjCClass_ro LazyClassName2Metaclass_ro = {
84 .nonMetaClass = &LazyClassName2,
87 struct ObjCClass LazyClassName2Metaclass = {
88 .isa = &OBJC_METACLASS_$_NSObject,
89 .superclass = &OBJC_METACLASS_$_NSObject,
90 .cachePtr = &_objc_empty_cache,
91 .data = (uintptr_t)&LazyClassName2Metaclass_ro,
94 struct ObjCClass_ro LazyClassName2_ro = {
99 struct ObjCClass LazyClassName2 = {
100 .isa = &LazyClassName2Metaclass,
101 .superclass = &OBJC_CLASS_$_NSObject,
102 .cachePtr = &_objc_empty_cache,
103 .data = (uintptr_t)&LazyClassName2_ro + 2,
106 static objc_hook_lazyClassNamer OrigNamer;
108 static const char *ClassNamer(Class cls) {
109 if (cls == (__bridge Class)&LazyClassName)
110 return "LazyClassName";
111 return OrigNamer(cls);
114 static objc_hook_lazyClassNamer OrigNamer2;
116 static const char *ClassNamer2(Class cls) {
117 if (cls == (__bridge Class)&LazyClassName2)
118 return "LazyClassName2";
119 return OrigNamer2(cls);
122 __attribute__((section("__DATA,__objc_classlist,regular,no_dead_strip")))
123 struct ObjCClass *LazyClassNamePtr = &LazyClassName;
124 __attribute__((section("__DATA,__objc_classlist,regular,no_dead_strip")))
125 struct ObjCClass *LazyClassNamePtr2 = &LazyClassName2;
128 #pragma clang diagnostic push
129 #pragma clang diagnostic ignored "-Wunguarded-availability"
130 objc_setHook_lazyClassNamer(ClassNamer, &OrigNamer);
131 objc_setHook_lazyClassNamer(ClassNamer2, &OrigNamer2);
132 #pragma clang diagnostic pop
134 printf("%s\n", class_getName([(__bridge id)&LazyClassName class]));
135 printf("%s\n", class_getName([(__bridge id)&LazyClassName2 class]));