用汇编语言写ESMTP邮件发送程序.doc_第1页
用汇编语言写ESMTP邮件发送程序.doc_第2页
用汇编语言写ESMTP邮件发送程序.doc_第3页
用汇编语言写ESMTP邮件发送程序.doc_第4页
用汇编语言写ESMTP邮件发送程序.doc_第5页
已阅读5页,还剩10页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

用汇编语言写ESMTP邮件发送程序最近在CSDN论坛上看到许多人问着同一个问题如何编写带服务器验证的 ESMTP 邮件发送程序,回答的人还真不少:有建议用 MAPI 的、有建议使用别人的类库的其实我对此是颇不以为然的。ESMTP 的编写并不困难,关键是弄清楚了协议只要严格按照协议来进行,就一定能OK,反而编程的技巧在此倒是无足轻重的。换句话说,写这个程序是Easy job,没有必要用到 MAPI 等“庞然大物”啊。既然如此,让我们来使用 Win32ASM 编写一个自己的 ESMTP “引擎”,可以用在你的病毒或者木马上哦!:)我们先来看看 SMTP 的发送协议,在 rfc821(smtp) 和 rfc1521(mime) 里面写得非常清楚,读者请自行参考这两个文档。什么?看不懂英文?没关系,我给大家整理一下。ESMTP 的整个发送过程如下:Socket连接后,按 ESMTP 协议通讯(注意每条命令结尾符“回车换行.回车换行”结束):1、EHLO rn这条命令可以不要,但是按照标准的写法,还是加上好。Example: EHLO rn2、AUTH LOGINrn告诉服务器,要进行验证了。3、Base64_Usernamern发送经过 Base64 编码的用户名给服务器。4、Base64_Passwordrn发送经过 Base64 编码的密码给服务器。5、MAIL FROM:rn发送者的Email地址。Example: MAIL FROM: rn6、RCPT TO:rn目标Email地址。Example: RCPT TO: rn7、DATArn开始传送数据。8、发送数据rn.rn注意:SMTP协议只发送信息,至于如何区分CC、BCC、Subject、Body等不属于SMTP的范围,详情请查看RFC文档MAIL格式部分简单说一下MAIL格式:Sunject:rnrn,还有好多返回值为“250 *”表示正常,同时*里含有MessageID等信息(前面的命令都有相应的返回信息)9、QUITrnOver,走人上面的是 ESMTP 的协议,如果我们严格按照上面的协议,就可以写出 ESMTP 的发送程序了。大家看出来了吗?其实 ESMTP 与 SMTP 唯一不同的地方,就是在于第三步和第四步缺少了这两个步骤, ESMTP 就等于 SMTP 了。至于如何区分正文和附件,其实是在 DATArn 后,通过一个叫做“Boundary”的分隔字符串来分隔开来的,这个“Boundary”可以是任意的字符串,随你喜欢怎么取都行,但是必须注意的是,分隔的时候要按照“-Boundary”的格式,结束的时候要用“-Boundary-”。而附件的内容,是通过 Base64 编码,包含在 DATA 里面进行发送;如果有多个附件,就要进行循环,把每个附件的内容包含进去,直至结束。这样说会不会太抽象了?好吧,我举个例子:EHLO , 13, 10AUTH LOGIN, 13, 10lcother, 13, 10lcother_password, 13, 10MAIL FROM:, 13, 10RCPT TO:, 13, 10DATA, 13, 10From: 老罗, 13, 10,To: Somebody, 13, 10, Subject: 你好吗?, 13, 10, 0MIME-Version: 1.0, 13, 10, X-Mailer: LCMailer by LC, 13, 10, Content-type:multipart/mixed;Boundary=www.LuoC, 13, 10, 13, 10, -www.LuoC, 13, 10, Content-type:text/plain;Charset=GB2312, 13, 10, Content-Transfer-Encoding:8bit, 13, 10, 13, 10, 好久不见,最近过得好吗?(正文内容), 13, 10, 13, 10, 0, .if (有附件)-, 13, 10, .while (files to be sent)13, 10, 13, 10, -, 13, 10, Content-Type:application/octet-stream;Name=文件名, 0, Content-Disposition:attachment;FileName=文件名, 0, 13, 10, Content-Transfer-Encoding:Base64, 13, 10, 13, 10, 0, 经过 Base64 编码的文件内容, 13, 10, 0.endw.endif13, 10, --, 13, 10, ., 13, 10QUIT, 13, 10最后我再给出一个用 Win32ASM 写的 ESMTP 发送程序。值得注意的是,为了尽量简化程序,我没有处理服务器返回的消息,而且我在内存的动态分配上偷懒了,附件的发送有可能会出错。如果你有兴趣对它进行研究,请自行想办法解决吧。如果它倒了你的胃口,那我真的是实在抱歉!_(代码写得很糟糕,我没有时间去 debug 了,见谅!)- 主程序 -文件名: smtp.asm-;*;程序名称:演示ESmtp发送原理;作者:罗聪;日期:2002-11-2;出处:(老罗的缤纷天地);注意事项:如欲转载,请保持本程序的完整,并注明:;转载自“老罗的缤纷天地”();*.386.model flat, stdcalloption casemap:noneinclude masm32includewindows.incinclude masm32includekernel32.incinclude masm32includeuser32.incinclude masm32includecomdlg32.incinclude masm32includewsock32.incinclude masm32includemasm32.incincludelib masm32libkernel32.libincludelib masm32libuser32.libincludelib masm32libcomdlg32.libincludelib masm32libwsock32.libincludelib masm32libmasm32.libWndProcproto:DWORD, :DWORD, :DWORD, :DWORDBase64Encode proto:DWORD, :DWORD, :DWORD.constIDI_LC equ1IDC_BUTTON_SENDequ3000IDC_EDIT_SMTPSERVERequ3001IDC_EDIT_USERNAMEequ3002IDC_EDIT_PASSWORDequ3003IDC_EDIT_FROMequ3004IDC_EDIT_TOequ3005IDC_EDIT_SUBJECT equ3006IDC_EDIT_CONTENT equ3007IDC_EDIT_ATTACHMENTequ3008IDC_BUTTON_BROWSEequ3009MAXNUM equ2048MAXFILESIZEequ87380.dataszDlgNamedblc_dialog, 0szCaptiondbESmtp demo by LC, 2002-10-12, 0szErrNoDll db装载winsock.dll时出错!, 0szErrSocketdb建立socket时出错!, 0szErrConnect db进行连接时出错!, 0szErrAuthdb用户名/密码 验证失败!, 0szSuccessSenddb发送成功!, 0szHeloFmtdbEHLO %s, 13, 10, 0szAuth dbAUTH LOGIN, 13, 10, 0szUsernameFmtdb%s, 13, 10, 0szPasswordFmtdb%s, 13, 10, 0szHeaderFmtdbMAIL FROM:%s, 13, 10 dbRCPT TO:%s, 13, 10, 0szBody1Fmt dbDATA, 13, 10 dbFrom:%s, 13, 10 dbTo:%s, 13, 10 dbSubject:%s, 13, 10 dbMIME_Version:1.0, 13, 10 dbContent-type:multipart/mixed;Boundary=www.LuoC, 13, 10, 13, 10 db-www.LuoC, 13, 10 dbContent-type:text/plain;Charset=GB2312, 13, 10 dbContent-Transfer-Encoding:8bit, 13, 10, 13, 10 db%s, 13, 10, 13, 10, 0szBody2db-www.LuoC, 13, 10, 0szBody3dbContent-Type:application/octet-stream;Name=, 0szBody4db13, 10, 0szBody5dbContent-Disposition:attachment;FileName=, 0szBody6db13, 10, 0szBody7dbContent-Transfer-Encoding:Base64, 13, 10, 13, 10, 0szBody8db13, 10, 13, 10, 0szBodyEnddb-www.LuoC- db13, 10, . , 13, 10, 0szQuit dbQUIT, 13, 10, 0dwSize dd0ofnOPENFILENAMEszFilterString db所有文件, 0, *.*, 0, 0szMyTitledb请打开一个文件作为附件!, 0reply_valdd0wsadataWSADATAsinsockaddr_in;下面是为了方便调试,预设的各项参数:, 0sz2dblcother, 0sz3dblcother, 0, 0, 0sz6db最近如何?, 0sz7db你好吗?, 0;Base64 - ASCII mapping tablebase64_alphabetdbABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=.data?hInstancedd?hSocketdd?szSmtpServer db255 dup(?)szFileName db256 dup(?)szBuffer dbMAXNUMdup(?)szBuf1 dbMAXNUMdup(?)szBuf2 dbMAXNUMdup(?)szBuf3 dbMAXNUMdup(?)szHelo dbMAXNUMdup(?)szUsername dbMAXNUMdup(?)szPassword dbMAXNUMdup(?)szHeader dbMAXNUMdup(?)szContentdbMAXFILESIZE+ 2048 dup(?).codemain:invoke GetModuleHandle, NULLmov hInstance, eaxinvoke DialogBoxParam, hInstance, offset szDlgName, 0, WndProc, 0invoke ExitProcess, eaxWndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAMLOCAL hFile: HANDLELOCAL hMapFile: HANDLELOCAL dwFileSize: DWORDLOCAL pMemory: DWORDLOCAL pContent: DWORDLOCAL pFileContent: DWORD.if uMsg = WM_CLOSEinvoke EndDialog, hWnd, 0.elseifuMsg = WM_INITDIALOGinvoke LoadIcon, hInstance, IDI_LCinvoke SendMessage, hWnd, WM_SETICON, ICON_SMALL, eax;下面是为了方便调试,填入预设的各项参数:invoke SetDlgItemText, hWnd, IDC_EDIT_SMTPSERVER, addr sz1invoke SetDlgItemText, hWnd, IDC_EDIT_USERNAME, addr sz2invoke SetDlgItemText, hWnd, IDC_EDIT_PASSWORD, addr sz3invoke SetDlgItemText, hWnd, IDC_EDIT_FROM, addr sz4invoke SetDlgItemText, hWnd, IDC_EDIT_TO, addr sz5invoke SetDlgItemText, hWnd, IDC_EDIT_SUBJECT, addr sz6invoke SetDlgItemText, hWnd, IDC_EDIT_CONTENT, addr sz7.elseif uMsg = WM_COMMANDmov eax, wParammov edx, eaxshr edx, 16movzx eax, ax.if edx = BN_CLICKED.if eax = IDC_BUTTON_SEND;以下是初始化 winsock :invoke WSAStartup, 101h, addr wsadata.if eax != NULLinvoke MessageBox, hWnd, addr szErrNoDll, addr szCaption, MB_OK or MB_ICONHAND.elseinvoke socket, AF_INET, SOCK_STREAM, 0.if eax = INVALID_SOCKETinvoke MessageBox, hWnd, addr szErrSocket, addr szCaption, MB_OK or MB_ICONHAND.elsemov hSocket, eaxmov sin.sin_family, AF_INETinvoke htons, 25mov sin.sin_port, axinvoke GetDlgItemText, hWnd, IDC_EDIT_SMTPSERVER, addr szSmtpServer, 255invoke gethostbyname, addr szSmtpServermov eax, eax + 12mov eax, eaxmov eax, eaxmov sin.sin_addr, eaxinvoke connect, hSocket, addr sin, sizeof sin.if eax 0invoke MessageBox, hWnd, addr szErrConnect, addr szCaption, MB_OK or MB_ICONHAND.elseinvoke RtlZeroMemory, addr szBuffer, MAXNUMinvoke RtlZeroMemory, addr szBuf1, MAXNUMinvoke RtlZeroMemory, addr szBuf2, MAXNUMinvoke RtlZeroMemory, addr szBuf3, MAXNUM;发送 Helo :invoke wsprintf, addr szHelo, addr szHeloFmt, addr szSmtpServerinvoke lstrlen, addr szHeloinvoke send, hSocket, addr szHelo, eax, 0invoke RtlZeroMemory, addr szBuffer, MAXNUM;发送 Auth :invoke lstrlen, addr szAuthinvoke send, hSocket, addr szAuth, eax, 0;发送 username:invoke GetDlgItemText, hWnd, IDC_EDIT_USERNAME, addr szBuffer, 100invoke Base64Encode, addr szBuffer, addr szBuf1, eaxinvoke wsprintf, addr szUsername, addr szUsernameFmt, addr szBuf1invoke lstrlen, addr szUsernameinvoke send, hSocket, addr szUsername, eax, 0invoke RtlZeroMemory, addr szBuf1, MAXNUMinvoke RtlZeroMemory, addr szBuffer, MAXNUM;发送 password:invoke GetDlgItemText, hWnd, IDC_EDIT_PASSWORD, addr szBuffer, 100invoke Base64Encode, addr szBuffer, addr szBuf1, eaxinvoke wsprintf, addr szPassword, addr szPasswordFmt, addr szBuf1invoke lstrlen, addr szPasswordinvoke send, hSocket, addr szPassword, eax, 0invoke RtlZeroMemory, addr szBuf1, MAXNUMinvoke RtlZeroMemory, addr szBuffer, MAXNUM;获得服务器返回的消息:invoke recv, hSocket, addr szBuffer, MAXNUM, 0invoke RtlZeroMemory, addr szBuffer, MAXNUMinvoke recv, hSocket, addr szBuffer, MAXNUM, 0invoke RtlZeroMemory, addr szBuffer, MAXNUMinvoke recv, hSocket, addr szBuffer, MAXNUM, 0invoke RtlZeroMemory, addr szBuffer, MAXNUMinvoke recv, hSocket, addr szBuffer, MAXNUM, 0invoke RtlZeroMemory, addr szBuffer, MAXNUMinvoke recv, hSocket, addr szBuffer, MAXNUM, 0;得到返回消息的前三个数字:mov byte ptr szBuffer + 3, 0invoke atodw, addr szBuffermov reply_val, eaxinvoke RtlZeroMemory, addr szBuffer, MAXNUM;判断用户名/密码是否正确:.if reply_val != 235invoke MessageBox, hWnd, addr szErrAuth, addr szCaption, MB_OK or MB_ICONHAND.else;发送 Header :invoke GetDlgItemText, hWnd, IDC_EDIT_FROM, addr szBuf1, MAXNUMinvoke GetDlgItemText, hWnd, IDC_EDIT_TO, addr szBuf2, MAXNUMinvoke wsprintf, addr szHeader, addr szHeaderFmt, addr szBuf1, addr szBuf2invoke lstrlen, addr szHeaderinvoke send, hSocket, addr szHeader, eax, 0;准备好 Body1 的内容:invoke GetDlgItemText, hWnd, IDC_EDIT_SUBJECT, addr szBuf3, MAXNUMadd dwSize, eaxinvoke GetDlgItemText, hWnd, IDC_EDIT_CONTENT, addr szBuffer, MAXNUMadd dwSize, eax;分配内存:;(这里为了方便,只分配了 10000000 个字节,;其实应该根据实际需要进行动态分配,否则有可能会导致错误)invoke LocalAlloc, LPTR, 10000000mov pContent, eaxinvoke wsprintf, pContent, addr szBody1Fmt, addr szBuf1, addr szBuf2, addr szBuf3, addr szBufferinvoke RtlZeroMemory, addr szBuffer, MAXNUM;获取文件名:invoke GetDlgItemText, hWnd, IDC_EDIT_ATTACHMENT, addr szBuffer, MAXNUM.if eax != 0;打开文件:invoke CreateFile, addr szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULLmov hFile, eax.if hFile != INVALID_HANDLE_VALUE;获得文件长度:invoke GetFileSize, hFile, NULLmov dwFileSize, eax;建立内存映射文件:invoke CreateFileMapping, hFile, NULL, PAGE_READONLY, 0, 0, NULLmov hMapFile, eax;映射文件进内存:invoke MapViewOfFile, hMapFile, FILE_MAP_READ, 0, 0, 0mov pMemory, eax;分配内存:;(这里为了方便,只分配了 10000000 个字节,;其实应该根据实际需要进行动态分配,否则有可能导致错误)invoke LocalAlloc, LPTR, 10000000mov pFileContent, eax;进行Base64转换:invoke Base64Encode, pMemory, pFileContent, dwFileSize;准备好 Attachment 的内容:invoke lstrcat, pContent, addr szBody2invoke lstrcat, pContent, addr szBody3invoke lstrcat, pContent, addr szFileNameinvoke lstrcat, pContent, addr szBody4invoke lstrcat, pContent, addr szBody5invoke lstrcat, pContent, addr szFileNameinvoke lstrcat, pContent, addr szBody6invoke lstrcat, pContent, addr szBody7invoke lstrcat, pContent, pFileContentinvoke lstrcat, pContent, addr szBody8;释放内存:invoke LocalFree, pFileContent;解除文件映射:invoke UnmapViewOfFile, pMemory;关闭内存映射文件:invoke CloseHandle, hMapFile;关闭文件:invoke CloseHandle, hFile.endif.endif;连接 rn.rn 到 Content 中:invoke lstrcat, pContent, addr szBodyEnd;发送 Content :invoke lstrlen, pContentinvoke send, hSocket, pContent, eax, 0invoke LocalFree, p

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论