True segment bounds not visible in Dyld cache
Author: jonpalmiscCreated Jun 11, 2026Updated Jun 12, 2026
Environment
Fri Jun 12 09:17:26 AEST 2026
radare2 6.1.7 +36062 abi:109 @ darwin-arm_64
birth: git.6.1.7 2026-06-11__10:44:32
commit: 5224c1d67858d909841d84c3e26772ce726785fc
options: gpl -O2 cs:5 cl:2 make
Darwin arm64Description
Normally when looking at a Mach-O, I would use iSS to see the segment bounds:
$ r2 /bin/ls
[0x100000960]> iSS
nth paddr size vaddr vsize perm flags type name
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
0 0x00010000 0x8000 0x100000000 0x8000 -r-x 0x0 MAP __TEXT
1 0x00018000 0x4000 0x100008000 0x4000 -rw- 0x0 MAP __DATA_CONST
2 0x0001c000 0x4000 0x10000c000 0x4000 -rw- 0x0 MAP __DATA
3 0x00020000 0x8000 0x100010000 0x8000 -r-- 0x0 MAP __LINKEDITWe can see that this info matches the load commands, which is what I want:
$ otool -l /bin/ls
...
Load command 1
cmd LC_SEGMENT_64
cmdsize 472
segname __TEXT
vmaddr 0x0000000100000000
vmsize 0x0000000000008000
fileoff 0
filesize 32768
maxprot 0x00000005
initprot 0x00000005
nsects 5
flags 0x0However, when loading a Dyld cache, iSS only returns cache_map entries:
[0x180000000]> iSS
nth paddr size vaddr vsize perm flags type name
――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
0 0x00000000 0xa0000 0x180000000 0xa0000 -r-x 0x0 MAP cache_map.0
1 0x000a4000 0x7d34000 0x180400000 0x7d34000 -r-x 0x0 MAP cache_map.1
2 0x07e18000 0x38000 0x188134000 0x38000 -r-x 0x0 MAP cache_map.2
...Using iS (sections) instead is insufficient, because the lowest (address) section inside of a segment is not necessarily the start of the segment:
40 0x1193c6610 0x3670bfc 0x2b0406610 0x3670bfc -r-x 0x0 ---- WebCore.framework/WebCore.0.__TEXT.__text
41 0x11ca37210 0x58f4 0x2b3a77210 0x58f4 -r-x 0x0 ---- WebCore.framework/WebCore.1.__TEXT.__objc_methlist
42 0x11ca3cb04 0x1284 0x2b3a7cb04 0x1284 -r-x 0x0 ---- WebCore.framework/WebCore.2.__TEXT.__getClass_cstr
43 0x11ca3dd88 0x75d7 0x2b3a7dd88 0x75d7 -r-x 0x0 ---- WebCore.framework/WebCore.3.__TEXT.__dlsym_cstrIf we split this library out of the shared cache and then open it, we can see the true segment bounds:
[0x2b0406610]> iSS
nth paddr size vaddr vsize perm flags type name
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
0 0x00000000 0x3c3a278 0x2b0404000 0x3c3a278 -r-x 0x0 MAP __TEXTIt would be great if the Dyld cache loader could retain the segment bounds info of the images inside the cache so that it can be looked up.
Source: radareorg/radare2