А®ТеS
12.08.2007, 06:49
Сегодня ночью мне не спалось (хотя уже трое суток не дрых!) и решил немного помучать компутер, а именно написать SOCKS4 проксик на MASM'e.
Почему именно прокси? Просто давно хотел попробовать реализовать этот протокол. Почему на MASM'e? Просто я мазохист :), к тому же если
сервер будет сильно загруженным, то "ручная" сборка будет лучше. Короче, хочу поделиться трудами, появившимися на свет благодаря часу непрерывной
работы и народному мату :), как профессиональную разработку его котировать разумеется нельзя, но учиться (на чужих ошибках ;-)) вполне.
Результирующий размер PE'шки получился 3,5 килобайта, строчек в сорце около 200. Вобщем заценяем код, ногами сильно не пинаем, а я пойду спать (уже четвертые сутки на исходе :)):
;Small SOCKS4 Proxy Server. Do not use for criminal, this is only example release SOCKS4 on x86 under win32... this is very old technology, i prefer .NET Framework :)
;(C)oded by A®TeS (king Artas ;-)), ICQ: 903521 (may be write to offline, generally my status is offline (NOT invisible - offline)), mail : Antichat's (http://forum.antichat.ru/) Private Message for user A®TeS :)
;Thnx: Gorl (for C++ source :)), Shturmovik, 1dt.w0lf, All ANTICHAT, All WASM.ru, All Cr@ckLab, All RST (project closed :( ), specialy: =HALK=, Dronga, Pete®, XSP, AM, Draco and other good people :).
;Best viewed with NOTEPAD! (about MASM32 code)
.386
.model flat, stdcall
option CaseMap : none
INCLUDE \masm32\include\kernel32.inc
INCLUDE \masm32\include\wsock32.inc
INCLUDE \masm32\include\windows.inc
INCLUDELIB \masm32\lib\kernel32.lib
INCLUDELIB \masm32\lib\wsock32.lib
SocksHandlerThreadProc proto : DWORD
FlushRecvBufferUntil proto : DWORD
SOCK4_REQUEST struct
ucVersion db ?
ucCommand db ?
wDestPort dw ?
dwDestIp dd ?
SOCK4_REQUEST ends
.data?
wsadata WSADATA <?>
l_sock SOCKET ?
sock4 sockaddr_in <?>
Client sockaddr <?>
size1 DWORD ?
h HANDLE ?
hMemory HANDLE ?
pMemory DWORD ?
hMemoryff HANDLE ?
pMemoryff DWORD ?
.code
start:
invoke WSAStartup, 2h, addr wsadata
invoke socket, AF_INET, SOCK_STREAM, IPPROTO_TCP
mov l_sock, EAX
mov sock4.sin_family, AF_INET
invoke htons, 1080d
mov sock4.sin_port, AX
mov sock4.sin_addr.S_un.S_addr, INADDR_ANY
mov size1, sizeof Client
invoke bind, dword ptr [l_sock], addr sock4, sizeof sock4
cmp EAX, 0h
jnz @end
invoke listen, dword ptr [l_sock], 0FFh
cmp EAX, 0h
jnz @end
@entry_to_while:
invoke accept, dword ptr [l_sock], addr Client, addr size1
invoke CreateThread, NULL, 0h, addr SocksHandlerThreadProc, EAX, 0, h
jmp @entry_to_while
@end:
invoke ExitProcess, 0h
SocksHandlerThreadProc proc pParam : DWORD
LOCAL s : SOCKET
LOCAL tunnelSock : SOCKET
LOCAL socks4Request : SOCK4_REQUEST
LOCAL socks4Response : SOCK4_REQUEST
LOCAL remoteAddr : sockaddr_in
LOCAL fds_read : fd_set
LOCAL tv : timeval
LOCAL bSocksVersion : BYTE
LOCAL dwVal : DWORD
mov EAX, pParam
mov s, EAX
mov tunnelSock, 0h
mov fds_read.fd_count, 0h
mov EAX, dword ptr [s]
mov fds_read.fd_array, EAX
inc fds_read.fd_count
mov tv.tv_sec, 30d
mov bSocksVersion, 0h
invoke select, 0h, addr fds_read, NULL, NULL, addr tv
cmp EAX, SOCKET_ERROR
jz @ret
not EAX
cmp EAX, 0h
jg @ret
mov dwVal, 0h
invoke ioctlsocket, dword ptr [s], FIONBIO, addr dwVal
invoke recv, dword ptr [s], addr bSocksVersion, 1, MSG_PEEK
cmp EAX, SOCKET_ERROR
jz @ret
cmp byte ptr [bSocksVersion], 4h
jnz @ret
invoke recv, dword ptr [s], addr socks4Request, sizeof socks4Request, 0h
cmp EAX, SOCKET_ERROR
jz @ret
mov dwVal, 1h
invoke ioctlsocket, dword ptr [s], FIONBIO, addr dwVal
invoke FlushRecvBufferUntil, dword ptr [s]
cmp byte ptr [socks4Request.ucCommand], 1h
jnz @ret
invoke ioctlsocket, dword ptr [s], FIONBIO, addr dwVal
mov remoteAddr.sin_family, AF_INET
mov EAX, socks4Request.dwDestIp
mov remoteAddr.sin_addr, EAX
mov AX, socks4Request.wDestPort
mov remoteAddr.sin_port, AX
invoke socket, AF_INET, SOCK_STREAM, 0h
mov tunnelSock, EAX
invoke connect, dword ptr [tunnelSock], addr remoteAddr, sizeof remoteAddr
cmp EAX, SOCKET_ERROR
jz @ret
mov socks4Response.ucCommand, 90d
mov socks4Response.ucVersion, 0h
invoke send, dword ptr [s], addr socks4Response, sizeof socks4Response, 0h
cmp EAX, SOCKET_ERROR
jz @ret
mov dwVal, 0h
invoke ioctlsocket, dword ptr [s], FIONBIO, addr dwVal
invoke ioctlsocket, dword ptr [tunnelSock], FIONBIO, addr dwVal
invoke GlobalAlloc, GMEM_MOVEABLE or GMEM_ZEROINIT, 65535d
mov hMemory, EAX
invoke GlobalLock, hMemory
mov pMemory, EAX
mov tv.tv_sec, 2h
@while_label:
mov fds_read.fd_count, 0h
mov EAX, dword ptr [s]
mov fds_read.fd_array, EAX
inc fds_read.fd_count
mov EAX, dword ptr [tunnelSock]
mov dword ptr [fds_read.fd_array + 4h], EAX
inc fds_read.fd_count
invoke select, 0, addr fds_read, NULL, NULL, addr tv
cmp EAX, 0h
jng @ret
invoke __WSAFDIsSet, dword ptr [s], addr fds_read
cmp EAX, TRUE
jnz @next
invoke recv, dword ptr [s], pMemory, sizeof pMemory, MSG_PEEK
cmp EAX, 0h
jz @ret
invoke recv, dword ptr [s], pMemory, sizeof pMemory, 0h
cmp EAX, SOCKET_ERROR
jz @ret
jng @ret
invoke send, dword ptr [tunnelSock], pMemory, sizeof pMemory, 0
@next:
invoke __WSAFDIsSet, dword ptr [tunnelSock], addr fds_read
cmp EAX, TRUE
jnz @jmp
invoke recv, dword ptr [tunnelSock], pMemory, sizeof pMemory, MSG_PEEK
cmp EAX, 0h
jz @ret
invoke recv, dword ptr [tunnelSock], pMemory, sizeof pMemory, 0h
cmp EAX, SOCKET_ERROR
jz @ret
jng @ret
invoke send, dword ptr [s], pMemory, sizeof pMemory, 0
@jmp:
jmp @while_label
@ret:
invoke GlobalUnlock, pMemory
invoke GlobalFree, hMemory
;invoke shutdown, dword ptr [s], 2h
invoke closesocket, dword ptr [s]
;invoke shutdown, dword ptr [tunnelSock], 2h
invoke closesocket, dword ptr [tunnelSock]
ret
SocksHandlerThreadProc endp
FlushRecvBufferUntil proc s : SOCKET
invoke GlobalAlloc, GMEM_MOVEABLE or GMEM_ZEROINIT, 1d
mov hMemoryff, EAX
invoke GlobalLock, hMemoryff
mov pMemoryff, EAX
@start_FlushRecvBufferUntil:
invoke recv, s, pMemoryff, 1, 0h
cmp pMemoryff, 0h
jz @ret
cmp EAX, SOCKET_ERROR
jz @ret
cmp EAX, 0h
jz @ret
jmp @start_FlushRecvBufferUntil
@ret:
invoke GlobalUnlock, pMemoryff
invoke GlobalFree, hMemoryff
ret
FlushRecvBufferUntil endp
end start
Почему именно прокси? Просто давно хотел попробовать реализовать этот протокол. Почему на MASM'e? Просто я мазохист :), к тому же если
сервер будет сильно загруженным, то "ручная" сборка будет лучше. Короче, хочу поделиться трудами, появившимися на свет благодаря часу непрерывной
работы и народному мату :), как профессиональную разработку его котировать разумеется нельзя, но учиться (на чужих ошибках ;-)) вполне.
Результирующий размер PE'шки получился 3,5 килобайта, строчек в сорце около 200. Вобщем заценяем код, ногами сильно не пинаем, а я пойду спать (уже четвертые сутки на исходе :)):
;Small SOCKS4 Proxy Server. Do not use for criminal, this is only example release SOCKS4 on x86 under win32... this is very old technology, i prefer .NET Framework :)
;(C)oded by A®TeS (king Artas ;-)), ICQ: 903521 (may be write to offline, generally my status is offline (NOT invisible - offline)), mail : Antichat's (http://forum.antichat.ru/) Private Message for user A®TeS :)
;Thnx: Gorl (for C++ source :)), Shturmovik, 1dt.w0lf, All ANTICHAT, All WASM.ru, All Cr@ckLab, All RST (project closed :( ), specialy: =HALK=, Dronga, Pete®, XSP, AM, Draco and other good people :).
;Best viewed with NOTEPAD! (about MASM32 code)
.386
.model flat, stdcall
option CaseMap : none
INCLUDE \masm32\include\kernel32.inc
INCLUDE \masm32\include\wsock32.inc
INCLUDE \masm32\include\windows.inc
INCLUDELIB \masm32\lib\kernel32.lib
INCLUDELIB \masm32\lib\wsock32.lib
SocksHandlerThreadProc proto : DWORD
FlushRecvBufferUntil proto : DWORD
SOCK4_REQUEST struct
ucVersion db ?
ucCommand db ?
wDestPort dw ?
dwDestIp dd ?
SOCK4_REQUEST ends
.data?
wsadata WSADATA <?>
l_sock SOCKET ?
sock4 sockaddr_in <?>
Client sockaddr <?>
size1 DWORD ?
h HANDLE ?
hMemory HANDLE ?
pMemory DWORD ?
hMemoryff HANDLE ?
pMemoryff DWORD ?
.code
start:
invoke WSAStartup, 2h, addr wsadata
invoke socket, AF_INET, SOCK_STREAM, IPPROTO_TCP
mov l_sock, EAX
mov sock4.sin_family, AF_INET
invoke htons, 1080d
mov sock4.sin_port, AX
mov sock4.sin_addr.S_un.S_addr, INADDR_ANY
mov size1, sizeof Client
invoke bind, dword ptr [l_sock], addr sock4, sizeof sock4
cmp EAX, 0h
jnz @end
invoke listen, dword ptr [l_sock], 0FFh
cmp EAX, 0h
jnz @end
@entry_to_while:
invoke accept, dword ptr [l_sock], addr Client, addr size1
invoke CreateThread, NULL, 0h, addr SocksHandlerThreadProc, EAX, 0, h
jmp @entry_to_while
@end:
invoke ExitProcess, 0h
SocksHandlerThreadProc proc pParam : DWORD
LOCAL s : SOCKET
LOCAL tunnelSock : SOCKET
LOCAL socks4Request : SOCK4_REQUEST
LOCAL socks4Response : SOCK4_REQUEST
LOCAL remoteAddr : sockaddr_in
LOCAL fds_read : fd_set
LOCAL tv : timeval
LOCAL bSocksVersion : BYTE
LOCAL dwVal : DWORD
mov EAX, pParam
mov s, EAX
mov tunnelSock, 0h
mov fds_read.fd_count, 0h
mov EAX, dword ptr [s]
mov fds_read.fd_array, EAX
inc fds_read.fd_count
mov tv.tv_sec, 30d
mov bSocksVersion, 0h
invoke select, 0h, addr fds_read, NULL, NULL, addr tv
cmp EAX, SOCKET_ERROR
jz @ret
not EAX
cmp EAX, 0h
jg @ret
mov dwVal, 0h
invoke ioctlsocket, dword ptr [s], FIONBIO, addr dwVal
invoke recv, dword ptr [s], addr bSocksVersion, 1, MSG_PEEK
cmp EAX, SOCKET_ERROR
jz @ret
cmp byte ptr [bSocksVersion], 4h
jnz @ret
invoke recv, dword ptr [s], addr socks4Request, sizeof socks4Request, 0h
cmp EAX, SOCKET_ERROR
jz @ret
mov dwVal, 1h
invoke ioctlsocket, dword ptr [s], FIONBIO, addr dwVal
invoke FlushRecvBufferUntil, dword ptr [s]
cmp byte ptr [socks4Request.ucCommand], 1h
jnz @ret
invoke ioctlsocket, dword ptr [s], FIONBIO, addr dwVal
mov remoteAddr.sin_family, AF_INET
mov EAX, socks4Request.dwDestIp
mov remoteAddr.sin_addr, EAX
mov AX, socks4Request.wDestPort
mov remoteAddr.sin_port, AX
invoke socket, AF_INET, SOCK_STREAM, 0h
mov tunnelSock, EAX
invoke connect, dword ptr [tunnelSock], addr remoteAddr, sizeof remoteAddr
cmp EAX, SOCKET_ERROR
jz @ret
mov socks4Response.ucCommand, 90d
mov socks4Response.ucVersion, 0h
invoke send, dword ptr [s], addr socks4Response, sizeof socks4Response, 0h
cmp EAX, SOCKET_ERROR
jz @ret
mov dwVal, 0h
invoke ioctlsocket, dword ptr [s], FIONBIO, addr dwVal
invoke ioctlsocket, dword ptr [tunnelSock], FIONBIO, addr dwVal
invoke GlobalAlloc, GMEM_MOVEABLE or GMEM_ZEROINIT, 65535d
mov hMemory, EAX
invoke GlobalLock, hMemory
mov pMemory, EAX
mov tv.tv_sec, 2h
@while_label:
mov fds_read.fd_count, 0h
mov EAX, dword ptr [s]
mov fds_read.fd_array, EAX
inc fds_read.fd_count
mov EAX, dword ptr [tunnelSock]
mov dword ptr [fds_read.fd_array + 4h], EAX
inc fds_read.fd_count
invoke select, 0, addr fds_read, NULL, NULL, addr tv
cmp EAX, 0h
jng @ret
invoke __WSAFDIsSet, dword ptr [s], addr fds_read
cmp EAX, TRUE
jnz @next
invoke recv, dword ptr [s], pMemory, sizeof pMemory, MSG_PEEK
cmp EAX, 0h
jz @ret
invoke recv, dword ptr [s], pMemory, sizeof pMemory, 0h
cmp EAX, SOCKET_ERROR
jz @ret
jng @ret
invoke send, dword ptr [tunnelSock], pMemory, sizeof pMemory, 0
@next:
invoke __WSAFDIsSet, dword ptr [tunnelSock], addr fds_read
cmp EAX, TRUE
jnz @jmp
invoke recv, dword ptr [tunnelSock], pMemory, sizeof pMemory, MSG_PEEK
cmp EAX, 0h
jz @ret
invoke recv, dword ptr [tunnelSock], pMemory, sizeof pMemory, 0h
cmp EAX, SOCKET_ERROR
jz @ret
jng @ret
invoke send, dword ptr [s], pMemory, sizeof pMemory, 0
@jmp:
jmp @while_label
@ret:
invoke GlobalUnlock, pMemory
invoke GlobalFree, hMemory
;invoke shutdown, dword ptr [s], 2h
invoke closesocket, dword ptr [s]
;invoke shutdown, dword ptr [tunnelSock], 2h
invoke closesocket, dword ptr [tunnelSock]
ret
SocksHandlerThreadProc endp
FlushRecvBufferUntil proc s : SOCKET
invoke GlobalAlloc, GMEM_MOVEABLE or GMEM_ZEROINIT, 1d
mov hMemoryff, EAX
invoke GlobalLock, hMemoryff
mov pMemoryff, EAX
@start_FlushRecvBufferUntil:
invoke recv, s, pMemoryff, 1, 0h
cmp pMemoryff, 0h
jz @ret
cmp EAX, SOCKET_ERROR
jz @ret
cmp EAX, 0h
jz @ret
jmp @start_FlushRecvBufferUntil
@ret:
invoke GlobalUnlock, pMemoryff
invoke GlobalFree, hMemoryff
ret
FlushRecvBufferUntil endp
end start