The MASM Forum

General => The Campus => Topic started by: vishwadt on March 16, 2014, 06:08:21 PM

Title: I'm trying to write a software that send emails with attachment using masm32
Post by: vishwadt on March 16, 2014, 06:08:21 PM
i couldn't find good resources from send emails in internet
Please help me
Title: Re: I'm trying to write a software that send emails with attachment using masm32
Post by: TouEnMasm on March 26, 2014, 06:43:39 PM

This one send email with one attachment file.
You have just to modify the parameters in text to reuse it.
http://masm32.com/board/index.php?topic=3034.msg31642#msg31642 (http://masm32.com/board/index.php?topic=3034.msg31642#msg31642)
Quote
CUNI (ssvr,"smtp.mail.com",0) ;mail server
CUNI (adrMailFrom,"foo@gmail.com",0) ;adress mail of the server
CUNI (adrMailTo,"foo@gmail.com",0) ;recept adress mail 
CUNI (ssbj,"Example CDO Message",0) ;subject of the mail
CUNI (snote,"This is some sample message text.",0) ;Message
CUNI (sfile,"c:\temp\test.txt",0) ;Name of the file to attach to the mail
CUNI (suser,"foo@gmail.com",0) ;--- for test ,adress mail of the server  -----------
CUNI (spass,"foo",0) ;password for the adress mail of the mail server
You need also the port number for the mail server

Title: Re: I'm trying to write a software that send emails with attachment using masm32
Post by: haoren108 on June 16, 2014, 12:25:49 PM
include masm32rt.inc
include wsock32.inc
includelib wsock32.lib
include shlwapi.inc ;StrStr
includelib shlwapi.lib
   .data
sEhlo db 'EHLO Local',13,10,0
sAuth db 'AUTH LOGIN',13,10,0
sMailFrom db 'MAIL FROM:<%s>',13,10,0
sRcptTo db 'RCPT TO:<%s>',13,10,0
sData db 'DATA',13,10,0
sFrom db 'From:%s',13,10,0
sTo db 'TO:%s',13,10,0
sSubject db 'SUBJECT:%s',13,10,0
sReplyTo db 'Reply-TO:%s',13,10,0
sCrLf db 13,10,0
sContent db '%s',13,10,0
sDot db '.',13,10,0
sQuit db 'QUIT',13,10,0

MAX_PARAM_NUM equ 99        ;允许命令行参数个数
dwArr dword MAX_PARAM_NUM+1 dup(0);存放各命令行参数首地址
;
base64_alphabet db "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",0

base64table db 43 dup (255)
db 62,255,255,255,63,52,53,54,55,56,57,58,59,60,61,255
db 255,255,0,255,255,255,0,1,2,3,4,5,6,7,8,9,10,11,12,13
db 14,15,16,17,18,19,20,21,22,23,24,25,255,255,255,255
db 255,255,26,27,28,29,30,31,32,33,34,35,36,37,38
db 39,40,41,42,43,44,45,46,47,48,49,50,51
db 132 dup (255)

;**************************************************************************************************
;进行base64编码的函数
;参数:_lpsInput 指向输入缓冲区  _lpsOtput 指向输出缓冲区  _dwInputLen 想要加密的长度
;返回值:成功返回0  失败返回 -1
;作者:zklhp  Email:zklhp@sina.com
;时间:2008.8.9
;版权所有   转载请保持完整
;**************************************************************************************************
.CODE
_Base64Encode proc uses ebx esi edi _lpsInput:DWORD,_lpsOtput:DWORD,_dwInputLen:DWORD

;错误处理
   .if (_lpsInput==NULL)||(_lpsOtput==NULL)||(_dwInputLen==0)
      xor eax,eax
      dec eax
      ret
   .endif

   mov eax,_dwInputLen
   xor edx,edx
   mov ecx,3
   div ecx
   push eax

   .if eax > 0
      dec eax
      .if eax > 0
         push eax

         push ebp
         mov esi,_lpsInput
         mov edi,_lpsOtput
         mov ebp,eax
         lea edi,[edi+ebp*4]
         neg ebp

         align 4
      @@:

         mov ebx,DWORD ptr [esi]
         bswap ebx
         mov ecx,ebx
         mov edx,ebx
         mov eax,ebx
         shr ecx,14
         shr edx,8
         shr eax,26
         and ecx,3Fh
         shr ebx,20
         and edx,3Fh
         and eax,3Fh
         movzx ecx, BYTE PTR [base64_alphabet+ecx]
         and ebx,3Fh
         mov ch , BYTE PTR [base64_alphabet+edx]
         movzx eax, BYTE PTR [base64_alphabet+eax]
         shl ecx,16
         mov ah,BYTE PTR [base64_alphabet+ebx]

         add esi,3
         or ecx,eax
         mov [edi+ebp*4],ecx

         add ebp,1
         jnz @B
         pop ebp

         pop eax
         mov ecx,eax
         mov ebx,3
         mul ebx
         add _lpsInput,eax
         shl ecx,2
         add _lpsOtput,ecx
      .endif

      mov esi,_lpsInput
      mov edi,_lpsOtput
      mov ebx,DWORD ptr [esi]
      bswap ebx
      mov ecx,ebx
      mov edx,ebx
      mov eax,ebx
      shr ecx,14
      shr edx,8
      shr eax,26
      and ecx,3Fh
      shr ebx,20
      and edx,3Fh
      and eax,3Fh
      movzx ecx, BYTE PTR [base64_alphabet+ecx]
      and ebx,3Fh
      mov ch , BYTE PTR [base64_alphabet+edx]
      movzx eax, BYTE PTR [base64_alphabet+eax]
      shl ecx,16
      mov ah,BYTE PTR [base64_alphabet+ebx]
      or ecx,eax
      mov [edi],ecx
      add _lpsInput,3
      add _lpsOtput,4
   .endif
   pop eax
   mov ecx,3
   mul ecx
   neg eax
   add eax,_dwInputLen
   ;int 3h
   .if eax == 1
      mov esi,_lpsInput
      mov edi,_lpsOtput
      movzx ecx,BYTE ptr [esi]
      mov ebx,ecx
      mov edx,ecx
      shr ecx,2
      movzx ecx,BYTE ptr [base64_alphabet+ecx]
      shl edx,4
      and edx,03fh
      movzx edx,[base64_alphabet+edx]
      shl edx,8
      or ecx,edx
      xor ebx,ebx
      mov bl,'='
      mov bh,'='
      shl ebx,16
      or ecx,ebx
      mov [edi],ecx
   .elseif eax == 2
      push eax
      mov esi,_lpsInput
      mov edi,_lpsOtput
      movzx ecx,BYTE ptr [esi]
      shr ecx,2
      movzx ecx,BYTE ptr [base64_alphabet+ecx]
      movzx eax,BYTE ptr [esi+1]
      shr eax,4
      movzx ebx,BYTE ptr [esi]
      shl ebx,4
      or ebx,eax
      and ebx,03fh
      movzx ebx,BYTE ptr [base64_alphabet+ebx]
      movzx eax,BYTE ptr [esi+1]
      shl eax,2
      and eax,03fh
      movzx eax,BYTE ptr [base64_alphabet+eax]
      xor edx,edx
      mov dh,'='
      shl edx,16
      or ecx,edx
      shl ebx,8
      or ecx,ebx
      shl eax,16
      or ecx,eax
      mov [edi],ecx
      pop eax
   .endif

   xor eax,eax
   ret
_Base64Encode endp

;**************************************************************************************************
;进行base64解码的函数
;参数:_lpsSrc 指向输入缓冲区  _lpsDst 指向输出缓冲区  _dwSrcLen 想要加密的长度
;返回值:成功返回0  失败返回 -1
;作者:zklhp  Email:zklhp@sina.com
;时间:2008.8.16
;版权所有   转载请保持完整
;**************************************************************************************************
_Base64Decode proc uses ebx edi esi _lpsSrc:DWORD,_lpsDst:DWORD,_dwSrcLen:DWORD

;错误处理
   .if (_lpsSrc==NULL)||(_lpsDst==NULL)||(_dwSrcLen==0)
      xor eax,eax
      dec eax
      ret
   .endif
   mov eax,_dwSrcLen
   and eax,11b
   .if eax != 0
      xor eax,eax
      dec eax
      ret
   .endif

   mov esi,_lpsSrc
   mov edi,_lpsDst
   mov ecx,_dwSrcLen
   shr ecx, 2
   cld

@@loop:
   xor ebx,ebx
   lodsd
   mov edx,eax

   and eax,0ffh
   mov al, BYTE ptr [offset base64table + eax]
   .if al == 255
      xor eax,eax
      dec eax
      ret
   .endif
   shl ebx,6
   or bl,al
   shr edx,8

   mov eax,edx
   and eax,0ffh
   mov al, BYTE ptr [offset base64table + eax]
   .if al == 255
      xor eax,eax
      dec eax
      ret
   .endif
   shl ebx,6
   or bl,al
   shr edx,8

   mov eax,edx
   and eax,0ffh
   mov al, BYTE ptr [offset base64table + eax]
   .if al == 255
      xor eax,eax
      dec eax
      ret
   .endif
   shl ebx,6
   or bl,al
   shr edx,8

   mov eax,edx
   and eax,0ffh
   mov al, BYTE ptr [offset base64table + eax]
   .if al == 255
      xor eax,eax
      dec eax
      ret
   .endif
   shl ebx,6
   or bl,al
   shr edx,8

   mov eax,ebx
   shl eax,8
   bswap eax
   stosd
   dec edi
   dec ecx
   jnz @@loop
   xor eax,eax
   ret

_Base64Decode endp
;
Save2File proc pFile:DWORD,pTxt:DWORD
   local hFile:DWORD
   local dwTemp:DWORD
   invoke CreateFile,pFile,GENERIC_ALL,NULL,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL
   mov hFile,eax
   invoke lstrlen,pTxt
   mov ecx,eax
   invoke WriteFile,hFile,pTxt,ecx,addr dwTemp,NULL
   invoke CloseHandle,hFile
   ret
Save2File endp
;
_SendProc   proc uses ebx edi esi sSmtpAddr,sUserName,sPassWord,sFromMail,sToMail,txtSubject,txtContent
   local   @hSocket:DWORD
   local   @stWsadata:WSADATA
   local   @stSin:sockaddr_in
   local   @sRcvBuffer[1024]:BYTE
   local   @sSend[4096]:BYTE
   local   @sBuffer[2048]:BYTE
   local @sLog[999]:byte
   ;
   invoke   RtlZeroMemory,addr @sLog,sizeof @sLog
   invoke   WSAStartup, 202h, addr @stWsadata
   invoke   socket, AF_INET, SOCK_STREAM, 0
   .if   eax == INVALID_SOCKET
      invoke   WSAGetLastError
      invoke   wsprintf,addr @sBuffer,CTXT('创建套接字出错 错误码 %x',0dh,0ah),eax
      invoke lstrcat,addr @sLog,addr @sBuffer
      jmp   @exit
   .endif
   mov   @hSocket, eax

   invoke   RtlZeroMemory,addr @stSin,sizeof @stSin
   mov   @stSin.sin_family, AF_INET
   invoke   htons,25   ;默认端口是25
   mov   @stSin.sin_port, ax
   invoke   gethostbyname,sSmtpAddr
   .if   eax
      mov   eax, [eax + hostent.h_list]
      mov   eax, [eax]
      mov   eax, [eax]
      mov   @stSin.sin_addr, eax
   .endif
   ;建立连接
   invoke   connect,@hSocket, addr @stSin, sizeof @stSin
   .if   eax == SOCKET_ERROR
      invoke   WSAGetLastError
      invoke   wsprintf,@sBuffer,CTXT('连接服务器出错 错误码 %x',0dh,0ah),eax
      invoke lstrcat,addr @sLog,addr @sBuffer
      jmp   @exit
   .endif

   invoke   RtlZeroMemory,addr @sRcvBuffer,sizeof @sRcvBuffer
   invoke   recv, @hSocket, addr @sRcvBuffer,sizeof @sRcvBuffer,0
   ;发送"ehlo local"
   invoke   lstrlen,offset sEhlo
   invoke   send, @hSocket, addr sEhlo, eax, 0
   invoke   RtlZeroMemory,addr @sRcvBuffer,sizeof @sRcvBuffer
   invoke   recv, @hSocket, addr @sRcvBuffer,sizeof @sRcvBuffer,0
   ;发送"auth login"
   ;好象大多数免费邮箱都支持login验证方式 支持cram-md5的却没找到~~~  这里只用login吧
   invoke   lstrlen,addr sAuth
   invoke   send, @hSocket, addr sAuth, eax, 0
   invoke   RtlZeroMemory,addr @sRcvBuffer,sizeof @sRcvBuffer
   invoke   recv, @hSocket, addr @sRcvBuffer,sizeof @sRcvBuffer,0
   lea   esi,@sRcvBuffer
   add   esi,4
   invoke   lstrlen,esi
   mov   edi,eax
   ;要把最后的\r\t除去
   dec   edi
   dec   edi
   ;貌似这样比 sub edi,2 省个字节 呵呵
   invoke   RtlZeroMemory,addr @sBuffer,sizeof @sBuffer
   invoke   _Base64Decode,esi,addr @sBuffer,edi
   invoke   wsprintf,addr @sRcvBuffer,CTXT('334 %s',0dh,0ah),addr @sBuffer   ;我们自己把他解码还原
   ;发送用户名
   invoke   lstrlen,sUserName
   invoke   _Base64Encode,sUserName,addr @sBuffer,eax
   invoke   wsprintf,addr @sSend,CTXT('%s',0dh,0ah),addr @sBuffer
   invoke   lstrlen,addr @sSend
   invoke   send, @hSocket, addr @sSend, eax, 0
   invoke   RtlZeroMemory,addr @sRcvBuffer,sizeof @sRcvBuffer
   invoke   recv, @hSocket, addr @sRcvBuffer,sizeof @sRcvBuffer,0
   lea   esi,@sRcvBuffer
   add   esi,4
   invoke   lstrlen,esi
   mov   edi,eax
   dec   edi
   dec   edi   ;貌似这样比 sub edi,2 省个字节 呵呵
   invoke   RtlZeroMemory,addr @sBuffer,sizeof @sBuffer
   invoke   _Base64Decode,esi,addr @sBuffer,edi
   invoke   wsprintf,addr @sRcvBuffer,CTXT('334 %s',0dh,0ah),addr @sBuffer   ;我们自己把他解码还原
   ;发送密码
   invoke   lstrlen,sPassWord
   invoke   _Base64Encode,sPassWord,addr @sBuffer,eax
   invoke   wsprintf,addr @sSend,CTXT('%s',0dh,0ah),addr @sBuffer
   invoke   lstrlen,addr @sSend
   invoke   send, @hSocket, addr @sSend, eax, 0
   invoke   RtlZeroMemory,addr @sRcvBuffer,sizeof @sRcvBuffer
   invoke   recv, @hSocket, addr @sRcvBuffer,sizeof @sRcvBuffer,0
   invoke   StrStr,addr @sRcvBuffer,CTXT('235')
   .if   eax == 0   ;没有就是验证不通过
      invoke lstrcat,addr @sLog,CTXT('验证失败',0dh,0ah)
      invoke   WSACleanup
      xor   eax,eax
      dec   eax
      jmp   @exit
   .endif
   ;发送"mail from"
   invoke   wsprintf,addr @sSend,addr sMailFrom,sFromMail
   invoke   lstrlen,addr @sSend
   invoke   send, @hSocket, addr @sSend,eax, 0
   invoke   RtlZeroMemory,addr @sRcvBuffer,sizeof @sRcvBuffer
   invoke   recv, @hSocket, addr @sRcvBuffer,sizeof @sRcvBuffer,0
   ;发送"rcpt to"
   invoke   wsprintf,addr @sSend,addr sRcptTo,sToMail
   invoke   lstrlen,addr @sSend
   invoke   send, @hSocket, addr @sSend,eax, 0
   invoke   RtlZeroMemory,addr @sRcvBuffer,sizeof @sRcvBuffer
   invoke   recv, @hSocket, addr @sRcvBuffer,sizeof @sRcvBuffer,0
   ;发送"data"
   invoke   lstrlen,addr sData
   invoke   send, @hSocket, addr sData, eax, 0
   invoke   RtlZeroMemory,addr @sRcvBuffer,sizeof @sRcvBuffer
   invoke   recv, @hSocket, addr @sRcvBuffer,sizeof @sRcvBuffer,0
   ;发送"from"
   invoke   wsprintf,addr @sSend,addr sFrom,sFromMail
   invoke   lstrlen,addr @sSend
   invoke   send, @hSocket, addr @sSend,eax, 0
   invoke   RtlZeroMemory,addr @sRcvBuffer,sizeof @sRcvBuffer
   invoke   Sleep,1000

   ;发送"to"
   invoke   wsprintf,addr @sSend,addr sTo,sToMail
   invoke   lstrlen,addr @sSend
   invoke   send, @hSocket, addr @sSend,eax, 0
   ;发送主题
   invoke   wsprintf,addr @sSend,addr sSubject,txtSubject
   invoke   lstrlen,addr @sSend
   invoke   send, @hSocket, addr @sSend,eax, 0
   ;发送"Reply-TO"
   invoke   RtlZeroMemory,addr @sSend,sizeof @sSend
   invoke   RtlZeroMemory,addr @sBuffer,sizeof @sBuffer
   invoke   wsprintf,addr @sSend,addr sReplyTo,sFromMail
   invoke   lstrlen,addr @sSend
   invoke   send, @hSocket, addr @sSend,eax, 0
   ;发送空行
   invoke   lstrlen,addr sCrLf
   invoke   send, @hSocket, addr sCrLf,eax, 0
   ;发送邮件正文
   invoke   RtlZeroMemory,addr @sSend,sizeof @sSend
   invoke   RtlZeroMemory,addr @sBuffer,sizeof @sBuffer
   invoke   wsprintf,addr @sSend,addr sContent,txtContent
   invoke   lstrlen,addr @sSend
   invoke   send, @hSocket, addr @sSend,eax, 0

   ;发送"."
   invoke   lstrlen,addr sDot
   invoke   send, @hSocket, addr sDot, eax, 0
   invoke   RtlZeroMemory,addr @sRcvBuffer,sizeof @sRcvBuffer
   invoke   recv, @hSocket, addr @sRcvBuffer,sizeof @sRcvBuffer,0
   ;发送"quit"
   invoke   lstrlen,addr sQuit
   invoke   send, @hSocket, addr sQuit, eax, 0
   ;断开连接
   invoke   closesocket, @hSocket
@exit:
   .if byte ptr @sLog[1]
      invoke lstrcat,addr @sLog,sToMail
      invoke lstrcat,addr @sLog,CTXT(13,10,0)
      ;invoke MessageBox,0,addr @sLog,0,0
      invoke Save2File,CTXT("Log.txt"),addr @sLog
   .endif
   invoke   WSACleanup
   xor   eax,eax
   ret
_SendProc endp
;

;///////////////
; 功能:取命令行并分析出参数
; 输入:pSrc:源字符串的内存空间首址
;       pArr:存放命令行参数首地址的内存空间首址
; 输出:无
;invoke Split,addr dwArr,addr sSrc,'`'
;mov edi,addr dwArr
;.while (byte ptr[edi]!= 0)
;   add edi,4
;.endw
;///////////////
Split proc pArr: dword,pSrc: LPSTR,cFind:byte
   local dwFlag: dword
   local dwParamCount: dword
   ;
   movzx ebx,cFind
   mov eax,pSrc
   mov esi,eax
   mov edi,pArr
   mov dword ptr [edi],eax    ;save param 0
   add edi,4
   mov dwFlag,1
   mov dwParamCount,1
@SplitNext:
   inc esi
   movzx eax,byte ptr [esi]
   cmp eax,0
   je  @SplitRet
   cmp eax,ebx         ;skip cFind
   jne @F
   cmp dwFlag,0
   je  @SplitNext
   jne @SplitEnd
@@:
   cmp eax,9           ;skip Tab
   jne @F
   cmp dwFlag,0
   jne @SplitEnd
   je  @SplitNext
@@:
   cmp dwFlag,0
   jne @SplitNext
@SplitSave:
   inc dwParamCount
   cmp dwParamCount,MAX_PARAM_NUM
   jg  @SplitRet
   mov dwFlag,eax
   mov dword ptr [edi],esi
   add edi,4
   jmp @SplitNext
@SplitEnd:
   mov dwFlag,0
   mov byte ptr [esi],0
   jmp @SplitNext
@SplitRet:
   mov eax,dwParamCount
   ret
Split  endp
;
start:
   invoke GetCommandLine   ;取命令行
   invoke Split,addr dwArr,eax,'`'
   .if (eax>7)
      mov edi,offset dwArr
      invoke _SendProc,[edi+4],[edi+8],[edi+12],\
         [edi+16],[edi+20],[edi+24],[edi+28]
   .else
      invoke MessageBox,0,CTXT("SendMail.exe `sSmtpAddr`sUserName`sPassWord`sFromMail`sToMail`txtSubject`txtContent"),0,0
   .endif
   invoke ExitProcess,eax
end start
Title: Re: I'm trying to write a software that send emails with attachment using masm32
Post by: jj2007 on June 16, 2014, 03:18:43 PM
Nice to see "true" Unicode in a source. Which IDE are you using?