; = =======================================
;Simple SMTP Send by FreeMan            |
; = =======================================
format PE GUI 4.0
entry start
		     
  include '%fasminc%\win32a.inc'
  include 'inc.inc'
  include 'sockets.inc'
		     
section '.code' code readable writable executable
		     
  start:     
		     
	  invoke     GetModuleHandle,0
	  invoke     DialogBoxParam,eax,IDD_DIALOG1,HWND_DESKTOP,DialogProc,0
	  or	     eax,eax
	  jz	     exit
		     
  exit:      
	  invoke     ExitProcess,0
		     
;--------------------------------------------------------------------------------;
; [DialogProc]
;--------------------------------------------------------------------------------;

  proc DialogProc hwnddlg,msg,wparam,lparam
	  push	     ebx esi edi
	  cmp	     [msg],WM_COMMAND
	  je	     wmcommand
	  cmp	     [msg],WM_CLOSE
	  je	     wmclose
	  xor	     eax,eax
	  jmp	     finish
  wmcommand: 
	  mov	     eax,[wparam]
	  shr	     eax,16
	  cmp	     eax,BN_CLICKED
	  jne	     processed
	  stdcall    GetInfoAndSend,[hwnddlg]
	  jmp	     processed
  wmclose:   
	  invoke     EndDialog,[hwnddlg],0
  processed: 
	  mov	     eax,1
  finish:    
	  pop	     edi esi ebx
	  ret	     
  endp	  
		     
;--------------------------------------------------------------------------------;
; [GetInfoAndSend]
;--------------------------------------------------------------------------------;

  proc GetInfoAndSend hwnd
    locals 
	  szmess	       db 200 dup (?)
	  szfrom	       db 200 dup (?)
	  szto		       db 200 dup (?)
	  szlog 	       db 200 dup (?)
	  szpass	       db 200 dup (?)
	  szserv	       db 200 dup (?)
	  szsubj	       db 200 dup (?)
    endl  
		     
	  mov	     ebx,7
	  lea	     esi,[szmess]
	  mov	     eax,IDC_EDIT1
    .getdataloop: 
	  push	     eax esi
		     
	  invoke     GetDlgItemText,dword [hwnd],eax,esi,200
		     
	  pop	     esi eax
	  inc	     eax
	  add	     esi,200
	  dec	     ebx
	  jnz	     .getdataloop
		     
	  lea	     eax,[szsubj]
	  push	     eax
	  lea	     eax,[szserv]
	  push	     eax
	  lea	     eax,[szpass]
	  push	     eax
	  lea	     eax,[szlog]
	  push	     eax
	  lea	     eax,[szto]
	  push	     eax
	  lea	     eax,[szfrom]
	  push	     eax
	  lea	     eax,[szmess]
	  push	     eax
	  call	     Send_Mail
		     
	  ret	     
  endp	  
		     
	  szEHLO	       db 'EHLO server',13,10,0
	  szAUTHLOGIN	       db 'AUTH LOGIN',13,10,0
	  szMAILFROM	       db 'MAIL FROM:<',0
	  szRCPTTO	       db 'RCPT TO:<',0
	  szSKOBKA	       db '>',13,10,0
	  szDATA	       db 'DATA',13,10,0
	  szSubject	       db 'Subject: ',0
	  szEnd 	       db 13,10,'.',13,10,0
	  szQuit	       db 'QUIT',13,10,0
	  saddr      sockaddr_in
	  wsad1      WSADATA
		     
;--------------------------------------------------------------------------------;
; [Send_Mail]
;--------------------------------------------------------------------------------;

  proc Send_Mail pszmess,pszfrom,pszto,pszlog,pszpass,pszserv,pszsubj
    locals 
		     
	  base64log	       db 200 dup (?)
	  base64pass	       db 200 dup (?)
		     
    endl  
	  lea	     ebx,[base64log]
	  invoke     lstrlen,[pszlog]
	  stdcall    Base64Encode,dword [pszlog],ebx,eax
	  add	     ebx,200
	  invoke     lstrlen,[pszpass]
	  stdcall    Base64Encode,dword [pszpass],ebx,eax
		     
	  invoke     WSAStartup,202h,wsad1
		     
	  invoke     socket,2,1,0
	  or	     eax,eax
	  jz	     nosock
	  mov	     ebx,eax
		     
	  invoke     gethostbyname,[pszserv]
	  test	     eax,eax
	  jz	     cantfinds
	  mov	     eax,[eax+0ch]
	  mov	     eax,[eax]
	  mov	     eax,[eax]
		     
	  mov	     dword [saddr.sin_addr],eax
		     
	  mov	     word  [saddr.sin_family],AF_INET
	  mov	     ax,25
	  xchg	     ah,al
	  mov	     word [saddr.sin_port],ax
		     
	  invoke     connect,ebx,saddr,sizeof.sockaddr_in
	  test	     eax,eax
	  jnz	     cantconnect
		     
	  call	     get_data
	  test	     eax,eax
	  jz	     errrecv
		     
	  mov	     eax,szEHLO
	  call	     sendNrecv
		     
	  mov	     eax,szAUTHLOGIN
	  call	     sendNrecv
		     
	  lea	     eax,[base64log]
	  stdcall    Send_String,eax
	  mov	     eax,szEnd+3
	  call	     sendNrecv
		     
	  lea	     eax,[base64pass]
	  stdcall    Send_String,eax
	  mov	     eax,szEnd+3
	  call	     sendNrecv
		     
	  stdcall    Send_String,szMAILFROM
	  stdcall    Send_String,[pszfrom]
	  mov	     eax,szSKOBKA
	  call	     sendNrecv
		     
	  stdcall    Send_String,szRCPTTO
	  stdcall    Send_String,[pszto]
	  mov	     eax,szSKOBKA
	  call	     sendNrecv
		     
	  stdcall    Send_String,szDATA
		     
	  stdcall    Send_String,szSubject
	  stdcall    Send_String,[pszsubj]
	  mov	     eax,szEnd+3
	  call	     sendNrecv
		     
	  stdcall    Send_String,[pszmess]
		     
	  mov	     eax,szEnd
	  call	     sendNrecv
		     
	  mov	     eax,szQuit
	  call	     sendNrecv
		     
	  invoke     MessageBox,0,all_ok_msg,all_ok_msg,0
		     
  closesock: 
	  invoke     closesocket,ebx
  nosock:    
	  invoke     WSACleanup
	  ret	     
		     
	  all_ok_msg	       db 'Message sent',0
	  cantconnects	       db 'Can''t connect to host',0
	  cantfind	       db 'Cant find server. Check Connection',0
  cantfinds: 
	  invoke     MessageBox,0,cantfind,0,0
	  jmp	     nosock
  cantconnect: 
	  invoke     MessageBox,0,cantconnects,0,0
	  jmp	     closesock
  errrecv:   
	  invoke     MessageBox,0,buf,0,0
	  jmp	     closesock
		     
  sendNrecv: 
	  stdcall    Send_String,eax
		     
	  call	     get_data
	  test	     eax,eax
	  pop	     ecx
	  jz	     errrecv
	  jmp	     ecx
  endp	  
		     
;--------------------------------------------------------------------------------;
; [Base64Encode]
;--------------------------------------------------------------------------------;

  proc Base64Encode lpSrc,lpDst,dwstrlen
	  push	     esi edi edx ebx
		     
	  mov	     esi,[lpSrc]
	  mov	     edi,[lpDst]
	  mov	     ebx,dword [dwstrlen]
	  call	     b64.encode
		     
	  pop	     ebx edx edi esi
	  ret	     
  endp	  
		     
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; base64 encoder without dictionary by RT Fishel
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		     
  b64:	     
    .newline:  
	  call	     b64.store_crlf
		     
    .encode:							; ebp = length, esi -> src buffer, edi -> dst buffer
	  push	     (76 shr 2) + 1
	  pop	     edx
		     
    .outer:    
	  dec	     edx
	  je	     b64.newline
	  lodsd      
	  dec	     esi
	  inc	     ebx
	  bswap      eax
	  mov	     ecx,4
		     
    .inner:    
	  rol	     eax,6
	  and	     al,3Fh
	  cmp	     al,3Eh
	  jb	     b64.testchar
	  shl	     al,2
	  sub	     al,((3Eh shl 2)+'A'-'+') and 0FFh
		     
    .testchar: 
	  sub	     al,4
	  cmp	     al,'0'
	  jnl	     b64.store
	  add	     al,'A'+4
	  cmp	     al,'Z'
	  jbe	     b64.store
	  add	     al,'a'-'Z'-1
		     
    .store:    
	  stosb      
	  dec	     ebx
	  loopne     b64.inner
	  jne	     b64.outer
	  mov	     al,'='
	  rep	     stosb
	  xor	     al,al
	  stosb      
	  ret	     
		     
    .store_crlf: 
	  mov	     ax,0a0dh
	  stosw      
		     
	  ret	     
		     
section '.idata' import data readable writeable
		     
  library kernel32,'KERNEL32.DLL',\
	  user32,'USER32.DLL',\ 
	  comctl32,'comctl32.dll',\ 
	  wsock32,'wsock32.dll' 
		     
  include '%fasminc%\apia\kernel32.inc'
  include '%fasminc%\apia\user32.inc'
  include '%fasminc%\apia\comctl32.inc'
  include '%fasminc%\apia\wsock32.inc'

section '.rsrc' resource from 'res.RES' data readable
