如何正确地将缓冲区指针传递给 x86_64 程序集中的 Linux 系统调用?

How to properly pass buffer pointers to Linux system calls in x86_64 assembly?

您好,我正在尝试学习如何使用 Linux 上的 x86_64 程序集进行系统调用。我 运行 遇到了一个问题,我似乎无法弄清楚如何正确传递 getpeername.

的参数

在这个使用 C 的 link 中,看起来他们正在使用运算符的地址来传递参数。我不知道如何在汇编中复制它。这是我的缓冲区不使用括号时的 strace。

首先我在 .data 部分定义了我的缓冲区

ip_buff:  times 14 db 0
.length: equ $-ip_buff

这是一个宏

%define SYS_getpeername 52

r12 存储来自套接字接受调用的 return 值

syscall getpeername,r12,ip_buff,15

这里是不使用括号的strace

[pid   749] accept(3, NULL, NULL <unfinished ...>
[pid   761] read(4, "", 1024)           = 0
[pid   761] write(1, "", 0)             = 0
[pid   761] getpeername(4, 0x600733, 0xf) = -1 EFAULT (Bad address)

这是我使用括号时的 strace。

[pid   749] accept(3, NULL, NULL <unfinished ...>
[pid   745] read(4, "GET / HTTP/1.1\r\nHost: 127.0.0.1:"..., 1024) = 78
[pid   745] write(1, "GET / HTTP/1.1\r\nHost: 127.0.0.1:"..., 78) = 78
[pid   745] getpeername(4, NULL, 0xf)   = -1 EFAULT (Bad address)

如何正确地进行这个系统调用?

实际问题不在于缓冲区,而在于它的长度。注意在原型中你有 socklen_t *addrlen 所以它应该是一个指针。您传递的值 15 不是指针,因此 -EFAULT.

您应该将 .length: equ $-ip_buff 更改为 ip_length: dd $-ip_buff,然后使用 syscall getpeername,r12,ip_buff,ip_length