mmap不会返回错误或有效的指针

时间:2019-06-21 23:22:57

标签: macos assembly x86-64 nasm

我一直在尝试使用 mmap 分配内存,但是到目前为止,我还不知道如何正确地进行分配。在下面可以看到我编写的一个函数,它从C调用。它产生的结果始终是197,与系统调用号相同。

C声明:

extern "C" void * ll_alloc ();

程序集定义:

_ll_alloc:
  sub rsp, 8
  mov r9, 0
  mov rdi, 0
  mov rax, 197         
  mov rsi, 4096          
  mov r8, -1            
  mov rdx, 0x02 | 0x01
  mov rcx, 0x1000 | 0x0001
  syscall
  add rsp, 8
  ret

我直接从C调用了mmap,一切正常,调用了我所做的:

void * mem = mmap(NULL, 4096, PROT_WRITE | PROT_READ, MAP_ANON | MAP_SHARED, -1, 0);

1 个答案:

答案 0 :(得分:1)

mov rcx, 0x1000 | 0x0001是不对的:syscall instruction本身会破坏RCX(带有保存的RIP)。

在x86-64 Linux上,syscall的调用约定将R10用作第4个arg,而不是按函数调用约定arg顺序使用RCX。 (What are the calling conventions for UNIX & Linux system calls on i386 and x86-64

我认为OS X做同样的事情(所以mov r10d, 0x1000 | 0x1 ),但是内核实际上无法读取syscall之前的用户空间RCX中的内容,所以绝对不是那个寄存器。另请参阅对64-bit syscall documentation for MacOS assembly

的评论

此外,x86-64 MacOS使用的呼叫号码与x86-64 Linux不同。尽管根据https://sigsegv.pl/osx-bsd-syscalls/ 197是正确的,但这似乎与x86-64有关。 (并且197不是Linux系统调用号)

我以为我记得需要设置更高位的实际EAX值,例如0x2000xyz;也许那是您需要添加的东西。 更新:是的,macOS 64-bit System Call Table说明将0x2000000添加到电话号码中是正确的。


通常可以调试这种东西

单步进入对C库mmap的调用,以在syscall指令从已知良好的库实现中运行时查看寄存器值。

还可以在您的手写asm程序上使用dtruss(MacOS)或strace 来查看内核认为它实际上在做什么。