Some of the Mach-O executables have an LC_UNIXTHREAD command with the following initial register values:
cmd LC_UNIXTHREAD
cmdsize 80
flavor i386_THREAD_STATE
count i386_THREAD_STATE_COUNT
eax 0x00000000 ebx 0x00000000 ecx 0x00000000 edx 0x00000000
edi 0x00000000 esi 0x00000000 ebp 0x00000000 esp 0x00000000
ss 0x0000001f eflags 0x00000000 eip 0x00002788 cs 0x00000017
ds 0x0000001f es 0x0000001f fs 0x00000000 gs 0x00000000
The eip is set to the entry point of the app, but for some reason the rest also have a special initial value. (If they are all zeroes, the application crashes randomly because some of the malloc() does not return with clean memory area.) Any idea about the mysterious 0x1F segment?
What's mysterious about it? You kinda need valid selectors for CS,DS,SS :)
selector 0x17: RPL3, LDT, descriptor index 0x10
selector 0x1F: RPL3, LDT, descriptor index 0x18
Windows (at least win7-32bit) uses the following two:
CODE: 0x1B - RPL3, GDT, descriptor index 0x10
DATA: 0x23 - RPL3, GDT, descriptor index 0x20
After a deeper look I finally found the reason: depending on the selected base SDK and deployment target, GCC uses different system libraries and common runtime library object (crt1.o)
SDK10.4, Target10.4: /Developer/SDKs/MacOSX10.4u.sdk/usr/lib/crt1.o
SDK10.5, Target10.4: /Developer/SDKs/MacOSX10.5.sdk/usr/lib/crt1.o
SDK10.5, Target10.5: /Developer/SDKs/MacOSX10.5.sdk/usr/lib/crt1.10.5.o
SDK10.6, Target10.4: /Developer/SDKs/MacOSX10.6.sdk/usr/lib/crt1.o
SDK10.6, Target10.5: /Developer/SDKs/MacOSX10.6.sdk/usr/lib/crt1.10.5.o
SDK10.6, Target10.6: /Developer/SDKs/MacOSX10.6.sdk/usr/lib/crt1.10.6.o
These object files contain the initial UNIX thread load command with the mentioned register states. If the selected SDK and the deployment target are both 10.4 (first line) then the CS,DS,ES,SS will differ from 0.
CS needs to be set to a selector that has the X flag on. DS, ES are data segments and therefore point onto a different selector. FS, GS are also different. I'm not sure about Mac OS but on Windows those two are used for very specific things:
Win32: FS is used to store information about the process (FS:[30] = PEB, FS:[0] = SEH Info) Win64: GS is used instead of FS, rest is more or less the same.
On some applications in Mac OS X you will see that GS has a value of 0x0F and FS is set to zero, chances are that GS:[XXX] contains informations regarding the process.
User contributions licensed under CC BY-SA 3.0