WSAENOTAVAIL在win64 nasm上的_bind ^^

时间:2015-01-14 18:12:33

标签: assembly nasm

所以我做了一大堆东西

首先是大会:

BITS 32
extern _WSAStartup
extern _bind
extern _ExitProcess
extern __cprintf
extern _WSAGetLastError
extern __getch
extern _htons
extern _socket
extern _inet_addr
;EXTERNAL CALLS START

;EXTERNAL CALLS END
global main ;ENTRY POINT
section .bss
;STRUCT DEC START
STRUC in_addr
s_addr: resd 1
ENDSTRUC 

STRUC sockaddr_in
sin_famlily: resd 1
sin_port: resd 1
sin_addr: resd 1 ;structure comes here
sin_zero: resb 8 
ENDSTRUC


STRUC WSADATA
wVersion:resw 1
wHighVersion:resw 1
szDescription:resb 1
szSystemStatus:resb 1
iMaxSockets:resd 1
iMaxUdpDg:resd 1
lpVendorInfo:resb 1
ENDSTRUC
;STRUCT DEC END
section .data
;STRUCT DEC START
stAddr_in:
ISTRUC in_addr
at s_addr,dd 0
IEND

stSockAddr_in:
ISTRUC sockaddr_in
at sin_famlily, dd 0
at sin_port, dd 0
at sin_addr, dd 0 ;structure comes here
at sin_zero, db 0 
IEND
stWSADATA:
ISTRUC WSADATA
at wVersion,dw 0
at wHighVersion,dw 0
at szDescription,db 0
at szSystemStatus,db 0
at iMaxSockets,dd 0
at iMaxUdpDg,dd 0
at lpVendorInfo,db 0
IEND
;STRUCT DEC END
;DWORD DEC START
SocketHandle dd 0
;DWORD DEC END
;BYTES DEC START
strIP db "127.0.0.1",0
errFormat db "ERROR CODE : %d",0ah,0
;BYTES DEC END
section .text
main:
;1.) Initialise the Windows Socket API
push stWSADATA
push 514 ;MAKEWORD(2,2)
call _WSAStartup
CMP eax,0
JNE lblErrExit

;2.) Initialise a Socket
push 6 ; TCP
push 1 ; SOCK_STREAM
push 2 ; AF_INET
call _socket
CMP eax,0xffff ;INVALID_SOCKET OR -1
JE lblErrExit
;ELSE
mov dword [SocketHandle] , eax ;Save The Socket Handle


;3.) Bind The Socket
;3.1) Setup the sockaddr_in structure
mov dword [stSockAddr_in+sin_famlily],2 ;AF_INET
push WORD 968
call _htons ;CONVERT FROM HOST BYTE ORDER TO NETWORK BYTE ORDER
mov dword [stSockAddr_in+sin_port], eax
mov dword [stSockAddr_in+sin_addr],stAddr_in ;Move the address of the stAddr_in structure into the stSockAddr_in memory address.
push strIP
call _inet_addr
mov dword [stAddr_in+s_addr],eax


;3.2) Call Bind
push 16 ;Tested in C
push stSockAddr_in
push dword [SocketHandle]
call _bind
cmp eax,0
JNE lblErrExit

call __getch

lblCleanExit:
push 0 ;ERROR_SUCCESS
call _ExitProcess
call __getch

lblErrExit:
call _WSAGetLastError
push eax
push errFormat
call __cprintf
add esp,8 ;Clean the stack
call __getch
push 1
call _ExitProcess

然后C:

#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#include <winsock2.h>
int main()
{
    WSADATA stLPWSADATA;
    WSAStartup(514,&stLPWSADATA); //WSA STARTED
    SOCKET mySock = socket(2,1,6);
    struct sockaddr_in stSockAddr;
    stSockAddr.sin_family = 2;//AF_INET
    stSockAddr.sin_port = htons(96); //HOST TO NETWORK ORDER
    stSockAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    printf("Size Of Structure : %d\n",sizeof(stSockAddr));
    if (bind(mySock,&stSockAddr,sizeof(stSockAddr)) != 0 )
        {
            printf("WSA ERROR : %d\n",WSAGetLastError());
        }
        else
        {
            puts("No Errors On Bind!");
        }
    printf("Last Error : %d\n",WSAGetLastError());
    getchar();
    return 0;
}

现在我觉得我已经掌握了一切,尽管我还有问题。装配程序不起作用,除非我删除指定端口的几行,在这种情况下它绑定到1147或类似的东西。

C程序不起作用:/

1 个答案:

答案 0 :(得分:0)

我不会修复C程序,因为我正在忙于其他事情XD 无论如何我的问题是我无法使用绑定函数来使用正确的端口。

我学到了一些东西。 答:您应该使用_htons将要使用的端口号转换为网络字节顺序(可以使用_ntohs转换回来) B.如何在nasm XD中使用结构内部的结构 C.这些东西在c#或delphi中看起来非常容易编码:/ D. Nasm没有对结构的内部支持,所以他们使用宏将结构扩展到一堆内存地址。

无论如何,这是我的更新代码,它成功绑定:

;4 Cups of coffee

; 514 ;the result of makeword(2,2) -> I Should do futher research on this but apparently it's only use is to generate the version num expected by WSAStartup
BITS 32
extern _WSAStartup
extern _bind
extern _ExitProcess
extern __cprintf
extern _WSAGetLastError
extern __getch
extern _htons
extern _ntohs
extern _socket
extern _inet_addr
;EXTERNAL CALLS START

;EXTERNAL CALLS END
global main ;ENTRY POINT
section .bss
;STRUCT DEC START
STRUC in_addr
s_addr: resd 1
ENDSTRUC 

STRUC sockaddr_in
sin_famlily: resd 1
sin_port: resd 1
sin_addr: resd 1 ;structure comes here
sin_zero: resb 8 
ENDSTRUC


STRUC WSADATA
wVersion:resw 1
wHighVersion:resw 1
szDescription:resb 1
szSystemStatus:resb 1
iMaxSockets:resd 1
iMaxUdpDg:resd 1
lpVendorInfo:resb 1
ENDSTRUC
;STRUCT DEC END
section .data
;STRUCT DEC START
stAddr_in:
ISTRUC in_addr
at s_addr,dd 0
IEND

stSockAddr_in:
ISTRUC sockaddr_in
at sin_famlily, dd 0
at sin_port, dd 0
at sin_addr, dd 0 ;structure comes here
at sin_zero, db 0 
IEND
stWSADATA:
ISTRUC WSADATA
at wVersion,dw 0
at wHighVersion,dw 0
at szDescription,db 0
at szSystemStatus,db 0
at iMaxSockets,dd 0
at iMaxUdpDg,dd 0
at lpVendorInfo,db 0
IEND
;STRUCT DEC END
;DWORD DEC START
SocketHandle dd 0
;DWORD DEC END
;BYTES DEC START
strIP db "127.0.0.1",0
strBindSuccess db "Bound To : %d",0ah,0
errFormat db "ERROR CODE : %d",0ah,0
;BYTES DEC END
section .text
main:
;1.) Initialise the Windows Socket API
push stWSADATA
push 514 ;MAKEWORD(2,2)
call _WSAStartup
CMP eax,0
JNE lblErrExit

;2.) Initialise a Socket
push 6 ; TCP
push 1 ; SOCK_STREAM
push 2 ; AF_INET
call _socket
CMP eax,0xffff ;INVALID_SOCKET OR -1
JE lblErrExit
;ELSE
mov dword [SocketHandle] , eax ;Save The Socket Handle


;3.) Bind The Socket
;3.1) Setup the sockaddr_in structure
mov dword [stSockAddr_in+sin_famlily],2 ;AF_INET
push dword 132
call _htons ;CONVERT FROM HOST BYTE ORDER TO NETWORK BYTE ORDER
mov dword [stSockAddr_in+2], eax  ;FOR  SOME REASON USING sin_port fails but using +2 ;reserved as the second byte works.
mov dword [stAddr_in+sin_addr],in_addr  ;I must be mistaking but sin_port should be two... i should check it out ^^
mov dword [stSockAddr_in+sin_addr],0x0 ;Move the address of the stAddr_in structure into the stSockAddr_in memory address.
push dword [stAddr_in+sin_port]


;3.2) Call Bind
push 16 ;Tested in C
push stSockAddr_in
push dword [SocketHandle]
call _bind
cmp eax,0
JNE lblErrExit


call __getch

lblCleanExit:
push 0 ;ERROR_SUCCESS
call _ExitProcess
call __getch

lblErrExit:
call _WSAGetLastError
push eax
push errFormat
call __cprintf
add esp,8 ;Clean the stack
call __getch
push 1
call _ExitProcess