format pe console 4.0
entry start
include '../jieLib.inc'
section '.idata' import data readable writeable
	library kernel32,'KERNEL32.DLL',\
	wsock32,'WSOCK32.DLL',\
	shell32,'shell32.dll',\
	user32,'USER32.DLL'
import shell32,\
	StrStr,'StrStrA'

	include 'api\kernel32.inc'
	include 'api\USER32.inc'
	include 'api\wsock32.inc'
;
	.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
wSocketVersion dd 0x0101
dwArr dd 12 dup(0);必须初始化0
sFile rb 256
;
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
proc _Base64Encode 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[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[base64_alphabet+ecx]
			and ebx,3Fh
			mov ch ,BYTE[base64_alphabet+edx]
			movzx eax,BYTE[base64_alphabet+eax]
			shl ecx,16
			mov ah,BYTE[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[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[base64_alphabet+ecx]
		and ebx,3Fh
		mov ch ,BYTE[base64_alphabet+edx]
		movzx eax,BYTE[base64_alphabet+eax]
		shl ecx,16
		mov ah,BYTE[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[esi]
		mov ebx,ecx
		mov edx,ecx
		shr ecx,2
		movzx ecx,BYTE[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[esi]
		shr ecx,2
		movzx ecx,BYTE[base64_alphabet+ecx]
		movzx eax,BYTE[esi+1]
		shr eax,4
		movzx ebx,BYTE[esi]
		shl ebx,4
		or ebx,eax
		and ebx,03fh
		movzx ebx,BYTE[base64_alphabet+ebx]
		movzx eax,BYTE[esi+1]
		shl eax,2
		and eax,03fh
		movzx eax,BYTE[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
endp

;**************************************************************************************************
;进行base64解码的函数
;参数:_lpsSrc 指向输入缓冲区  _lpsDst 指向输出缓冲区  _dwSrcLen 想要加密的长度
;返回值:成功返回0  失败返回 -1
;作者:zklhp  Email:zklhp@sina.com
;时间:2008.8.16
;版权所有	转载请保持完整
;**************************************************************************************************
proc _Base64Decode 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[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[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[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[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

endp
;
proc _SendProc uses ebx edi esi,sSmtpAddr,sUserName,sPassWord,sFromMail,sToMail,txtSubject,txtContent
	INVALID_SOCKET equ NOT 0
	SOCKET_ERROR equ -1
	LEN_BUF EQU 2048
	local	@hSocket:DWORD
	local	@stWsadata:WSADATA
	local	@stSin:sockaddr_in
	local	@sRcvBuffer[2048]:BYTE
	local	@sSend[4096]:BYTE
	local	@sBuffer[2048]:BYTE
	local	@sLog[999]:BYTE
	;
	invoke	RtlZeroMemory,addr @sLog,999 ;sizeof.@sLog
	invoke	WSAStartup,202h,addr @stWsadata
	invoke	socket,AF_INET,SOCK_STREAM,0
	.if	eax = INVALID_SOCKET
		invoke	WSAGetLastError
		invoke	wsprintf,addr @sBuffer,<'创建套接字出错 错误码 %x',0dh,0ah>,eax
		invoke lstrcat,addr @sLog,addr @sBuffer
		jmp	@exit
	.endif
	mov	[@hSocket],eax

	invoke	RtlZeroMemory,addr @stSin,sizeof.sockaddr_in
	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_addr_list]
		mov	eax,[eax]
		mov	eax,[eax]
		mov	[@stSin.sin_addr],eax
	.endif
	;建立连接
	invoke	connect,[@hSocket],addr @stSin,	sizeof.sockaddr_in
	.if	eax = SOCKET_ERROR
		invoke	WSAGetLastError
		invoke	wsprintf,addr @sBuffer,<'连接服务器出错 错误码 %x',0dh,0ah>,eax
		invoke lstrcat,addr @sLog,addr @sBuffer
		jmp	@exit
	.endif

	invoke	RtlZeroMemory,addr @sRcvBuffer,LEN_BUF
	invoke	recv,[@hSocket],addr @sRcvBuffer,LEN_BUF,0
	;发送"ehlo local"
	invoke	lstrlen,addr sEhlo
	invoke	send,[@hSocket],addr sEhlo,eax,0
	invoke	RtlZeroMemory,addr @sRcvBuffer,LEN_BUF
	invoke	recv,[@hSocket],addr @sRcvBuffer,LEN_BUF,0
	;发送"auth login"
	;好象大多数免费邮箱都支持login验证方式 支持cram-md5的却没找到~~~  这里只用login吧
	invoke	lstrlen,addr sAuth
	invoke	send,[@hSocket],addr sAuth,eax,0
	invoke	RtlZeroMemory,addr @sRcvBuffer,LEN_BUF
	invoke	recv,[@hSocket],addr @sRcvBuffer,LEN_BUF,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,LEN_BUF
	stdcall	_Base64Decode,esi,addr @sBuffer,edi
	invoke	wsprintf,addr @sRcvBuffer,<'334 %s',0dh,0ah>,addr @sBuffer	;我们自己把他解码还原
	;发送用户名
	invoke	lstrlen,[sUserName]
	stdcall	_Base64Encode,[sUserName],addr @sBuffer,eax
	invoke	wsprintf,addr @sSend,<'%s',0dh,0ah>,addr @sBuffer
	invoke	lstrlen,addr @sSend
	invoke	send,[@hSocket],addr @sSend,eax,0
	invoke	RtlZeroMemory,addr @sRcvBuffer,LEN_BUF
	invoke	recv,[@hSocket],addr @sRcvBuffer,LEN_BUF,0
	lea	esi,[@sRcvBuffer]
	add	esi,4
	invoke	lstrlen,esi
	mov	edi,eax
	dec	edi
	dec	edi	;貌似这样比 sub edi,2 省个字节 呵呵
	invoke	RtlZeroMemory,addr @sBuffer,LEN_BUF
	stdcall	_Base64Decode,esi,addr @sBuffer,edi
	invoke	wsprintf,addr @sRcvBuffer,<'334 %s',0dh,0ah>,addr @sBuffer	;我们自己把他解码还原
	;发送密码
	invoke	lstrlen,[sPassWord]
	stdcall	_Base64Encode,[sPassWord],addr @sBuffer,eax
	invoke	wsprintf,addr @sSend,<'%s',0dh,0ah>,addr @sBuffer
	invoke	lstrlen,addr @sSend
	invoke	send,[@hSocket],addr @sSend,eax,0
	invoke	RtlZeroMemory,addr @sRcvBuffer,LEN_BUF
	invoke	recv,[@hSocket],addr @sRcvBuffer,LEN_BUF,0
	invoke	StrStr,addr @sRcvBuffer,'235'
	.if	eax = 0	;没有就是验证不通过
		invoke lstrcat,addr @sLog,<'验证失败',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,LEN_BUF
	invoke	recv,[@hSocket],addr @sRcvBuffer,LEN_BUF,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,LEN_BUF
	invoke	recv,[@hSocket],addr @sRcvBuffer,LEN_BUF,0
	;发送"data"
	invoke	lstrlen,addr sData
	invoke	send,[@hSocket],addr sData,eax,0
	invoke	RtlZeroMemory,addr @sRcvBuffer,LEN_BUF
	invoke	recv,[@hSocket],addr @sRcvBuffer,LEN_BUF,0
	;发送"from"
	invoke	wsprintf,addr @sSend,addr sFrom,[sFromMail]
	invoke	lstrlen,addr @sSend
	invoke	send,[@hSocket],addr @sSend,eax,0
	invoke	RtlZeroMemory,addr @sRcvBuffer,LEN_BUF
	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,LEN_BUF*2
	invoke	RtlZeroMemory,addr @sBuffer,LEN_BUF
	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,LEN_BUF*2
	invoke	RtlZeroMemory,addr @sBuffer,LEN_BUF
	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,LEN_BUF
	invoke	recv,[@hSocket],addr @sRcvBuffer,LEN_BUF,0
	;发送"quit"
	invoke	lstrlen,addr sQuit
	invoke	send,[@hSocket],addr sQuit,eax,0
	;断开连接
	invoke	closesocket,[@hSocket]
@exit:
	.if byte[@sLog]=0
		invoke lstrcat,addr @sLog,[sToMail]
		invoke lstrcat,addr @sLog,<13,10,0>
		stdcall getAppDirJie,sFile
		stdcall strcatJie,sFile,'1.Log'
		stdcall appendFileJie,sFile,addr @sLog
	.endif
	invoke	WSACleanup
	xor	eax,eax
	ret
endp
;
start:
	invoke GetCommandLine   ;取命令行
	stdcall splitJie,dwArr,eax,('`')

;push eax
;invoke wsprintf,sFile,"%s",[dwArr+4]
;invoke MessageBox,0,sFile,0,0
;pop eax
	.if eax>7
		stdcall _SendProc,[dwArr+4],[dwArr+8],[dwArr+12],[dwArr+8],[dwArr+20],[dwArr+24],[dwArr+28]
	.else
		invoke MessageBox,0,"SendMail.exe `sSmtpAddr`sUserName`sPassWord`sFromMail`sToMail`txtSubject`txtContent",0,0
	.endif
	invoke ExitProcess,eax
