
首先系统调用号大大的不同
mac64和linux32的系统调用号也不同(虽然局部可能有相同)
mac64的系统调用号在:
/usr/include/sys/syscall.h
可以查到,但是调用的时候其值要加上0x2000000,可以写一个宏处理:
%define mk64 0x2000000+
使用方式如下:
mov rax,mk64 1 ;exit NOmov rdi,0 ;error_codesyscall
符号名称不同
如果在mac64下汇编要与C库相链接,所有extern符号名前要加下划线,包括入口点main:
extern _strerrorextern _printfglobal _main_main:
而linux64下汇编和C库链接的时候必须去掉符号前的下划线。
PIE
mac里的PIE(参考:http://blog.csdn.net/mydo/article/details/44906109),在直接使用绝对地址时会发出警告,如想去除警告,必须使用相对地址:
;mov rbx,addr;上一条指令要换成下一条lea rbx,[rel addr]mov rsi,[rbx]
绝对地址赋值
mac64下不允许将值赋到32位的绝对地址里去,比如以下指令出错:
mov [addr],rax
需要强制声明为64位地址或者改用相对地址:
mov [qword addr],rax ;okmov [rel addr],rax ;ok too
但linux64下无此限制。
C库包装
mac64和linux64对系统调用的C库包装有所不同,尤其是处理系统调用返回值的时候;比如mmap调用,linux64 C库貌似不检查参数,而是依据syscall自身检查;
而mac64在调用前会检查参数,如果参数有误,根本不会进行系统调用,直接设置errno,然后返回。
再拿mmap来说,如果在mmap C库函数上设断点,那么在经过N次的fast_syscall_stub之后:
-> 0x7fff8c4fc3b5 : callq 0x7fff8c4fd9e0 ; _dyld_fast_stub_entry(void*, long)
才会进入断点,所以要在fast_syscall_stub上设置条件断点,忽略前面N次的捕获(我测试的程序时或略前面28次),然后会进入kernel动态库中的mmap函数:
libsystem_kernel.dylib`mmap:-> 0x7fff8ad05a96 : pushq %rbp 0x7fff8ad05a97 : movq %rsp, %rbp 0x7fff8ad05a9a : pushq %r15 0x7fff8ad05a9c : pushq %r14 0x7fff8ad05a9e : pushq %r12 0x7fff8ad05aa0 : pushq %rbx 0x7fff8ad05aa1 : movl %r8d, %r15d 0x7fff8ad05aa4 : movq %rsi, %r14
其对传入mmap的参数进行了检查,如果发现参数错误,不会调用真正的__mmap函数,而是设置错误码,然后根据不同的错误类型跳至对应的C库错误处理函数:
0x7fff8ad05b11 : movl $0x16, %edi 0x7fff8ad05b16 : callq 0x7fff8ad03c53 ; cerror_nocancel
下面是cerror_nocancel函数的反汇编:
libsystem_kernel.dylib`cerror_nocancel:-> 0x7fff8ad03c53 : movl %edi, -0x14a629d9(%rip) ; errno 0x7fff8ad03c59 : movq %gs:0x8, %rax 0x7fff8ad03c62 : testq %rax, %rax 0x7fff8ad03c65 : je 0x7fff8ad03c69 ; 0x7fff8ad03c67 : movl %edi, (%rax) 0x7fff8ad03c69 : movq $-0x1, %rax 0x7fff8ad03c70 : movq $-0x1, %rdx 0x7fff8ad03c77 : retq
错误码的返回位置
而且最为关键的一点是,貌似mac64直接将系统调用错误码通过rax返回,而不像linux64那样返回的是错误码的补码。
所以博文linux64汇编调用mmap的例子(博文链接:http://blog.csdn.net/mydo/article/details/45007989)里,syscall返回后的代码必须改写为如下代码:
;syscall for mmap syscall cmp rax,0xfff ja next push rax mov [rel errno],rax pop rax or rax,-1
暂时只想到这么多不同点,大家可以继续搭楼 ;)