DEBUG equ 0
.386
.model flat, stdcall ;32 bit memory model
option casemap :none ;case sensitive
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
include wsock32.inc
includelib wsock32.lib
include Comctl32.inc
include shell32.inc
includelib Comctl32.lib
includelib shell32.lib
include odbc32.inc
includelib odbc32.lib
include ws2_32.inc
includelib ws2_32.lib
include MACROS.ASM
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; equ 数据
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN equ 1000
DLG_MAIN equ 2000
IDC_COUNT equ 2001
TCP_PORT equ 9999
F_STOP equ 0001h
DATA_BUFSIZE equ 8192
WSABUF STRUCT
len DWORD ?
buf DWORD ?
WSABUF ENDS
;数据重叠结构
SOCKETCONTEXT STRUCT
Overlapped OVERLAPPED <> ;覆盖参数
DataBuf WSABUF <> ;接收缓冲区{缓冲区大小,缓冲区指针}〖指针指向下面的缓冲区〗
Buffer db DATA_BUFSIZE dup(?) ;发送缓冲区
SendSize dd ? ;需要发送字节数
BytesRecv dd ? ;接收到的字节数
BytesSend dd ? ;已经发送字节数
dwIoFlag dd ? ;IO标志【读/写/转发】
hAccept dd ? ;客户端Socket连接句柄
dwRegisted dd ? ;是否已经注册
lpBytesRecv dd ? ;接收数据指针
lpFlags dd ? ;
SOCKETCONTEXT ENDS
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hInstance dd ?
hWinMain dd ?
dwFlag dd ?
F_STOP equ 0001h
stCS CRITICAL_SECTION <?>
.const
szErrBind db '无法绑定到TCP端口9999,请检查是否有其它程序在使用!',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
if DEBUG
include \masm32\debug\Debug.asm
endif
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 服务线程
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
assume esi:ptr SOCKETCONTEXT
_ServerWorkerThread proc uses ebx esi edi _lParam:DWORD
LOCAL @BytesTransferred :DWORD
LOCAL @dwFlags :DWORD
LOCAL @lpContext :DWORD
LOCAL @Overlapped :OVERLAPPED
LOCAL @hToken :DWORD
LOCAL @lpDecodeData :DWORD
invoke GlobalAlloc,GPTR,DATA_BUFSIZE
mov @lpDecodeData,eax
.while TRUE
invoke GetQueuedCompletionStatus,_lParam,addr @BytesTransferred,\
addr @lpContext,addr @Overlapped,INFINITE
.break .if !eax
mov esi,@lpContext
.if @BytesTransferred==0 ;用户退出
invoke closesocket,[esi].hAccept
.break .if eax==SOCKET_ERROR
invoke GlobalFree,@lpContext
.continue
.endif
mov eax,[esi].BytesRecv
.if !eax
push @BytesTransferred
pop [esi].BytesRecv
mov [esi].BytesSend,0
.else
mov eax,[esi].BytesSend
add eax,@BytesTransferred
mov [esi].BytesSend,eax
.endif
mov eax,[esi].BytesSend
mov ebx,[esi].BytesRecv
.if ebx>eax ;需要接收
invoke RtlZeroMemory,addr [esi].Overlapped,sizeof OVERLAPPED
mov eax,[esi].BytesSend
add eax,sizeof SOCKETCONTEXT.Buffer
mov [esi].DataBuf.buf,eax
mov eax,[esi].BytesRecv
sub eax,[esi].BytesSend
mov [esi].DataBuf.buf,eax
invoke WSASend,[esi].hAccept,\
addr [esi].DataBuf,\
1,addr [esi].BytesSend,0,\
addr [esi].Overlapped,0
.if eax==SOCKET_ERROR
invoke WSAGetLastError
.break .if eax!=ERROR_IO_PENDING
.endif
.else ;需要发送
mov [esi].BytesRecv,0
mov [esi].dwIoFlag,0
invoke RtlZeroMemory,addr [esi].Overlapped,sizeof OVERLAPPED
mov [esi].DataBuf.len,DATA_BUFSIZE
lea eax,[esi].Buffer
mov [esi].DataBuf.buf,eax
invoke WSARecv,[esi].hAccept,\
addr [esi].Buffer,\
1, addr [esi].BytesRecv, \
addr [esi].dwIoFlag,\
addr [esi].Overlapped,NULL
.if eax==SOCKET_ERROR
invoke WSAGetLastError
.break .if eax!=ERROR_IO_PENDING
.endif
.endif
.endw
ret
_ServerWorkerThread endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 监听线程
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ListenThread proc uses ebx edi esi _lParam
LOCAL @hCompletionPort,@hListen,@hAccept,@hPerHandleData
LOCAL @stSin:sockaddr_in,@dwThreadID
invoke CreateIoCompletionPort,INVALID_HANDLE_VALUE,NULL,0,0
mov @hCompletionPort,eax
invoke CreateThread,NULL,NULL,offset _ServerWorkerThread,\
@hCompletionPort,0,addr @dwThreadID
invoke CloseHandle,eax ;关闭句柄,能避免线程异常退出资源泄露
invoke WSASocket,AF_INET,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED
mov @hListen,eax
invoke RtlZeroMemory,addr @stSin,sizeof @stSin
invoke htons,TCP_PORT
mov @stSin.sin_port,ax
mov @stSin.sin_family,AF_INET
mov @stSin.sin_addr,INADDR_ANY
invoke bind,@hListen,addr @stSin,sizeof @stSin
.if eax==SOCKET_ERROR
invoke MessageBox,hWinMain,addr szErrBind,\
NULL,MB_OK or MB_ICONSTOP
invoke ExitProcess,NULL
ret
.endif
invoke listen,@hListen,5
.while TRUE
invoke WSAAccept,@hListen,NULL,NULL,NULL,0
mov @hAccept,eax
invoke GlobalAlloc,GPTR,sizeof SOCKETCONTEXT
.break .if !eax
mov @hPerHandleData,eax
mov esi,@hPerHandleData
push @hAccept
pop [esi].hAccept
invoke CreateIoCompletionPort,@hAccept,@hCompletionPort,@hPerHandleData,0 ;将客户端关联到完成端口
.break .if !eax
mov esi,@hPerHandleData
mov [esi].BytesSend,0
mov [esi].BytesRecv,0
mov [esi].DataBuf.len,DATA_BUFSIZE
lea edx,[esi].Buffer
mov [esi].DataBuf.buf,edx
mov [esi].dwIoFlag,0
invoke WSARecv,@hAccept,addr [esi].Buffer,\
1,addr [esi].BytesRecv,\
addr [esi].dwIoFlag,\
addr [esi].Overlapped,NULL
.if eax==SOCKET_ERROR
invoke WSAGetLastError
.break .if eax!=ERROR_IO_PENDING
.endif
.endw
ret
_ListenThread endp
assume esi:nothing
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 主窗口程序
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcDlgMain proc uses ebx edi esi hWnd,wMsg,wParam,lParam
local @stWsa:WSADATA,@dwThreadID
mov eax,wMsg
;********************************************************************
.if eax == WM_INITDIALOG
push hWnd
pop hWinMain
invoke LoadIcon,hInstance,ICO_MAIN
invoke SendMessage,hWnd,WM_SETICON,ICON_BIG,eax
invoke InitializeCriticalSection,addr stCS
invoke WSAStartup,0202h,addr @stWsa ;eax为0表示成功
invoke CreateThread,NULL,0,offset _ListenThread,0,NULL,addr @dwThreadID
invoke CloseHandle,eax
;********************************************************************
.elseif eax == WM_CLOSE
invoke WSACleanup
invoke DeleteCriticalSection,addr stCS
invoke EndDialog,hWinMain,NULL
;********************************************************************
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
_ProcDlgMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 程序开始
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,0
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start
[注意]看雪招聘,专注安全领域的专业人才平台!