Mach-O position-independent code design is based on the observation that the __DATA segment is always located at a constant offset from the __TEXT segment. That is, the dynamic loader, when loading any Mach-O file, never moves a file’s __TEXT segment relative to its __DATA segment. Therefore, a function can use its own current address plus a fixed offset to determine the location of the data it wishes to access. All segments of a Mach-O file, not only the __TEXT and __DATA segments, are at fixed offsets relative to the other segments.
Note: If you are familiar with the Executable and Linking Format (ELF), you may note that Mach-O position-independent code is similar to the GOT (global offset table) scheme. The primary difference is that Mach-O code references data using a direct offset, while ELF indirects all data access through the global offset table.
Now, I haven't actual spent any time digging through leopard, aside from a simple test of compiling a test program with the gcc on their (v4.0.1) to see if it had SSP (it had never heard of the flags -fstack-protector or -fstack-protector-all ?)- but it seems like if Apple PIC binaries contain this trait you end up with a couple complications.
The first and most obvious would be that you can't randomize per section, although in theory i believe you should be able to randomize the stack and heap, although that may cause problems in one of those funko languages like obj-c. The second problem is that because the text is not randomized, and because all i need to know is the base address of the image, which is pretty likely considering all of the segments that are not randomized and then look for variable references that take observation of the fact that section offsets are constant, and it would seem like I could reverse the address space layout that way.
I mean examining the .text or anything dealing with libraries, such as dyld, should reveal a lot of those references, it seems pretty much like overkill at this point in the game because all you really need is a jmp/call addr/reg, but honestly this seems like a deep flaw in the ASLR logic; maybe i just need more sleep?