有其它系统基础的很容易理解, 没有基础的可以先看看其它系统的. 目前水果 pc 端 CPU 大部分都是 intel, 虽然他支持很多框架. 因此这里只说 intel 的.
我们先调用一个系统函数 frok, 代码如下:
- int main(int argc, char * argv[])
- {
- fork();
- return 1;
- }
下断在 fork(), 然后我们直接看汇编, 如图所示:
他直接 0x100000f76 <+22>: callq 0x100000f8c ; symbol stub for: fork
我们进入这个函数(xcode 不能直接步入), 如图所示:
0x100000f8c <+0>: ff 25 7e 00 00 00 jmpq 0x7e(%rip) ; (void )0x00007fff7eb4d084: fork
发现还在当前模块, 我们继续进入, 如图所示:
现在到了 libsystem_c.dylib 模块, 调用:
0x7fff7eb4d090 <+12>: e8 a1 11 07 00 callq 0x7fff7ebbe236 ; symbol stub for: __fork
继续进入, 如图所示:
还在这个模块.
libsystem_c.dylib`__fork: 0x7fff7ebbe236 <+0>: ff 25 94 ae d1 32 jmpq *0x32d1ae94(%rip) ; (void *)0x00007fff7ec30a44: __fork
继续进入, 如图所示:
我们对比 Windows 的看看.
发现水果的调用号很大, 但是看 xun 源码压根没有这么大一个数组, 同时也不可能有这么大一个数组, 其实他有好几层意思, 第一是调用号左移 24 位, 代表是哪种系统调用. 因为水内核还是很杂的内核分 bsd, 下层又是 mach. 同时他是 POSIX 系统标准.
大部分人都熟悉 POSIX 系统调用. 然而在 XNU 中, POSIX 系统调用只是 4 种系统调用的类别之一:
怎么找呢, intel64 位新加了快速调用, 有一组 MSR 寄存器, 有一个寄存器保存的是一个内核函数地址.(可以先看 Windows 的 https://bbs.pediy.com/thread-216995.htm)
这个内核函数地址其实就是一个中断例程, 经过一等系列调用 (因为要兼容其它框架) 最后就到了上面那几种类型种的其中一种. 这里只看 64 位.
我们直接看源码, 直接搜索 mach_call_munger 如图所示:
我们查看源码, 发现它做了一个位运算.
看看那个掩码, 做了三次定义.
手动算下:
0xFF <<24=0xFF000000 ~0xFF000000=0x00FFFFFF
然后他与 rax 相 & 就是去掉最前面俩位, fook 调用号是 0x2000002, 而他的 call_number 是 0x2.
查看 mach_syscall_name_table, 就能找到对应函数.
发现未定义, 这个还得后面调试, 先写到这里.
完整 lldb
(lldb) di -b -s 0x100000f8c MachPortDump`fork: 0x100000f8c <+0>: ff 25 7e 00 00 00 jmpq *0x7e(%rip) ; (void *)0x00007fff7eb4d084: fork 0x100000f92: 00 00 addb %al, (%rax) 0x100000f94: 4c 8d 1d 6d 00 00 00 leaq 0x6d(%rip), %r11 ; (void *)0x000000010008b0f0: initialPoolContent + 1216 0x100000f9b: 41 53 pushq %r11 0x100000f9d: ff 25 5d 00 00 00 jmpq *0x5d(%rip) ; (void *)0x00007fff7eadcac4: dyld_stub_binder 0x100000fa3: 90 nop 0x100000fa4: 68 00 00 00 00 pushq $0x0 (lldb) di -b -s 0x00007fff7eb4d084 libsystem_c.dylib`fork: 0x7fff7eb4d084 <+0>: 55 pushq %rbp 0x7fff7eb4d085 <+1>: 48 89 e5 movq %rsp, %rbp 0x7fff7eb4d088 <+4>: 53 pushq %rbx 0x7fff7eb4d089 <+5>: 50 pushq %rax 0x7fff7eb4d08a <+6>: ff 15 90 ef d8 32 callq *0x32d8ef90(%rip) ; _libSystem_atfork_prepare 0x7fff7eb4d090 <+12>: e8 a1 11 07 00 callq 0x7fff7ebbe236 ; symbol stub for: __fork 0x7fff7eb4d095 <+17>: 89 c3 movl %eax, %ebx 0x7fff7eb4d097 <+19>: 85 db testl %ebx, %ebx 0x7fff7eb4d099 <+21>: 74 12 je 0x7fff7eb4d0ad ; <+41> 0x7fff7eb4d09b <+23>: 83 fb ff cmpl $-0x1, %ebx 0x7fff7eb4d09e <+26>: 75 17 jne 0x7fff7eb4d0b7 ; <+51> (lldb) di -b -s 0x7fff7ebbe236 libsystem_c.dylib`__fork: 0x7fff7ebbe236 <+0>: ff 25 94 ae d1 32 jmpq *0x32d1ae94(%rip) ; (void *)0x00007fff7ec30a44: __fork libsystem_c.dylib`__fpclassifyd: 0x7fff7ebbe23c <+0>: ff 25 96 ae d1 32 jmpq *0x32d1ae96(%rip) ; (void *)0x00007fff7ec53df2: __fpclassifyd libsystem_c.dylib`__fpclassifyl: 0x7fff7ebbe242 <+0>: ff 25 98 ae d1 32 jmpq *0x32d1ae98(%rip) ; (void *)0x00007fff7ec5fac1: __fpclassify libsystem_c.dylib`__fstat64_extended: 0x7fff7ebbe248 <+0>: ff 25 9a ae d1 32 jmpq *0x32d1ae9a(%rip) ; (void *)0x00007fff7ec306a4: __fstat64_extended libsystem_c.dylib`__fstat_extended: 0x7fff7ebbe24e <+0>: ff 25 9c ae d1 32 jmpq *0x32d1ae9c(%rip) ; (void *)0x00007fff7ec4814c: __fstat_extended (lldb) di -b -s 0x00007fff7ec30a44 libsystem_kernel.dylib`__fork: 0x7fff7ec30a44 <+0>: 48 83 ec 18 subq $0x18, %rsp 0x7fff7ec30a48 <+4>: b8 02 00 00 02 movl $0x2000002, %eax ; imm = 0x2000002 0x7fff7ec30a4d <+9>: 0f 05 syscall 0x7fff7ec30a4f <+11>: 73 14 jae 0x7fff7ec30a65 ; <+33> 0x7fff7ec30a51 <+13>: 48 89 c7 movq %rax, %rdi 0x7fff7ec30a54 <+16>: e8 28 99 ff ff callq 0x7fff7ec2a381 ; cerror 0x7fff7ec30a59 <+21>: 48 c7 c0 ff ff ff ff movq $-0x1, %rax 0x7fff7ec30a60 <+28>: 48 83 c4 18 addq $0x18, %rsp (lldb)
来源: http://www.bubuko.com/infodetail-3089926.html