分段故障recvfrom assembly

时间:2017-03-09 19:47:50

标签: sockets assembly nasm

我收到以下汇编代码的分段错误,这些代码在socket

中获取消息
global _start

struc sockaddr_in
    .sin_family resw 1
    .sin_port resw 1
    .sin_addr resd 1
    .sin_zero resb 8
endstruc

struc img
    .source_ip  resb 4
    .int_ip resb 4
    .group_ip   resb 4
endstruc

section .bss

    listen_socket:  resq 1
    buffer: resb 2048

section .data

pop_sa istruc sockaddr_in
        at sockaddr_in.sin_family, dw 2           ; AF_INET
        at sockaddr_in.sin_port, dw 0x4b9c        ; port 40011
        at sockaddr_in.sin_addr, dd 0xb46c0ef             ; INADDR_ANY
        at sockaddr_in.sin_zero, dd 0, 0
iend
sockaddr_in_len     equ $ - pop_sa

pop_mc  istruc img  ;
    at img.source_ip,   dd 0xb46c0ef ;
    at img.int_ip,      dd 0             ; INADDR_ANY
    at img.group_ip,    dd 0x5a81320a ;
iend
img_len equ $ - pop_mc
from_ip:    dw 0    
from_ip_len:    db 16

section .text

_start:

    mov rdi, 2      ;AF_INET
    mov rsi, 2      ;SOCK_DGRAM
    mov rdx, 0      ;IPPROTO_UDP
    mov rax, 41
    syscall         ;sys_create_udp_socket
    mov[listen_socket], rax

    mov r8, 4        
    mov r10, 1   
    mov rdx, 2  ;SO_REUSEADDR
    mov rsi, 1  ;SOL_SOCKET
    mov rdi,[listen_socket]
    mov rax, 54
    syscall         ;sys_setsockopt

    mov rdx, sockaddr_in_len
    mov rsi, pop_sa
    mov rdi,[listen_socket]
    mov rax, 49
    syscall         ;sys_bind

    mov r8, img_len
    mov r10, pop_mc
    mov rdx, 39     ;IP_ADD_SOURCE_MEMBERSHIP
    mov rsi, 0  ;IPPROTO_UDP
    mov rdi,[listen_socket]
    mov rax, 54
    syscall         ;sys_setsockopt

    mov r9, [from_ip_len]   ;
    mov r8, [from_ip]
    mov r10, 0
    mov rdx, 2047
    mov rsi, buffer
    mov rdi,[listen_socket]
    mov rax, 45
    syscall         ;sys_recvfrom

    mov rdi, 0
    mov rax, 60
    syscall         ;sys_exit

所有系统调用在sys_recvfrom之前返回正确的值,在那里我得到错误 - 在sys_recvfrom函数中的EFAULT,有什么问题? 64位汇编nasm。

1 个答案:

答案 0 :(得分:0)

r8和r9(sockaddr和socklen)应该是类型指针。您将值从dw变量的地址移动到寄存器中,是否意味着将lea用于r8?即便如此,将指针传递给两个字节的变量,你说的是16字节大(socklen)

我的汇编程序,尤其是我的unix相关汇编程序是生锈的,但我的猜测是

  1. 你认为dw是16字节,而它是16位。
  2. 使用mov reg,[variable]将值加载到r8,r9而不是使用lea reg,[variable]
  3. 的地址