In the DATA segment of a Mach-O binary, there are a few objective-C specific sections (mentioned on page 7 of the Mach-O file format)
To quote the PiOS paper:
the __objc_classlist section contains a list of all classes whose implementation is present in the analyzed binary (that is, all classes implemented by the developer or included by the static linker)
and
The __objc_classref section, on the other hand, contains references to all classes that are used by the application. The implementations of these classes need not be contained in the binary itself, but may be provided by the runtime framework (the equivalent of dynamically-linked libraries).
They mention that the layout of these structure is available from the Objective C runtime headers (which are available here).
What are the actual structures of the __objc_classref
and __objc_classlist
sections?
Thanks in advance.
Take a look at the definition of the GETSECT
macro in a slightly newer version of the Objective-C runtime implementation. It looks like so:
#define GETSECT(name, type, sectname) \
type *name(const header_info *hi, size_t *outCount) \
{ \
unsigned long byteCount = 0; \
type *data = (type *) \
getsectiondata(hi->mhdr, SEG_DATA, sectname, &byteCount); \
*outCount = byteCount / sizeof(type); \
return data; \
}
This tells us that each section is an array of items of type type
.
It's used a few lines later to declare functions named _getObjc2ClassRefs
and _getObjc2ClassList
which read the two sections that you're interested in:
GETSECT(_getObjc2ClassRefs, class_t *, "__objc_classrefs");
GETSECT(_getObjc2ClassList, classref_t, "__objc_classlist");
So __objc_classrefs
contains class_t *
s, and __objc_classlist
contains classref_t
s. Interpreting those fields should be relatively self-explanatory.