【发布时间】:2015-01-27 16:52:42
【问题描述】:
我开始用 asm (NASM) 编写网络程序,从技术上讲,accept 函数会阻塞程序(被动套接字)。好吧,在我的程序中,我执行程序并且程序完成。我已经测试过将 backlog 设置为 1(监听功能),但这不是问题......会发生什么?
BITS 32
section .text
global _start
_start:
; Create the socket file descriptor
; int socket(int domain, int type, int protocol);
mov eax, 102 ; __NR_socketcall
mov ebx, 1 ; socketcall type (socket)
; socket parameters
push 0 ; IPPROTO_TCP
push 1 ; SOCK_STREAM
push 2 ; AF_INET
int 0x80 ; socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
mov edx, eax ; edx = socketfd
; Bind the socket with an address type
; int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
mov eax, 102 ; __NR_socketcall
mov ebx, 2 ; socketcall type (bind)
; build the sockaddr_in struct
push 0 ; INADDR_ANY
push WORD 0x0457 ; port 1111
push WORD 2 ; AF_INET
mov ecx, esp ; struct ptr
; bind parameters
push 16 ; sockaddr struct size = sizeof(struct sockaddr) = 16
push ecx ; sockaddr_in struct ptr
push edx ; socket fd
int 0x80 ; bind(sockfd, {AF_INET, 11111, INADDR_ANY}, 16)
; Prepare to listen the incoming connection (passive socket)
; int listen(int sockfd, int backlog);
mov eax, 102 ; __NR_socketcall
mov ebx, 4 ; socketcall type (listen)
; listen parameters
push 0 ; nº connections in the waiting queue (0 = accept and we haven't queue)
push edx ; socket fd
int 0x80 ; listen(sockfd, 0);
; Accept the incoming connection
; int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
mov eax, 102 ; __NR_socketcall
mov ebx, 5 ; socketcall type (accept)
; accept parameters
push 0
push 0
push edx ; socket fd
int 0x80 ; accept(sockfd, NULL, NULL)
; Exit
; int exit(int status)
mov eax, 1 ; __NR_exit
mov ebx, 0 ; exit code
int 0x80
【问题讨论】:
-
当你调用
int 0x80时,Linux 不使用%ebx、%ecx和%edx寄存器作为第一、第二和第三个参数吗? -
什么?我使用的是 NASM(我把它作为标签),所以它是 ebx 而不是 %ebx 并且所有的 movs、push 等都被注释了。
-
是的,我使用的是不同的寄存器格式;并不重要。 socketcall 调用always 只接受两个参数——socketcall 类型和一个指向包含其余参数的用户地址的指针。手工编码是一种皇家痛苦。您在提交代码时绝对没有错误,这意味着不会检测到任何调用中的任何失败,从而导致 accept 调用失败。
-
那你建议我的程序做得很好,问题出在我的电脑上,我必须处理错误才能知道“一些东西”,不是吗?如果 eax(我没有找到有关处理 socketcall 的信息)为 -1,我是否必须检查所有 socketcall 类型(在执行 int 0x80 之后)?
-
我认为您需要更频繁地
mov ecx, esp(正如 Petesh 建议的那样)。ecx需要指向你的结构(在堆栈上)。