trying to make a commandline emailer program (lazy mans telnet)
any suggesions on how to get the body of the email from the commandline if the text is spaced getcommandline wont work.. maybe write the text with blah~blah~blah then parse the ~'s or something... also wondering on how to recieve the smtps responses

the exe recievers email your email subject
| | | |
USES: c:\ExSendMail.exe[imgmail][/imgmail][imgmail][/imgmail] Reminder
.model flat,stdcall
option casemap:none
include \masm32\include\
include \masm32\include\
includelib \masm32\lib\wsock32.lib
include \masm32\include\
includelib \masm32\lib\user32.lib
include \masm32\include\
includelib \masm32\lib\kernel32.lib
include \masm32\include\
includelib \masm32\lib\masm32.lib


from db "mail from: %s",13,10,0 ;tell it your address
send_to db "rcpt to: %s",13,10,0 ; whom you wanna send to
data1 db "data",13,10,0 ;rfc email command to say your sending data
subject db "subject: %s",13,10,13,10,0 ; the subject "free pr0n!!"
data db "i luv you",13,10,".",13,10,0 ;the body of the email
quit db "quit",13,10,0 ;obvious :D
hostname db "",0 ;the address of the smtp
hello db "helo illwill-mail",0dh,0ah ; say hi
szDone db "Your mail was sent.",0
Port dd 25 ; smtp port = always 25
wsadata WSADATA <>
sin sockaddr_in <>
commandL dd 0

frombuffer db 256 dup(?)
sendtobuffer db 256 dup(?)
subjectbuffer db 256 dup(?)
databuffer db 256 dup(?)
fromsend db 256 dup(?)
send_tosend db 256 dup(?)
subjectsend db 256 dup(?)
datasend db 256 dup(?)
gymsock dd ?

invoke GetCommandLine
mov commandL, eax

invoke GetCL, 1, addr frombuffer ; get your own email address
invoke wsprintf,addr fromsend,addr from,addr frombuffer
invoke StdOut, addr fromsend

invoke GetCL, 2, addr sendtobuffer ; get the bad guys email addy
invoke wsprintf,addr send_tosend,addr send_to,addr sendtobuffer
invoke StdOut, addr send_tosend

invoke GetCL, 3, addr subjectbuffer ; get the subject you wanna send
invoke wsprintf,addr subjectsend,addr subject,addr subjectbuffer
invoke StdOut, addr subjectsend
;----------- skip this for now----------------------------------------------------------------------------
;invoke GetCL, 4, addr databuffer ; get the body you wanna send
; invoke lstrcat,addr data,addr databuffer
;invoke StdOut, addr databuffer
;gotta start up some socks, i bet you used to wear striped socks up to your knee caps
invoke WSAStartup,101h,addr wsadata
je sockzerror ;error initializing winsock
invoke socket,AF_INET,SOCK_STREAM,0
mov gymsock,eax
invoke WSAAsyncSelect,gymsock,0,WM_SOCKET,FD_CLOSE+FD_READ
mov sin.sin_family,AF_INET
invoke htons,Port
mov sin.sin_port,ax
invoke gethostbyname,addr hostname ; this part here
cmp eax,0 ; it resolves smtp and
jz sockzerror ; If not reachable, try again.
mov eax,[eax+12]
mov eax,[eax]
mov eax,[eax]
mov sin.sin_addr,eax
invoke connect,gymsock,addr sin,sizeof sin
;================== send that shit , took out the error checking :D ===========================================
invoke send,gymsock,addr hello,sizeof hello,0
invoke send,gymsock,addr fromsend,sizeof fromsend,0
invoke send,gymsock,addr send_tosend,sizeof send_tosend,0
invoke send,gymsock,addr data1,sizeof data1,0
invoke send,gymsock,addr subjectsend,sizeof subjectsend,0
invoke send,gymsock,addr data,sizeof data,0
invoke send,gymsock,addr quit,sizeof quit,0
; peace out cub scout
invoke StdOut, addr szDone
invoke ExitProcess,0

;a little bit of sock error checking
invoke WSACleanup
invoke Sleep, 3000
jmp sockz
end start
Posted on 2003-10-03 17:46:51 by illwill
Can't you just enclose the body text in quotes?
Posted on 2003-10-03 20:37:30 by Will
hi illwill

one way to do it is to save every line from the body in text file and then, when reading the file you make the "\n" to "\r\n" and you send it
Posted on 2003-10-04 02:13:52 by matix
You can take the body parameter as file path pointing to a file where you have already saved the body.

As for recieving, you use the "recv" socket API, which takes the same parameters that "send" takes. You will note taht the SMTP server will respond at once you "connect" to it. For most cases, you willl only need to parse the first 3 characters of the response, which will represent the code that indicate wheather everything is fine.

Whenever you get a reply beginning with 2xx, it means the operationhas been done successfully. Replies beginning with 4xx and 5xx, indicate there is something wrong. And usually, replies beginning with 3xx represent a waiting state, as for the case when you issue a DATA command.

If this does not help, and you need more info, I suggest that you read RFC 821 and/or 2821.
Posted on 2003-10-04 12:52:58 by hosam_shahin
we meet again , :tongue:

If you are seriously considering to make this into a actual console application (not just purely commandline), you have to create a handle for console i/o, and then use the console APIs supplied to read/write from it. Since you are doing it in masm:


buffer BYTE BUFFER_SIZE dup(?),0,0 ;2 nulls
nBytesRead DWORD ?



;GetStdHandle prototype:
;GetStdHandle PROTO nStdHandle:DWORD
invoke GetStdHandle, STD_INPUT_HANDLE ; standard input handle
mov hInStdHandle, eax

;ReadConsole prototype:
;ReadConsole PROTO handle:DWORD, pBuffer:PTR BYTE, maxBytes:DWORD, pBytesRead:PTR DWORD, Reserved:DWORD

invoke ReadConsole, hInStdHandle, addr buffer, BUFFER_SIZE-2, addr nBytesRead, 0

;buffer now holds input

invoke ExitProcess, 0
end start

If you want to output something, you can use WriteConsole(), which also requires a seperate handle (output), basically the same thing:


message BYTE "drocon is teh s3x",0dh,0ah
message_size equ ($-message)

hOutStdHandle DWORD ?
nBytesWritten DWORD ?



invoke GetStdHandle, STD_OUTPUT_HANDLE
mov hOutStdHandle, eax

invoke WriteConsole, hOutStdHandle, addr message, message_size, addr nBytesWritten, 0

invoke ExitProcess,0

end start

But as for the SMTP replies, you better take a look at the RFCs, or just directly pipe the output.

damn i'm forgetting my masm syntax :P i almost typed 'buffer times 256 db 0'.

<3 nasm :grin:
Posted on 2003-10-04 22:17:54 by Drocon
I wrote a command line e-mailer as an error notifier for an VB application I wrote. I needed a low level error control that did not have to depend on much of the OS to work in order to function.

I simply translated commas into CR,LF pairs in the body portion of the commandline until there was no more commandline to process.

First part of parsing the commandline were for known fields for the e-mail, then the body was added at the end with commas for lines.

It was programmed as a regular window for to process messages, but did not call ShowWindow, so nothing was shown to the user.

Regards, P1 :cool:
Posted on 2003-10-06 10:47:31 by Pone