Skip to content

Conversation

@WHW0x455
Copy link

The patch is only tested on 5.2.8614.

Based on opensource code loader.h and dyld, the lowest byte in sect.flags stands for section type.

section name section type value
__auth_got or __got S_NON_LAZY_SYMBOL_POINTERS 0x6
__init_offsets S_INIT_FUNC_OFFSETS 0x16

The problem for sect.flags & S_NON_LAZY_SYMBOL_POINTERS is that if flags is S_INIT_FUNC_OFFSETS, mach-o view will confuse __init_offsets with __auth_got(or __got). The checks for other section types have also been improved.

Based on opensource code [`loader.h`](https://github.com/apple-oss-distributions/xnu/blob/f6217f891ac0bb64f3d375211650a4c1ff8ca1ea/EXTERNAL_HEADERS/mach-o/loader.h#L470) and [`dyld`](https://github.com/apple-oss-distributions/dyld), the lowest byte in `sect.flags` stands for section type.

|      section name       |        section type        | value |
| :---------------------: | :------------------------: | :---: |
| `__auth_got` or `__got` | S_NON_LAZY_SYMBOL_POINTERS |  0x6  |
|    `__init_offsets`     |    S_INIT_FUNC_OFFSETS     | 0x16  |

The problem for `sect.flags & S_NON_LAZY_SYMBOL_POINTERS` is that if
`flags` is `S_INIT_FUNC_OFFSETS`, mach-o view will confuse `__init_offsets`
with `__auth_got`(or `__got`). The checks for other section types have
also been improved.
@CLAassistant
Copy link

CLAassistant commented Dec 29, 2025

CLA assistant check
All committers have signed the CLA.

@bdash
Copy link
Contributor

bdash commented Dec 29, 2025

Thank you for sending this PR. The change seems correct, but I do want to look into why this existing code was matching on section names before I merge it.

Is there a particular Mach-O binary on which you noticed the incorrect section type handling causing a problem?

@WHW0x455
Copy link
Author

The mach-o I analyzed is a 2023 iOS in-the-wild (ITW) malware sample called Predator. It was uploaded and shared by Google GTIG/TAG; their blog post is available here. The sample can be downloaded here.

I loaded the sample into Binary Ninja and noticed that the entire __init_offsets section was incorrect. The section was filled with wrong symbols. I then dug into it and found the the incorrect section type handling.

Support for the __init_offsets section was introduced in commit 4bc3153. Previously, __mod_init_func was identified by matching section names, and it is possible that the author of this commit directly adopted the same approach.

One more issue is that I missed S_SYMBOL_STUBS in the first commit of this PR. Although I later added a commit to handle S_SYMBOL_STUBS, I suspect the check is still incorrect. S_ATTR_SELF_MODIFYING_CODE is only used for i386 code stubs. After reviewing the relevant dyld code, I think this check can be improved.

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

Successfully merging this pull request may close these issues.

3 participants