First of all, Im sorry for my bad english, english isn't my first language. So, I'm trying to write chat program in Assembly 32 BIT, MASM.
Right Now, I'm writing the server side code, So far I used the WSAStartUp and Socket - Windows API functions, and Now im trying to use the Bind function.
The link for the bind function: https://msdn.microsoft.com/en-us/library/windows/desktop/ms737550(v=vs.85).aspx
This is the code that I have written so far(My problem is written after the code):
.386
.MODEL Flat, STDCALL
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\Ws2_32.inc
includelib \masm32\lib\Ws2_32.lib
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
.DATA
Success db 'WSAStartUp Succseed!',0
NO_Success db 'WSAStartUp NOT Succseed....',0
Socketsu db 'Socket :(:(:(:(',0
SocketSuccess db 'Socket Success!! :)',0
Bindno db 'Bind Error',0
Bindyes db 'Bind Success! :)',0
LocalIP db "127.0.0.1",0
port dd 8020
.DATA?
wsadata db 400 dup (?) ;WSADATA struct that hold the information about the Windows Sockets implementation.(info ret from WSATSTARTUP)
flag dw ?
ListenSocket dd ?
SockAddrStruct db 30 dup (?)
;so sockaddr_in <?>
sockaddrs db 16 dup (?)
.CONST
wVersionRequested equ 0101h
.CODE
main:
;-------------------WSAStartUp-----------------------;
;Initialize the work with winsock (WS StartUp = WINSOCK START UP)
invoke WSAStartup,wVersionRequested, offset wsadata
.if eax!=0
invoke MessageBoxA,NULL,offset NO_Success,offset NO_Success,MB_OK
jmp End_Program
.else
invoke MessageBoxA,NULL,offset Success,offset Success,MB_OK
.endif
;-------------------Socket-----------------------;
;AF_INET - address family(in format: host,port) to likboa the type of addresses that the socket can communicate with
invoke socket,AF_INET,SOCK_STREAM,IPPROTO_TCP
.IF eax==INVALID_SOCKET
invoke MessageBoxA,NULL,offset Socketsu,offset Socketsu,MB_OK
jmp End_Program
.else
invoke MessageBoxA,NULL,offset SocketSuccess,offset SocketSuccess,MB_OK
mov [ListenSocket],eax
.ENDIF
;-------------------Bind-------------------------;
;SockAddr Struct:
mov eax,AF_INET
mov [dword ptr sockaddrs],eax
invoke htons,[port]
mov [dword ptr sockaddrs+2],eax
invoke inet_addr,[dword ptr LocalIP]
mov [dword ptr sockaddrs+4],eax
invoke bind,SIZEOF sockaddrs,offset sockaddrs,ListenSocket
.if eax==0
invoke MessageBoxA,NULL,offset Bindyes,offset Bindyes,MB_OK
.else
invoke MessageBoxA,NULL,offset Bindno,offset Bindno,MB_OK
.endif
End_Program:
invoke ExitProcess,0
end main
I don't know what is the problem. But when I run the code I'm getting the MessageBox that I Built that says:Bind Error.
I guess that this is a problem in sockaddrs struct (the way that I put values in to it). But I don't know what do I need to change and how to fix it.
I thought maybe to use WSAGetLastError Function to see what is the Error but I don't know how to print the value that the function returns and see what is the error(I can't put in the invoke MessageBox, a parameter EAX(the register that hold the value that returns)) .
So can someone help me fix the problem In the 'Bind' part?
You have a couple questions. I'll start by giving you one method of retrieving a message representing the last WSAGetLastError
(it also works with GetLastError
). The Win32 API way is to use FormatMessage
to convert the error message code returned by WSAGetLastError
. Information from MSDN on FormatMessage can be found here, along with an example similar to the code we'll use. It is defined as:
DWORD WINAPI FormatMessage(
In DWORD dwFlags,
In_opt LPCVOID lpSource,
In DWORD dwMessageId,
In DWORD dwLanguageId,
Out LPTSTR lpBuffer,
In DWORD nSize,
In_opt va_list *Arguments
);
In your .DATA?
area, add a variable to store the buffer pointer that we'll return from FormatMessage
:
lpErrorMsg dd ?
To then retrieve and display the last WSA error you can use something like this after a socket related call (like bind
):
.if eax==SOCKET_ERROR
invoke WSAGetLastError
invoke FormatMessageA, FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, eax, LANG_NEUTRAL, offset lpErrorMsg, 0, NULL
invoke MessageBoxA,NULL,lpErrorMsg,offset Bindno,MB_OK
.endif
There are a number of problems in your code. The first one I observed was that port
need to be a 32 bit Integer so it should be defined as:
port dd 8020
Without this change htons
will not work properly as it is expecting a 32-bit Integer.
The next bug is here:
invoke MessageBoxA,NULL,offset SocketSuccess,offset SocketSuccess,MB_OK
mov [ListenSocket],eax
You are clobbering eax
by calling MessageBoxA
first. You probably meant to save it first:
mov [ListenSocket],eax
invoke MessageBoxA,NULL,offset SocketSuccess,offset SocketSuccess,MB_OK
There appear to be a number of issues in this code:
mov eax,AF_INET
mov [dword ptr sockaddrs],eax
This is incorrect as it works with 32-bit Integer and we need a WORD(16-bit). It should be:
mov ax,AF_INET
mov [word ptr sockaddrs],ax
This also required to use a 16-bit WORD to be stored at sockaddrs+2
:
invoke htons,[port]
mov [dword ptr sockaddrs+2],eax
So should have been:
invoke htons,[port]
mov [word ptr sockaddrs+2],ax
This is incorrect since we don't want to de-reference what is at LocalIP, we just want LocalIP's address:
invoke inet_addr,[dword ptr LocalIP]
mov [dword ptr sockaddrs+4],eax
So this seems to be more correct:
invoke inet_addr, offset LocalIP
mov [dword ptr sockaddrs+4],eax
You then mixed up the parameters to bind
. You had:
invoke bind,SIZEOF sockaddrs,offset sockaddrs,ListenSocket
It should have been:
invoke bind,ListenSocket,offset sockaddrs,SIZEOF sockaddrs
MASM32 defines a sockaddr_in
with all the fields defined. To make working with this structure easier and to make the code more readable, you might want to consider altering SockAddrStruct
to be defined as (and zeroed out):
SockAddrStruct sockaddr_in <0>
With SockAddrStruct
defined this way you can now change your socket code to read something like this:
;-------------------Bind-------------------------;
;SockAddr Struct:
mov SockAddrStruct.sin_family,AF_INET
invoke htons, [port]
mov SockAddrStruct.sin_port,ax
invoke inet_addr, offset LocalIP
mov SockAddrStruct.sin_addr.S_un.S_addr, eax
invoke bind,ListenSocket,offset SockAddrStruct,SIZEOF SockAddrStruct