所以我做了一大堆东西
首先是大会:
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程序不起作用:/
答案 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