0

I'm trying to analyze and get the full list of selectors and their related classes in objective-c by first reading the __objc_classlist section and getting pointers to the struct objc_class list to traverse my way to class_ro_t struct from the bits member and then get to the the struct method_list_t and then get all the methods implementations and selectors.

I read my macho file and set the cursor to the section's addr member and then try to read pointer sized values, problem is I'm getting completely different values from what I inspect in ghidra for example where I see another pointer value that leads to an actualyl objc_class instance. I validated my code with just printing the bytes at this place: dd bs=1 "skip=2240984" "count=$((2240992 - 2240984))" if=framework | xxd

Where 2240984 is the start address of the __objc_classlist section and I observe same pointer values as in my code, so I wonder what I am doing wrong and why in ghidra I see different valid pointer values?

1 Answer 1

0

I would need to concrete binary you are talking about for specifics, but it's plausible that you are running into the concept of "Chained Fixup Pointers"

The value you are reading from the raw binary could then be the pointer sized value that encodes the information that is later used by the loader to write the correctly rebased pointer to this location.

It's not clear to me if your script is running inside Ghidra, or parsing the binary itself? With a Ghidra Script there should be APIs to read the fixed up value after rebasing.

8
  • Youre probably right, I read it's probably the case due to the binary being arm64 macOS 13 or something, I'm wondering why the objc runtime even encode these pointers and they're in need of a rebase/ The objc_classlist is the classlist of the binary itself, sure it contains binding and rebase information for imported symbols but why for its owned class list?
    – Jorayen
    Commented Sep 27, 2023 at 17:36
  • Ok just to clarify I'm not using running my scripts in Ghidra I just use it as a basis to analyze a macho myself. I've parsed the chained_fixups and I don't see any rebase value with a target of 2240984 which is the start of the __objc_classlist section, Maybe I just don't understand what I should do with the values of the dyld_chained_ptr_64_rebase struct and how it would help me to produce fixed values for whatever in the addresses of the __objc_classlist section. Also I've noticed that if I search for the _OBJC_CLASS_$_XXX symbol in the sym table the value of it is just the
    – Jorayen
    Commented Sep 27, 2023 at 21:51
  • address shown in Ghidra, so did I even need to parse the chained fixups?
    – Jorayen
    Commented Sep 27, 2023 at 21:51
  • Ghidra should already show the rebased pointers. But I'm not sure if this is the question you are asking? Commented Sep 28, 2023 at 12:36
  • No, just to clarify I'm using ghidra only as a tool to verify my own macho parsing. I've been able to parse the chained fixups, but what I do not understand is how from the rebase/bind structure do I get the fixed pointer values of data in the __objc_classlist section? I'm looking at the rebases of the chain (as far as I understand __objc_classlist is own binary classes so no binding info is needed her - but I might be wrong?) and I have the target field of the struct dyld_chained_ptr_64_rebase (from xnu macho/fixup-chains.h) and I wonder how do I go about from this struct data to
    – Jorayen
    Commented Sep 29, 2023 at 6:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.