Author Topic: Basic Win32 API Socket Server  (Read 4958 times)

Offline encryptor256

  • Full Member
  • **
  • Posts: 250
  • Country: lv
  • Win64 .
    • On Youtube: encryptor256
Basic Win32 API Socket Server
« on: July 24, 2013, 12:24:26 PM »
Hello!

This is Win32 Socket Server.

Easy to read, easy to understand.

What will you find here:
  • Create Win32 API Socket Server
  • Compile with NASM and link with ALINK, build win32 exe file
  • How to use Command Prompt Telnet command, to receive text from server

Server will start on 127.0.0.1:36665 and wait for a single client,
when client connects, server sends data to client,and shutdowns.

+ If some WSA Socket error occur, there should be a message box for it.

Code is managed into seperate parts, files:
  • server.asm
  • WSAStartup.asm
  • socket.asm
  • bind.asm
  • listen.asm
  • accept.asm
  • send.asm
  • closeAcceptedConnection.asm
  • closesocket.asm
  • WSACleanup.asm

Main compile file is "server.asm",
all others are just include files.



Create Win32 API Socket Server

Create file "server.asm" and put this following code in it:

Code: [Select]
[BITS 32]

; Import function macro
%MACRO dllimport 2
IMPORT %2 %1
EXTERN %2
%ENDMACRO

; Import some function
dllimport kernel32.dll, ExitProcess
dllimport kernel32.dll, Sleep
dllimport user32.dll, MessageBoxA
dllimport Ws2_32.dll, socket
dllimport Ws2_32.dll, WSAStartup
dllimport Ws2_32.dll, WSACleanup
dllimport Ws2_32.dll, WSAGetLastError
dllimport Ws2_32.dll, inet_addr
dllimport Ws2_32.dll, htons
dllimport Ws2_32.dll, bind
dllimport Ws2_32.dll, listen
dllimport Ws2_32.dll, closesocket
dllimport Ws2_32.dll, accept
dllimport Ws2_32.dll, send
dllimport user32.dll, wsprintfA

; Socket constants
AF_INET equ 2
SOCK_STREAM equ 1
IPPROTO_TCP equ 6

; MessageBox constants
MB_OK equ 0x00000000
MB_ICONEXCLAMATION equ 0x00000030

; Macro to display WSA error code and custom error message
%macro display_wsa_error 1
call [WSAGetLastError]
push dword eax
push dword wsaErrorFormat
push dword wsaErrorBuffer
call [wsprintfA]
pop eax
pop eax
pop eax

push dword MB_OK + MB_ICONEXCLAMATION
push dword wsaErrorBuffer
push dword %1
push dword 0
call [MessageBoxA]
%endmacro

[SEGMENT .BSS USE32]

wsaData resb 400
socketHandle resb 4
sockAddr resb 16
wsaErrorBuffer resb 256
acceptHandle resb 4

[SEGMENT .DATA USE32]

text_error_WSAStartup db "WSAStartup error",0
text_error_socket db "socket error",0
text_error_WSACleanup db "WSACleanup error",0
text_error_bind db "bind error",0
text_error_listen db "listen error",0
text_error_closesocket db "closesocket error",0
text_error_accept db "accept error",0
text_error_send db "send error",0
text_error_closeacc db "close accepted connection error",0

startupSuccessState db 0
socketCreationState db 0

wsaErrorFormat db "wsaErrorCode: %d",0

ipAddress db "127.0.0.1",0

text_send db "Hello, it's me, your Encryptor256 !!!",0
text_send_len equ 38

[SEGMENT .TEXT USE32]

..start:

%include "WSAStartup.asm"

%include "socket.asm"

%include "bind.asm"

%include "listen.asm"

%include "accept.asm"

%include "send.asm"

%include "closeAcceptedConnection.asm"

quitProgram:

%include "closesocket.asm"

%include "WSACleanup.asm"

push dword 0
call [ExitProcess]


Create file "WSAStartup.asm" and put this following code in it:

Code: [Select]


; # WSAStartup - initiates use of the Windows Sockets DLL by a process
push dword wsaData
push dword 0x202
call [WSAStartup]
cmp eax,0
je WSAStartupSuccess

; ERROR --------------------------------
display_wsa_error text_error_WSAStartup
jmp quitProgram

WSAStartupSuccess:
mov byte [startupSuccessState],byte 1

Create file "socket.asm" and put this following code in it:

Code: [Select]

; # socket - creates a socket which is bound to a specific service provider
push dword IPPROTO_TCP
push dword SOCK_STREAM
push dword AF_INET
call [socket]
mov [socketHandle],eax
cmp eax,dword 0
jne socketSuccess

; ERROR --------------------------
display_wsa_error text_error_socket
jmp quitProgram

socketSuccess:
mov byte [socketCreationState], byte 1

Create file "bind.asm" and put this following code in it:

Code: [Select]


; # bind - associates a local address with a socket

; Family
mov [sockAddr],dword AF_INET

; Port
push dword 36665
call [htons]
mov [sockAddr+2],eax

; Address
push dword ipAddress
call [inet_addr]
mov [sockAddr+4],eax

; Bind
push dword 16
push dword sockAddr
push dword [socketHandle]
call [bind]
cmp eax,0
je .bindSuccess

; ERROR --------------------------
display_wsa_error text_error_bind
jmp quitProgram

.bindSuccess:

Create file "listen.asm" and put this following code in it:

Code: [Select]

; # listen - establishes a socket to listen for an incoming connection
push dword 1
push dword [socketHandle]
call [listen]
cmp eax,0
je .listenSuccess

; ERROR --------------------------
display_wsa_error text_error_listen
jmp quitProgram

.listenSuccess:

Create file "accept.asm" and put this following code in it:

Code: [Select]

; # accept - accepts a connection on a socket
push dword 0
push dword 0
push dword [socketHandle]
call [accept]
mov [acceptHandle],eax
cmp eax,0
jne .acceptSuccess

; ERROR --------------------------
display_wsa_error text_error_accept
jmp quitProgram

.acceptSuccess:

Create file "send.asm" and put this following code in it:

Code: [Select]

; # send - sends data on a connected socket

; Wait a bit, just for fun, before sending our data
push dword 512
call [Sleep]

; Send data to client
push dword 0
push dword text_send_len
push dword text_send
push dword [acceptHandle]
call [send]
cmp eax,text_send_len
je .sendSuccess

; ERROR --------------------------
display_wsa_error text_error_send
jmp quitProgram

.sendSuccess:

Create file "closeAcceptedConnection.asm" and put this following code in it:

Code: [Select]

push dword [acceptHandle]
call [closesocket]
cmp eax,0
je .closeAcceptedConnection

; ERROR --------------------------
display_wsa_error text_error_closeacc
jmp quitProgram

.closeAcceptedConnection:

Create file "closesocket.asm" and put this following code in it:

Code: [Select]

; # closesocket - closes a socket
cmp byte [socketCreationState],byte 1
jne .noSocket

push dword [socketHandle]
call [closesocket]
cmp eax,0
je .closeSocketSuccess

; ERROR --------------------------
display_wsa_error text_error_closesocket

.noSocket:
.closeSocketSuccess:

Create file "WSACleanup.asm" and put this following code in it:

Code: [Select]

; # WSACleanup - terminates use of the Windows Sockets DLL
cmp byte [startupSuccessState],byte 1
jne .noStartup

call [WSACleanup]
cmp eax,0
je .cleanupSuccess

; ERROR --------------------------
display_wsa_error text_error_WSACleanup

.noStartup:
.cleanupSuccess:



Compile with NASM and link with ALINK, build win32 exe file

NASM cmd: "nasm -fobj server.asm"
ALINK cmd: "alink -c -oPE -subsys windows server.obj"



How to use Command Prompt Telnet command, to receive text from server

  • Run server.exe
  • Open command promt console, that is,  cmd
  • Type telnet 127.0.0.1 36665

If all goes well, you should receive message from server.

I tested, it works, also with hyperterminal.

Done, Bye! :)

Edit: Added attachment, available for download
« Last Edit: July 25, 2013, 03:07:22 PM by encryptor256 »
Encryptor256's Investigation \ Research Department.