I'm wondering how the info stored in the chained fixups in the Mach-O file is used to resolve binding and rebases?
My question originated from wanting to parse all the Objective-C classes inside a Mach-O and parse their respective
objc_class and get a list of selectors.
In-order to achieve that I started by parsing the Mach-O segments to get to the section
__objc_classlist and read the pointers that should point to struct of type
What I don't understand is how to use the stored information there to fix these pointers for example. Taking as a ref point I have a binary that the first pointer on disk (
0x00231D8) in the
__objc_classlist section points to
0x0025EED0 which is its related
objc_class struct (validated using Ghidra). When I read from
0x00231D8 I get
0x801000000000022a which is not a valid pointer, pointing to the mapped file.
After seeing that the pointers are invalid I was noted that I should parse and use the information stored in the chained fixups load command to fix the pointers.
So I parsed the chained fixups but I'm not sure how to use the parsed binds/rebases structs in-order to fix the pointers for example at the
Taking the ref point I'm working on to validate my work, I use Ghidra to see what symbol the first pointer in the
__objc_classlist actually is and I look for any binding info related to that symbol in my parsed result to find the following both in the fixups of the
__DATA_CONST and the
BIND ordinal: 554 addend: 0 reserved: 0 (_OBJC_METACLASS_$_XYZ)
I understand that the ordinal is the index into the symbol table pointer to by the
imports_offset which I also printed to validate the ordinal is correct:
 lib_ordinal: 15 weak_import: 0 name_offset: 13346 (ABC)  lib_ordinal: 0 weak_import: 0 name_offset: 13380 (_OBJC_CLASS_$_XYZ)  lib_ordinal: 0 weak_import: 0 name_offset: 13429 (_OBJC_CLASS_$_DEF)
Now I'm not sure if what I should be looking for in the chained fixups in-order to fix these class pointers is rebase/bind information. I know rebase is used for ASLR when loading other libs so if the objective-c class list is the binary owned class list there's no reason for rebases at least for these pointers, on the other hand even though I find related binding information to my class I don't see why do we need this information if it's a data owned by the binary and not some other dylib, why do we need to bind it in runtime?
Even so, how do I even use this information in-order to fix the pointer for example at
0x00231D8 in the
__objc_classlist? All I have is the binding information which gives an ordinal to the chained fixups imports as-well as
addend field which seems to always be 0 and I have no idea what it is used for.
The only logical jump I could've make is that if I look for the same import by its symbol name in the symbol table pointed by the symbol table command and take the
n_value of the symbol I get that elusive
0x0025EED0 pointer value.
But that still doesn't answer on how this symbol value should be the pointer in the first address of the
0x00231D8, what BINDs them together?
Continuing on, even if I read the value from disk in address
0x0025EED0 which should be the
objc_class struct of that symbol that resides in
__DATA.__objc_data, I get
80 10 00 00 00 00 03 c7 and by looking at the valid data in Ghidra I see
f8 ee 25 00 00 00 00 00, so clearly another discrepancy and maybe this data also need rebase/binding?
So I tried to take the address of the struct
0x0025EED0 and see if I can find rebase information (didn't look for binding information since it's not a symbol just a struct data?) on it from the chained fixups but couldn't find any so I'm not sure what needs to be done to fix it?