【问题标题】:Mac OSX 64bit assembly - fork() test/jne doesn't work?Macos 64 位程序集 - fork() 测试/jne 不起作用?
【发布时间】:2013-11-12 21:41:31
【问题描述】:

我正在尝试编写一个执行fork() 系统调用的程序,并且子/父分别编写不同的字符串和exit(0)

问题是 - 尽管fork() 是成功的(因为我看到了 2 行输出),但由于某种原因,父进程和子进程都输出了父字符串。

代码如下:

BITS 64

section .data
msg1:    db    "Hello from child", 0x0a
len1:    equ   $-msg1
msg2:    db    "Hello from parent", 0x0a
len2:    equ   $-msg2

section .text
global start

start:
        xor rax,rax
        mov rax,0x2000002    ; fork() syscall
        syscall

        test eax,eax
        jne flow_parent

        mov rax, 0x2000004   ; SYS_write
        mov rdi, 1           ; stdout
        mov rsi, msg1
        mov rdx, len1
        syscall

        xor rdi,rdi
        mov rax,0x2000001
        syscall

flow_parent:
        mov rax, 0x2000004   ; SYS_write
        mov rdi, 1           ; stdout
        mov rsi, msg2
        mov rdx, len2
        syscall

        xor rdi,rdi
        mov rax,0x2000001
        syscall

我的输出:

$ nasm -f macho64 code.s -o code.o
$ ld -o code -e start -macosx_version_min 10.7 code.o
$ ./code
Hello from parent
Hello from parent
$

关于如何解决这个问题的任何想法?

【问题讨论】:

    标签: assembly fork x86-64 system-calls shellcode


    【解决方案1】:

    首先,您在 Mac OS X 上进行系统调用,并假设它的行为与 Linux 内核一样,这显然是错误的(Linux fork 系统调用约定!= XNU fork 系统调用约定)。 Mac OS X 不支持用户不通过 libSystem 库直接进行系统调用。

    暂且不说,我不确定您运行的是哪个版本的 XNU 内核,但如果您真正查看 libsyscall 库中 fork function 的源代码,您会发现应该使用 edx 寄存器(或 %edx,%edx)来确定进程是子进程还是父进程。

    同样,这仍然不是实现此功能的可靠方式,因为 Apple 将来可能会根据自己的意愿轻松更改界面。

    【讨论】:

    • 约瑟夫,感谢一百万的精心回复和源代码参考,它奏效了。
    • 为了记录,test same,sameor same,same 更有效地根据寄存器设置 FLAGS,尤其是在分支上时,因为test 可以与 JCC 进行宏融合,但 @987654326 @ 不能。在 XNU 源代码中 or 的用法是 a bad legacy idiom anti-optimization,除非他们此时主动需要将 EDX 零扩展为 RDX,如果可能的话,它可能还没有被零扩展。在这种情况下,他们应该and %edx,%edx 仍然融合在 SnB-fam 上
    【解决方案2】:

    不要测试寄存器 eax! 需要测试寄存器rdx才能得到返回值!

    【讨论】:

    • 现有答案已经说要检查 EDX。您确定来自 fork 的返回值(PID?)在 RDX 中是 64 位,而不仅仅是低 32 位? JosephH 的回答链接了 XNU 源代码,显示 x86-64 代码仍然使用 EDX。
    • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
    • 这没有提供问题的答案。一旦你有足够的reputation,你就可以comment on any post;相反,provide answers that don't require clarification from the asker。 - From Review
    猜你喜欢
    • 2020-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多